Core/Followers: Updated behaviours and scaling

This commit is contained in:
SistemasCPU
2026-09-22 00:07:27 +02:00
parent c2c22d88e8
commit 0cca4fcaf3
4 changed files with 1026 additions and 176 deletions
@@ -584,6 +584,8 @@ void LFGMgr::JoinLfg(Player* player, uint8 roles, LfgDungeonSet& dungeons)
{
Player* plrg = itr.GetSource();
ObjectGuid pguid = plrg->GetGUID();
uint8 memberRoles = (pguid == guid) ? roles : grp->GetLfgRoles(pguid);
SetRoles(pguid, memberRoles);
plrg->GetSession()->SendLfgUpdateStatus(updateData, true);
SetState(pguid, LFG_STATE_ROLECHECK);
SetTicket(pguid, ticket);
@@ -1383,6 +1385,12 @@ void LFGMgr::TeleportPlayer(Player* player, bool out, bool fromOpcode /*= false*
{
TC_LOG_DEBUG("lfg.teleport", "Player {} is being teleported out. Current Map {} - Expected Map {}",
player->GetName(), player->GetMapId(), uint32(dungeon->map));
// In a follower dungeon, clean up the companion party before the player leaves the map
// so the client doesn't keep "Unknown" members in the group frame.
if (group)
group->DespawnFollowerModeBots(player);
if (player->GetMapId() == uint32(dungeon->map))
player->TeleportToBGEntryPoint();
+22 -3
View File
@@ -581,10 +581,19 @@ bool Group::RemoveMember(ObjectGuid guid, RemoveMethod method /*= GROUP_REMOVEME
Player* player = ObjectAccessor::FindConnectedPlayer(guid);
if (player)
{
for (GroupReference const& itr : GetMembers())
// Snapshot member GUIDs first: aura removal below can re-enter group code
// (script hooks, follower bot cleanup) and mutate m_memberSlots, which would
// leave this loop walking a dead list.
std::vector<ObjectGuid> memberGuids;
memberGuids.reserve(m_memberSlots.size());
for (MemberSlot const& slot : m_memberSlots)
if (slot.guid != guid && slot.guid.IsPlayer())
memberGuids.push_back(slot.guid);
for (ObjectGuid const& memberGuid : memberGuids)
{
Player* groupMember = itr.GetSource();
if (groupMember->GetGUID() == guid)
Player* groupMember = ObjectAccessor::FindConnectedPlayer(memberGuid);
if (!groupMember)
continue;
groupMember->RemoveAllGroupBuffsFromCaster(guid);
@@ -2163,6 +2172,10 @@ void Group::DespawnFollowerModeBots(Player* player)
if (!player)
return;
// Clean up LFG data so the player doesn't keep a stale follower dungeon state.
if (isLFGGroup())
sLFGMgr->RemoveGroupData(GetGUID());
uint32 playerMembers = 0;
for (MemberSlot const& slot : m_memberSlots)
if (slot.guid.IsPlayer())
@@ -2202,6 +2215,12 @@ void Group::DespawnFollowerModeBots(Player* player)
}
}
// NOTE: never call RemoveMember() here. This runs inside
// GroupScript::OnRemoveMember during an in-flight RemoveMember(); a nested
// removal can Disband()/delete `this` and leave the outer call running on a
// dead object. The outer RemoveMember (or the OnMapChanged LFG script)
// removes the last real player and disbands the group by itself.
SendUpdate();
}
+18 -1
View File
@@ -329,7 +329,24 @@ void WorldSession::SendLfgUpdateStatus(lfg::LfgUpdateData const& updateData, boo
{
return sLFGMgr->GetLFGDungeonEntry(dungeonId);
});
lfgUpdateStatus.RequestedRoles = sLFGMgr->GetRoles(_player->GetGUID());
uint8 requestedRoles = sLFGMgr->GetRoles(_player->GetGUID());
if (requestedRoles == 0)
{
if (Group* group = _player->GetGroup())
requestedRoles = group->GetLfgRoles(_player->GetGUID());
if (requestedRoles == 0)
{
uint32 roleForGroup = _player->GetRoleForGroup();
if (roleForGroup == ROLE_TANK)
requestedRoles = lfg::PLAYER_ROLE_TANK;
else if (roleForGroup == ROLE_HEALER)
requestedRoles = lfg::PLAYER_ROLE_HEALER;
else
requestedRoles = lfg::PLAYER_ROLE_DAMAGE;
}
}
lfgUpdateStatus.RequestedRoles = requestedRoles;
//lfgUpdateStatus.SuspendedPlayers;
lfgUpdateStatus.IsParty = party;
lfgUpdateStatus.NotifyUI = true;
File diff suppressed because it is too large Load Diff