From c4950f1beb4cdc15c326e789cf4413623b35bd8a Mon Sep 17 00:00:00 2001 From: David Cernat Date: Tue, 3 Dec 2019 22:40:02 +0200 Subject: [PATCH] [Client] Implement PlayerTeam packet, part 2 When determining actors siding with someone, also check the team members of DedicatedPlayers, not just those of the LocalPlayer. Don't set players as each other's hitAttemptActor if they are team members. Don't run startCombat() for DedicatedPlayers who get attacked. --- apps/openmw/mwclass/creature.cpp | 9 ++++-- apps/openmw/mwclass/npc.cpp | 9 ++++-- apps/openmw/mwmechanics/actors.cpp | 18 ++++++++++- .../mwmechanics/mechanicsmanagerimp.cpp | 12 +++++++ apps/openmw/mwmp/MechanicsHelper.hpp | 2 +- .../processors/player/ProcessorPlayerTeam.hpp | 31 ++++++++++++++++--- 6 files changed, 71 insertions(+), 10 deletions(-) diff --git a/apps/openmw/mwclass/creature.cpp b/apps/openmw/mwclass/creature.cpp index 92861bcc2..833871b05 100644 --- a/apps/openmw/mwclass/creature.cpp +++ b/apps/openmw/mwclass/creature.cpp @@ -433,20 +433,25 @@ namespace MWClass Instead of only checking whether an attacker is the LocalPlayer, also check if they are a DedicatedPlayer + + Additionally, if the two players are on each other's team, don't track + their hits */ // First handle the attacked actor if ((stats.getHitAttemptActorId() == -1) && (statsAttacker.getAiSequence().isInCombat(ptr) || attacker == MWMechanics::getPlayer() - || mwmp::PlayerList::isDedicatedPlayer(attacker))) + || mwmp::PlayerList::isDedicatedPlayer(attacker)) + && !MechanicsHelper::isTeamMember(attacker, ptr)) stats.setHitAttemptActorId(statsAttacker.getActorId()); // Next handle the attacking actor if ((statsAttacker.getHitAttemptActorId() == -1) && (statsAttacker.getAiSequence().isInCombat(ptr) || attacker == MWMechanics::getPlayer() - || mwmp::PlayerList::isDedicatedPlayer(attacker))) + || mwmp::PlayerList::isDedicatedPlayer(attacker)) + && !MechanicsHelper::isTeamMember(ptr, attacker)) statsAttacker.setHitAttemptActorId(stats.getActorId()); /* diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index a4900b982..8360393b5 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -768,20 +768,25 @@ namespace MWClass Instead of only checking whether an attacker is the LocalPlayer, also check if they are a DedicatedPlayer + + Additionally, if the two players are on each other's team, don't track + their hits */ // First handle the attacked actor if ((stats.getHitAttemptActorId() == -1) && (statsAttacker.getAiSequence().isInCombat(ptr) || attacker == MWMechanics::getPlayer() - || mwmp::PlayerList::isDedicatedPlayer(attacker))) + || mwmp::PlayerList::isDedicatedPlayer(attacker)) + && !MechanicsHelper::isTeamMember(attacker, ptr)) stats.setHitAttemptActorId(statsAttacker.getActorId()); // Next handle the attacking actor if ((statsAttacker.getHitAttemptActorId() == -1) && (statsAttacker.getAiSequence().isInCombat(ptr) || attacker == MWMechanics::getPlayer() - || mwmp::PlayerList::isDedicatedPlayer(attacker))) + || mwmp::PlayerList::isDedicatedPlayer(attacker)) + && !MechanicsHelper::isTeamMember(ptr, attacker)) statsAttacker.setHitAttemptActorId(stats.getActorId()); /* diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index 7ab630860..2fdc60aa6 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -2363,8 +2363,11 @@ namespace MWMechanics /* Start of tes3mp addition - If we're checking a player and the iteratedActor is another player belonging to this one's teamMembers, + If we're checking the LocalPlayer and the iteratedActor is a DedicatedPlayer belonging to this one's teamMembers, include the iteratedActor in the actors siding with the player + + Alternatively, if we're checking a DedicatedPlayer and the iteratedActor is a LocalPlayer or DedicatedPlayer + belonging to their team members, include the iteratedActor in the actors siding with them */ if (actor == getPlayer() && mwmp::PlayerList::isDedicatedPlayer(iteratedActor)) { @@ -2373,6 +2376,19 @@ namespace MWMechanics list.push_back(iteratedActor); } } + else if (mwmp::PlayerList::isDedicatedPlayer(actor)) + { + if (iteratedActor == getPlayer() && + Utils::vectorContains(mwmp::PlayerList::getPlayer(actor)->teamMembers, mwmp::Main::get().getLocalPlayer()->guid)) + { + list.push_back(iteratedActor); + } + else if (mwmp::PlayerList::isDedicatedPlayer(iteratedActor) && + Utils::vectorContains(mwmp::PlayerList::getPlayer(actor)->teamMembers, mwmp::PlayerList::getPlayer(iteratedActor)->guid)) + { + list.push_back(iteratedActor); + } + } /* End of tes3mp addition */ diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp index 986c540fc..ccac57e82 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp @@ -1577,6 +1577,18 @@ namespace MWMechanics if (target == player || !attacker.getClass().isActor()) return false; + /* + Start of tes3mp change (major) + + Don't set DedicatedPlayers as being in combat with the attacker, to prevent + AI actors from deciding to reciprocate by also starting combat + */ + if (mwmp::PlayerList::isDedicatedPlayer(target)) + return false; + /* + End of tes3mp change (major) + */ + MWMechanics::CreatureStats& statsTarget = target.getClass().getCreatureStats(target); /* Start of tes3mp change (major) diff --git a/apps/openmw/mwmp/MechanicsHelper.hpp b/apps/openmw/mwmp/MechanicsHelper.hpp index c4bd358ad..a2f5cdf4f 100644 --- a/apps/openmw/mwmp/MechanicsHelper.hpp +++ b/apps/openmw/mwmp/MechanicsHelper.hpp @@ -38,7 +38,7 @@ namespace MechanicsHelper // Note: This is not supposed to also check if playerWithTeam is on playerChecked's // team, because it should technically be possible to be allied to someone // who isn't mutually allied to you - bool isTeamMember(const MWWorld::Ptr& playedChecked, const MWWorld::Ptr& playerWithTeam); + bool isTeamMember(const MWWorld::Ptr& playerChecked, const MWWorld::Ptr& playerWithTeam); bool getSpellSuccess(std::string spellId, const MWWorld::Ptr& caster); diff --git a/apps/openmw/mwmp/processors/player/ProcessorPlayerTeam.hpp b/apps/openmw/mwmp/processors/player/ProcessorPlayerTeam.hpp index 8d7464cb9..262165678 100644 --- a/apps/openmw/mwmp/processors/player/ProcessorPlayerTeam.hpp +++ b/apps/openmw/mwmp/processors/player/ProcessorPlayerTeam.hpp @@ -17,11 +17,11 @@ namespace mwmp virtual void Do(PlayerPacket &packet, BasePlayer *player) { + mwmp::LocalPlayer *localPlayer = mwmp::Main::get().getLocalPlayer(); + if (isLocal()) { - LOG_MESSAGE_SIMPLE(TimedLog::LOG_INFO, "Received ID_PLAYER_TEAM about LocalPlayer from server"); - - mwmp::LocalPlayer *localPlayer = mwmp::Main::get().getLocalPlayer(); + LOG_MESSAGE_SIMPLE(TimedLog::LOG_INFO, "Received ID_PLAYER_TEAM about LocalPlayer %s from server", localPlayer->npc.mName.c_str()); for (std::vector::iterator iter = localPlayer->teamMembers.begin(); iter != localPlayer->teamMembers.end(); ) { @@ -29,7 +29,30 @@ namespace mwmp if (dedicatedPlayer) { - LOG_APPEND(TimedLog::LOG_INFO, "- Adding %s to our team members", dedicatedPlayer->npc.mName.c_str()); + LOG_APPEND(TimedLog::LOG_INFO, "- Adding DedicatedPlayer %s to our team members", dedicatedPlayer->npc.mName.c_str()); + } + + ++iter; + } + } + else if (player != 0) + { + LOG_MESSAGE_SIMPLE(TimedLog::LOG_INFO, "Received ID_PLAYER_TEAM about DedicatedPlayer %s from server", player->npc.mName.c_str()); + + for (std::vector::iterator iter = player->teamMembers.begin(); iter != player->teamMembers.end(); ) + { + if (*iter == localPlayer->guid) + { + LOG_APPEND(TimedLog::LOG_INFO, "- Adding LocalPlayer %s to their team members", localPlayer->npc.mName.c_str()); + } + else + { + DedicatedPlayer *otherDedicatedPlayer = PlayerList::getPlayer(*iter); + + if (otherDedicatedPlayer) + { + LOG_APPEND(TimedLog::LOG_INFO, "- Adding DedicatedPlayer %s to their team members", otherDedicatedPlayer->npc.mName.c_str()); + } } ++iter;