diff --git a/src/game/Map.cpp b/src/game/Map.cpp index 9ec26167a..c6385e787 100644 --- a/src/game/Map.cpp +++ b/src/game/Map.cpp @@ -31,7 +31,6 @@ #include "ObjectMgr.h" #include "World.h" #include "ScriptCalls.h" -#include "ScriptMgr.h" #include "Group.h" #include "MapRefManager.h" #include "DBCEnums.h" @@ -39,14 +38,6 @@ #include "VMapFactory.h" #include "BattleGroundMgr.h" -struct ScriptAction -{ - ObjectGuid sourceGuid; - ObjectGuid targetGuid; - ObjectGuid ownerGuid; // owner of source if source is item - ScriptInfo const* script; // pointer to static script data -}; - Map::~Map() { ObjectAccessor::DelinkMap(this); @@ -227,24 +218,20 @@ Map::EnsureGridCreated(const GridPair &p) { if(!getNGrid(p.x_coord, p.y_coord)) { - Guard guard(*this); - if(!getNGrid(p.x_coord, p.y_coord)) - { - setNGrid(new NGridType(p.x_coord*MAX_NUMBER_OF_GRIDS + p.y_coord, p.x_coord, p.y_coord, i_gridExpiry, sWorld.getConfig(CONFIG_BOOL_GRID_UNLOAD)), - p.x_coord, p.y_coord); + setNGrid(new NGridType(p.x_coord*MAX_NUMBER_OF_GRIDS + p.y_coord, p.x_coord, p.y_coord, i_gridExpiry, sWorld.getConfig(CONFIG_BOOL_GRID_UNLOAD)), + p.x_coord, p.y_coord); - // build a linkage between this map and NGridType - buildNGridLinkage(getNGrid(p.x_coord, p.y_coord)); + // build a linkage between this map and NGridType + buildNGridLinkage(getNGrid(p.x_coord, p.y_coord)); - getNGrid(p.x_coord, p.y_coord)->SetGridState(GRID_STATE_IDLE); + getNGrid(p.x_coord, p.y_coord)->SetGridState(GRID_STATE_IDLE); - //z coord - int gx = (MAX_NUMBER_OF_GRIDS - 1) - p.x_coord; - int gy = (MAX_NUMBER_OF_GRIDS - 1) - p.y_coord; + //z coord + int gx = (MAX_NUMBER_OF_GRIDS - 1) - p.x_coord; + int gy = (MAX_NUMBER_OF_GRIDS - 1) - p.y_coord; - if(!m_bLoadedGrids[gx][gy]) - LoadMapAndVMap(gx,gy); - } + if(!m_bLoadedGrids[gx][gy]) + LoadMapAndVMap(gx,gy); } } @@ -1319,118 +1306,115 @@ bool InstanceMap::Add(Player *player) // GMs still can teleport player in instance. // Is it needed? - { - Guard guard(*this); - if (!CanEnter(player)) - return false; + if (!CanEnter(player)) + return false; - // Dungeon only code - if (IsDungeon()) + // Dungeon only code + if (IsDungeon()) + { + // check for existing instance binds + InstancePlayerBind *playerBind = player->GetBoundInstance(GetId(), GetDifficulty()); + if (playerBind && playerBind->perm) { - // check for existing instance binds - InstancePlayerBind *playerBind = player->GetBoundInstance(GetId(), GetDifficulty()); - if (playerBind && playerBind->perm) + // cannot enter other instances if bound permanently + if (playerBind->save != GetInstanceSave()) { - // cannot enter other instances if bound permanently - if (playerBind->save != GetInstanceSave()) + sLog.outError("InstanceMap::Add: player %s(%d) is permanently bound to instance %d,%d,%d,%d,%d,%d but he is being put in instance %d,%d,%d,%d,%d,%d", + player->GetName(), player->GetGUIDLow(), playerBind->save->GetMapId(), + playerBind->save->GetInstanceId(), playerBind->save->GetDifficulty(), + playerBind->save->GetPlayerCount(), playerBind->save->GetGroupCount(), + playerBind->save->CanReset(), + GetInstanceSave()->GetMapId(), GetInstanceSave()->GetInstanceId(), + GetInstanceSave()->GetDifficulty(), GetInstanceSave()->GetPlayerCount(), + GetInstanceSave()->GetGroupCount(), GetInstanceSave()->CanReset()); + MANGOS_ASSERT(false); + } + } + else + { + Group *pGroup = player->GetGroup(); + if (pGroup) + { + // solo saves should be reset when entering a group + InstanceGroupBind *groupBind = pGroup->GetBoundInstance(this,GetDifficulty()); + if (playerBind) { - sLog.outError("InstanceMap::Add: player %s(%d) is permanently bound to instance %d,%d,%d,%d,%d,%d but he is being put in instance %d,%d,%d,%d,%d,%d", - player->GetName(), player->GetGUIDLow(), playerBind->save->GetMapId(), - playerBind->save->GetInstanceId(), playerBind->save->GetDifficulty(), - playerBind->save->GetPlayerCount(), playerBind->save->GetGroupCount(), - playerBind->save->CanReset(), - GetInstanceSave()->GetMapId(), GetInstanceSave()->GetInstanceId(), - GetInstanceSave()->GetDifficulty(), GetInstanceSave()->GetPlayerCount(), - GetInstanceSave()->GetGroupCount(), GetInstanceSave()->CanReset()); - MANGOS_ASSERT(false); + sLog.outError("InstanceMap::Add: %s is being put in instance %d,%d,%d,%d,%d,%d but he is in group (Id: %d) and is bound to instance %d,%d,%d,%d,%d,%d!", + player->GetGuidStr().c_str(), GetInstanceSave()->GetMapId(), GetInstanceSave()->GetInstanceId(), + GetInstanceSave()->GetDifficulty(), GetInstanceSave()->GetPlayerCount(), GetInstanceSave()->GetGroupCount(), + GetInstanceSave()->CanReset(), pGroup->GetId(), + playerBind->save->GetMapId(), playerBind->save->GetInstanceId(), playerBind->save->GetDifficulty(), + playerBind->save->GetPlayerCount(), playerBind->save->GetGroupCount(), playerBind->save->CanReset()); + + if (groupBind) + sLog.outError("InstanceMap::Add: the group (Id: %d) is bound to instance %d,%d,%d,%d,%d,%d", + pGroup->GetId(), + groupBind->save->GetMapId(), groupBind->save->GetInstanceId(), groupBind->save->GetDifficulty(), + groupBind->save->GetPlayerCount(), groupBind->save->GetGroupCount(), groupBind->save->CanReset()); + + // no reason crash if we can fix state + player->UnbindInstance(GetId(), GetDifficulty()); + } + + // bind to the group or keep using the group save + if (!groupBind) + pGroup->BindToInstance(GetInstanceSave(), false); + else + { + // cannot jump to a different instance without resetting it + if (groupBind->save != GetInstanceSave()) + { + sLog.outError("InstanceMap::Add: %s is being put in instance %d,%d,%d but he is in group (Id: %d) which is bound to instance %d,%d,%d!", + player->GetGuidStr().c_str(), GetInstanceSave()->GetMapId(), + GetInstanceSave()->GetInstanceId(), GetInstanceSave()->GetDifficulty(), + pGroup->GetId(), groupBind->save->GetMapId(), + groupBind->save->GetInstanceId(), groupBind->save->GetDifficulty()); + + if (GetInstanceSave()) + sLog.outError("MapSave players: %d, group count: %d", + GetInstanceSave()->GetPlayerCount(), GetInstanceSave()->GetGroupCount()); + else + sLog.outError("MapSave NULL"); + + if (groupBind->save) + sLog.outError("GroupBind save players: %d, group count: %d", groupBind->save->GetPlayerCount(), groupBind->save->GetGroupCount()); + else + sLog.outError("GroupBind save NULL"); + MANGOS_ASSERT(false); + } + // if the group/leader is permanently bound to the instance + // players also become permanently bound when they enter + if (groupBind->perm) + { + WorldPacket data(SMSG_INSTANCE_SAVE_CREATED, 4); + data << uint32(0); + player->GetSession()->SendPacket(&data); + player->BindToInstance(GetInstanceSave(), true); + } } } else { - Group *pGroup = player->GetGroup(); - if (pGroup) - { - // solo saves should be reset when entering a group - InstanceGroupBind *groupBind = pGroup->GetBoundInstance(this,GetDifficulty()); - if (playerBind) - { - sLog.outError("InstanceMap::Add: %s is being put in instance %d,%d,%d,%d,%d,%d but he is in group (Id: %d) and is bound to instance %d,%d,%d,%d,%d,%d!", - player->GetGuidStr().c_str(), GetInstanceSave()->GetMapId(), GetInstanceSave()->GetInstanceId(), - GetInstanceSave()->GetDifficulty(), GetInstanceSave()->GetPlayerCount(), GetInstanceSave()->GetGroupCount(), - GetInstanceSave()->CanReset(), pGroup->GetId(), - playerBind->save->GetMapId(), playerBind->save->GetInstanceId(), playerBind->save->GetDifficulty(), - playerBind->save->GetPlayerCount(), playerBind->save->GetGroupCount(), playerBind->save->CanReset()); - - if (groupBind) - sLog.outError("InstanceMap::Add: the group (Id: %d) is bound to instance %d,%d,%d,%d,%d,%d", - pGroup->GetId(), - groupBind->save->GetMapId(), groupBind->save->GetInstanceId(), groupBind->save->GetDifficulty(), - groupBind->save->GetPlayerCount(), groupBind->save->GetGroupCount(), groupBind->save->CanReset()); - - // no reason crash if we can fix state - player->UnbindInstance(GetId(), GetDifficulty()); - } - - // bind to the group or keep using the group save - if (!groupBind) - pGroup->BindToInstance(GetInstanceSave(), false); - else - { - // cannot jump to a different instance without resetting it - if (groupBind->save != GetInstanceSave()) - { - sLog.outError("InstanceMap::Add: %s is being put in instance %d,%d,%d but he is in group (Id: %d) which is bound to instance %d,%d,%d!", - player->GetGuidStr().c_str(), GetInstanceSave()->GetMapId(), - GetInstanceSave()->GetInstanceId(), GetInstanceSave()->GetDifficulty(), - pGroup->GetId(), groupBind->save->GetMapId(), - groupBind->save->GetInstanceId(), groupBind->save->GetDifficulty()); - - if (GetInstanceSave()) - sLog.outError("MapSave players: %d, group count: %d", - GetInstanceSave()->GetPlayerCount(), GetInstanceSave()->GetGroupCount()); - else - sLog.outError("MapSave NULL"); - - if (groupBind->save) - sLog.outError("GroupBind save players: %d, group count: %d", groupBind->save->GetPlayerCount(), groupBind->save->GetGroupCount()); - else - sLog.outError("GroupBind save NULL"); - MANGOS_ASSERT(false); - } - // if the group/leader is permanently bound to the instance - // players also become permanently bound when they enter - if (groupBind->perm) - { - WorldPacket data(SMSG_INSTANCE_SAVE_CREATED, 4); - data << uint32(0); - player->GetSession()->SendPacket(&data); - player->BindToInstance(GetInstanceSave(), true); - } - } - } + // set up a solo bind or continue using it + if(!playerBind) + player->BindToInstance(GetInstanceSave(), false); else - { - // set up a solo bind or continue using it - if(!playerBind) - player->BindToInstance(GetInstanceSave(), false); - else - // cannot jump to a different instance without resetting it - MANGOS_ASSERT(playerBind->save == GetInstanceSave()); - } + // cannot jump to a different instance without resetting it + MANGOS_ASSERT(playerBind->save == GetInstanceSave()); } } - - // for normal instances cancel the reset schedule when the - // first player enters (no players yet) - SetResetSchedule(false); - - DETAIL_LOG("MAP: Player '%s' is entering instance '%u' of map '%s'", player->GetName(), GetInstanceId(), GetMapName()); - // initialize unload state - m_unloadTimer = 0; - m_resetAfterUnload = false; - m_unloadWhenEmpty = false; } + // for normal instances cancel the reset schedule when the + // first player enters (no players yet) + SetResetSchedule(false); + + DETAIL_LOG("MAP: Player '%s' is entering instance '%u' of map '%s'", player->GetName(), GetInstanceId(), GetMapName()); + // initialize unload state + m_unloadTimer = 0; + m_resetAfterUnload = false; + m_unloadWhenEmpty = false; + // this will acquire the same mutex so it cannot be in the previous block Map::Add(player); @@ -1649,13 +1633,12 @@ bool BattleGroundMap::CanEnter(Player * player) bool BattleGroundMap::Add(Player * player) { - { - Guard guard(*this); - if(!CanEnter(player)) - return false; - // reset instance validity, battleground maps do not homebind - player->m_InstanceValid = true; - } + if(!CanEnter(player)) + return false; + + // reset instance validity, battleground maps do not homebind + player->m_InstanceValid = true; + return Map::Add(player); } diff --git a/src/game/Map.h b/src/game/Map.h index cfcaeb880..8c5129427 100644 --- a/src/game/Map.h +++ b/src/game/Map.h @@ -35,6 +35,7 @@ #include "GameSystem/GridRefManager.h" #include "MapRefManager.h" #include "Utilities/TypeList.h" +#include "ScriptMgr.h" #include #include @@ -46,7 +47,6 @@ class InstanceData; class Group; class InstanceSave; struct ScriptInfo; -struct ScriptAction; class BattleGround; class GridMap; @@ -80,7 +80,7 @@ enum LevelRequirementVsMode #define MIN_UNLOAD_DELAY 1 // immediate unload -class MANGOS_DLL_SPEC Map : public GridRefManager, public MaNGOS::ObjectLevelLockable +class MANGOS_DLL_SPEC Map : public GridRefManager { friend class MapReference; friend class ObjectGridLoader; @@ -276,7 +276,6 @@ class MANGOS_DLL_SPEC Map : public GridRefManager, public MaNGOS::Obj void SendObjectUpdates(); std::set i_objectsToClientUpdate; protected: - typedef MaNGOS::ObjectLevelLockable::Lock Guard; MapEntry const* i_mapEntry; uint8 i_spawnMode; diff --git a/src/game/ScriptMgr.h b/src/game/ScriptMgr.h index 28ed34467..1f5e61fc3 100644 --- a/src/game/ScriptMgr.h +++ b/src/game/ScriptMgr.h @@ -21,6 +21,7 @@ #include "Common.h" #include "Policies/Singleton.h" +#include "ObjectGuid.h" enum eScriptCommand { @@ -269,6 +270,14 @@ struct ScriptInfo } }; +struct ScriptAction +{ + ObjectGuid sourceGuid; + ObjectGuid targetGuid; + ObjectGuid ownerGuid; // owner of source if source is item + ScriptInfo const* script; // pointer to static script data +}; + typedef std::multimap ScriptMap; typedef std::map ScriptMapMap; extern ScriptMapMap sQuestEndScripts; diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 5cabf6793..18fb3c5af 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 "10913" + #define REVISION_NR "10914" #endif // __REVISION_NR_H__