From 9c3da411307b9f7f18db454d9499ec4a58fa48e7 Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Fri, 15 Jun 2018 14:03:43 +0400 Subject: [PATCH] Add murder bounty when a player follower commits murder (bug #2852) --- CHANGELOG.md | 1 + apps/openmw/mwmechanics/actors.cpp | 25 +++++++++++-------- .../mwmechanics/mechanicsmanagerimp.cpp | 18 ++++++++++--- 3 files changed, 30 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3a59aca8e..d32f48103 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ Bug #2222: Fatigue's effect on selling price is backwards Bug #2326: After a bound item expires the last equipped item of that type is not automatically re-equipped Bug #2835: Player able to slowly move when overencumbered + Bug #2852: No murder bounty when a player follower commits murder Bug #2971: Compiler did not reject lines with naked expressions beginning with x.y Bug #3374: Touch spells not hitting kwama foragers Bug #3591: Angled hit distance too low diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index f1bc6907c..9f73b79cc 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -760,11 +760,14 @@ namespace MWMechanics { // The actor was killed by a magic effect. Figure out if the player was responsible for it. const ActiveSpells& spells = creatureStats.getActiveSpells(); - bool killedByPlayer = false; MWWorld::Ptr player = getPlayer(); + std::set playerFollowers; + getActorsSidingWith(player, playerFollowers); + for (ActiveSpells::TIterator it = spells.begin(); it != spells.end(); ++it) { const ActiveSpells::ActiveSpellParams& spell = it->second; + MWWorld::Ptr caster = MWBase::Environment::get().getWorld()->searchPtrViaActorId(spell.mCasterActorId); for (std::vector::const_iterator effectIt = spell.mEffects.begin(); effectIt != spell.mEffects.end(); ++effectIt) { @@ -782,17 +785,19 @@ namespace MWMechanics isDamageEffect = true; } - MWWorld::Ptr caster = MWBase::Environment::get().getWorld()->searchPtrViaActorId(spell.mCasterActorId); - if (isDamageEffect && caster == player) - killedByPlayer = true; + if (isDamageEffect) + { + if (caster == player || playerFollowers.find(caster) != playerFollowers.end()) + { + if (caster.getClass().getNpcStats(caster).isWerewolf()) + caster.getClass().getNpcStats(caster).addWerewolfKill(); + + MWBase::Environment::get().getMechanicsManager()->actorKilled(ptr, player); + break; + } + } } } - if (killedByPlayer) - { - MWBase::Environment::get().getMechanicsManager()->actorKilled(ptr, player); - if (player.getClass().getNpcStats(player).isWerewolf()) - player.getClass().getNpcStats(player).addWerewolfKill(); - } } // TODO: dirty flag for magic effects to avoid some unnecessary work below? diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp index 80b9ace86..1fc98a327 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp @@ -1495,7 +1495,7 @@ namespace MWMechanics void MechanicsManager::actorKilled(const MWWorld::Ptr &victim, const MWWorld::Ptr &attacker) { - if (attacker.isEmpty() || attacker != getPlayer()) + if (attacker.isEmpty() || victim.isEmpty()) return; if (victim == attacker) @@ -1505,13 +1505,23 @@ namespace MWMechanics return; // TODO: implement animal rights const MWMechanics::NpcStats& victimStats = victim.getClass().getNpcStats(victim); + if (victimStats.getCrimeId() == -1) + return; + + // For now we report only about crimes of player and player's followers + const MWWorld::Ptr &player = getPlayer(); + if (attacker != player) + { + std::set playerFollowers; + getActorsSidingWith(player, playerFollowers); + if (playerFollowers.find(attacker) == playerFollowers.end()) + return; + } // Simple check for who attacked first: if the player attacked first, a crimeId should be set // Doesn't handle possible edge case where no one reported the assault, but in such a case, // for bystanders it is not possible to tell who attacked first, anyway. - if (victimStats.getCrimeId() != -1) - commitCrime(attacker, victim, MWBase::MechanicsManager::OT_Murder); - + commitCrime(player, victim, MWBase::MechanicsManager::OT_Murder); } bool MechanicsManager::awarenessCheck(const MWWorld::Ptr &ptr, const MWWorld::Ptr &observer)