mirror of
				https://github.com/OpenMW/openmw.git
				synced 2025-10-25 11:26:37 +00:00 
			
		
		
		
	Handle death in actor update rather than instantly (Fixes #1866)
This commit is contained in:
		
							parent
							
								
									58f92f3659
								
							
						
					
					
						commit
						db879e77c2
					
				
					 7 changed files with 33 additions and 37 deletions
				
			
		|  | @ -198,9 +198,8 @@ namespace MWBase | ||||||
|             ///             making it more likely for the function to return true.
 |             ///             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; |             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.
 |             /// Resurrects the player if necessary
 | ||||||
|             /// This will increase the death count for any actors that were killed.
 |             virtual void keepPlayerAlive() = 0; | ||||||
|             virtual void killDeadActors() = 0; |  | ||||||
|     }; |     }; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -1282,23 +1282,10 @@ namespace MWMechanics | ||||||
|                     continue; |                     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<float> stat (stats.getHealth()); |  | ||||||
| 
 |  | ||||||
|                 if (stat.getModified()<1) |  | ||||||
|                 { |  | ||||||
|                     stat.setModified(1, 0); |  | ||||||
|                     stats.setHealth(stat); |  | ||||||
|                 } |  | ||||||
|                 stats.resurrect(); |  | ||||||
|                 continue; |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             if (iter->second->kill()) |             if (iter->second->kill()) | ||||||
|             { |             { | ||||||
|  |                 iter->first.getClass().getCreatureStats(iter->first).notifyDied(); | ||||||
|  | 
 | ||||||
|                 ++mDeathCount[Misc::StringUtils::lowerCase(iter->first.getCellRef().getRefId())]; |                 ++mDeathCount[Misc::StringUtils::lowerCase(iter->first.getCellRef().getRefId())]; | ||||||
| 
 | 
 | ||||||
|                 // Make sure spell effects with CasterLinked flag are removed
 |                 // Make sure spell effects with CasterLinked flag are removed
 | ||||||
|  |  | ||||||
|  | @ -44,6 +44,8 @@ namespace MWMechanics | ||||||
| 
 | 
 | ||||||
|             void updateCrimePersuit (const MWWorld::Ptr& ptr, float duration); |             void updateCrimePersuit (const MWWorld::Ptr& ptr, float duration); | ||||||
| 
 | 
 | ||||||
|  |             void killDeadActors (); | ||||||
|  | 
 | ||||||
|         public: |         public: | ||||||
| 
 | 
 | ||||||
|             Actors(); |             Actors(); | ||||||
|  | @ -98,9 +100,6 @@ namespace MWMechanics | ||||||
|             int countDeaths (const std::string& id) const; |             int countDeaths (const std::string& id) const; | ||||||
|             ///< Return the number of deaths for actors with the given ID.
 |             ///< Return the number of deaths for actors with the given ID.
 | ||||||
| 
 | 
 | ||||||
|             ///@see MechanicsManager::killDeadActors
 |  | ||||||
|             void killDeadActors (); |  | ||||||
| 
 |  | ||||||
|         void forceStateUpdate(const MWWorld::Ptr &ptr); |         void forceStateUpdate(const MWWorld::Ptr &ptr); | ||||||
| 
 | 
 | ||||||
|         void playAnimationGroup(const MWWorld::Ptr& ptr, const std::string& groupName, int mode, int number); |         void playAnimationGroup(const MWWorld::Ptr& ptr, const std::string& groupName, int mode, int number); | ||||||
|  |  | ||||||
|  | @ -188,16 +188,10 @@ namespace MWMechanics | ||||||
| 
 | 
 | ||||||
|         if (index==0 && mDynamic[index].getCurrent()<1) |         if (index==0 && mDynamic[index].getCurrent()<1) | ||||||
|         { |         { | ||||||
|             if (!mDead) |  | ||||||
|                 mDied = true; |  | ||||||
| 
 |  | ||||||
|             mDead = true; |             mDead = true; | ||||||
| 
 | 
 | ||||||
|             if (mDied) |             if (MWBase::Environment::get().getWorld()->getGodModeState()) | ||||||
|                 // Must increase death count immediately. There are scripts that use getDeadCount as reaction to onDeath
 |                 MWBase::Environment::get().getMechanicsManager()->keepPlayerAlive(); | ||||||
|                 // 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(); |  | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | @ -242,6 +236,11 @@ namespace MWMechanics | ||||||
|         return mDead; |         return mDead; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     void CreatureStats::notifyDied() | ||||||
|  |     { | ||||||
|  |         mDied = true; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     bool CreatureStats::hasDied() const |     bool CreatureStats::hasDied() const | ||||||
|     { |     { | ||||||
|         return mDied; |         return mDied; | ||||||
|  |  | ||||||
|  | @ -168,6 +168,8 @@ namespace MWMechanics | ||||||
| 
 | 
 | ||||||
|         bool isDead() const; |         bool isDead() const; | ||||||
| 
 | 
 | ||||||
|  |         void notifyDied(); | ||||||
|  | 
 | ||||||
|         bool hasDied() const; |         bool hasDied() const; | ||||||
| 
 | 
 | ||||||
|         void clearHasDied(); |         void clearHasDied(); | ||||||
|  |  | ||||||
|  | @ -664,11 +664,6 @@ namespace MWMechanics | ||||||
|         return mActors.countDeaths (id); |         return mActors.countDeaths (id); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     void MechanicsManager::killDeadActors() |  | ||||||
|     { |  | ||||||
|         mActors.killDeadActors(); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     void MechanicsManager::getPersuasionDispositionChange (const MWWorld::Ptr& npc, PersuasionType type, |     void MechanicsManager::getPersuasionDispositionChange (const MWWorld::Ptr& npc, PersuasionType type, | ||||||
|         float currentTemporaryDispositionDelta, bool& success, float& tempChange, float& permChange) |         float currentTemporaryDispositionDelta, bool& success, float& tempChange, float& permChange) | ||||||
|     { |     { | ||||||
|  | @ -1303,4 +1298,21 @@ namespace MWMechanics | ||||||
| 
 | 
 | ||||||
|         return (fight >= 100); |         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<float> stat (stats.getHealth()); | ||||||
|  | 
 | ||||||
|  |             if (stat.getModified()<1) | ||||||
|  |             { | ||||||
|  |                 stat.setModified(1, 0); | ||||||
|  |                 stats.setHealth(stat); | ||||||
|  |             } | ||||||
|  |             stats.resurrect(); | ||||||
|  |         } | ||||||
|  |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -162,9 +162,7 @@ namespace MWMechanics | ||||||
|             ///             making it more likely for the function to return true.
 |             ///             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); |             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.
 |             virtual void keepPlayerAlive(); | ||||||
|             /// This will increase the death count for any actors that were killed.
 |  | ||||||
|             virtual void killDeadActors(); |  | ||||||
|     }; |     }; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue