fix(Core/Battlefield): repop ghosts when their Wintergrasp graveyard is captured (#26395)

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Andrew
2026-06-30 11:01:40 -03:00
committed by GitHub
parent 0769f095e0
commit b5ddd6f8bd
2 changed files with 35 additions and 0 deletions
@@ -23,6 +23,7 @@
#include "BattlefieldWG.h"
#include "ScriptMgr.h"
#include "Chat.h"
#include "GameGraveyard.h"
#include "GameTime.h"
#include "MapMgr.h"
#include "Opcodes.h"
@@ -580,6 +581,32 @@ uint32 BattlefieldWG::GetAreaByGraveyardId(uint8 gId) const
return 0;
}
void BattlefieldWG::RelocateDeadPlayers(uint8 graveyardId, TeamId newOwner)
{
BfGraveyard const* graveyard = GetGraveyardById(graveyardId);
if (!graveyard)
return;
GraveyardStruct const* capturedLoc = sGraveyard->GetGraveyard(graveyard->GetGraveyardId());
if (!capturedLoc)
return;
ForEachPlayerInZone([this, capturedLoc, newOwner](Player* player)
{
// Only players of the losing team waiting to resurrect; they would otherwise be
// revived in place on the now-inaccessible captured platform.
if (player->GetTeamId() == newOwner || !player->HasAura(SPELL_WAITING_FOR_RESURRECT))
return;
// Restrict to ghosts actually waiting at the captured graveyard, not elsewhere in the zone.
if (player->GetDistance2d(capturedLoc->x, capturedLoc->y) > 50.0f)
return;
if (GraveyardStruct const* safeLoc = GetClosestGraveyard(player))
player->TeleportTo(safeLoc->Map, safeLoc->x, safeLoc->y, safeLoc->z, player->GetOrientation());
});
}
void BattlefieldWG::OnCreatureCreate(Creature* creature)
{
// Accessing to db spawned creatures
@@ -400,6 +400,9 @@ public:
uint8 GetSpiritGraveyardId(uint32 areaId) const;
uint32 GetAreaByGraveyardId(uint8 gId) const;
// Teleport ghosts waiting at a just-captured graveyard to their team's nearest controlled one.
void RelocateDeadPlayers(uint8 graveyardId, TeamId newOwner);
uint32 GetData(uint32 data) const override;
// True iff the most recent battle ended with the keep captured (attacker win).
@@ -1469,6 +1472,11 @@ struct WGWorkshop
{
bf->UpdateCounterVehicle(false);
bf->CapturePointTaken(bf->GetAreaByGraveyardId(workshopId));
// Workshop graveyard share the workshop id; repop ghosts that lost it.
// Only on an actual capture, not while the workshop is merely contested (neutral).
if (IsCapturable() && teamControl != TEAM_NEUTRAL)
bf->RelocateDeadPlayers(workshopId, teamControl);
}
}