[11898] Prevent resetting instances while offline players are in it

Signed-off-by: Schmoozerd <schmoozerd@scriptdev2.com>
This commit is contained in:
cyberium 2012-01-31 22:09:48 +01:00 committed by Schmoozerd
parent 2836e704a8
commit 35e991d70e
4 changed files with 46 additions and 10 deletions

View file

@ -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<uint32> 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

View file

@ -195,6 +195,7 @@ class MANGOS_DLL_SPEC Group
std::string name;
uint8 group;
bool assistant;
uint32 lastMap;
};
typedef std::list<MemberSlot> 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<Player*> InvitesList;
typedef std::vector<Roll*> 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 ***/
/*********************************************************/

View file

@ -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)
{

View file

@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__
#define __REVISION_NR_H__
#define REVISION_NR "11897"
#define REVISION_NR "11898"
#endif // __REVISION_NR_H__