From b3d984a9b1bd855e2f048f193e51730fe462bfcb Mon Sep 17 00:00:00 2001 From: Evil Eye Date: Wed, 18 Dec 2024 23:46:00 +0100 Subject: [PATCH] Replace HitAttemptActorId with a RefNum --- apps/openmw/mwclass/creature.cpp | 8 +++--- apps/openmw/mwclass/npc.cpp | 8 +++--- apps/openmw/mwmechanics/actors.cpp | 26 +++++++++++-------- apps/openmw/mwmechanics/aicombat.cpp | 9 +++++-- apps/openmw/mwmechanics/creaturestats.cpp | 8 +++--- apps/openmw/mwmechanics/creaturestats.hpp | 6 ++--- .../mwmechanics/mechanicsmanagerimp.cpp | 5 ++-- apps/openmw/mwworld/player.cpp | 1 + 8 files changed, 41 insertions(+), 30 deletions(-) diff --git a/apps/openmw/mwclass/creature.cpp b/apps/openmw/mwclass/creature.cpp index c2c930ce1b..7effead29f 100644 --- a/apps/openmw/mwclass/creature.cpp +++ b/apps/openmw/mwclass/creature.cpp @@ -376,14 +376,14 @@ namespace MWClass { MWMechanics::CreatureStats& statsAttacker = attacker.getClass().getCreatureStats(attacker); // First handle the attacked actor - if ((stats.getHitAttemptActorId() == -1) + if (!stats.getHitAttemptActor().isSet() && (statsAttacker.getAiSequence().isInCombat(ptr) || attacker == MWMechanics::getPlayer())) - stats.setHitAttemptActorId(statsAttacker.getActorId()); + stats.setHitAttemptActor(attacker.getCellRef().getRefNum()); // Next handle the attacking actor - if ((statsAttacker.getHitAttemptActorId() == -1) + if (!statsAttacker.getHitAttemptActor().isSet() && (statsAttacker.getAiSequence().isInCombat(ptr) || attacker == MWMechanics::getPlayer())) - statsAttacker.setHitAttemptActorId(stats.getActorId()); + statsAttacker.setHitAttemptActor(ptr.getCellRef().getRefNum()); } if (!object.empty()) diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index fd62765e61..7af84d1a48 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -728,14 +728,14 @@ namespace MWClass { MWMechanics::CreatureStats& statsAttacker = attacker.getClass().getCreatureStats(attacker); // First handle the attacked actor - if ((stats.getHitAttemptActorId() == -1) + if (!stats.getHitAttemptActor().isSet() && (statsAttacker.getAiSequence().isInCombat(ptr) || attacker == MWMechanics::getPlayer())) - stats.setHitAttemptActorId(statsAttacker.getActorId()); + stats.setHitAttemptActor(attacker.getCellRef().getRefNum()); // Next handle the attacking actor - if ((statsAttacker.getHitAttemptActorId() == -1) + if (!statsAttacker.getHitAttemptActor().isSet() && (statsAttacker.getAiSequence().isInCombat(ptr) || attacker == MWMechanics::getPlayer())) - statsAttacker.setHitAttemptActorId(stats.getActorId()); + statsAttacker.setHitAttemptActor(ptr.getCellRef().getRefNum()); } if (!object.empty()) diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index 786539e585..9e0279e8b9 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -25,6 +25,7 @@ #include "../mwworld/inventorystore.hpp" #include "../mwworld/player.hpp" #include "../mwworld/scene.hpp" +#include "../mwworld/worldmodel.hpp" #include "../mwbase/dialoguemanager.hpp" #include "../mwbase/environment.hpp" @@ -641,12 +642,13 @@ namespace MWMechanics if (creatureStats1.getAiSequence().isInCombat(ally)) continue; - if (creatureStats2.matchesActorId(ally.getClass().getCreatureStats(ally).getHitAttemptActorId())) + ESM::RefNum allyHitNum = ally.getClass().getCreatureStats(ally).getHitAttemptActor(); + if (allyHitNum.isSet() && actor2.getCellRef().getRefNum() == allyHitNum) { mechanicsManager->startCombat(actor1, actor2, &cachedAllies.getActorsSidingWith(actor2)); // Also set the same hit attempt actor. Otherwise, if fighting the player, they may stop combat // if the player gets out of reach, while the ally would continue combat with the player - creatureStats1.setHitAttemptActorId(ally.getClass().getCreatureStats(ally).getHitAttemptActorId()); + creatureStats1.setHitAttemptActor(allyHitNum); return; } @@ -1155,9 +1157,10 @@ namespace MWMechanics = esmStore.get().find("iCrimeThresholdMultiplier")->mValue.getInteger(); if (playerStats.getBounty() >= cutoff * iCrimeThresholdMultiplier) { + ESM::RefNum playerNum = player.getCellRef().getRefNum(); mechanicsManager->startCombat(ptr, player, &cachedAllies.getActorsSidingWith(player)); // Stops the guard from quitting combat if player is unreachable - creatureStats.setHitAttemptActorId(playerClass.getCreatureStats(player).getActorId()); + creatureStats.setHitAttemptActor(playerNum); } else creatureStats.getAiSequence().stack(AiPursue(player), ptr); @@ -1517,13 +1520,14 @@ namespace MWMechanics SidingCache cachedAllies{ *this, true }; // will be filled as engageCombat iterates const bool aiActive = MWBase::Environment::get().getMechanicsManager()->isAIActive(); - const int attackedByPlayerId = player.getClass().getCreatureStats(player).getHitAttemptActorId(); - if (attackedByPlayerId != -1) + const ESM::RefNum attackedByPlayerNum = player.getClass().getCreatureStats(player).getHitAttemptActor(); + if (attackedByPlayerNum.isSet()) { - const MWWorld::Ptr playerHitAttemptActor = world->searchPtrViaActorId(attackedByPlayerId); + const MWWorld::Ptr playerHitAttemptActor + = MWBase::Environment::get().getWorldModel()->getPtr(attackedByPlayerNum); if (!playerHitAttemptActor.isInCell()) - player.getClass().getCreatureStats(player).setHitAttemptActorId(-1); + player.getClass().getCreatureStats(player).setHitAttemptActor({}); } const int actorsProcessingRange = Settings::game().mActorsProcessingRange; @@ -1548,10 +1552,10 @@ namespace MWMechanics || !actor.getPtr().getClass().getCreatureStats(actor.getPtr()).getAiSequence().isInCombat() || !inProcessingRange)) { - actor.getPtr().getClass().getCreatureStats(actor.getPtr()).setHitAttemptActorId(-1); - if (player.getClass().getCreatureStats(player).getHitAttemptActorId() - == actor.getPtr().getClass().getCreatureStats(actor.getPtr()).getActorId()) - player.getClass().getCreatureStats(player).setHitAttemptActorId(-1); + actor.getPtr().getClass().getCreatureStats(actor.getPtr()).setHitAttemptActor({}); + ESM::RefNum playerHitNum = player.getClass().getCreatureStats(player).getHitAttemptActor(); + if (playerHitNum.isSet() && playerHitNum == actor.getPtr().getCellRef().getRefNum()) + player.getClass().getCreatureStats(player).setHitAttemptActor({}); } const Misc::TimerStatus engageCombatTimerStatus = actor.updateEngageCombatTimer(duration); diff --git a/apps/openmw/mwmechanics/aicombat.cpp b/apps/openmw/mwmechanics/aicombat.cpp index 0ddcf409b6..cd92e4cc96 100644 --- a/apps/openmw/mwmechanics/aicombat.cpp +++ b/apps/openmw/mwmechanics/aicombat.cpp @@ -36,6 +36,12 @@ namespace osg::Vec3f AimDirToMovingTarget(const MWWorld::Ptr& actor, const MWWorld::Ptr& target, const osg::Vec3f& vLastTargetPos, float duration, int weapType, float strength); + + bool hitAttemptMatchesTarget(const MWWorld::Ptr& actor, const MWWorld::Ptr& target) + { + ESM::RefNum hitNum = actor.getClass().getCreatureStats(actor).getHitAttemptActor(); + return hitNum.isSet() && target.getCellRef().getRefNum() == hitNum; + } } namespace MWMechanics @@ -194,8 +200,7 @@ namespace MWMechanics = (std::find(playerFollowersAndEscorters.begin(), playerFollowersAndEscorters.end(), target) != playerFollowersAndEscorters.end()); if ((target == MWMechanics::getPlayer() || targetSidesWithPlayer) - && ((stats.getHitAttemptActorId() == target.getClass().getCreatureStats(target).getActorId()) - || (target.getClass().getCreatureStats(target).getHitAttemptActorId() == stats.getActorId()))) + && (hitAttemptMatchesTarget(actor, target) || hitAttemptMatchesTarget(target, actor))) forceFlee = true; else // Otherwise end combat return true; diff --git a/apps/openmw/mwmechanics/creaturestats.cpp b/apps/openmw/mwmechanics/creaturestats.cpp index 24b5891c1c..3329d87cbf 100644 --- a/apps/openmw/mwmechanics/creaturestats.cpp +++ b/apps/openmw/mwmechanics/creaturestats.cpp @@ -365,14 +365,14 @@ namespace MWMechanics return mLastHitAttemptObject; } - void CreatureStats::setHitAttemptActorId(int actorId) + void CreatureStats::setHitAttemptActor(ESM::RefNum actor) { - mHitAttemptActorId = actorId; + mHitAttemptActor = actor; } - int CreatureStats::getHitAttemptActorId() const + ESM::RefNum CreatureStats::getHitAttemptActor() const { - return mHitAttemptActorId; + return mHitAttemptActor; } void CreatureStats::addToFallHeight(float height) diff --git a/apps/openmw/mwmechanics/creaturestats.hpp b/apps/openmw/mwmechanics/creaturestats.hpp index aa46e9504f..ab8e03a294 100644 --- a/apps/openmw/mwmechanics/creaturestats.hpp +++ b/apps/openmw/mwmechanics/creaturestats.hpp @@ -76,7 +76,7 @@ namespace MWMechanics int mActorId = -1; // Stores an actor that attacked this actor. Only one is stored at a time, and it is not changed if a different // actor attacks. It is cleared when combat ends. - int mHitAttemptActorId = -1; + ESM::RefNum mHitAttemptActor; // The difference between view direction and lower body direction. float mSideMovementAngle = 0; @@ -266,8 +266,8 @@ namespace MWMechanics void setLastHitAttemptObject(const ESM::RefId& objectid); void clearLastHitAttemptObject(); const ESM::RefId& getLastHitAttemptObject() const; - void setHitAttemptActorId(const int actorId); - int getHitAttemptActorId() const; + void setHitAttemptActor(ESM::RefNum actorId); + ESM::RefNum getHitAttemptActor() const; void writeState(ESM::CreatureStats& state) const; diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp index a494153543..3db7015d63 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp @@ -1734,8 +1734,9 @@ namespace MWMechanics // if guard starts combat with player, guards pursuing player should do the same if (ptr.getClass().isClass(ptr, "Guard")) { + const ESM::RefNum playerNum = target.getCellRef().getRefNum(); // Stops guard from ending combat if player is unreachable - stats.setHitAttemptActorId(target.getClass().getCreatureStats(target).getActorId()); + stats.setHitAttemptActor(playerNum); for (const Actor& actor : mActors) { if (actor.isInvalid()) @@ -1752,7 +1753,7 @@ namespace MWMechanics actor.getPtr() .getClass() .getCreatureStats(actor.getPtr()) - .setHitAttemptActorId(target.getClass().getCreatureStats(target).getActorId()); + .setHitAttemptActor(playerNum); } } } diff --git a/apps/openmw/mwworld/player.cpp b/apps/openmw/mwworld/player.cpp index 7bbc469e07..a8cbdb447b 100644 --- a/apps/openmw/mwworld/player.cpp +++ b/apps/openmw/mwworld/player.cpp @@ -343,6 +343,7 @@ namespace MWWorld MWBase::Environment::get().getWorldModel()->deregisterLiveCellRef(mPlayer); mPlayer.load(player.mObject); + MWBase::Environment::get().getWorldModel()->registerPtr(getPlayer()); for (size_t i = 0; i < mSaveAttributes.size(); ++i) mSaveAttributes[i] = player.mSaveAttributes[i];