Skip to content

Commit 202580d

Browse files
Merge AzerothCore 3.3.5 to ElunaAzerothcore [skip ci]
2 parents 94d57e5 + 74b798c commit 202580d

9 files changed

Lines changed: 135 additions & 165 deletions

File tree

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
-- DB update 2026_05_26_00 -> 2026_05_28_00
2+
--
3+
DELETE FROM `spawn_group` WHERE `spawnId` IN (153154, 153155, 153156, 153157);
4+
INSERT INTO `spawn_group` (`groupId`, `spawnType`, `spawnId`) VALUES
5+
(1, 0, 153154),
6+
(1, 0, 153155),
7+
(1, 0, 153156),
8+
(1, 0, 153157);

src/server/game/Battlefield/Battlefield.cpp

Lines changed: 20 additions & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -74,19 +74,20 @@ Battlefield::~Battlefield()
7474
CapturePoints.clear();
7575
}
7676

77-
void Battlefield::HandlePlayerEnterZone(Player* player, uint32 /*zone*/)
77+
void Battlefield::RemovePlayerFromTracking(ObjectGuid playerGuid)
7878
{
79-
// Clear any stale entries from a prior visit that did not unwind cleanly.
80-
// Runs before the script hook so scripts see a clean state if they read any
81-
// of these containers.
8279
for (uint8 i = 0; i < PVP_TEAMS_COUNT; ++i)
8380
{
84-
PlayersInWar[i].erase(player->GetGUID());
85-
InvitedPlayers[i].erase(player->GetGUID());
86-
PlayersInQueue[i].erase(player->GetGUID());
87-
PlayersWillBeKick[i].erase(player->GetGUID());
88-
Players[i].erase(player->GetGUID());
81+
InvitedPlayers[i].erase(playerGuid);
82+
PlayersInQueue[i].erase(playerGuid);
83+
PlayersWillBeKick[i].erase(playerGuid);
84+
Players[i].erase(playerGuid);
8985
}
86+
}
87+
88+
void Battlefield::HandlePlayerEnterZone(Player* player, uint32 /*zone*/)
89+
{
90+
RemovePlayerFromTracking(player->GetGUID());
9091

9192
// Allow scripts to adjust the player's effective team or appearance before
9293
// any team-based battlefield containers (such as player lists or queues) are updated.
@@ -141,13 +142,7 @@ void Battlefield::HandlePlayerLeaveZone(Player* player, uint32 /*zone*/)
141142
for (BfCapturePoint* cp : CapturePoints)
142143
cp->HandlePlayerLeave(player);
143144

144-
for (uint8 i = 0; i < PVP_TEAMS_COUNT; ++i)
145-
{
146-
InvitedPlayers[i].erase(player->GetGUID());
147-
PlayersInQueue[i].erase(player->GetGUID());
148-
PlayersWillBeKick[i].erase(player->GetGUID());
149-
Players[i].erase(player->GetGUID());
150-
}
145+
RemovePlayerFromTracking(player->GetGUID());
151146
SendRemoveWorldStates(player);
152147
RemovePlayerFromResurrectQueue(player->GetGUID());
153148
OnPlayerLeaveZone(player);
@@ -634,34 +629,22 @@ GraveyardStruct const* Battlefield::GetClosestGraveyard(Player* player)
634629
return nullptr;
635630
}
636631

637-
void Battlefield::AddPlayerToResurrectQueue(ObjectGuid npcGuid, ObjectGuid playerGuid)
632+
void Battlefield::AddPlayerToResurrectQueue(ObjectGuid /*npcGuid*/, ObjectGuid playerGuid)
638633
{
639-
for (BfGraveyard* gy : GraveyardList)
640-
{
641-
if (!gy)
642-
continue;
634+
Player* player = ObjectAccessor::FindPlayer(playerGuid);
635+
if (!player)
636+
return;
643637

644-
if (gy->HasNpc(npcGuid))
645-
{
646-
gy->AddPlayer(playerGuid);
647-
break;
648-
}
649-
}
638+
player->CastSpell(player, SPELL_WAITING_FOR_RESURRECT, true);
650639
}
651640

652641
void Battlefield::RemovePlayerFromResurrectQueue(ObjectGuid playerGuid)
653642
{
654-
for (BfGraveyard* gy : GraveyardList)
655-
{
656-
if (!gy)
657-
continue;
643+
Player* player = ObjectAccessor::FindPlayer(playerGuid);
644+
if (!player)
645+
return;
658646

659-
if (gy->HasPlayer(playerGuid))
660-
{
661-
gy->RemovePlayer(playerGuid);
662-
break;
663-
}
664-
}
647+
player->RemoveAurasDueToSpell(SPELL_WAITING_FOR_RESURRECT);
665648
}
666649

667650
void Battlefield::SendAreaSpiritHealerQueryOpcode(Player* player, ObjectGuid const& guid)
@@ -707,80 +690,9 @@ float BfGraveyard::GetDistance(Player* player)
707690
return player->GetDistance2d(safeLoc->x, safeLoc->y);
708691
}
709692

710-
void BfGraveyard::AddPlayer(ObjectGuid playerGuid)
711-
{
712-
if (!ResurrectQueue.count(playerGuid))
713-
{
714-
ResurrectQueue.insert(playerGuid);
715-
716-
if (Player* player = ObjectAccessor::FindPlayer(playerGuid))
717-
player->CastSpell(player, SPELL_WAITING_FOR_RESURRECT, true);
718-
}
719-
}
720-
721-
void BfGraveyard::RemovePlayer(ObjectGuid playerGuid)
722-
{
723-
ResurrectQueue.erase(ResurrectQueue.find(playerGuid));
724-
725-
if (Player* player = ObjectAccessor::FindPlayer(playerGuid))
726-
player->RemoveAurasDueToSpell(SPELL_WAITING_FOR_RESURRECT);
727-
}
728-
729-
void BfGraveyard::Resurrect()
730-
{
731-
if (ResurrectQueue.empty())
732-
return;
733-
734-
for (ObjectGuid const& guid : ResurrectQueue)
735-
{
736-
// Get player object from his guid
737-
Player* player = ObjectAccessor::FindPlayer(guid);
738-
if (!player)
739-
continue;
740-
741-
// Check if the player is in world and on the good graveyard
742-
if (player->IsInWorld())
743-
if (Unit* spirit = ObjectAccessor::GetCreature(*player, SpiritGuide[ControlTeam]))
744-
spirit->CastSpell(spirit, SPELL_SPIRIT_HEAL, true);
745-
746-
// Resurrect player
747-
player->CastSpell(player, SPELL_RESURRECTION_VISUAL, true);
748-
player->ResurrectPlayer(1.0f);
749-
player->CastSpell(player, 6962, true);
750-
player->CastSpell(player, SPELL_SPIRIT_HEAL_MANA, true);
751-
752-
player->SpawnCorpseBones(false);
753-
}
754-
755-
ResurrectQueue.clear();
756-
}
757-
758-
// For changing graveyard control
759693
void BfGraveyard::GiveControlTo(TeamId team)
760694
{
761695
ControlTeam = team;
762-
// Teleport to other graveyard, players which were on this graveyard
763-
RelocateDeadPlayers();
764-
}
765-
766-
void BfGraveyard::RelocateDeadPlayers()
767-
{
768-
GraveyardStruct const* closestGrave = nullptr;
769-
for (ObjectGuid const& guid : ResurrectQueue)
770-
{
771-
Player* player = ObjectAccessor::FindPlayer(guid);
772-
if (!player)
773-
continue;
774-
775-
if (closestGrave)
776-
player->TeleportTo(player->GetMapId(), closestGrave->x, closestGrave->y, closestGrave->z, player->GetOrientation());
777-
else
778-
{
779-
closestGrave = Bf->GetClosestGraveyard(player);
780-
if (closestGrave)
781-
player->TeleportTo(player->GetMapId(), closestGrave->x, closestGrave->y, closestGrave->z, player->GetOrientation());
782-
}
783-
}
784696
}
785697

786698
Creature* Battlefield::SpawnCreature(uint32 entry, Position pos, TeamId teamId)

src/server/game/Battlefield/Battlefield.h

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -169,18 +169,6 @@ class BfGraveyard
169169
// Set spirit service for the graveyard
170170
void SetSpirit(Creature* spirit, TeamId team);
171171

172-
// Add a player to the graveyard
173-
void AddPlayer(ObjectGuid playerGuid);
174-
175-
// Remove a player from the graveyard
176-
void RemovePlayer(ObjectGuid playerGuid);
177-
178-
// Resurrect players
179-
void Resurrect();
180-
181-
// Move players waiting to that graveyard on the nearest one
182-
void RelocateDeadPlayers();
183-
184172
// Check if this graveyard has a spirit guide
185173
bool HasNpc(ObjectGuid guid)
186174
{
@@ -190,8 +178,7 @@ class BfGraveyard
190178
return (SpiritGuide[0] == guid || SpiritGuide[1] == guid);
191179
}
192180

193-
// Check if a player is in this graveyard's resurrect queue
194-
bool HasPlayer(ObjectGuid guid) const { return ResurrectQueue.find(guid) != ResurrectQueue.end(); }
181+
ObjectGuid GetSpiritGuide(TeamId team) const { return SpiritGuide[team]; }
195182

196183
// Get the graveyard's ID.
197184
uint32 GetGraveyardId() const { return GraveyardId; }
@@ -200,7 +187,6 @@ class BfGraveyard
200187
TeamId ControlTeam;
201188
uint32 GraveyardId;
202189
ObjectGuid SpiritGuide[2];
203-
GuidUnorderedSet ResurrectQueue;
204190
Battlefield* Bf;
205191
};
206192

@@ -444,6 +430,8 @@ class Battlefield : public ZoneScript
444430
/// Returns true if the player is already tracked as actively in the war or invited to join it.
445431
bool IsPlayerInWarOrInvited(Player* player) const;
446432

433+
void RemovePlayerFromTracking(ObjectGuid playerGuid);
434+
447435
// Player-iteration helpers: resolve each GUID to a live Player* and call fn(player).
448436
// Using templates avoids std::function overhead and works naturally with lambdas.
449437
template<typename Func>

src/server/game/Battlefield/Zones/BattlefieldWG.cpp

Lines changed: 34 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -193,9 +193,39 @@ bool BattlefieldWG::SetupBattlefield()
193193
_scheduler.Schedule(Milliseconds(RESURRECTION_INTERVAL),
194194
BATTLEFIELD_TIMER_GROUP_RESURRECT, [this](TaskContext context)
195195
{
196-
for (BfGraveyard* gy : GraveyardList)
197-
if (gy)
198-
gy->Resurrect();
196+
ForEachPlayerInZone([this](Player* player)
197+
{
198+
if (!player->HasAura(SPELL_WAITING_FOR_RESURRECT))
199+
return;
200+
201+
TeamId team = player->GetTeamId();
202+
Unit* closestSpirit = nullptr;
203+
float closestDist = -1.0f;
204+
for (BfGraveyard* gy : GraveyardList)
205+
{
206+
if (!gy)
207+
continue;
208+
Unit* spirit = ObjectAccessor::GetCreature(*player, gy->GetSpiritGuide(team));
209+
if (!spirit)
210+
continue;
211+
float dist = player->GetDistance(spirit);
212+
if (closestDist < 0.0f || dist < closestDist)
213+
{
214+
closestDist = dist;
215+
closestSpirit = spirit;
216+
}
217+
}
218+
219+
if (closestSpirit)
220+
closestSpirit->CastSpell(closestSpirit, SPELL_SPIRIT_HEAL, true);
221+
222+
player->CastSpell(player, SPELL_RESURRECTION_VISUAL, true);
223+
player->ResurrectPlayer(1.0f);
224+
player->CastSpell(player, 6962, true);
225+
player->CastSpell(player, SPELL_SPIRIT_HEAL_MANA, true);
226+
player->SpawnCorpseBones(false);
227+
player->RemoveAurasDueToSpell(SPELL_WAITING_FOR_RESURRECT);
228+
});
199229
context.Repeat();
200230
});
201231

@@ -266,19 +296,7 @@ void BattlefieldWG::OnBattleStart()
266296
capturePoint->SetCapturePointData(capturePoint->GetCapturePointGo(),
267297
capturePoint->GetCapturePointGo()->GetEntry() == GO_WINTERGRASP_FACTORY_BANNER_SE || capturePoint->GetCapturePointGo()->GetEntry() == GO_WINTERGRASP_FACTORY_BANNER_SW ? GetAttackerTeam() : GetDefenderTeam());
268298

269-
for (uint8 team = 0; team < 2; ++team)
270-
for (ObjectGuid const& guid : Players[team])
271-
{
272-
// Kick player in orb room, TODO: offline player ?
273-
if (Player* player = ObjectAccessor::FindPlayer(guid))
274-
{
275-
float x, y, z;
276-
player->GetPosition(x, y, z);
277-
if (5500 > x && x > 5392 && y < 2880 && y > 2800 && z < 480)
278-
player->TeleportTo(MAP_NORTHREND, 5349.8686f, 2838.481f, 409.240f, 0.046328f);
279-
SendInitWorldStatesTo(player);
280-
}
281-
}
299+
SendInitWorldStatesToAll();
282300
// Initialize vehicle counter
283301
UpdateCounterVehicle(true);
284302
// Send start warning to all players

src/server/game/DungeonFinding/LFGMgr.cpp

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1692,18 +1692,32 @@ namespace lfg
16921692
LfgGuidList players;
16931693
GuidUnorderedSet playersToTeleport;
16941694

1695-
for (LfgProposalPlayerContainer::const_iterator it = proposal.players.begin(); it != proposal.players.end(); ++it)
1696-
{
1697-
ObjectGuid guid = it->first;
1698-
if (guid == proposal.leader)
1699-
players.push_front(guid);
1700-
else
1701-
players.push_back(guid);
1695+
// Sort players by role, leader first, then tank, healer and dps
1696+
std::vector<ObjectGuid> tanks, healers, dps;
1697+
1698+
if (proposal.leader && proposal.players.contains(proposal.leader))
1699+
players.push_back(proposal.leader);
17021700

1701+
for (auto const& [guid, player] : proposal.players)
1702+
{
17031703
if (proposal.isNew || GetGroup(guid) != proposal.group)
17041704
playersToTeleport.insert(guid);
1705+
1706+
if (guid == proposal.leader)
1707+
continue;
1708+
1709+
if (player.role & lfg::PLAYER_ROLE_TANK)
1710+
tanks.push_back(guid);
1711+
else if (player.role & lfg::PLAYER_ROLE_HEALER)
1712+
healers.push_back(guid);
1713+
else
1714+
dps.push_back(guid);
17051715
}
17061716

1717+
players.insert(players.end(), tanks.begin(), tanks.end());
1718+
players.insert(players.end(), healers.begin(), healers.end());
1719+
players.insert(players.end(), dps.begin(), dps.end());
1720+
17071721
// Set the dungeon difficulty
17081722
LFGDungeonData const* dungeon = GetLFGDungeon(proposal.dungeonId);
17091723
ASSERT(dungeon);

src/server/game/Handlers/LFGHandler.cpp

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -569,12 +569,32 @@ void WorldSession::SendLfgUpdateProposal(lfg::LfgProposal const& proposal)
569569
data << uint8(silent); // Show proposal window
570570
data << uint8(proposal.players.size()); // Group size
571571

572-
for (lfg::LfgProposalPlayerContainer::const_iterator it = proposal.players.begin(); it != proposal.players.end(); ++it)
572+
// Sort by roles: tank, healer, dps
573+
std::vector<ObjectGuid> ordered;
574+
ordered.reserve(proposal.players.size());
575+
576+
std::vector<ObjectGuid> tanks, healers, dps;
577+
578+
for (auto const& [pguid, player] : proposal.players)
579+
{
580+
if (player.role & lfg::PLAYER_ROLE_TANK)
581+
tanks.push_back(pguid);
582+
else if (player.role & lfg::PLAYER_ROLE_HEALER)
583+
healers.push_back(pguid);
584+
else
585+
dps.push_back(pguid);
586+
}
587+
588+
ordered.insert(ordered.end(), tanks.begin(), tanks.end());
589+
ordered.insert(ordered.end(), healers.begin(), healers.end());
590+
ordered.insert(ordered.end(), dps.begin(), dps.end());
591+
592+
for (auto const& pguid : ordered)
573593
{
574-
lfg::LfgProposalPlayer const& player = it->second;
594+
lfg::LfgProposalPlayer const& player = proposal.players.find(pguid)->second;
575595
data << uint32(player.role); // Role
576-
data << uint8(it->first == guid); // Self player
577-
if (!player.group) // Player not it a group
596+
data << uint8(pguid == guid); // Self player
597+
if (!player.group) // Player not in a group
578598
{
579599
data << uint8(0); // Not in dungeon
580600
data << uint8(0); // Not same group

src/server/game/Spells/Auras/SpellAuraEffects.cpp

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5347,13 +5347,10 @@ void AuraEffect::HandleAuraDummy(AuraApplication const* aurApp, uint8 mode, bool
53475347
{
53485348
case 2584: // Waiting to Resurrect
53495349
// Waiting to resurrect spell cancel, we must remove player from resurrect queue
5350+
// bf branch omitted: it would cascade back into this handler.
53505351
if (target->IsPlayer())
5351-
{
53525352
if (Battleground* bg = target->ToPlayer()->GetBattleground())
53535353
bg->RemovePlayerFromResurrectQueue(target->ToPlayer());
5354-
if (Battlefield* bf = sBattlefieldMgr->GetBattlefieldToZoneId(target->GetZoneId()))
5355-
bf->RemovePlayerFromResurrectQueue(target->GetGUID());
5356-
}
53575354
break;
53585355
case 43681: // Inactive
53595356
{

0 commit comments

Comments
 (0)