aboutsummaryrefslogtreecommitdiff
path: root/src/server/game/Groups/Group.cpp
diff options
context:
space:
mode:
authorWyrserth <43747507+Wyrserth@users.noreply.github.com>2019-06-15 14:19:58 +0200
committerGiacomo Pozzoni <giacomopoz@gmail.com>2019-06-15 14:19:58 +0200
commite906a2fe7d71fc17de9f7ea4778970beb3f9265e (patch)
tree02ac22a52d44549ee829eece372fd888e1d4fa44 /src/server/game/Groups/Group.cpp
parente6ad9b10cf381625ca1955cf6081ea1a8b14de11 (diff)
Core/Group: implement automatic party/raid leader change when the leader has been offline for two minutes (#23398)
* Core/Group: implement automatic party/raid leader change when the leader has been offline for two minutes. * Add #23396 to make testing easier. * Prioritize assistants in raids. * Fix dumb mistake and apply suggested change, thanks VincentVanclef and jackpoz!
Diffstat (limited to 'src/server/game/Groups/Group.cpp')
-rw-r--r--src/server/game/Groups/Group.cpp62
1 files changed, 61 insertions, 1 deletions
diff --git a/src/server/game/Groups/Group.cpp b/src/server/game/Groups/Group.cpp
index 3a63033575d..74fc5cbdfb7 100644
--- a/src/server/game/Groups/Group.cpp
+++ b/src/server/game/Groups/Group.cpp
@@ -63,7 +63,7 @@ Loot* Roll::getLoot()
Group::Group() : m_leaderGuid(), m_leaderName(""), m_groupType(GROUPTYPE_NORMAL),
m_dungeonDifficulty(DUNGEON_DIFFICULTY_NORMAL), m_raidDifficulty(RAID_DIFFICULTY_10MAN_NORMAL),
m_bgGroup(nullptr), m_bfGroup(nullptr), m_lootMethod(FREE_FOR_ALL), m_lootThreshold(ITEM_QUALITY_UNCOMMON), m_looterGuid(),
-m_masterLooterGuid(), m_subGroupsCounts(nullptr), m_guid(), m_counter(0), m_maxEnchantingLevel(0), m_dbStoreId(0)
+m_masterLooterGuid(), m_subGroupsCounts(nullptr), m_guid(), m_counter(0), m_maxEnchantingLevel(0), m_dbStoreId(0), m_isLeaderOffline(false)
{
for (uint8 i = 0; i < TARGETICONCOUNT; ++i)
m_targetIcons[i].Clear();
@@ -99,6 +99,55 @@ Group::~Group()
delete[] m_subGroupsCounts;
}
+void Group::Update(uint32 diff)
+{
+ if (m_isLeaderOffline && (m_groupType == GROUPTYPE_NORMAL || m_groupType == GROUPTYPE_RAID))
+ {
+ m_leaderOfflineTimer.Update(diff);
+ if (m_leaderOfflineTimer.Passed())
+ {
+ SelectNewPartyOrRaidLeader();
+ m_isLeaderOffline = false;
+ }
+ }
+}
+
+void Group::SelectNewPartyOrRaidLeader()
+{
+ Player* newLeader = nullptr;
+
+ // Attempt to give leadership to main assistant first
+ if (m_groupType == GROUPTYPE_RAID)
+ {
+ for (auto memberSlot : m_memberSlots)
+ {
+ if ((memberSlot.flags & MEMBER_FLAG_ASSISTANT) == MEMBER_FLAG_ASSISTANT)
+ if (Player* player = ObjectAccessor::FindPlayer(memberSlot.guid))
+ {
+ 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)
+ {
+ for (auto memberSlot : m_memberSlots)
+ if (Player* player = ObjectAccessor::FindPlayer(memberSlot.guid))
+ {
+ newLeader = player;
+ break;
+ }
+ }
+
+ if (newLeader)
+ {
+ ChangeLeader(newLeader->GetGUID());
+ SendUpdate();
+ }
+}
+
bool Group::Create(Player* leader)
{
ObjectGuid leaderGuid = leader->GetGUID();
@@ -2554,3 +2603,14 @@ void Group::ToggleGroupMemberFlag(member_witerator slot, uint8 flag, bool apply)
else
slot->flags &= ~flag;
}
+
+void Group::StartLeaderOfflineTimer()
+{
+ m_isLeaderOffline = true;
+ m_leaderOfflineTimer.Reset(2 * MINUTE * IN_MILLISECONDS);
+}
+
+void Group::StopLeaderOfflineTimer()
+{
+ m_isLeaderOffline = false;
+}