From 4b30a44816e5ca36550c5b4ed9b58fb133dae610 Mon Sep 17 00:00:00 2001 From: David Cernat Date: Fri, 6 Jul 2018 14:17:54 +0300 Subject: [PATCH] [Client] Compare crimeTime and deathTime when NPCs forgive player crimes Previously, all crime witnesses stopped being hostile to a respawning player for as long as the player's diedSinceArrestAttempt was true. That meant that, in an area with no guards to arrest the player, crime witnesses did not enage in combat with the player at all ever again until diedSinceArrestAttempt became false. This commit makes it so the time of the last crime is recorded for each witness, and that is then compared with the time of the LocalPlayer's last death for a one-time crime forgiveness during that player's current life. This is essentially a gameplay adjustment for "singleplayer with respawns," and will have to be reworked to make sense for every player in multiplayer, though that requires reworking the crime system as a whole and is thus on hold. --- apps/openmw/mwmechanics/actors.cpp | 14 ++++++++---- apps/openmw/mwmechanics/npcstats.cpp | 30 ++++++++++++++++++++++++++ apps/openmw/mwmechanics/npcstats.hpp | 32 ++++++++++++++++++++++++++++ apps/openmw/mwmp/LocalPlayer.cpp | 5 +++++ apps/openmw/mwmp/LocalPlayer.hpp | 2 ++ 5 files changed, 79 insertions(+), 4 deletions(-) diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index 0fd87592a..9006c81af 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -1197,16 +1197,22 @@ namespace MWMechanics /* Start of tes3mp addition - If the player has died, stop combat with them as though they had - paid their bounty + If the player has died since their crime was committed, stop combat + with them as though they have paid their bounty */ - else if (mwmp::Main::get().getLocalPlayer()->diedSinceArrestAttempt) + else if (mwmp::Main::get().getLocalPlayer()->diedSinceArrestAttempt && creatureStats.getAiSequence().isInCombat(player)) { - if (creatureStats.getAiSequence().isInCombat(player)) + if (difftime(mwmp::Main::get().getLocalPlayer()->deathTime, npcStats.getCrimeTime())) { creatureStats.getAiSequence().stopCombat(); creatureStats.setAttacked(false); creatureStats.setAlarmed(false); + creatureStats.setAiSetting(CreatureStats::AI_Fight, ptr.getClass().getBaseFightRating(ptr)); + + npcStats.setCrimeId(-1); + npcStats.setCrimeTime(time(0)); + LOG_MESSAGE_SIMPLE(Log::LOG_INFO, "NPC %s %i-%i has forgiven player's crimes after the player's death", + ptr.getCellRef().getRefId().c_str(), ptr.getCellRef().getRefNum().mIndex, ptr.getCellRef().getMpNum()); } } /* diff --git a/apps/openmw/mwmechanics/npcstats.cpp b/apps/openmw/mwmechanics/npcstats.cpp index b4f5545e9..e80a38552 100644 --- a/apps/openmw/mwmechanics/npcstats.cpp +++ b/apps/openmw/mwmechanics/npcstats.cpp @@ -324,6 +324,25 @@ void MWMechanics::NpcStats::setSkillIncrease(int attribute, int value) End of tes3mp addition */ +/* + Start of tes3mp addition + + Make it possible to get and set the time of the last crime witnessed by the NPC, + used to stop combat with a player after that player dies and is resurrected +*/ +std::time_t MWMechanics::NpcStats::getCrimeTime() +{ + return mCrimeTime; +} + +void MWMechanics::NpcStats::setCrimeTime(std::time_t crimeTime) +{ + mCrimeTime = crimeTime; +} +/* + End of tes3mp addition +*/ + void MWMechanics::NpcStats::levelUp() { const MWWorld::Store &gmst = @@ -412,6 +431,17 @@ int MWMechanics::NpcStats::getCrimeId() const void MWMechanics::NpcStats::setCrimeId(int id) { mCrimeId = id; + + /* + Start of tes3mp addition + + Record this as the time of the last crime witnessed by this NPC + */ + if (id != -1) + setCrimeTime(time(0)); + /* + End of tes3mp addition + */ } bool MWMechanics::NpcStats::hasSkillsForRank (const std::string& factionId, int rank) const diff --git a/apps/openmw/mwmechanics/npcstats.hpp b/apps/openmw/mwmechanics/npcstats.hpp index 69e7df3bb..c4ffa99e6 100644 --- a/apps/openmw/mwmechanics/npcstats.hpp +++ b/apps/openmw/mwmechanics/npcstats.hpp @@ -6,6 +6,16 @@ #include #include +/* + Start of tes3mp addition + + Include additional headers for multiplayer purposes +*/ +#include +/* + End of tes3mp addition +*/ + #include "creaturestats.hpp" namespace ESM @@ -26,6 +36,16 @@ namespace MWMechanics int mReputation; int mCrimeId; + /* + Start of tes3mp addition + + Add a variable used to track the time of the most recent crime by a player + */ + time_t mCrimeTime = time(0); + /* + End of tes3mp addition + */ + // ----- used by the player only, maybe should be moved at some point ------- int mBounty; int mWerewolfKills; @@ -97,6 +117,18 @@ namespace MWMechanics End of tes3mp addition */ + /* + Start of tes3mp addition + + Make it possible to get and set the time of the last crime witnessed by the NPC, + used to stop combat with a player after that player dies and is resurrected + */ + time_t getCrimeTime(); + void setCrimeTime(time_t crimeTime); + /* + End of tes3mp addition + */ + int getLevelupAttributeMultiplier(int attribute) const; int getSkillIncreasesForSpecialization(int spec) const; diff --git a/apps/openmw/mwmp/LocalPlayer.cpp b/apps/openmw/mwmp/LocalPlayer.cpp index 767397b0d..d20c3f28a 100644 --- a/apps/openmw/mwmp/LocalPlayer.cpp +++ b/apps/openmw/mwmp/LocalPlayer.cpp @@ -44,6 +44,8 @@ using namespace std; LocalPlayer::LocalPlayer() { + deathTime = time(0); + charGenState.currentStage = 0; charGenState.endStage = 1; charGenState.isFinished = false; @@ -800,6 +802,9 @@ void LocalPlayer::resurrect() // Record that the player has died since the last attempt was made to arrest them, // used to make guards lenient enough to attempt an arrest again diedSinceArrestAttempt = true; + + deathTime = time(0); + LOG_APPEND(Log::LOG_INFO, "- diedSinceArrestAttempt is now true"); // Record that we are no longer a known werewolf, to avoid being attacked infinitely diff --git a/apps/openmw/mwmp/LocalPlayer.hpp b/apps/openmw/mwmp/LocalPlayer.hpp index 4e67a8605..36c114da0 100644 --- a/apps/openmw/mwmp/LocalPlayer.hpp +++ b/apps/openmw/mwmp/LocalPlayer.hpp @@ -15,6 +15,8 @@ namespace mwmp LocalPlayer(); virtual ~LocalPlayer(); + time_t deathTime; + void update(); bool processCharGen();