From 20e37c87ab69665e0d9b111b3c88e4caeac04a5a Mon Sep 17 00:00:00 2001 From: FrancescoBorzi Date: Tue, 16 Jun 2026 13:02:02 +0200 Subject: [PATCH] fix: enforce assigned-team consistency in BGs --- src/CFBG.cpp | 51 ++++++++++++++++++++++++++++++++++++++----------- src/CFBG.h | 3 +++ src/CFBG_SC.cpp | 13 ++++++++++++- 3 files changed, 55 insertions(+), 12 deletions(-) diff --git a/src/CFBG.cpp b/src/CFBG.cpp index 95f22d2..445d15a 100644 --- a/src/CFBG.cpp +++ b/src/CFBG.cpp @@ -274,21 +274,18 @@ void CFBG::ValidatePlayerForBG(Battleground* bg, Player* player) BalanceTeamsOnEntry(bg, player); - TeamId teamId{ player->GetBgTeamId() }; + TeamId const assigned = player->GetBgTeamId(); - if (player->GetTeamId(true) == teamId) - return; - - BGData& bgdata = player->GetBGData(); - - if (bgdata.bgTeamId != teamId) - bgdata.bgTeamId = teamId; + // Keep bgTeamId authoritative (also covers the TEAM_NEUTRAL bootstrap where GetBgTeamId() falls back to m_team) + player->GetBGData().bgTeamId = assigned; - SetFakeRaceAndMorph(player); + EnforceBGTeamConsistency(player); - if (bg->GetMapId() == MapAlteracValley) + // AV forced reactions apply only to a cross-faction (faked) player; + // a native player already holds the correct Frostwolf/Stormpike standings. + if (!IsPlayingNative(player) && bg->GetMapId() == MapAlteracValley) { - if (teamId == TEAM_HORDE) + if (assigned == TEAM_HORDE) { player->GetReputationMgr().ApplyForceReaction(FACTION_FROSTWOLF_CLAN, REP_FRIENDLY, true); player->GetReputationMgr().ApplyForceReaction(FACTION_STORMPIKE_GUARD, REP_HOSTILE, true); @@ -303,6 +300,38 @@ void CFBG::ValidatePlayerForBG(Battleground* bg, Player* player) } } +void CFBG::EnforceBGTeamConsistency(Player* player) +{ + if (!player || !player->InBattleground()) + return; + + Battleground* bg = player->GetBattleground(); + if (!bg || bg->isArena()) + return; + + TeamId const assigned = player->GetBgTeamId(); + + // Native: must not carry a fake. + if (player->GetTeamId(true) == assigned) + { + if (IsPlayerFake(player)) + ClearFakePlayer(player); + return; + } + + // Cross-faction: must be faked to `assigned`. + FakePlayer const* info = GetFakePlayer(player); + if (!info) + SetFakeRaceAndMorph(player); // not faked yet -> apply + else if (info->FakeTeamID != assigned) + { + ClearFakePlayer(player); // stale wrong-team fake -> redo + SetFakeRaceAndMorph(player); + } + else + ReapplyFakePlayer(player); // correct side -> re-push reset values +} + void CFBG::BalanceTeamsOnEntry(Battleground* bg, Player* player) { // The invite-time team was chosen using level/ilvl, but declined invites can diff --git a/src/CFBG.h b/src/CFBG.h index de58498..ac894ae 100644 --- a/src/CFBG.h +++ b/src/CFBG.h @@ -160,6 +160,9 @@ class CFBG bool IsPlayingNative(Player* player); void ValidatePlayerForBG(Battleground* bg, Player* player); + // Forces race/faction/m_team/fake-store into agreement with the player's + // assigned BG team (GetBgTeamId()); idempotent and self-correcting. + void EnforceBGTeamConsistency(Player* player); void SetFakeRaceAndMorph(Player* player); void SetFakeRaceAndMorphForBF(Player* player, TeamId assignedTeam); void SetFactionForRace(Player* player, uint8 Race, TeamId teamId); diff --git a/src/CFBG_SC.cpp b/src/CFBG_SC.cpp index e1b9181..b101fe0 100644 --- a/src/CFBG_SC.cpp +++ b/src/CFBG_SC.cpp @@ -218,7 +218,18 @@ class CFBG_Player : public PlayerScript void OnPlayerResurrect(Player* player, float /*restorePercent*/, bool& /*applySickness*/) override { - if (!sCFBG->IsEnableSystem() || !sCFBG->IsEnableWGSystem() || !sCFBG->IsEnableWGReapplyOnResurrect()) + if (!sCFBG->IsEnableSystem()) + return; + + // Battleground fakes are not re-pushed elsewhere on resurrect; + // re-assert assigned-team consistency after the ghost->alive transition. + if (player->InBattleground()) + { + sCFBG->EnforceBGTeamConsistency(player); + return; + } + + if (!sCFBG->IsEnableWGSystem() || !sCFBG->IsEnableWGReapplyOnResurrect()) return; if (!sCFBG->IsPlayerFake(player))