forked from teamnwah/openmw-tes3coop
Implement friendly hits on followers (Fixes #1139)
This commit is contained in:
parent
2d74388a76
commit
639ae7e06c
5 changed files with 37 additions and 24 deletions
|
@ -128,6 +128,7 @@ 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;
|
||||
/// 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
|
||||
|
|
|
@ -333,16 +333,11 @@ namespace MWClass
|
|||
getCreatureStats(ptr).setAttacked(true);
|
||||
|
||||
// Self defense
|
||||
if ( ((!attacker.isEmpty() && attacker.getClass().getCreatureStats(attacker).getAiSequence().isInCombat(ptr))
|
||||
|| attacker == MWBase::Environment::get().getWorld()->getPlayerPtr())
|
||||
&& !ptr.getClass().getCreatureStats(ptr).getAiSequence().isInCombat(attacker)
|
||||
&& (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)
|
||||
)
|
||||
&& !attacker.isEmpty())
|
||||
{
|
||||
// Attacker is in combat with us, but we are not in combat with the attacker yet. Time to fight back.
|
||||
// Note: accidental or collateral damage attacks are ignored.
|
||||
MWBase::Environment::get().getMechanicsManager()->startCombat(ptr, attacker);
|
||||
MWBase::Environment::get().getMechanicsManager()->actorAttacked(ptr, attacker);
|
||||
}
|
||||
|
||||
if(!successful)
|
||||
|
|
|
@ -639,26 +639,13 @@ namespace MWClass
|
|||
|
||||
// NOTE: 'object' and/or 'attacker' may be empty.
|
||||
|
||||
if (ptr != MWBase::Environment::get().getWorld()->getPlayerPtr())
|
||||
{
|
||||
// Attacking peaceful NPCs is a crime
|
||||
if (!attacker.isEmpty() && !ptr.getClass().getCreatureStats(ptr).getAiSequence().isInCombat(attacker)
|
||||
&& !MWBase::Environment::get().getMechanicsManager()->isAggressive(ptr, attacker))
|
||||
MWBase::Environment::get().getMechanicsManager()->commitCrime(attacker, ptr, MWBase::MechanicsManager::OT_Assault);
|
||||
|
||||
if (!attacker.isEmpty() && attacker.getClass().getCreatureStats(attacker).getAiSequence().isInCombat(ptr)
|
||||
&& !ptr.getClass().getCreatureStats(ptr).getAiSequence().isInCombat(attacker))
|
||||
{
|
||||
// Attacker is in combat with us, but we are not in combat with the attacker yet. Time to fight back.
|
||||
// Note: accidental or collateral damage attacks are ignored.
|
||||
MWBase::Environment::get().getMechanicsManager()->startCombat(ptr, attacker);
|
||||
}
|
||||
}
|
||||
|
||||
bool wasDead = getCreatureStats(ptr).isDead();
|
||||
|
||||
getCreatureStats(ptr).setAttacked(true);
|
||||
|
||||
if (!attacker.isEmpty())
|
||||
MWBase::Environment::get().getMechanicsManager()->actorAttacked(ptr, attacker);
|
||||
|
||||
if(!successful)
|
||||
{
|
||||
// TODO: Handle HitAttemptOnMe script function
|
||||
|
|
|
@ -1106,6 +1106,35 @@ namespace MWMechanics
|
|||
}
|
||||
}
|
||||
|
||||
void MechanicsManager::actorAttacked(const MWWorld::Ptr &ptr, const MWWorld::Ptr &attacker)
|
||||
{
|
||||
if (ptr == MWBase::Environment::get().getWorld()->getPlayerPtr())
|
||||
return;
|
||||
|
||||
std::list<MWWorld::Ptr> followers = getActorsFollowing(attacker);
|
||||
if (std::find(followers.begin(), followers.end(), ptr) != followers.end())
|
||||
{
|
||||
ptr.getClass().getCreatureStats(ptr).friendlyHit();
|
||||
|
||||
if (ptr.getClass().getCreatureStats(ptr).getFriendlyHits() < 4)
|
||||
return;
|
||||
}
|
||||
|
||||
// Attacking peaceful NPCs is a crime
|
||||
if (ptr.getClass().isNpc() && !attacker.isEmpty() && !ptr.getClass().getCreatureStats(ptr).getAiSequence().isInCombat(attacker)
|
||||
&& !isAggressive(ptr, attacker))
|
||||
commitCrime(attacker, ptr, MWBase::MechanicsManager::OT_Assault);
|
||||
|
||||
if (!attacker.isEmpty() && (attacker.getClass().getCreatureStats(attacker).getAiSequence().isInCombat(ptr)
|
||||
|| attacker == MWBase::Environment::get().getWorld()->getPlayerPtr())
|
||||
&& !ptr.getClass().getCreatureStats(ptr).getAiSequence().isInCombat(attacker))
|
||||
{
|
||||
// Attacker is in combat with us, but we are not in combat with the attacker yet. Time to fight back.
|
||||
// Note: accidental or collateral damage attacks are ignored.
|
||||
startCombat(ptr, attacker);
|
||||
}
|
||||
}
|
||||
|
||||
bool MechanicsManager::awarenessCheck(const MWWorld::Ptr &ptr, const MWWorld::Ptr &observer)
|
||||
{
|
||||
if (observer.getClass().getCreatureStats(observer).isDead())
|
||||
|
|
|
@ -119,6 +119,7 @@ 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);
|
||||
/// 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