diff --git a/Source/Game/Groups/Group.cs b/Source/Game/Groups/Group.cs index 8416a04cf..b676ca50f 100644 --- a/Source/Game/Groups/Group.cs +++ b/Source/Game/Groups/Group.cs @@ -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; diff --git a/Source/Game/Groups/GroupManager.cs b/Source/Game/Groups/GroupManager.cs index 0c2e78774..80566ac7a 100644 --- a/Source/Game/Groups/GroupManager.cs +++ b/Source/Game/Groups/GroupManager.cs @@ -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 GroupStore = new(); Dictionary GroupDbStore = new(); ulong NextGroupId; diff --git a/Source/Game/Handlers/CharacterHandler.cs b/Source/Game/Handlers/CharacterHandler.cs index 529a4bbdb..8fa2620f8 100644 --- a/Source/Game/Handlers/CharacterHandler.cs +++ b/Source/Game/Handlers/CharacterHandler.cs @@ -861,6 +861,8 @@ namespace Game { group.SendUpdate(); group.ResetMaxEnchantingLevel(); + if (group.GetLeaderGUID() == pCurrChar.GetGUID()) + group.StopLeaderOfflineTimer(); } // friend status diff --git a/Source/Game/Server/WorldSession.cs b/Source/Game/Server/WorldSession.cs index 76eaacf14..f98153c17 100644 --- a/Source/Game/Server/WorldSession.cs +++ b/Source/Game/Server/WorldSession.cs @@ -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