From 68894320301d1027e55ae3d87a5817197f3024c3 Mon Sep 17 00:00:00 2001 From: James Carty Date: Thu, 16 Aug 2018 00:26:02 +0100 Subject: [PATCH 1/6] Move code to seperate functions for reusability --- apps/openmw/mwmechanics/aisequence.cpp | 15 +++++++++++ apps/openmw/mwmechanics/aisequence.hpp | 3 +++ .../mwmechanics/mechanicsmanagerimp.cpp | 27 ++++++++----------- .../mwmechanics/mechanicsmanagerimp.hpp | 2 ++ 4 files changed, 31 insertions(+), 16 deletions(-) diff --git a/apps/openmw/mwmechanics/aisequence.cpp b/apps/openmw/mwmechanics/aisequence.cpp index 0851748200..d55ba13dd8 100644 --- a/apps/openmw/mwmechanics/aisequence.cpp +++ b/apps/openmw/mwmechanics/aisequence.cpp @@ -19,6 +19,7 @@ #include "aicombataction.hpp" #include "aipursue.hpp" #include "actorutil.hpp" +#include "../mwworld/class.hpp" namespace MWMechanics { @@ -122,6 +123,20 @@ bool AiSequence::isInCombat() const return false; } +bool AiSequence::isEngagedWithActor() const +{ + bool isFightingNpc = false; + for (std::list::const_iterator it = mPackages.begin(); it != mPackages.end(); ++it) + { + if ((*it)->getTypeId() == AiPackage::TypeIdCombat) + { + MWWorld::Ptr target2 = (*it)->getTarget(); + if (!target2.isEmpty() && target2.getClass().isNpc()) + isFightingNpc = true; + } + } +} + bool AiSequence::hasPackage(int typeId) const { for (std::list::const_iterator it = mPackages.begin(); it != mPackages.end(); ++it) diff --git a/apps/openmw/mwmechanics/aisequence.hpp b/apps/openmw/mwmechanics/aisequence.hpp index 5c72bcc4ca..4d0482a985 100644 --- a/apps/openmw/mwmechanics/aisequence.hpp +++ b/apps/openmw/mwmechanics/aisequence.hpp @@ -88,6 +88,9 @@ namespace MWMechanics /// Is there any combat package? bool isInCombat () const; + /// Are we in combat with any other actor, who's also engaging us? + bool isEngagedWithActor () const; + /// Does this AI sequence have the given package type? bool hasPackage(int typeId) const; diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp index 7814b4a91e..6ef3587906 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp @@ -1460,24 +1460,11 @@ namespace MWMechanics } } - // Attacking an NPC that is already in combat with any other NPC is not a crime - AiSequence& seq = statsTarget.getAiSequence(); - bool isFightingNpc = false; - for (std::list::const_iterator it = seq.begin(); it != seq.end(); ++it) - { - if ((*it)->getTypeId() == AiPackage::TypeIdCombat) - { - MWWorld::Ptr target2 = (*it)->getTarget(); - if (!target2.isEmpty() && target2.getClass().isNpc()) - isFightingNpc = true; - } - } - - if (target.getClass().isNpc() && !attacker.isEmpty() && !seq.isInCombat(attacker) - && !isAggressive(target, attacker) && !isFightingNpc - && !target.getClass().getCreatureStats(target).getAiSequence().hasPackage(AiPackage::TypeIdPursue)) + if (canCommitCrimeAgainst(target, attacker)) commitCrime(attacker, target, MWBase::MechanicsManager::OT_Assault); + AiSequence& seq = statsTarget.getAiSequence(); + if (!attacker.isEmpty() && (attacker.getClass().getCreatureStats(attacker).getAiSequence().isInCombat(target) || attacker == getPlayer()) && !seq.isInCombat(attacker)) @@ -1504,6 +1491,14 @@ namespace MWMechanics return true; } + bool MechanicsManager::canCommitCrimeAgainst(const MWWorld::Ptr &target, const MWWorld::Ptr &attacker) + { + MWMechanics::AiSequence seq = target.getClass().getCreatureStats(target).getAiSequence(); + return target.getClass().isNpc() && !attacker.isEmpty() && !seq.isInCombat(attacker) + && !isAggressive(target, attacker) && !seq.isEngagedWithActor() + && !target.getClass().getCreatureStats(target).getAiSequence().hasPackage(AiPackage::TypeIdPursue); + } + void MechanicsManager::actorKilled(const MWWorld::Ptr &victim, const MWWorld::Ptr &attacker) { if (attacker.isEmpty() || victim.isEmpty()) diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp index 676a75cafb..85d2e65cfb 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp @@ -132,6 +132,8 @@ namespace MWMechanics /// @note No-op for non-player attackers virtual void actorKilled (const MWWorld::Ptr& victim, const MWWorld::Ptr& attacker); + virtual bool canCommitCrimeAgainst(const MWWorld::Ptr& victim, const MWWorld::Ptr& attacker); + /// Utility to check if taking this item is illegal and calling commitCrime if so /// @param container The container the item is in; may be empty for an item in the world virtual void itemTaken (const MWWorld::Ptr& ptr, const MWWorld::Ptr& item, const MWWorld::Ptr& container, From 4b0a6074e7b7024aa54a6bd026a88203093af46a Mon Sep 17 00:00:00 2001 From: James Carty Date: Thu, 16 Aug 2018 00:29:14 +0100 Subject: [PATCH 2/6] Add comment --- apps/openmw/mwmechanics/mechanicsmanagerimp.hpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp index 85d2e65cfb..8c8a9e68f9 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp @@ -132,6 +132,10 @@ namespace MWMechanics /// @note No-op for non-player attackers virtual void actorKilled (const MWWorld::Ptr& victim, const MWWorld::Ptr& attacker); + /// Checks if commiting a crime is currently valid + /// @param victim The actor being attacked + /// @param attacker The actor commiting the crime + /// @return true if the victim is a valid target for crime virtual bool canCommitCrimeAgainst(const MWWorld::Ptr& victim, const MWWorld::Ptr& attacker); /// Utility to check if taking this item is illegal and calling commitCrime if so From 43f1c9163cc254db8fd390604cbaa77a7edb9dfe Mon Sep 17 00:00:00 2001 From: James Carty Date: Thu, 16 Aug 2018 18:58:51 +0100 Subject: [PATCH 3/6] Fix issue in which murder wouldn't be reported after paying fine --- apps/openmw/mwmechanics/mechanicsmanagerimp.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp index 6ef3587906..a46204e668 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp @@ -1511,11 +1511,10 @@ namespace MWMechanics return; // TODO: implement animal rights const MWMechanics::NpcStats& victimStats = victim.getClass().getNpcStats(victim); - if (victimStats.getCrimeId() == -1) - return; + const MWWorld::Ptr &player = getPlayer(); + bool canCommit = attacker == player && canCommitCrimeAgainst(attacker, victim); // For now we report only about crimes of player and player's followers - const MWWorld::Ptr &player = getPlayer(); if (attacker != player) { std::set playerFollowers; @@ -1524,6 +1523,9 @@ namespace MWMechanics return; } + if (!canCommit && victimStats.getCrimeId() == -1) + 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. From 99b465eede0a76058e5fdd498b9c079d6a89a4a2 Mon Sep 17 00:00:00 2001 From: James Carty Date: Fri, 17 Aug 2018 13:54:58 +0100 Subject: [PATCH 4/6] Update authors --- AUTHORS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/AUTHORS.md b/AUTHORS.md index d2fd051809..bc22b230f8 100644 --- a/AUTHORS.md +++ b/AUTHORS.md @@ -172,6 +172,7 @@ Programmers Vincent Heuken vocollapse zelurker + James Carty (MrTopCat) Documentation ------------- From 513e99148e135fbf60309db718b3853d12898918 Mon Sep 17 00:00:00 2001 From: James Carty Date: Fri, 17 Aug 2018 20:17:26 +0100 Subject: [PATCH 5/6] Fix function with no return value --- apps/openmw/mwmechanics/aisequence.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwmechanics/aisequence.cpp b/apps/openmw/mwmechanics/aisequence.cpp index d55ba13dd8..9a42168d63 100644 --- a/apps/openmw/mwmechanics/aisequence.cpp +++ b/apps/openmw/mwmechanics/aisequence.cpp @@ -125,16 +125,16 @@ bool AiSequence::isInCombat() const bool AiSequence::isEngagedWithActor() const { - bool isFightingNpc = false; for (std::list::const_iterator it = mPackages.begin(); it != mPackages.end(); ++it) { if ((*it)->getTypeId() == AiPackage::TypeIdCombat) { MWWorld::Ptr target2 = (*it)->getTarget(); if (!target2.isEmpty() && target2.getClass().isNpc()) - isFightingNpc = true; + return true; } } + return false; } bool AiSequence::hasPackage(int typeId) const From 4489838ea386f16975646c1366ef3025b69469e3 Mon Sep 17 00:00:00 2001 From: James Carty Date: Fri, 17 Aug 2018 22:35:04 +0100 Subject: [PATCH 6/6] Fix incorrect function call --- apps/openmw/mwmechanics/mechanicsmanagerimp.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp index a46204e668..42e46016a5 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp @@ -1512,7 +1512,7 @@ namespace MWMechanics const MWMechanics::NpcStats& victimStats = victim.getClass().getNpcStats(victim); const MWWorld::Ptr &player = getPlayer(); - bool canCommit = attacker == player && canCommitCrimeAgainst(attacker, victim); + bool canCommit = attacker == player && canCommitCrimeAgainst(victim, attacker); // For now we report only about crimes of player and player's followers if (attacker != player)