From e0046d8ba8c712b89b9c9302658bd00fff02db44 Mon Sep 17 00:00:00 2001 From: Andrew <47818697+Nyeriah@users.noreply.github.com> Date: Sun, 24 May 2026 09:26:47 -0300 Subject: [PATCH] fix(Core/Battlefield): Restrict Within Our Grasp to attackers (#25945) Co-authored-by: Claude Opus 4.7 (1M context) --- src/server/game/Battlefield/BattlefieldMgr.cpp | 7 +++++++ src/server/game/Battlefield/BattlefieldMgr.h | 3 +++ src/server/game/Battlefield/Zones/BattlefieldWG.cpp | 3 +++ src/server/game/Battlefield/Zones/BattlefieldWG.h | 5 +++++ src/server/scripts/Northrend/zone_wintergrasp.cpp | 4 ++++ 5 files changed, 22 insertions(+) diff --git a/src/server/game/Battlefield/BattlefieldMgr.cpp b/src/server/game/Battlefield/BattlefieldMgr.cpp index 152102cb3..7b7dfff9e 100644 --- a/src/server/game/Battlefield/BattlefieldMgr.cpp +++ b/src/server/game/Battlefield/BattlefieldMgr.cpp @@ -112,6 +112,13 @@ Battlefield* BattlefieldMgr::GetBattlefieldByBattleId(uint32 battleId) return nullptr; } +bool BattlefieldMgr::IsWintergraspAttackerVictory() +{ + if (Battlefield* bf = GetBattlefieldByBattleId(BATTLEFIELD_BATTLEID_WG)) + return static_cast(bf)->IsLastBattleAttackerVictory(); + return false; +} + void BattlefieldMgr::Update(uint32 diff) { _updateTimer += diff; diff --git a/src/server/game/Battlefield/BattlefieldMgr.h b/src/server/game/Battlefield/BattlefieldMgr.h index c15bfa2cc..4f94743c9 100644 --- a/src/server/game/Battlefield/BattlefieldMgr.h +++ b/src/server/game/Battlefield/BattlefieldMgr.h @@ -47,6 +47,9 @@ public: Battlefield* GetBattlefieldToZoneId(uint32 zoneId); Battlefield* GetBattlefieldByBattleId(uint32 battleId); + // True iff the most recent Wintergrasp battle ended with the keep captured. + [[nodiscard]] bool IsWintergraspAttackerVictory(); + ZoneScript* GetZoneScript(uint32 zoneId); void AddZone(uint32 zoneId, Battlefield* handle); diff --git a/src/server/game/Battlefield/Zones/BattlefieldWG.cpp b/src/server/game/Battlefield/Zones/BattlefieldWG.cpp index 501cd4151..b6fb57392 100644 --- a/src/server/game/Battlefield/Zones/BattlefieldWG.cpp +++ b/src/server/game/Battlefield/Zones/BattlefieldWG.cpp @@ -348,6 +348,9 @@ void BattlefieldWG::CapturePointTaken(uint32 areaId) void BattlefieldWG::OnBattleEnd(bool endByTimer) { + // Must be set before SPELL_VICTORY_REWARD so the 1755 criterion can gate on it. + LastBattleAttackerVictory = !endByTimer; + // Remove relic if (GameObject* go = GetRelic()) go->RemoveFromWorld(); diff --git a/src/server/game/Battlefield/Zones/BattlefieldWG.h b/src/server/game/Battlefield/Zones/BattlefieldWG.h index 8ea7d3ef3..b5bc7ecf2 100644 --- a/src/server/game/Battlefield/Zones/BattlefieldWG.h +++ b/src/server/game/Battlefield/Zones/BattlefieldWG.h @@ -403,6 +403,9 @@ public: uint32 GetData(uint32 data) const override; + // True iff the most recent battle ended with the keep captured (attacker win). + [[nodiscard]] bool IsLastBattleAttackerVictory() const { return LastBattleAttackerVictory; } + bool IsKeepNpc(uint32 entry) { switch (entry) @@ -451,6 +454,8 @@ protected: int32 TenacityStack; ObjectGuid TitansRelic; + + bool LastBattleAttackerVictory{false}; }; uint8 const WG_MAX_OBJ = 32; diff --git a/src/server/scripts/Northrend/zone_wintergrasp.cpp b/src/server/scripts/Northrend/zone_wintergrasp.cpp index 770c8ae07..68c2917bd 100644 --- a/src/server/scripts/Northrend/zone_wintergrasp.cpp +++ b/src/server/scripts/Northrend/zone_wintergrasp.cpp @@ -1160,6 +1160,10 @@ public: if (!wintergrasp) return false; + // Attacker-only achievement -- defenders winning fast must not qualify. + if (!sBattlefieldMgr->IsWintergraspAttackerVictory()) + return false; + return wintergrasp->GetTimer() >= (20 * MINUTE * IN_MILLISECONDS); } };