mirror of
https://github.com/mangosfour/server.git
synced 2025-12-13 22:37:03 +00:00
[11126] Rewrite InstanceSaveMgr related code.
* For better fit name to related map type class InstanceMap renamed -> DungeonMap. This clarify usage Instanceable()/IsDungeon() because BG/Arenas maps also instanceable maps. * InstanceSave have many code related to only DungeonMap case, so it replaced by 3 new classes: - MapPersistentState as base class, used for non-instanceable maps (continents and some other) (!Instenceable()) - DungeonPersistentState subclass of MapPersistentState, used for DungeonMap states (IsDungoen()) - BattlegroundPersistentState subclass of MapPersistentState, used for BattlegroundMap states (IsBattleGroundOrArena()) Now all dungeon resets code moved to subclass and all player/gpoup bound functions/structures also use it. * Map::GetInstanceSave renamed to Map::GetPersistentState and DungeonMap have specialized version return DungeonPersistentState (same pointer in fact with proper subcalss type) * InstanceResetScheduler renamed to DungeonResetScheduler
This commit is contained in:
parent
0d16b0bdc7
commit
dde16bc48c
22 changed files with 683 additions and 550 deletions
|
|
@ -103,10 +103,10 @@ Group::~Group()
|
|||
|
||||
// it is undefined whether objectmgr (which stores the groups) or instancesavemgr
|
||||
// will be unloaded first so we must be prepared for both cases
|
||||
// this may unload some instance saves
|
||||
// this may unload some dungeon persistent state
|
||||
for(uint8 i = 0; i < MAX_DIFFICULTY; ++i)
|
||||
for(BoundInstancesMap::iterator itr2 = m_boundInstances[i].begin(); itr2 != m_boundInstances[i].end(); ++itr2)
|
||||
itr2->second.save->RemoveGroup(this);
|
||||
itr2->second.state->RemoveGroup(this);
|
||||
|
||||
// Sub group counters clean up
|
||||
if (m_subGroupsCounts)
|
||||
|
|
@ -1170,11 +1170,11 @@ bool Group::_addMember(ObjectGuid guid, const char* name, bool isAssistant, uint
|
|||
|
||||
SubGroupCounterIncrease(group);
|
||||
|
||||
if(player)
|
||||
if (player)
|
||||
{
|
||||
player->SetGroupInvite(NULL);
|
||||
//if player is in group and he is being added to BG raid group, then call SetBattleGroundRaid()
|
||||
if( player->GetGroup() && isBGGroup() )
|
||||
if (player->GetGroup() && isBGGroup())
|
||||
player->SetBattleGroundRaid(this, group);
|
||||
//if player is in bg raid and we are adding him to normal group, then call SetOriginalGroup()
|
||||
else if ( player->GetGroup() )
|
||||
|
|
@ -1182,19 +1182,20 @@ bool Group::_addMember(ObjectGuid guid, const char* name, bool isAssistant, uint
|
|||
//if player is not in group, then call set group
|
||||
else
|
||||
player->SetGroup(this, group);
|
||||
|
||||
// if the same group invites the player back, cancel the homebind timer
|
||||
InstanceGroupBind *bind = GetBoundInstance(player->GetMapId(), player);
|
||||
if(bind && bind->save->GetInstanceId() == player->GetInstanceId())
|
||||
player->m_InstanceValid = true;
|
||||
if (InstanceGroupBind *bind = GetBoundInstance(player->GetMapId(), player))
|
||||
if (bind->state->GetInstanceId() == player->GetInstanceId())
|
||||
player->m_InstanceValid = true;
|
||||
}
|
||||
|
||||
if(!isRaidGroup()) // reset targetIcons for non-raid-groups
|
||||
if (!isRaidGroup()) // reset targetIcons for non-raid-groups
|
||||
{
|
||||
for(int i = 0; i < TARGET_ICON_COUNT; ++i)
|
||||
m_targetIcons[i].Clear();
|
||||
}
|
||||
|
||||
if(!isBGGroup())
|
||||
if (!isBGGroup())
|
||||
{
|
||||
// insert into group table
|
||||
CharacterDatabase.PExecute("INSERT INTO group_member(groupId,memberGuid,assistant,subgroup) VALUES('%u','%u','%u','%u')",
|
||||
|
|
@ -1280,7 +1281,7 @@ void Group::_setLeader(ObjectGuid guid)
|
|||
{
|
||||
if(itr->second.perm)
|
||||
{
|
||||
itr->second.save->RemoveGroup(this);
|
||||
itr->second.state->RemoveGroup(this);
|
||||
m_boundInstances[i].erase(itr++);
|
||||
}
|
||||
else
|
||||
|
|
@ -1676,9 +1677,9 @@ void Group::ResetInstances(InstanceResetMethod method, bool isRaid, Player* Send
|
|||
|
||||
for(BoundInstancesMap::iterator itr = m_boundInstances[diff].begin(); itr != m_boundInstances[diff].end();)
|
||||
{
|
||||
InstanceSave *p = itr->second.save;
|
||||
DungeonPersistentState *state = itr->second.state;
|
||||
const MapEntry *entry = sMapStore.LookupEntry(itr->first);
|
||||
if (!entry || entry->IsRaid() != isRaid || (!p->CanReset() && method != INSTANCE_RESET_GROUP_DISBAND))
|
||||
if (!entry || entry->IsRaid() != isRaid || (!state->CanReset() && method != INSTANCE_RESET_GROUP_DISBAND))
|
||||
{
|
||||
++itr;
|
||||
continue;
|
||||
|
|
@ -1696,31 +1697,31 @@ void Group::ResetInstances(InstanceResetMethod method, bool isRaid, Player* Send
|
|||
|
||||
bool isEmpty = true;
|
||||
// if the map is loaded, reset it
|
||||
Map *map = sMapMgr.FindMap(p->GetMapId(), p->GetInstanceId());
|
||||
if(map && map->IsDungeon() && !(method == INSTANCE_RESET_GROUP_DISBAND && !p->CanReset()))
|
||||
isEmpty = ((InstanceMap*)map)->Reset(method);
|
||||
if (Map *map = sMapMgr.FindMap(state->GetMapId(), state->GetInstanceId()))
|
||||
if (map->IsDungeon() && !(method == INSTANCE_RESET_GROUP_DISBAND && !state->CanReset()))
|
||||
isEmpty = ((DungeonMap*)map)->Reset(method);
|
||||
|
||||
if(SendMsgTo)
|
||||
if (SendMsgTo)
|
||||
{
|
||||
if(isEmpty)
|
||||
SendMsgTo->SendResetInstanceSuccess(p->GetMapId());
|
||||
if (isEmpty)
|
||||
SendMsgTo->SendResetInstanceSuccess(state->GetMapId());
|
||||
else
|
||||
SendMsgTo->SendResetInstanceFailed(0, p->GetMapId());
|
||||
SendMsgTo->SendResetInstanceFailed(0, state->GetMapId());
|
||||
}
|
||||
|
||||
if(isEmpty || method == INSTANCE_RESET_GROUP_DISBAND || method == INSTANCE_RESET_CHANGE_DIFFICULTY)
|
||||
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
|
||||
if(p->CanReset())
|
||||
p->DeleteFromDB();
|
||||
if (state->CanReset())
|
||||
state->DeleteFromDB();
|
||||
else
|
||||
CharacterDatabase.PExecute("DELETE FROM group_instance WHERE instance = '%u'", p->GetInstanceId());
|
||||
CharacterDatabase.PExecute("DELETE FROM group_instance WHERE instance = '%u'", state->GetInstanceId());
|
||||
// i don't know for sure if hash_map iterators
|
||||
m_boundInstances[diff].erase(itr);
|
||||
itr = m_boundInstances[diff].begin();
|
||||
// this unloads the instance save unless online players are bound to it
|
||||
// (eg. permanent binds or GM solo binds)
|
||||
p->RemoveGroup(this);
|
||||
state->RemoveGroup(this);
|
||||
}
|
||||
else
|
||||
++itr;
|
||||
|
|
@ -1730,18 +1731,18 @@ void Group::ResetInstances(InstanceResetMethod method, bool isRaid, Player* Send
|
|||
InstanceGroupBind* Group::GetBoundInstance(uint32 mapid, Player* player)
|
||||
{
|
||||
MapEntry const* mapEntry = sMapStore.LookupEntry(mapid);
|
||||
if(!mapEntry)
|
||||
if (!mapEntry)
|
||||
return NULL;
|
||||
|
||||
Difficulty difficulty = player->GetDifficulty(mapEntry->IsRaid());
|
||||
|
||||
// some instances only have one difficulty
|
||||
MapDifficulty const* mapDiff = GetMapDifficultyData(mapid,difficulty);
|
||||
if(!mapDiff)
|
||||
if (!mapDiff)
|
||||
difficulty = DUNGEON_DIFFICULTY_NORMAL;
|
||||
|
||||
BoundInstancesMap::iterator itr = m_boundInstances[difficulty].find(mapid);
|
||||
if(itr != m_boundInstances[difficulty].end())
|
||||
if (itr != m_boundInstances[difficulty].end())
|
||||
return &itr->second;
|
||||
else
|
||||
return NULL;
|
||||
|
|
@ -1751,45 +1752,45 @@ InstanceGroupBind* Group::GetBoundInstance(Map* aMap, Difficulty difficulty)
|
|||
{
|
||||
// some instances only have one difficulty
|
||||
MapDifficulty const* mapDiff = GetMapDifficultyData(aMap->GetId(),difficulty);
|
||||
if(!mapDiff)
|
||||
if (!mapDiff)
|
||||
return NULL;
|
||||
|
||||
BoundInstancesMap::iterator itr = m_boundInstances[difficulty].find(aMap->GetId());
|
||||
if(itr != m_boundInstances[difficulty].end())
|
||||
if (itr != m_boundInstances[difficulty].end())
|
||||
return &itr->second;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
InstanceGroupBind* Group::BindToInstance(InstanceSave *save, bool permanent, bool load)
|
||||
InstanceGroupBind* Group::BindToInstance(DungeonPersistentState *state, bool permanent, bool load)
|
||||
{
|
||||
if (save && !isBGGroup())
|
||||
if (state && !isBGGroup())
|
||||
{
|
||||
InstanceGroupBind& bind = m_boundInstances[save->GetDifficulty()][save->GetMapId()];
|
||||
if (bind.save)
|
||||
InstanceGroupBind& bind = m_boundInstances[state->GetDifficulty()][state->GetMapId()];
|
||||
if (bind.state)
|
||||
{
|
||||
// when a boss is killed or when copying the players's binds to the group
|
||||
if (permanent != bind.perm || save != bind.save)
|
||||
if (permanent != bind.perm || state != bind.state)
|
||||
if (!load)
|
||||
CharacterDatabase.PExecute("UPDATE group_instance SET instance = '%u', permanent = '%u' WHERE leaderGuid = '%u' AND instance = '%u'",
|
||||
save->GetInstanceId(), permanent, GetLeaderGuid().GetCounter(), bind.save->GetInstanceId());
|
||||
state->GetInstanceId(), permanent, GetLeaderGuid().GetCounter(), bind.state->GetInstanceId());
|
||||
}
|
||||
else if (!load)
|
||||
CharacterDatabase.PExecute("INSERT INTO group_instance (leaderGuid, instance, permanent) VALUES ('%u', '%u', '%u')",
|
||||
GetLeaderGuid().GetCounter(), save->GetInstanceId(), permanent);
|
||||
GetLeaderGuid().GetCounter(), state->GetInstanceId(), permanent);
|
||||
|
||||
if(bind.save != save)
|
||||
if (bind.state != state)
|
||||
{
|
||||
if(bind.save)
|
||||
bind.save->RemoveGroup(this);
|
||||
save->AddGroup(this);
|
||||
if (bind.state)
|
||||
bind.state->RemoveGroup(this);
|
||||
state->AddGroup(this);
|
||||
}
|
||||
|
||||
bind.save = save;
|
||||
bind.state = state;
|
||||
bind.perm = permanent;
|
||||
if (!load)
|
||||
DEBUG_LOG("Group::BindToInstance: Group (Id: %d) is now bound to map %d, instance %d, difficulty %d",
|
||||
GetId(), save->GetMapId(), save->GetInstanceId(), save->GetDifficulty());
|
||||
GetId(), state->GetMapId(), state->GetInstanceId(), state->GetDifficulty());
|
||||
return &bind;
|
||||
}
|
||||
else
|
||||
|
|
@ -1803,8 +1804,8 @@ void Group::UnbindInstance(uint32 mapid, uint8 difficulty, bool unload)
|
|||
{
|
||||
if (!unload)
|
||||
CharacterDatabase.PExecute("DELETE FROM group_instance WHERE leaderGuid = '%u' AND instance = '%u'",
|
||||
GetLeaderGuid().GetCounter(), itr->second.save->GetInstanceId());
|
||||
itr->second.save->RemoveGroup(this); // save can become invalid
|
||||
GetLeaderGuid().GetCounter(), itr->second.state->GetInstanceId());
|
||||
itr->second.state->RemoveGroup(this); // state can become invalid
|
||||
m_boundInstances[difficulty].erase(itr);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue