diff --git a/src/game/Group.cpp b/src/game/Group.cpp index e0cd4a65e..b8ae12046 100644 --- a/src/game/Group.cpp +++ b/src/game/Group.cpp @@ -1168,6 +1168,7 @@ bool Group::_addMember(ObjectGuid guid, const char* name, bool isAssistant, uint member.name = name; member.group = group; member.assistant = isAssistant; + member.lastMap = player->GetMapId(); m_memberSlots.push_back(member); SubGroupCounterIncrease(group); @@ -1667,9 +1668,21 @@ bool Group::InCombatToInstance(uint32 instanceId) return false; } +bool Group::SetPlayerMap(const ObjectGuid guid, uint32 mapid) +{ + member_witerator slot = _getMemberWSlot(guid); + if (slot != m_memberSlots.end()) + { + slot->lastMap = mapid; + DEBUG_LOG("Group::SetPlayerMap> map is updated"); + return true; + } + return false; +} + void Group::ResetInstances(InstanceResetMethod method, bool isRaid, Player* SendMsgTo) { - if(isBGGroup()) + if (isBGGroup()) return; // method can be INSTANCE_RESET_ALL, INSTANCE_RESET_CHANGE_DIFFICULTY, INSTANCE_RESET_GROUP_DISBAND @@ -1677,17 +1690,30 @@ void Group::ResetInstances(InstanceResetMethod method, bool isRaid, Player* Send // we assume that when the difficulty changes, all instances that can be reset will be Difficulty diff = GetDifficulty(isRaid); - for(BoundInstancesMap::iterator itr = m_boundInstances[diff].begin(); itr != m_boundInstances[diff].end();) + typedef std::set OfflineMapSet; + OfflineMapSet mapsWithOfflinePlayer; // to store map of offline players + + if (method != INSTANCE_RESET_GROUP_DISBAND) { - DungeonPersistentState *state = itr->second.state; - const MapEntry *entry = sMapStore.LookupEntry(itr->first); + // Store maps in which are offline members for instance reset check. + for (member_citerator itr = m_memberSlots.begin(); itr != m_memberSlots.end(); ++itr) + { + if (!ObjectAccessor::FindPlayer(itr->guid)) + mapsWithOfflinePlayer.insert(itr->lastMap); // add last map from offline player + } + } + + for (BoundInstancesMap::iterator itr = m_boundInstances[diff].begin(); itr != m_boundInstances[diff].end();) + { + DungeonPersistentState* state = itr->second.state; + const MapEntry* entry = sMapStore.LookupEntry(itr->first); if (!entry || entry->IsRaid() != isRaid || (!state->CanReset() && method != INSTANCE_RESET_GROUP_DISBAND)) { ++itr; continue; } - if(method == INSTANCE_RESET_ALL) + if (method == INSTANCE_RESET_ALL) { // the "reset all instances" method can only reset normal maps if (entry->map_type == MAP_RAID || diff == DUNGEON_DIFFICULTY_HEROIC) @@ -1698,9 +1724,13 @@ void Group::ResetInstances(InstanceResetMethod method, bool isRaid, Player* Send } bool isEmpty = true; - // if the map is loaded, reset it - if (Map *map = sMapMgr.FindMap(state->GetMapId(), state->GetInstanceId())) - if (map->IsDungeon() && !(method == INSTANCE_RESET_GROUP_DISBAND && !state->CanReset())) + // check if there are offline members on the map + if (method != INSTANCE_RESET_GROUP_DISBAND && mapsWithOfflinePlayer.find(state->GetMapId()) != mapsWithOfflinePlayer.end()) + isEmpty = false; + + // if the map is loaded, reset it if can + if (isEmpty && entry->IsDungeon() && !(method == INSTANCE_RESET_GROUP_DISBAND && !state->CanReset())) + if (Map* map = sMapMgr.FindMap(state->GetMapId(), state->GetInstanceId())) isEmpty = ((DungeonMap*)map)->Reset(method); if (SendMsgTo) @@ -1711,6 +1741,7 @@ void Group::ResetInstances(InstanceResetMethod method, bool isRaid, Player* Send SendMsgTo->SendResetInstanceFailed(0, state->GetMapId()); } + // TODO - Adapt here when clear how difficulty changes must be handled if (isEmpty || method == INSTANCE_RESET_GROUP_DISBAND || method == INSTANCE_RESET_CHANGE_DIFFICULTY) { // do not reset the instance, just unbind if others are permanently bound to it diff --git a/src/game/Group.h b/src/game/Group.h index b67438937..5599ea9b0 100644 --- a/src/game/Group.h +++ b/src/game/Group.h @@ -195,6 +195,7 @@ class MANGOS_DLL_SPEC Group std::string name; uint8 group; bool assistant; + uint32 lastMap; }; typedef std::list MemberSlotList; typedef MemberSlotList::const_iterator member_citerator; @@ -203,7 +204,6 @@ class MANGOS_DLL_SPEC Group protected: typedef MemberSlotList::iterator member_witerator; typedef std::set InvitesList; - typedef std::vector Rolls; public: @@ -339,6 +339,8 @@ class MANGOS_DLL_SPEC Group void RewardGroupAtKill(Unit* pVictim, Player* player_tap); + bool SetPlayerMap(const ObjectGuid guid, uint32 mapid); + /*********************************************************/ /*** LOOT SYSTEM ***/ /*********************************************************/ diff --git a/src/game/Player.cpp b/src/game/Player.cpp index aafc4e8a8..2c378d82e 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -1659,6 +1659,9 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati DEBUG_LOG("Player %s is being teleported to map %u", GetName(), mapid); } + if (Group* grp = GetGroup()) + grp->SetPlayerMap(GetObjectGuid(), mapid); + // if we were on a transport, leave if (!(options & TELE_TO_NOT_LEAVE_TRANSPORT) && m_transport) { diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 4a8d3913a..577580c2c 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "11897" + #define REVISION_NR "11898" #endif // __REVISION_NR_H__