diff --git a/apps/openmw/mwbase/mechanicsmanager.hpp b/apps/openmw/mwbase/mechanicsmanager.hpp index 532c1c3faa..e99f4ca3cd 100644 --- a/apps/openmw/mwbase/mechanicsmanager.hpp +++ b/apps/openmw/mwbase/mechanicsmanager.hpp @@ -198,9 +198,8 @@ namespace MWBase /// making it more likely for the function to return true. virtual bool isAggressive (const MWWorld::Ptr& ptr, const MWWorld::Ptr& target, int bias=0, bool ignoreDistance=false) = 0; - /// Usually done once a frame, but can be invoked manually in time-critical situations. - /// This will increase the death count for any actors that were killed. - virtual void killDeadActors() = 0; + /// Resurrects the player if necessary + virtual void keepPlayerAlive() = 0; }; } diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index 0ac21f3353..9e11529dd3 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -1292,23 +1292,10 @@ namespace MWMechanics continue; } - // If it's the player and God Mode is turned on, keep it alive - if (iter->first.getRefData().getHandle()=="player" && - MWBase::Environment::get().getWorld()->getGodModeState()) - { - MWMechanics::DynamicStat stat (stats.getHealth()); - - if (stat.getModified()<1) - { - stat.setModified(1, 0); - stats.setHealth(stat); - } - stats.resurrect(); - continue; - } - if (iter->second->kill()) { + iter->first.getClass().getCreatureStats(iter->first).notifyDied(); + ++mDeathCount[Misc::StringUtils::lowerCase(iter->first.getCellRef().getRefId())]; // Make sure spell effects with CasterLinked flag are removed diff --git a/apps/openmw/mwmechanics/actors.hpp b/apps/openmw/mwmechanics/actors.hpp index f893f7596a..55f1719f62 100644 --- a/apps/openmw/mwmechanics/actors.hpp +++ b/apps/openmw/mwmechanics/actors.hpp @@ -44,6 +44,8 @@ namespace MWMechanics void updateCrimePersuit (const MWWorld::Ptr& ptr, float duration); + void killDeadActors (); + public: Actors(); @@ -98,9 +100,6 @@ namespace MWMechanics int countDeaths (const std::string& id) const; ///< Return the number of deaths for actors with the given ID. - ///@see MechanicsManager::killDeadActors - void killDeadActors (); - void forceStateUpdate(const MWWorld::Ptr &ptr); void playAnimationGroup(const MWWorld::Ptr& ptr, const std::string& groupName, int mode, int number); diff --git a/apps/openmw/mwmechanics/creaturestats.cpp b/apps/openmw/mwmechanics/creaturestats.cpp index 6c0356a040..7a2ece6cad 100644 --- a/apps/openmw/mwmechanics/creaturestats.cpp +++ b/apps/openmw/mwmechanics/creaturestats.cpp @@ -188,16 +188,10 @@ namespace MWMechanics if (index==0 && mDynamic[index].getCurrent()<1) { - if (!mDead) - mDied = true; - mDead = true; - if (mDied) - // Must increase death count immediately. There are scripts that use getDeadCount as reaction to onDeath - // and rely on the increased value. - // Would be more appropriate to use a killActor(actor) function, but we don't have access to the Ptr in CreatureStats. - MWBase::Environment::get().getMechanicsManager()->killDeadActors(); + if (MWBase::Environment::get().getWorld()->getGodModeState()) + MWBase::Environment::get().getMechanicsManager()->keepPlayerAlive(); } } @@ -242,6 +236,11 @@ namespace MWMechanics return mDead; } + void CreatureStats::notifyDied() + { + mDied = true; + } + bool CreatureStats::hasDied() const { return mDied; diff --git a/apps/openmw/mwmechanics/creaturestats.hpp b/apps/openmw/mwmechanics/creaturestats.hpp index 037f37cc91..827408e111 100644 --- a/apps/openmw/mwmechanics/creaturestats.hpp +++ b/apps/openmw/mwmechanics/creaturestats.hpp @@ -168,6 +168,8 @@ namespace MWMechanics bool isDead() const; + void notifyDied(); + bool hasDied() const; void clearHasDied(); diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp index b6b2c213d6..8547188637 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp @@ -664,11 +664,6 @@ namespace MWMechanics return mActors.countDeaths (id); } - void MechanicsManager::killDeadActors() - { - mActors.killDeadActors(); - } - void MechanicsManager::getPersuasionDispositionChange (const MWWorld::Ptr& npc, PersuasionType type, float currentTemporaryDispositionDelta, bool& success, float& tempChange, float& permChange) { @@ -1303,4 +1298,21 @@ namespace MWMechanics return (fight >= 100); } + + void MechanicsManager::keepPlayerAlive() + { + MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); + CreatureStats& stats = player.getClass().getCreatureStats(player); + if (stats.isDead()) + { + MWMechanics::DynamicStat stat (stats.getHealth()); + + if (stat.getModified()<1) + { + stat.setModified(1, 0); + stats.setHealth(stat); + } + stats.resurrect(); + } + } } diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp index 7dbc6da74f..48553e099f 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp @@ -162,9 +162,7 @@ namespace MWMechanics /// making it more likely for the function to return true. virtual bool isAggressive (const MWWorld::Ptr& ptr, const MWWorld::Ptr& target, int bias=0, bool ignoreDistance=false); - /// Usually done once a frame, but can be invoked manually in time-critical situations. - /// This will increase the death count for any actors that were killed. - virtual void killDeadActors(); + virtual void keepPlayerAlive(); }; }