mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-02-10 21:40:15 +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
@ -128,7 +128,8 @@ namespace MWBase
|
|||||||
OffenseType type, int arg=0) = 0;
|
OffenseType type, int arg=0) = 0;
|
||||||
virtual void reportCrime (const MWWorld::Ptr& ptr, const MWWorld::Ptr& victim,
|
virtual void reportCrime (const MWWorld::Ptr& ptr, const MWWorld::Ptr& victim,
|
||||||
OffenseType type, int arg=0) = 0;
|
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
|
/// 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;
|
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
|
/// 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);
|
getCreatureStats(ptr).setAttacked(true);
|
||||||
|
|
||||||
// Self defense
|
// 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
|
if ((canWalk(ptr) || canFly(ptr) || canSwim(ptr)) // No retaliation for totally static creatures
|
||||||
// (they have no movement or attacks anyway)
|
// (they have no movement or attacks anyway)
|
||||||
&& !attacker.isEmpty())
|
&& !attacker.isEmpty())
|
||||||
{
|
{
|
||||||
MWBase::Environment::get().getMechanicsManager()->actorAttacked(ptr, attacker);
|
setOnPcHitMe = MWBase::Environment::get().getMechanicsManager()->actorAttacked(ptr, attacker);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!successful)
|
if(!successful)
|
||||||
@ -357,7 +358,7 @@ namespace MWClass
|
|||||||
if(!object.isEmpty())
|
if(!object.isEmpty())
|
||||||
getCreatureStats(ptr).setLastHitObject(object.getClass().getId(object));
|
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;
|
const std::string &script = ptr.get<ESM::Creature>()->mBase->mScript;
|
||||||
/* Set the OnPCHitMe script variable. The script is responsible for clearing it. */
|
/* Set the OnPCHitMe script variable. The script is responsible for clearing it. */
|
||||||
|
@ -644,11 +644,13 @@ namespace MWClass
|
|||||||
|
|
||||||
bool wasDead = getCreatureStats(ptr).isDead();
|
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))
|
if (!attacker.isEmpty() && !ptr.getClass().getCreatureStats(ptr).getAiSequence().isInCombat(attacker))
|
||||||
{
|
{
|
||||||
getCreatureStats(ptr).setAttacked(true);
|
getCreatureStats(ptr).setAttacked(true);
|
||||||
|
|
||||||
MWBase::Environment::get().getMechanicsManager()->actorAttacked(ptr, attacker);
|
setOnPcHitMe = MWBase::Environment::get().getMechanicsManager()->actorAttacked(ptr, attacker);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!successful)
|
if(!successful)
|
||||||
@ -663,7 +665,7 @@ namespace MWClass
|
|||||||
if(!object.isEmpty())
|
if(!object.isEmpty())
|
||||||
getCreatureStats(ptr).setLastHitObject(object.getClass().getId(object));
|
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);
|
const std::string &script = ptr.getClass().getScript(ptr);
|
||||||
/* Set the OnPCHitMe script variable. The script is responsible for clearing it. */
|
/* 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)
|
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
|
// 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))
|
|| it->getClass().getCreatureStats(*it).getAiSequence().isInCombat(actor2))
|
||||||
|
&& !creatureStats.getAiSequence().isInCombat(*it))
|
||||||
aggressive = true;
|
aggressive = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -337,6 +338,9 @@ namespace MWMechanics
|
|||||||
if (followTarget.isEmpty())
|
if (followTarget.isEmpty())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if (creatureStats.getAiSequence().isInCombat(followTarget))
|
||||||
|
continue;
|
||||||
|
|
||||||
// need to check both ways since player doesn't use AI packages
|
// need to check both ways since player doesn't use AI packages
|
||||||
if (creatureStats2.getAiSequence().isInCombat(followTarget)
|
if (creatureStats2.getAiSequence().isInCombat(followTarget)
|
||||||
|| followTarget.getClass().getCreatureStats(followTarget).getAiSequence().isInCombat(actor2))
|
|| 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())
|
if (ptr == MWBase::Environment::get().getWorld()->getPlayerPtr())
|
||||||
return;
|
return false;
|
||||||
|
|
||||||
std::list<MWWorld::Ptr> followers = getActorsFollowing(attacker);
|
std::list<MWWorld::Ptr> followers = getActorsFollowing(attacker);
|
||||||
if (std::find(followers.begin(), followers.end(), ptr) != followers.end())
|
if (std::find(followers.begin(), followers.end(), ptr) != followers.end())
|
||||||
@ -1124,7 +1124,7 @@ namespace MWMechanics
|
|||||||
if (ptr.getClass().getCreatureStats(ptr).getFriendlyHits() < 4)
|
if (ptr.getClass().getCreatureStats(ptr).getFriendlyHits() < 4)
|
||||||
{
|
{
|
||||||
MWBase::Environment::get().getDialogueManager()->say(ptr, "hit");
|
MWBase::Environment::get().getDialogueManager()->say(ptr, "hit");
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1153,6 +1153,8 @@ namespace MWMechanics
|
|||||||
// Note: accidental or collateral damage attacks are ignored.
|
// Note: accidental or collateral damage attacks are ignored.
|
||||||
startCombat(ptr, attacker);
|
startCombat(ptr, attacker);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MechanicsManager::awarenessCheck(const MWWorld::Ptr &ptr, const MWWorld::Ptr &observer)
|
bool MechanicsManager::awarenessCheck(const MWWorld::Ptr &ptr, const MWWorld::Ptr &observer)
|
||||||
|
@ -120,7 +120,8 @@ namespace MWMechanics
|
|||||||
OffenseType type, int arg=0);
|
OffenseType type, int arg=0);
|
||||||
virtual void reportCrime (const MWWorld::Ptr& ptr, const MWWorld::Ptr& victim,
|
virtual void reportCrime (const MWWorld::Ptr& ptr, const MWWorld::Ptr& victim,
|
||||||
OffenseType type, int arg=0);
|
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
|
/// 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);
|
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
|
/// Utility to check if opening (i.e. unlocking) this object is illegal and calling commitCrime if so
|
||||||
|
Loading…
x
Reference in New Issue
Block a user