mirror of
				https://github.com/OpenMW/openmw.git
				synced 2025-10-31 20:56:39 +00:00 
			
		
		
		
	Don't trigger OnPcHitMe for friendly hits (Fixes #1950)
Don't consider actors as followers if they are also in combat with the follow target
This commit is contained in:
		
							parent
							
								
									4b8ea25cf0
								
							
						
					
					
						commit
						e868a48a63
					
				
					 6 changed files with 21 additions and 10 deletions
				
			
		|  | @ -128,7 +128,8 @@ namespace MWBase | |||
|                                       OffenseType type, int arg=0) = 0; | ||||
|             virtual void reportCrime (const MWWorld::Ptr& ptr, const MWWorld::Ptr& victim, | ||||
|                                       OffenseType type, int arg=0) = 0; | ||||
|             virtual void actorAttacked (const MWWorld::Ptr& victim, const MWWorld::Ptr& attacker) = 0; | ||||
|             /// @return false if the attack was considered a "friendly hit" and forgiven
 | ||||
|             virtual bool actorAttacked (const MWWorld::Ptr& victim, const MWWorld::Ptr& attacker) = 0; | ||||
|             /// Utility to check if taking this item is illegal and calling commitCrime if so
 | ||||
|             virtual void itemTaken (const MWWorld::Ptr& ptr, const MWWorld::Ptr& item, int count) = 0; | ||||
|             /// Utility to check if opening (i.e. unlocking) this object is illegal and calling commitCrime if so
 | ||||
|  |  | |||
|  | @ -338,11 +338,12 @@ namespace MWClass | |||
|             getCreatureStats(ptr).setAttacked(true); | ||||
| 
 | ||||
|         // Self defense
 | ||||
|         bool setOnPcHitMe = true; // Note OnPcHitMe is not set for friendly hits.
 | ||||
|         if ((canWalk(ptr) || canFly(ptr) || canSwim(ptr)) // No retaliation for totally static creatures
 | ||||
|                                                               // (they have no movement or attacks anyway)
 | ||||
|             && !attacker.isEmpty()) | ||||
|         { | ||||
|             MWBase::Environment::get().getMechanicsManager()->actorAttacked(ptr, attacker); | ||||
|             setOnPcHitMe = MWBase::Environment::get().getMechanicsManager()->actorAttacked(ptr, attacker); | ||||
|         } | ||||
| 
 | ||||
|         if(!successful) | ||||
|  | @ -357,7 +358,7 @@ namespace MWClass | |||
|         if(!object.isEmpty()) | ||||
|             getCreatureStats(ptr).setLastHitObject(object.getClass().getId(object)); | ||||
| 
 | ||||
|         if(!attacker.isEmpty() && attacker.getRefData().getHandle() == "player") | ||||
|         if(setOnPcHitMe && !attacker.isEmpty() && attacker.getRefData().getHandle() == "player") | ||||
|         { | ||||
|             const std::string &script = ptr.get<ESM::Creature>()->mBase->mScript; | ||||
|             /* Set the OnPCHitMe script variable. The script is responsible for clearing it. */ | ||||
|  |  | |||
|  | @ -644,11 +644,13 @@ namespace MWClass | |||
| 
 | ||||
|         bool wasDead = getCreatureStats(ptr).isDead(); | ||||
| 
 | ||||
|         // Note OnPcHitMe is not set for friendly hits.
 | ||||
|         bool setOnPcHitMe = true; | ||||
|         if (!attacker.isEmpty() && !ptr.getClass().getCreatureStats(ptr).getAiSequence().isInCombat(attacker)) | ||||
|         { | ||||
|             getCreatureStats(ptr).setAttacked(true); | ||||
| 
 | ||||
|             MWBase::Environment::get().getMechanicsManager()->actorAttacked(ptr, attacker); | ||||
|             setOnPcHitMe = MWBase::Environment::get().getMechanicsManager()->actorAttacked(ptr, attacker); | ||||
|         } | ||||
| 
 | ||||
|         if(!successful) | ||||
|  | @ -663,7 +665,7 @@ namespace MWClass | |||
|         if(!object.isEmpty()) | ||||
|             getCreatureStats(ptr).setLastHitObject(object.getClass().getId(object)); | ||||
| 
 | ||||
|         if(!attacker.isEmpty() && attacker.getRefData().getHandle() == "player") | ||||
|         if(setOnPcHitMe && !attacker.isEmpty() && attacker.getRefData().getHandle() == "player") | ||||
|         { | ||||
|             const std::string &script = ptr.getClass().getScript(ptr); | ||||
|             /* Set the OnPCHitMe script variable. The script is responsible for clearing it. */ | ||||
|  |  | |||
|  | @ -323,8 +323,9 @@ namespace MWMechanics | |||
|         for (std::list<MWWorld::Ptr>::const_iterator it = followers.begin(); it != followers.end(); ++it) | ||||
|         { | ||||
|             // need to check both ways since player doesn't use AI packages
 | ||||
|             if (creatureStats2.getAiSequence().isInCombat(*it) | ||||
|             if ((creatureStats2.getAiSequence().isInCombat(*it) | ||||
|                     || it->getClass().getCreatureStats(*it).getAiSequence().isInCombat(actor2)) | ||||
|                     && !creatureStats.getAiSequence().isInCombat(*it)) | ||||
|                 aggressive = true; | ||||
|         } | ||||
| 
 | ||||
|  | @ -337,6 +338,9 @@ namespace MWMechanics | |||
|                 if (followTarget.isEmpty()) | ||||
|                     continue; | ||||
| 
 | ||||
|                 if (creatureStats.getAiSequence().isInCombat(followTarget)) | ||||
|                     continue; | ||||
| 
 | ||||
|                 // need to check both ways since player doesn't use AI packages
 | ||||
|                 if (creatureStats2.getAiSequence().isInCombat(followTarget) | ||||
|                         || followTarget.getClass().getCreatureStats(followTarget).getAiSequence().isInCombat(actor2)) | ||||
|  |  | |||
|  | @ -1111,10 +1111,10 @@ namespace MWMechanics | |||
|         } | ||||
|     } | ||||
| 
 | ||||
|     void MechanicsManager::actorAttacked(const MWWorld::Ptr &ptr, const MWWorld::Ptr &attacker) | ||||
|     bool MechanicsManager::actorAttacked(const MWWorld::Ptr &ptr, const MWWorld::Ptr &attacker) | ||||
|     { | ||||
|         if (ptr == MWBase::Environment::get().getWorld()->getPlayerPtr()) | ||||
|             return; | ||||
|             return false; | ||||
| 
 | ||||
|         std::list<MWWorld::Ptr> followers = getActorsFollowing(attacker); | ||||
|         if (std::find(followers.begin(), followers.end(), ptr) != followers.end()) | ||||
|  | @ -1124,7 +1124,7 @@ namespace MWMechanics | |||
|             if (ptr.getClass().getCreatureStats(ptr).getFriendlyHits() < 4) | ||||
|             { | ||||
|                 MWBase::Environment::get().getDialogueManager()->say(ptr, "hit"); | ||||
|                 return; | ||||
|                 return false; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|  | @ -1153,6 +1153,8 @@ namespace MWMechanics | |||
|             // Note: accidental or collateral damage attacks are ignored.
 | ||||
|             startCombat(ptr, attacker); | ||||
|         } | ||||
| 
 | ||||
|         return true; | ||||
|     } | ||||
| 
 | ||||
|     bool MechanicsManager::awarenessCheck(const MWWorld::Ptr &ptr, const MWWorld::Ptr &observer) | ||||
|  |  | |||
|  | @ -120,7 +120,8 @@ namespace MWMechanics | |||
|                                       OffenseType type, int arg=0); | ||||
|             virtual void reportCrime (const MWWorld::Ptr& ptr, const MWWorld::Ptr& victim, | ||||
|                                       OffenseType type, int arg=0); | ||||
|             virtual void actorAttacked (const MWWorld::Ptr& victim, const MWWorld::Ptr& attacker); | ||||
|             /// @return false if the attack was considered a "friendly hit" and forgiven
 | ||||
|             virtual bool actorAttacked (const MWWorld::Ptr& victim, const MWWorld::Ptr& attacker); | ||||
|             /// Utility to check if taking this item is illegal and calling commitCrime if so
 | ||||
|             virtual void itemTaken (const MWWorld::Ptr& ptr, const MWWorld::Ptr& item, int count); | ||||
|             /// Utility to check if opening (i.e. unlocking) this object is illegal and calling commitCrime if so
 | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue