Core/Group: implement automatic party/raid leader change when the leader has been offline for two minutes

Port From (https://github.com/TrinityCore/TrinityCore/commit/cc141e9bad5dc06a56179f820670bd6944651804)
This commit is contained in:
hondacrx
2021-12-17 19:04:23 -05:00
parent 1021eadd36
commit 05e3cfc118
4 changed files with 84 additions and 22 deletions
+70 -5
View File
@@ -44,6 +44,63 @@ namespace Game.Groups
m_lootThreshold = ItemQuality.Uncommon;
}
public void Update(uint diff)
{
if (_isLeaderOffline)
{
_leaderOfflineTimer.Update((int)diff);
if (_leaderOfflineTimer.Passed())
{
SelectNewPartyOrRaidLeader();
_isLeaderOffline = false;
}
}
UpdateReadyCheck(diff);
}
void SelectNewPartyOrRaidLeader()
{
Player newLeader = null;
// Attempt to give leadership to main assistant first
if (IsRaidGroup())
{
foreach (var memberSlot in m_memberSlots)
{
if (memberSlot.flags.HasFlag(GroupMemberFlags.Assistant))
{
Player player = Global.ObjAccessor.FindPlayer(memberSlot.guid);
if (player != null)
{
newLeader = player;
break;
}
}
}
}
// If there aren't assistants in raid, or if the group is not a raid, pick the first available member
if (!newLeader)
{
foreach (var memberSlot in m_memberSlots)
{
Player player = Global.ObjAccessor.FindPlayer(memberSlot.guid);
if (player != null)
{
newLeader = player;
break;
}
}
}
if (newLeader)
{
ChangeLeader(newLeader.GetGUID());
SendUpdate();
}
}
public bool Create(Player leader)
{
ObjectGuid leaderGuid = leader.GetGUID();
@@ -2150,11 +2207,6 @@ namespace Game.Groups
return slot.roles;
}
public void Update(uint diff)
{
UpdateReadyCheck(diff);
}
void UpdateReadyCheck(uint diff)
{
if (!m_readyCheckStarted)
@@ -2567,6 +2619,17 @@ namespace Game.Groups
slot.flags &= ~flag;
}
public void StartLeaderOfflineTimer()
{
_isLeaderOffline = true;
_leaderOfflineTimer.Reset(2 * Time.Minute * Time.InMilliseconds);
}
public void StopLeaderOfflineTimer()
{
_isLeaderOffline = false;
}
public void SetEveryoneIsAssistant(bool apply)
{
if (apply)
@@ -2620,6 +2683,8 @@ namespace Game.Groups
ObjectGuid m_guid;
uint m_maxEnchantingLevel;
uint m_dbStoreId;
bool _isLeaderOffline;
TimeTrackerSmall _leaderOfflineTimer = new();
// Ready Check
bool m_readyCheckStarted;
+6 -9
View File
@@ -89,6 +89,12 @@ namespace Game.Groups
return GroupStore.LookupByKey(groupId.GetCounter());
}
public void Update(uint diff)
{
foreach (var group in GroupStore.Values)
group.Update(diff);
}
public void AddGroup(Group group)
{
GroupStore[group.GetGUID().GetCounter()] = group;
@@ -222,15 +228,6 @@ namespace Game.Groups
}
}
public void Update(uint diff)
{
foreach (var group in GroupStore.Values)
{
if (group)
group.Update(diff);
}
}
Dictionary<ulong, Group> GroupStore = new();
Dictionary<uint, Group> GroupDbStore = new();
ulong NextGroupId;
+2
View File
@@ -861,6 +861,8 @@ namespace Game
{
group.SendUpdate();
group.ResetMaxEnchantingLevel();
if (group.GetLeaderGUID() == pCurrChar.GetGUID())
group.StopLeaderOfflineTimer();
}
// friend status
+6 -8
View File
@@ -188,16 +188,14 @@ namespace Game
// If the player is in a group (or invited), remove him. If the group if then only 1 person, disband the group.
_player.UninviteFromGroup();
// remove player from the group if he is:
// a) in group; b) not in raid group; c) logging out normally (not being kicked or disconnected)
if (_player.GetGroup() && !_player.GetGroup().IsRaidGroup() && m_Socket[(int)ConnectionType.Realm] != null)
_player.RemoveFromGroup();
//! Send update to group and reset stored max enchanting level
if (_player.GetGroup())
var group = _player.GetGroup();
if (group != null)
{
_player.GetGroup().SendUpdate();
_player.GetGroup().ResetMaxEnchantingLevel();
group.SendUpdate();
group.ResetMaxEnchantingLevel();
if (group.GetLeaderGUID() == _player.GetGUID())
group.StartLeaderOfflineTimer();
}
//! Broadcast a logout message to the player's friends