From 642bd1936b341a098d7c8d5f3089988409e4d6bb Mon Sep 17 00:00:00 2001 From: Axel Cocat Date: Thu, 27 Jul 2023 13:37:20 +0200 Subject: [PATCH] fix(Core/Arena): allow crossfaction arena teams (#16823) --- .../apps/worldserver/worldserver.conf.dist | 8 ++++ src/server/game/Battlegrounds/Arena.cpp | 42 ++++++++++++++++++ src/server/game/Handlers/ArenaTeamHandler.cpp | 4 +- src/server/game/Handlers/PetitionsHandler.cpp | 43 +++++++++++-------- src/server/game/World/IWorld.h | 1 + src/server/game/World/World.cpp | 1 + 6 files changed, 78 insertions(+), 21 deletions(-) diff --git a/src/server/apps/worldserver/worldserver.conf.dist b/src/server/apps/worldserver/worldserver.conf.dist index be7c50cf7..4efa2d5db 100644 --- a/src/server/apps/worldserver/worldserver.conf.dist +++ b/src/server/apps/worldserver/worldserver.conf.dist @@ -1563,6 +1563,14 @@ AllowTwoSide.Interaction.Group = 0 AllowTwoSide.Interaction.Guild = 0 +# +# AllowTwoSide.Interaction.Arena +# Description: Allow joining arena teams between factions. +# Default: 0 - (Disabled) +# 1 - (Enabled) + +AllowTwoSide.Interaction.Arena = 0 + # # AllowTwoSide.Interaction.Auction # Description: Allow auctions between factions. diff --git a/src/server/game/Battlegrounds/Arena.cpp b/src/server/game/Battlegrounds/Arena.cpp index dfb84271d..bfc27f00d 100644 --- a/src/server/game/Battlegrounds/Arena.cpp +++ b/src/server/game/Battlegrounds/Arena.cpp @@ -17,6 +17,7 @@ #include "Arena.h" #include "ArenaTeamMgr.h" +#include "GroupMgr.h" #include "Log.h" #include "ObjectAccessor.h" #include "Player.h" @@ -93,6 +94,47 @@ void Arena::AddPlayer(Player* player) } UpdateArenaWorldState(); + + Group* group = player->GetGroup(); + if (group) + { + // Hackfix for crossfaction arenas, recreate group when joining + // Without this, players in a crossfaction arena group would not be able to cast beneficial spells on their teammates + + std::vector members; + bool isCrossfaction = false; + for (Group::member_citerator mitr = group->GetMemberSlots().begin(); mitr != group->GetMemberSlots().end(); ++mitr) + { + Player* member = ObjectAccessor::FindPlayer(mitr->guid); + if (!member || member->GetGUID() == player->GetGUID()) + { + continue; + } + members.push_back(member); + if (member->GetTeamId(true) != player->GetTeamId(true)) + { + isCrossfaction = true; + } + } + + if (isCrossfaction) + { + for (Player* member : members) + { + member->RemoveFromGroup(); + } + group->Disband(); + + group = new Group(); + SetBgRaid(player->GetBgTeamId(), group); + group->Create(player); + sGroupMgr->AddGroup(group); + for (Player* member : members) + { + group->AddMember(member); + } + } + } } void Arena::RemovePlayer(Player* /*player*/) diff --git a/src/server/game/Handlers/ArenaTeamHandler.cpp b/src/server/game/Handlers/ArenaTeamHandler.cpp index 98455adfd..e48b6bbbf 100644 --- a/src/server/game/Handlers/ArenaTeamHandler.cpp +++ b/src/server/game/Handlers/ArenaTeamHandler.cpp @@ -133,7 +133,7 @@ void WorldSession::HandleArenaTeamInviteOpcode(WorldPacket& recvData) if (player->GetSocial()->HasIgnore(GetPlayer()->GetGUID())) return; - if (!sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD) && player->GetTeamId() != GetPlayer()->GetTeamId()) + if (!sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_ARENA) && player->GetTeamId() != GetPlayer()->GetTeamId()) { SendArenaTeamCommandResult(ERR_ARENA_TEAM_INVITE_SS, "", "", ERR_ARENA_TEAM_NOT_ALLIED); return; @@ -185,7 +185,7 @@ void WorldSession::HandleArenaTeamAcceptOpcode(WorldPacket& /*recvData*/) } // Only allow members of the other faction to join the team if cross faction interaction is enabled - if (!sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD) && _player->GetTeamId() != sCharacterCache->GetCharacterTeamByGuid(arenaTeam->GetCaptain())) + if (!sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_ARENA) && _player->GetTeamId() != sCharacterCache->GetCharacterTeamByGuid(arenaTeam->GetCaptain())) { SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, "", "", ERR_ARENA_TEAM_NOT_ALLIED); return; diff --git a/src/server/game/Handlers/PetitionsHandler.cpp b/src/server/game/Handlers/PetitionsHandler.cpp index 0f159d1fe..79b9f703e 100644 --- a/src/server/game/Handlers/PetitionsHandler.cpp +++ b/src/server/game/Handlers/PetitionsHandler.cpp @@ -414,18 +414,14 @@ void WorldSession::HandlePetitionSignOpcode(WorldPacket& recvData) if (!signatures) return; - // not let enemies sign guild charter - if (!sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD) && GetPlayer()->GetTeamId() != sCharacterCache->GetCharacterTeamByGuid(petition->ownerGuid)) - { - if (type != GUILD_CHARTER_TYPE) - SendArenaTeamCommandResult(ERR_ARENA_TEAM_INVITE_SS, "", "", ERR_ARENA_TEAM_NOT_ALLIED); - else - Guild::SendCommandResult(this, GUILD_COMMAND_CREATE, ERR_GUILD_NOT_ALLIED); - return; - } - if (type != GUILD_CHARTER_TYPE) { + if (!sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_ARENA) && GetPlayer()->GetTeamId() != sCharacterCache->GetCharacterTeamByGuid(petition->ownerGuid)) + { + SendArenaTeamCommandResult(ERR_ARENA_TEAM_INVITE_SS, "", "", ERR_ARENA_TEAM_NOT_ALLIED); + return; + } + if (_player->GetLevel() < sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL)) { SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, "", _player->GetName().c_str(), ERR_ARENA_TEAM_TARGET_TOO_LOW_S); @@ -450,6 +446,12 @@ void WorldSession::HandlePetitionSignOpcode(WorldPacket& recvData) } else { + if (!sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD) && GetPlayer()->GetTeamId() != sCharacterCache->GetCharacterTeamByGuid(petition->ownerGuid)) + { + Guild::SendCommandResult(this, GUILD_COMMAND_CREATE, ERR_GUILD_NOT_ALLIED); + return; + } + if (_player->GetGuildId()) { Guild::SendCommandResult(this, GUILD_COMMAND_INVITE, ERR_ALREADY_IN_GUILD_S, _player->GetName()); @@ -565,17 +567,14 @@ void WorldSession::HandleOfferPetitionOpcode(WorldPacket& recvData) if (!petition) return; - if (GetPlayer()->GetTeamId() != player->GetTeamId()) - { - if (petition->petitionType != GUILD_CHARTER_TYPE) - SendArenaTeamCommandResult(ERR_ARENA_TEAM_INVITE_SS, "", "", ERR_ARENA_TEAM_NOT_ALLIED); - else - Guild::SendCommandResult(this, GUILD_COMMAND_CREATE, ERR_GUILD_NOT_ALLIED); - return; - } - if (petition->petitionType != GUILD_CHARTER_TYPE) { + if (GetPlayer()->GetTeamId() != player->GetTeamId() && !sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_ARENA)) + { + SendArenaTeamCommandResult(ERR_ARENA_TEAM_INVITE_SS, "", "", ERR_ARENA_TEAM_NOT_ALLIED); + return; + } + if (player->GetLevel() < sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL)) { // player is too low level to join an arena team @@ -602,6 +601,12 @@ void WorldSession::HandleOfferPetitionOpcode(WorldPacket& recvData) } else { + if (GetPlayer()->GetTeamId() != player->GetTeamId() && !sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD)) + { + Guild::SendCommandResult(this, GUILD_COMMAND_CREATE, ERR_GUILD_NOT_ALLIED); + return; + } + if (player->GetGuildId()) { Guild::SendCommandResult(this, GUILD_COMMAND_INVITE, ERR_ALREADY_IN_GUILD_S, _player->GetName()); diff --git a/src/server/game/World/IWorld.h b/src/server/game/World/IWorld.h index 2c8eac640..46f3b267c 100644 --- a/src/server/game/World/IWorld.h +++ b/src/server/game/World/IWorld.h @@ -79,6 +79,7 @@ enum WorldBoolConfigs CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHANNEL, CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP, CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD, + CONFIG_ALLOW_TWO_SIDE_INTERACTION_ARENA, CONFIG_ALLOW_TWO_SIDE_INTERACTION_AUCTION, CONFIG_ALLOW_TWO_SIDE_INTERACTION_MAIL, CONFIG_ALLOW_TWO_SIDE_WHO_LIST, diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index 559186f01..fd0c836b5 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -730,6 +730,7 @@ void World::LoadConfigSettings(bool reload) _bool_configs[CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHANNEL] = sConfigMgr->GetOption("AllowTwoSide.Interaction.Channel", false); _bool_configs[CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP] = sConfigMgr->GetOption("AllowTwoSide.Interaction.Group", false); _bool_configs[CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD] = sConfigMgr->GetOption("AllowTwoSide.Interaction.Guild", false); + _bool_configs[CONFIG_ALLOW_TWO_SIDE_INTERACTION_ARENA] = sConfigMgr->GetOption("AllowTwoSide.Interaction.Arena", false); _bool_configs[CONFIG_ALLOW_TWO_SIDE_INTERACTION_AUCTION] = sConfigMgr->GetOption("AllowTwoSide.Interaction.Auction", false); _bool_configs[CONFIG_ALLOW_TWO_SIDE_INTERACTION_MAIL] = sConfigMgr->GetOption("AllowTwoSide.Interaction.Mail", false); _bool_configs[CONFIG_ALLOW_TWO_SIDE_WHO_LIST] = sConfigMgr->GetOption("AllowTwoSide.WhoList", false);