diff --git a/src/server/game/Battlefield/Zones/BattlefieldWG.cpp b/src/server/game/Battlefield/Zones/BattlefieldWG.cpp index e931557773..4ec8f9a3b9 100644 --- a/src/server/game/Battlefield/Zones/BattlefieldWG.cpp +++ b/src/server/game/Battlefield/Zones/BattlefieldWG.cpp @@ -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 diff --git a/src/server/game/Battlefield/Zones/BattlefieldWG.h b/src/server/game/Battlefield/Zones/BattlefieldWG.h index 6f3ccc6f70..8d163424b7 100644 --- a/src/server/game/Battlefield/Zones/BattlefieldWG.h +++ b/src/server/game/Battlefield/Zones/BattlefieldWG.h @@ -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); } }