mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-19 21:23:52 +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));
|
const ESM::Enchantment* enchantment = MWBase::Environment::get().getWorld()->getStore().get<ESM::Enchantment>().find(mItem->getClass().getEnchantment(*mItem));
|
||||||
int types = getRangeTypes(enchantment->mEffects);
|
int types = getRangeTypes(enchantment->mEffects);
|
||||||
|
|
||||||
|
isRanged = (types & RangeTypes::Target) | (types & RangeTypes::Self);
|
||||||
return suggestCombatRange(types);
|
return suggestCombatRange(types);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -54,7 +54,7 @@ namespace MWMechanics
|
||||||
virtual float getCombatRange (bool& isRanged) const;
|
virtual float getCombatRange (bool& isRanged) const;
|
||||||
|
|
||||||
/// Since this action has no animation, apply a small cool down for using it
|
/// 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
|
class ActionPotion : public Action
|
||||||
|
@ -68,7 +68,7 @@ namespace MWMechanics
|
||||||
virtual bool isAttackingOrSpell() const { return false; }
|
virtual bool isAttackingOrSpell() const { return false; }
|
||||||
|
|
||||||
/// Since this action has no animation, apply a small cool down for using it
|
/// 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
|
class ActionWeapon : public Action
|
||||||
|
|
|
@ -46,6 +46,26 @@ namespace
|
||||||
}
|
}
|
||||||
return toCure;
|
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
|
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));
|
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)
|
if (enchantment->mData.mType == ESM::Enchantment::CastOnce)
|
||||||
{
|
{
|
||||||
return rateEffects(enchantment->mEffects, actor, enemy);
|
return rateEffects(enchantment->mEffects, actor, enemy);
|
||||||
}
|
}
|
||||||
else
|
else if (enchantment->mData.mType == ESM::Enchantment::WhenUsed)
|
||||||
{
|
{
|
||||||
//if (!ptr.getClass().canBeEquipped(ptr, actor))
|
MWWorld::InventoryStore& store = actor.getClass().getInventoryStore(actor);
|
||||||
return 0.f;
|
|
||||||
|
// 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)
|
float rateEffect(const ESM::ENAMstruct &effect, const MWWorld::Ptr &actor, const MWWorld::Ptr &enemy)
|
||||||
|
|
Loading…
Reference in a new issue