1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2025-03-29 04:20:29 +00:00

Remove heal cooldown

This commit is contained in:
Evil Eye 2023-01-15 19:59:22 +01:00
parent ee92ae7e34
commit fb10014d6e
8 changed files with 23 additions and 66 deletions

View File

@ -153,7 +153,6 @@ namespace MWMechanics
updateFleeing(actor, target, duration, characterController.getSupportedMovementDirections(), storage); updateFleeing(actor, target, duration, characterController.getSupportedMovementDirections(), storage);
} }
storage.mActionCooldown -= duration; storage.mActionCooldown -= duration;
storage.mHealCooldown -= duration;
if (storage.mReaction.update(duration) == Misc::TimerStatus::Waiting) if (storage.mReaction.update(duration) == Misc::TimerStatus::Waiting)
return false; return false;
@ -177,7 +176,6 @@ namespace MWMechanics
storage.stopAttack(); storage.stopAttack();
actor.getClass().getCreatureStats(actor).setAttackingOrSpell(false); actor.getClass().getCreatureStats(actor).setAttackingOrSpell(false);
storage.mActionCooldown = 0.f; storage.mActionCooldown = 0.f;
storage.mHealCooldown = 0.f;
// Continue combat if target is player or player follower/escorter and an attack has been attempted // Continue combat if target is player or player follower/escorter and an attack has been attempted
const auto& playerFollowersAndEscorters const auto& playerFollowersAndEscorters
= MWBase::Environment::get().getMechanicsManager()->getActorsSidingWith(MWMechanics::getPlayer()); = MWBase::Environment::get().getMechanicsManager()->getActorsSidingWith(MWMechanics::getPlayer());
@ -198,7 +196,6 @@ namespace MWMechanics
actorClass.getCreatureStats(actor).setMovementFlag(CreatureStats::Flag_Run, true); actorClass.getCreatureStats(actor).setMovementFlag(CreatureStats::Flag_Run, true);
float& actionCooldown = storage.mActionCooldown; float& actionCooldown = storage.mActionCooldown;
float& healCooldown = storage.mHealCooldown;
std::unique_ptr<Action>& currentAction = storage.mCurrentAction; std::unique_ptr<Action>& currentAction = storage.mCurrentAction;
if (!forceFlee) if (!forceFlee)
@ -208,16 +205,14 @@ namespace MWMechanics
if (characterController.readyToPrepareAttack()) if (characterController.readyToPrepareAttack())
{ {
currentAction = prepareNextAction(actor, target, healCooldown <= 0.f); currentAction = prepareNextAction(actor, target);
actionCooldown = currentAction->getActionCooldown(); actionCooldown = currentAction->getActionCooldown();
healCooldown = currentAction->getHealCooldown();
} }
} }
else else
{ {
currentAction = std::make_unique<ActionFlee>(); currentAction = std::make_unique<ActionFlee>();
actionCooldown = currentAction->getActionCooldown(); actionCooldown = currentAction->getActionCooldown();
healCooldown = currentAction->getHealCooldown();
} }
if (!currentAction) if (!currentAction)
@ -322,7 +317,6 @@ namespace MWMechanics
actor.getClass().getCreatureStats(actor).setAttackingOrSpell(false); actor.getClass().getCreatureStats(actor).setAttackingOrSpell(false);
currentAction = std::make_unique<ActionFlee>(); currentAction = std::make_unique<ActionFlee>();
actionCooldown = currentAction->getActionCooldown(); actionCooldown = currentAction->getActionCooldown();
healCooldown = currentAction->getHealCooldown();
storage.startFleeing(); storage.startFleeing();
MWBase::Environment::get().getDialogueManager()->say(actor, ESM::RefId::stringRefId("flee")); MWBase::Environment::get().getDialogueManager()->say(actor, ESM::RefId::stringRefId("flee"));
} }
@ -514,7 +508,6 @@ namespace MWMechanics
, mCell(nullptr) , mCell(nullptr)
, mCurrentAction() , mCurrentAction()
, mActionCooldown(0.0f) , mActionCooldown(0.0f)
, mHealCooldown(0.f)
, mStrength() , mStrength()
, mForceNoShortcut(false) , mForceNoShortcut(false)
, mShortcutFailPos() , mShortcutFailPos()

View File

@ -36,7 +36,6 @@ namespace MWMechanics
const MWWorld::CellStore* mCell; const MWWorld::CellStore* mCell;
std::unique_ptr<Action> mCurrentAction; std::unique_ptr<Action> mCurrentAction;
float mActionCooldown; float mActionCooldown;
float mHealCooldown;
float mStrength; float mStrength;
bool mForceNoShortcut; bool mForceNoShortcut;
ESM::Position mShortcutFailPos; ESM::Position mShortcutFailPos;

View File

@ -162,7 +162,7 @@ namespace MWMechanics
return mWeapon.get<ESM::Weapon>()->mBase; return mWeapon.get<ESM::Weapon>()->mBase;
} }
std::unique_ptr<Action> prepareNextAction(const MWWorld::Ptr& actor, const MWWorld::Ptr& enemy, bool allowHealing) std::unique_ptr<Action> prepareNextAction(const MWWorld::Ptr& actor, const MWWorld::Ptr& enemy)
{ {
Spells& spells = actor.getClass().getCreatureStats(actor).getSpells(); Spells& spells = actor.getClass().getCreatureStats(actor).getSpells();
@ -182,24 +182,23 @@ namespace MWMechanics
for (MWWorld::ContainerStoreIterator it = store.begin(); it != store.end(); ++it) for (MWWorld::ContainerStoreIterator it = store.begin(); it != store.end(); ++it)
{ {
bool isPureHealing = false;
if (it->getType() == ESM::Potion::sRecordId) if (it->getType() == ESM::Potion::sRecordId)
{ {
float rating = ratePotion(*it, actor, isPureHealing); float rating = ratePotion(*it, actor);
if (rating > bestActionRating && (!isPureHealing || allowHealing)) if (rating > bestActionRating)
{ {
bestActionRating = rating; bestActionRating = rating;
bestAction = std::make_unique<ActionPotion>(*it, isPureHealing); bestAction = std::make_unique<ActionPotion>(*it);
antiFleeRating = std::numeric_limits<float>::max(); antiFleeRating = std::numeric_limits<float>::max();
} }
} }
else if (!it->getClass().getEnchantment(*it).empty()) else if (!it->getClass().getEnchantment(*it).empty())
{ {
float rating = rateMagicItem(*it, actor, enemy, isPureHealing); float rating = rateMagicItem(*it, actor, enemy);
if (rating > bestActionRating && (!isPureHealing || allowHealing)) if (rating > bestActionRating)
{ {
bestActionRating = rating; bestActionRating = rating;
bestAction = std::make_unique<ActionEnchantedItem>(it, isPureHealing); bestAction = std::make_unique<ActionEnchantedItem>(it);
antiFleeRating = std::numeric_limits<float>::max(); antiFleeRating = std::numeric_limits<float>::max();
} }
} }
@ -237,11 +236,8 @@ namespace MWMechanics
float rating = rateSpell(spell, actor, enemy); float rating = rateSpell(spell, actor, enemy);
if (rating > bestActionRating) if (rating > bestActionRating)
{ {
bool isPureHealingSpell = isPureHealing(spell->mEffects);
if (isPureHealingSpell && !allowHealing)
continue;
bestActionRating = rating; bestActionRating = rating;
bestAction = std::make_unique<ActionSpell>(spell->mId, isPureHealingSpell); bestAction = std::make_unique<ActionSpell>(spell->mId);
antiFleeRating = vanillaRateSpell(spell, actor, enemy); antiFleeRating = vanillaRateSpell(spell, actor, enemy);
} }
} }
@ -270,10 +266,9 @@ namespace MWMechanics
{ {
MWWorld::InventoryStore& store = actor.getClass().getInventoryStore(actor); MWWorld::InventoryStore& store = actor.getClass().getInventoryStore(actor);
bool pureHealing;
for (MWWorld::ContainerStoreIterator it = store.begin(); it != store.end(); ++it) for (MWWorld::ContainerStoreIterator it = store.begin(); it != store.end(); ++it)
{ {
float rating = rateMagicItem(*it, actor, enemy, pureHealing); float rating = rateMagicItem(*it, actor, enemy);
if (rating > bestActionRating) if (rating > bestActionRating)
{ {
bestActionRating = rating; bestActionRating = rating;

View File

@ -10,18 +10,11 @@ namespace MWMechanics
{ {
class Action class Action
{ {
float mHealCooldown;
public: public:
Action(bool healing)
: mHealCooldown(healing ? 5.f : 0.f)
{
}
virtual ~Action() {} virtual ~Action() {}
virtual void prepare(const MWWorld::Ptr& actor) = 0; virtual void prepare(const MWWorld::Ptr& actor) = 0;
virtual float getCombatRange(bool& isRanged) const = 0; virtual float getCombatRange(bool& isRanged) const = 0;
virtual float getActionCooldown() const { return 0.f; } virtual float getActionCooldown() const { return 0.f; }
virtual float getHealCooldown() const { return mHealCooldown; }
virtual const ESM::Weapon* getWeapon() const { return nullptr; } virtual const ESM::Weapon* getWeapon() const { return nullptr; }
virtual bool isAttackingOrSpell() const { return true; } virtual bool isAttackingOrSpell() const { return true; }
virtual bool isFleeing() const { return false; } virtual bool isFleeing() const { return false; }
@ -30,10 +23,7 @@ namespace MWMechanics
class ActionFlee : public Action class ActionFlee : public Action
{ {
public: public:
ActionFlee() ActionFlee() {}
: Action(false)
{
}
void prepare(const MWWorld::Ptr& actor) override {} void prepare(const MWWorld::Ptr& actor) override {}
float getCombatRange(bool& isRanged) const override { return 0.0f; } float getCombatRange(bool& isRanged) const override { return 0.0f; }
float getActionCooldown() const override { return 3.0f; } float getActionCooldown() const override { return 3.0f; }
@ -44,9 +34,8 @@ namespace MWMechanics
class ActionSpell : public Action class ActionSpell : public Action
{ {
public: public:
ActionSpell(const ESM::RefId& spellId, bool healing = false) ActionSpell(const ESM::RefId& spellId)
: Action(healing) : mSpellId(spellId)
, mSpellId(spellId)
{ {
} }
ESM::RefId mSpellId; ESM::RefId mSpellId;
@ -59,9 +48,8 @@ namespace MWMechanics
class ActionEnchantedItem : public Action class ActionEnchantedItem : public Action
{ {
public: public:
ActionEnchantedItem(const MWWorld::ContainerStoreIterator& item, bool healing) ActionEnchantedItem(const MWWorld::ContainerStoreIterator& item)
: Action(healing) : mItem(item)
, mItem(item)
{ {
} }
MWWorld::ContainerStoreIterator mItem; MWWorld::ContainerStoreIterator mItem;
@ -76,9 +64,8 @@ namespace MWMechanics
class ActionPotion : public Action class ActionPotion : public Action
{ {
public: public:
ActionPotion(const MWWorld::Ptr& potion, bool healing) ActionPotion(const MWWorld::Ptr& potion)
: Action(healing) : mPotion(potion)
, mPotion(potion)
{ {
} }
MWWorld::Ptr mPotion; MWWorld::Ptr mPotion;
@ -100,8 +87,7 @@ namespace MWMechanics
public: public:
/// \a weapon may be empty for hand-to-hand combat /// \a weapon may be empty for hand-to-hand combat
ActionWeapon(const MWWorld::Ptr& weapon, const MWWorld::Ptr& ammo = MWWorld::Ptr()) ActionWeapon(const MWWorld::Ptr& weapon, const MWWorld::Ptr& ammo = MWWorld::Ptr())
: Action(false) : mAmmunition(ammo)
, mAmmunition(ammo)
, mWeapon(weapon) , mWeapon(weapon)
{ {
} }
@ -111,7 +97,7 @@ namespace MWMechanics
const ESM::Weapon* getWeapon() const override; const ESM::Weapon* getWeapon() const override;
}; };
std::unique_ptr<Action> prepareNextAction(const MWWorld::Ptr& actor, const MWWorld::Ptr& enemy, bool allowHealing); std::unique_ptr<Action> prepareNextAction(const MWWorld::Ptr& actor, const MWWorld::Ptr& enemy);
float getBestActionRating(const MWWorld::Ptr& actor, const MWWorld::Ptr& enemy); float getBestActionRating(const MWWorld::Ptr& actor, const MWWorld::Ptr& enemy);
float getDistanceMinusHalfExtents(const MWWorld::Ptr& actor, const MWWorld::Ptr& enemy, bool minusZDist = false); float getDistanceMinusHalfExtents(const MWWorld::Ptr& actor, const MWWorld::Ptr& enemy, bool minusZDist = false);

View File

@ -122,13 +122,12 @@ namespace MWMechanics
return types; return types;
} }
float ratePotion(const MWWorld::Ptr& item, const MWWorld::Ptr& actor, bool& pureHealing) float ratePotion(const MWWorld::Ptr& item, const MWWorld::Ptr& actor)
{ {
if (item.getType() != ESM::Potion::sRecordId) if (item.getType() != ESM::Potion::sRecordId)
return 0.f; return 0.f;
const ESM::Potion* potion = item.get<ESM::Potion>()->mBase; const ESM::Potion* potion = item.get<ESM::Potion>()->mBase;
pureHealing = isPureHealing(potion->mEffects);
return rateEffects(potion->mEffects, actor, MWWorld::Ptr()); return rateEffects(potion->mEffects, actor, MWWorld::Ptr());
} }
@ -160,15 +159,13 @@ namespace MWMechanics
return rateEffects(spell->mEffects, actor, enemy) * (successChance / 100.f); return rateEffects(spell->mEffects, actor, enemy) * (successChance / 100.f);
} }
float rateMagicItem( float rateMagicItem(const MWWorld::Ptr& ptr, const MWWorld::Ptr& actor, const MWWorld::Ptr& enemy)
const MWWorld::Ptr& ptr, const MWWorld::Ptr& actor, const MWWorld::Ptr& enemy, bool& pureHealing)
{ {
if (ptr.getClass().getEnchantment(ptr).empty()) if (ptr.getClass().getEnchantment(ptr).empty())
return 0.f; return 0.f;
const ESM::Enchantment* enchantment = MWBase::Environment::get().getESMStore()->get<ESM::Enchantment>().find( const ESM::Enchantment* enchantment = MWBase::Environment::get().getESMStore()->get<ESM::Enchantment>().find(
ptr.getClass().getEnchantment(ptr)); ptr.getClass().getEnchantment(ptr));
pureHealing = isPureHealing(enchantment->mEffects);
// Spells don't stack, so early out if the spell is still active on the target // Spells don't stack, so early out if the spell is still active on the target
int types = getRangeTypes(enchantment->mEffects); int types = getRangeTypes(enchantment->mEffects);

View File

@ -27,9 +27,8 @@ namespace MWMechanics
float rateSpell( float rateSpell(
const ESM::Spell* spell, const MWWorld::Ptr& actor, const MWWorld::Ptr& enemy, bool checkMagicka = true); const ESM::Spell* spell, const MWWorld::Ptr& actor, const MWWorld::Ptr& enemy, bool checkMagicka = true);
float rateMagicItem( float rateMagicItem(const MWWorld::Ptr& ptr, const MWWorld::Ptr& actor, const MWWorld::Ptr& enemy);
const MWWorld::Ptr& ptr, const MWWorld::Ptr& actor, const MWWorld::Ptr& enemy, bool& pureHealing); float ratePotion(const MWWorld::Ptr& item, const MWWorld::Ptr& actor);
float ratePotion(const MWWorld::Ptr& item, const MWWorld::Ptr& actor, bool& pureHealing);
/// @note target may be empty /// @note target may be empty
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);

View File

@ -257,13 +257,4 @@ namespace MWMechanics
const auto spell = MWBase::Environment::get().getESMStore()->get<ESM::Spell>().search(spellId); const auto spell = MWBase::Environment::get().getESMStore()->get<ESM::Spell>().search(spellId);
return spell && spellIncreasesSkill(spell); return spell && spellIncreasesSkill(spell);
} }
bool isPureHealing(const ESM::EffectList& list)
{
auto nonHealing = std::find_if(list.mList.begin(), list.mList.end(), [](const auto& effect) {
return effect.mEffectID < ESM::MagicEffect::RestoreAttribute
|| effect.mEffectID > ESM::MagicEffect::RestoreSkill;
});
return nonHealing == list.mList.end();
}
} }

View File

@ -5,7 +5,6 @@
namespace ESM namespace ESM
{ {
struct EffectList;
struct ENAMstruct; struct ENAMstruct;
struct Enchantment; struct Enchantment;
struct MagicEffect; struct MagicEffect;
@ -55,8 +54,6 @@ namespace MWMechanics
/// Get whether or not the given spell contributes to skill progress. /// Get whether or not the given spell contributes to skill progress.
bool spellIncreasesSkill(const ESM::Spell* spell); bool spellIncreasesSkill(const ESM::Spell* spell);
bool spellIncreasesSkill(const ESM::RefId& spellId); bool spellIncreasesSkill(const ESM::RefId& spellId);
bool isPureHealing(const ESM::EffectList& list);
} }
#endif #endif