diff --git a/apps/openmw/mwclass/creature.cpp b/apps/openmw/mwclass/creature.cpp index fb6b02e29..79c9d9bb1 100644 --- a/apps/openmw/mwclass/creature.cpp +++ b/apps/openmw/mwclass/creature.cpp @@ -411,17 +411,31 @@ namespace MWClass if (!attacker.isEmpty() && attacker.getClass().isActor() && !ptr.isEmpty() && ptr.getClass().isActor()) { MWMechanics::CreatureStats& statsAttacker = attacker.getClass().getCreatureStats(attacker); + + /* + Start of tes3mp change (minor) + + Instead of only checking whether an attacker is the LocalPlayer, also + check if they are a DedicatedPlayer + */ + // First handle the attacked actor if ((stats.getHitAttemptActorId() == -1) && (statsAttacker.getAiSequence().isInCombat(ptr) - || attacker == MWMechanics::getPlayer())) + || attacker == MWMechanics::getPlayer() + || mwmp::PlayerList::isDedicatedPlayer(attacker))) stats.setHitAttemptActorId(statsAttacker.getActorId()); // Next handle the attacking actor if ((statsAttacker.getHitAttemptActorId() == -1) && (statsAttacker.getAiSequence().isInCombat(ptr) - || attacker == MWMechanics::getPlayer())) + || attacker == MWMechanics::getPlayer() + || mwmp::PlayerList::isDedicatedPlayer(attacker))) statsAttacker.setHitAttemptActorId(stats.getActorId()); + + /* + End of tes3mp change (minor) + */ } if (!object.isEmpty()) diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index 0482172e7..a71ea38a1 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -740,17 +740,31 @@ namespace MWClass if (!attacker.isEmpty() && attacker.getClass().isActor() && !ptr.isEmpty() && ptr.getClass().isActor()) { MWMechanics::CreatureStats& statsAttacker = attacker.getClass().getCreatureStats(attacker); + + /* + Start of tes3mp change (minor) + + Instead of only checking whether an attacker is the LocalPlayer, also + check if they are a DedicatedPlayer + */ + // First handle the attacked actor if ((stats.getHitAttemptActorId() == -1) && (statsAttacker.getAiSequence().isInCombat(ptr) - || attacker == MWMechanics::getPlayer())) + || attacker == MWMechanics::getPlayer() + || mwmp::PlayerList::isDedicatedPlayer(attacker))) stats.setHitAttemptActorId(statsAttacker.getActorId()); // Next handle the attacking actor if ((statsAttacker.getHitAttemptActorId() == -1) && (statsAttacker.getAiSequence().isInCombat(ptr) - || attacker == MWMechanics::getPlayer())) + || attacker == MWMechanics::getPlayer() + || mwmp::PlayerList::isDedicatedPlayer(attacker))) statsAttacker.setHitAttemptActorId(stats.getActorId()); + + /* + End of tes3mp change (minor) + */ } if (!object.isEmpty()) diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index 243946d86..f068812fa 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -1189,16 +1189,26 @@ namespace MWMechanics End of tes3mp addition */ + /* + Start of tes3mp change (major) + + Allow this code to use the same logic for DedicatedPlayers as for LocalPlayers + */ // If dead or no longer in combat, no longer store any actors who attempted to hit us. Also remove for the player. - if (iter->first != player && (iter->first.getClass().getCreatureStats(iter->first).isDead() + if (iter->first != player && !mwmp::PlayerList::isDedicatedPlayer(iter->first) &&(iter->first.getClass().getCreatureStats(iter->first).isDead() || !iter->first.getClass().getCreatureStats(iter->first).getAiSequence().isInCombat() || !inProcessingRange)) { iter->first.getClass().getCreatureStats(iter->first).setHitAttemptActorId(-1); if (player.getClass().getCreatureStats(player).getHitAttemptActorId() == iter->first.getClass().getCreatureStats(iter->first).getActorId()) player.getClass().getCreatureStats(player).setHitAttemptActorId(-1); + + mwmp::PlayerList::clearHitAttemptActorId(iter->first.getClass().getCreatureStats(iter->first).getActorId()); } + /* + End of tes3mp change (major) + */ const MWWorld::Ptr playerHitAttemptActor = MWBase::Environment::get().getWorld()->searchPtrViaActorId(player.getClass().getCreatureStats(player).getHitAttemptActorId()); diff --git a/apps/openmw/mwmp/PlayerList.cpp b/apps/openmw/mwmp/PlayerList.cpp index 9c3d6ddcd..13848a2b0 100644 --- a/apps/openmw/mwmp/PlayerList.cpp +++ b/apps/openmw/mwmp/PlayerList.cpp @@ -264,3 +264,23 @@ bool PlayerList::isDedicatedPlayer(const MWWorld::Ptr &ptr) return (getPlayer(ptr) != 0); } + +/* + Go through all DedicatedPlayers checking if their mHitAttemptActorId matches this one + and set it to -1 if it does + + This resets the combat target for a DedicatedPlayer's followers in Actors::update() +*/ +void PlayerList::clearHitAttemptActorId(int actorId) +{ + for (std::map ::iterator it = players.begin(); it != players.end(); it++) + { + if (it->second == 0 || it->second->getPtr().mRef == 0) + continue; + + MWMechanics::CreatureStats *playerCreatureStats = &it->second->getPtr().getClass().getCreatureStats(it->second->getPtr()); + + if (playerCreatureStats->getHitAttemptActorId() == actorId) + playerCreatureStats->setHitAttemptActorId(-1); + } +} diff --git a/apps/openmw/mwmp/PlayerList.hpp b/apps/openmw/mwmp/PlayerList.hpp index 1f5e4478a..84c39077e 100644 --- a/apps/openmw/mwmp/PlayerList.hpp +++ b/apps/openmw/mwmp/PlayerList.hpp @@ -38,6 +38,8 @@ namespace mwmp static bool isDedicatedPlayer(const MWWorld::Ptr &ptr); + static void clearHitAttemptActorId(int actorId); + private: static std::map players;