mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-30 03:15:32 +00:00
Combat AI: use WhenUsed enchantments
This commit is contained in:
parent
604f9ee323
commit
cf7a6232d0
3 changed files with 51 additions and 5 deletions
|
@ -71,6 +71,8 @@ namespace MWMechanics
|
|||
{
|
||||
const ESM::Enchantment* enchantment = MWBase::Environment::get().getWorld()->getStore().get<ESM::Enchantment>().find(mItem->getClass().getEnchantment(*mItem));
|
||||
int types = getRangeTypes(enchantment->mEffects);
|
||||
|
||||
isRanged = (types & RangeTypes::Target) | (types & RangeTypes::Self);
|
||||
return suggestCombatRange(types);
|
||||
}
|
||||
|
||||
|
|
|
@ -54,7 +54,7 @@ namespace MWMechanics
|
|||
virtual float getCombatRange (bool& isRanged) const;
|
||||
|
||||
/// Since this action has no animation, apply a small cool down for using it
|
||||
virtual float getActionCooldown() { return 1.f; }
|
||||
virtual float getActionCooldown() { return 0.75f; }
|
||||
};
|
||||
|
||||
class ActionPotion : public Action
|
||||
|
@ -68,7 +68,7 @@ namespace MWMechanics
|
|||
virtual bool isAttackingOrSpell() const { return false; }
|
||||
|
||||
/// Since this action has no animation, apply a small cool down for using it
|
||||
virtual float getActionCooldown() { return 1.f; }
|
||||
virtual float getActionCooldown() { return 0.75f; }
|
||||
};
|
||||
|
||||
class ActionWeapon : public Action
|
||||
|
|
|
@ -46,6 +46,26 @@ namespace
|
|||
}
|
||||
return toCure;
|
||||
}
|
||||
|
||||
float getSpellDuration (const MWWorld::Ptr& actor, const std::string& spellId)
|
||||
{
|
||||
float duration = 0;
|
||||
const MWMechanics::ActiveSpells& activeSpells = actor.getClass().getCreatureStats(actor).getActiveSpells();
|
||||
for (MWMechanics::ActiveSpells::TIterator it = activeSpells.begin(); it != activeSpells.end(); ++it)
|
||||
{
|
||||
if (it->first != spellId)
|
||||
continue;
|
||||
|
||||
const MWMechanics::ActiveSpells::ActiveSpellParams& params = it->second;
|
||||
for (std::vector<MWMechanics::ActiveSpells::ActiveEffect>::const_iterator effectIt = params.mEffects.begin();
|
||||
effectIt != params.mEffects.end(); ++effectIt)
|
||||
{
|
||||
if (effectIt->mDuration > duration)
|
||||
duration = effectIt->mDuration;
|
||||
}
|
||||
}
|
||||
return duration;
|
||||
}
|
||||
}
|
||||
|
||||
namespace MWMechanics
|
||||
|
@ -114,15 +134,39 @@ namespace MWMechanics
|
|||
|
||||
const ESM::Enchantment* enchantment = MWBase::Environment::get().getWorld()->getStore().get<ESM::Enchantment>().find(ptr.getClass().getEnchantment(ptr));
|
||||
|
||||
// Spells don't stack, so early out if the spell is still active on the target
|
||||
int types = getRangeTypes(enchantment->mEffects);
|
||||
if ((types & Self) && actor.getClass().getCreatureStats(actor).getActiveSpells().isSpellActive(ptr.getCellRef().getRefId()))
|
||||
return 0.f;
|
||||
|
||||
if (types & (Touch|Target) && getSpellDuration(enemy, ptr.getCellRef().getRefId()) > 3)
|
||||
return 0.f;
|
||||
|
||||
if (enchantment->mData.mType == ESM::Enchantment::CastOnce)
|
||||
{
|
||||
return rateEffects(enchantment->mEffects, actor, enemy);
|
||||
}
|
||||
else
|
||||
else if (enchantment->mData.mType == ESM::Enchantment::WhenUsed)
|
||||
{
|
||||
//if (!ptr.getClass().canBeEquipped(ptr, actor))
|
||||
return 0.f;
|
||||
MWWorld::InventoryStore& store = actor.getClass().getInventoryStore(actor);
|
||||
|
||||
// Creatures can not wear armor/clothing, so allow creatures to use non-equipped items,
|
||||
if (actor.getClass().isNpc() && !store.isEquipped(ptr))
|
||||
return 0.f;
|
||||
|
||||
int castCost = getEffectiveEnchantmentCastCost(static_cast<float>(enchantment->mData.mCost), actor);
|
||||
|
||||
if (ptr.getCellRef().getEnchantmentCharge() != -1
|
||||
&& ptr.getCellRef().getEnchantmentCharge() < castCost)
|
||||
return 0.f;
|
||||
|
||||
float rating = rateEffects(enchantment->mEffects, actor, enemy);
|
||||
|
||||
rating *= 2; // prefer rechargable magic items over spells
|
||||
return rating;
|
||||
}
|
||||
|
||||
return 0.f;
|
||||
}
|
||||
|
||||
float rateEffect(const ESM::ENAMstruct &effect, const MWWorld::Ptr &actor, const MWWorld::Ptr &enemy)
|
||||
|
|
Loading…
Reference in a new issue