aboutsummaryrefslogtreecommitdiff
path: root/src/server/game/Globals/ObjectMgr.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/server/game/Globals/ObjectMgr.cpp')
-rw-r--r--src/server/game/Globals/ObjectMgr.cpp265
1 files changed, 193 insertions, 72 deletions
diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp
index 8a8651f3aa0..78cd1e7e5b9 100644
--- a/src/server/game/Globals/ObjectMgr.cpp
+++ b/src/server/game/Globals/ObjectMgr.cpp
@@ -1872,8 +1872,8 @@ void ObjectMgr::LoadCreatures()
QueryResult result = WorldDatabase.Query("SELECT creature.guid, id, map, modelid, equipment_id, position_x, position_y, position_z, orientation, spawntimesecs, spawndist, "
// 11 12 13 14 15 16 17 18 19 20 21
"currentwaypoint, curhealth, curmana, MovementType, spawnMask, eventEntry, pool_entry, creature.npcflag, creature.unit_flags, creature.unit_flags2, creature.unit_flags3, "
- // 22 23 24 25
- "creature.dynamicflags, creature.phaseid, creature.phasegroup, creature.ScriptName "
+ // 22 23 24 25 26 27
+ "creature.dynamicflags, creature.phaseUseFlags, creature.phaseid, creature.phasegroup, creature.terrainSwapMap, creature.ScriptName "
"FROM creature "
"LEFT OUTER JOIN game_event_creature ON creature.guid = game_event_creature.guid "
"LEFT OUTER JOIN pool_creature ON creature.guid = pool_creature.guid");
@@ -1930,9 +1930,11 @@ void ObjectMgr::LoadCreatures()
data.unit_flags2 = fields[20].GetUInt32();
data.unit_flags3 = fields[21].GetUInt32();
data.dynamicflags = fields[22].GetUInt32();
- data.phaseId = fields[23].GetUInt32();
- data.phaseGroup = fields[24].GetUInt32();
- data.ScriptId = GetScriptId(fields[25].GetString());
+ data.phaseUseFlags = fields[23].GetUInt8();
+ data.phaseId = fields[24].GetUInt32();
+ data.phaseGroup = fields[25].GetUInt32();
+ data.terrainSwapMap = fields[26].GetInt32();
+ data.ScriptId = GetScriptId(fields[27].GetString());
if (!data.ScriptId)
data.ScriptId = cInfo->ScriptID;
@@ -2020,6 +2022,19 @@ void ObjectMgr::LoadCreatures()
data.orientation = Position::NormalizeOrientation(data.orientation);
}
+ if (data.phaseUseFlags & ~PHASE_USE_FLAGS_ALL)
+ {
+ TC_LOG_ERROR("sql.sql", "Table `creature` have creature (GUID: " UI64FMTD " Entry: %u) has unknown `phaseUseFlags` set, removed unknown value.", guid, data.id);
+ data.phaseUseFlags &= PHASE_USE_FLAGS_ALL;
+ }
+
+ if (data.phaseUseFlags & PHASE_USE_FLAGS_ALWAYS_VISIBLE && data.phaseUseFlags & PHASE_USE_FLAGS_INVERSE)
+ {
+ TC_LOG_ERROR("sql.sql", "Table `creature` have creature (GUID: " UI64FMTD " Entry: %u) has both `phaseUseFlags` PHASE_USE_FLAGS_ALWAYS_VISIBLE and PHASE_USE_FLAGS_INVERSE,"
+ " removing PHASE_USE_FLAGS_INVERSE.", guid, data.id);
+ data.phaseUseFlags &= ~PHASE_USE_FLAGS_INVERSE;
+ }
+
if (data.phaseGroup && data.phaseId)
{
TC_LOG_ERROR("sql.sql", "Table `creature` have creature (GUID: " UI64FMTD " Entry: %u) with both `phaseid` and `phasegroup` set, `phasegroup` set to 0", guid, data.id);
@@ -2037,13 +2052,28 @@ void ObjectMgr::LoadCreatures()
if (data.phaseGroup)
{
- if (sDB2Manager.GetPhasesForGroup(data.phaseGroup).empty())
+ if (!sDB2Manager.GetPhasesForGroup(data.phaseGroup))
{
TC_LOG_ERROR("sql.sql", "Table `creature` have creature (GUID: " UI64FMTD " Entry: %u) with `phasegroup` %u does not exist, set to 0", guid, data.id, data.phaseGroup);
data.phaseGroup = 0;
}
}
+ if (data.terrainSwapMap != -1)
+ {
+ MapEntry const* terrainSwapEntry = sMapStore.LookupEntry(data.terrainSwapMap);
+ if (!terrainSwapEntry)
+ {
+ TC_LOG_ERROR("sql.sql", "Table `creature` have creature (GUID: " UI64FMTD " Entry: %u) with `terrainSwapMap` %u does not exist, set to -1", guid, data.id, data.terrainSwapMap);
+ data.terrainSwapMap = -1;
+ }
+ else if (terrainSwapEntry->ParentMapID != data.mapid)
+ {
+ TC_LOG_ERROR("sql.sql", "Table `creature` have creature (GUID: " UI64FMTD " Entry: %u) with `terrainSwapMap` %u which cannot be used on spawn map, set to -1", guid, data.id, data.terrainSwapMap);
+ data.terrainSwapMap = -1;
+ }
+ }
+
if (sWorld->getBoolConfig(CONFIG_CALCULATE_CREATURE_ZONE_AREA_DATA))
{
uint32 zoneId = 0;
@@ -2202,8 +2232,8 @@ void ObjectMgr::LoadGameobjects()
QueryResult result = WorldDatabase.Query("SELECT gameobject.guid, id, map, position_x, position_y, position_z, orientation, "
// 7 8 9 10 11 12 13 14 15 16
"rotation0, rotation1, rotation2, rotation3, spawntimesecs, animprogress, state, spawnMask, eventEntry, pool_entry, "
- // 17 18 19
- "phaseid, phasegroup, ScriptName "
+ // 17 18 19 20 21
+ "phaseUseFlags, phaseid, phasegroup, terrainSwapMap, ScriptName "
"FROM gameobject LEFT OUTER JOIN game_event_gameobject ON gameobject.guid = game_event_gameobject.guid "
"LEFT OUTER JOIN pool_gameobject ON gameobject.guid = pool_gameobject.guid");
@@ -2317,8 +2347,22 @@ void ObjectMgr::LoadGameobjects()
int16 gameEvent = fields[15].GetInt8();
uint32 PoolId = fields[16].GetUInt32();
- data.phaseId = fields[17].GetUInt32();
- data.phaseGroup = fields[18].GetUInt32();
+ data.phaseUseFlags = fields[17].GetUInt8();
+ data.phaseId = fields[18].GetUInt32();
+ data.phaseGroup = fields[19].GetUInt32();
+
+ if (data.phaseUseFlags & ~PHASE_USE_FLAGS_ALL)
+ {
+ TC_LOG_ERROR("sql.sql", "Table `gameobject` have gameobject (GUID: " UI64FMTD " Entry: %u) has unknown `phaseUseFlags` set, removed unknown value.", guid, data.id);
+ data.phaseUseFlags &= PHASE_USE_FLAGS_ALL;
+ }
+
+ if (data.phaseUseFlags & PHASE_USE_FLAGS_ALWAYS_VISIBLE && data.phaseUseFlags & PHASE_USE_FLAGS_INVERSE)
+ {
+ TC_LOG_ERROR("sql.sql", "Table `gameobject` have gameobject (GUID: " UI64FMTD " Entry: %u) has both `phaseUseFlags` PHASE_USE_FLAGS_ALWAYS_VISIBLE and PHASE_USE_FLAGS_INVERSE,"
+ " removing PHASE_USE_FLAGS_INVERSE.", guid, data.id);
+ data.phaseUseFlags &= ~PHASE_USE_FLAGS_INVERSE;
+ }
if (data.phaseGroup && data.phaseId)
{
@@ -2337,14 +2381,30 @@ void ObjectMgr::LoadGameobjects()
if (data.phaseGroup)
{
- if (sDB2Manager.GetPhasesForGroup(data.phaseGroup).empty())
+ if (!sDB2Manager.GetPhasesForGroup(data.phaseGroup))
{
TC_LOG_ERROR("sql.sql", "Table `gameobject` have gameobject (GUID: " UI64FMTD " Entry: %u) with `phaseGroup` %u does not exist, set to 0", guid, data.id, data.phaseGroup);
data.phaseGroup = 0;
}
}
- data.ScriptId = GetScriptId(fields[19].GetString());
+ data.terrainSwapMap = fields[20].GetInt32();
+ if (data.terrainSwapMap != -1)
+ {
+ MapEntry const* terrainSwapEntry = sMapStore.LookupEntry(data.terrainSwapMap);
+ if (!terrainSwapEntry)
+ {
+ TC_LOG_ERROR("sql.sql", "Table `gameobject` have gameobject (GUID: " UI64FMTD " Entry: %u) with `terrainSwapMap` %u does not exist, set to -1", guid, data.id, data.terrainSwapMap);
+ data.terrainSwapMap = -1;
+ }
+ else if (terrainSwapEntry->ParentMapID != data.mapid)
+ {
+ TC_LOG_ERROR("sql.sql", "Table `gameobject` have gameobject (GUID: " UI64FMTD " Entry: %u) with `terrainSwapMap` %u which cannot be used on spawn map, set to -1", guid, data.id, data.terrainSwapMap);
+ data.terrainSwapMap = -1;
+ }
+ }
+
+ data.ScriptId = GetScriptId(fields[21].GetString());
if (!data.ScriptId)
data.ScriptId = gInfo->ScriptId;
@@ -9394,18 +9454,42 @@ void ObjectMgr::LoadFactionChangeTitles()
TC_LOG_INFO("server.loading", ">> Loaded %u faction change title pairs in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
}
-void ObjectMgr::LoadTerrainSwapDefaults()
+void ObjectMgr::LoadPhases()
+{
+ for (PhaseEntry const* phase : sPhaseStore)
+ _phaseInfoById.emplace(std::make_pair(phase->ID, PhaseInfoStruct{ phase->ID, std::unordered_set<uint32>{} }));
+
+ for (MapEntry const* map : sMapStore)
+ if (map->ParentMapID != -1)
+ _terrainSwapInfoById.emplace(std::make_pair(map->ID, TerrainSwapInfo{ map->ID, std::vector<uint32>{} }));
+
+ TC_LOG_INFO("server.loading", "Loading Terrain World Map definitions...");
+ LoadTerrainWorldMaps();
+
+ TC_LOG_INFO("server.loading", "Loading Terrain Swap Default definitions...");
+ LoadTerrainSwapDefaults();
+
+ TC_LOG_INFO("server.loading", "Loading Phase Area definitions...");
+ LoadAreaPhases();
+}
+
+void ObjectMgr::UnloadPhaseConditions()
{
- _terrainMapDefaultStore.clear();
+ for (auto itr = _phaseInfoByArea.begin(); itr != _phaseInfoByArea.end(); ++itr)
+ for (PhaseAreaInfo& phase : itr->second)
+ phase.Conditions.clear();
+}
+void ObjectMgr::LoadTerrainWorldMaps()
+{
uint32 oldMSTime = getMSTime();
- // 0 1
- QueryResult result = WorldDatabase.Query("SELECT MapId, TerrainSwapMap FROM `terrain_swap_defaults`");
+ // 0 1
+ QueryResult result = WorldDatabase.Query("SELECT TerrainSwapMap, WorldMapArea FROM `terrain_worldmap`");
if (!result)
{
- TC_LOG_INFO("server.loading", ">> Loaded 0 terrain swap defaults. DB table `terrain_swap_defaults` is empty.");
+ TC_LOG_INFO("server.loading", ">> Loaded 0 terrain world maps. DB table `terrain_worldmap` is empty.");
return;
}
@@ -9415,41 +9499,40 @@ void ObjectMgr::LoadTerrainSwapDefaults()
Field* fields = result->Fetch();
uint32 mapId = fields[0].GetUInt32();
+ uint32 worldMapArea = fields[1].GetUInt32();
if (!sMapStore.LookupEntry(mapId))
{
- TC_LOG_ERROR("sql.sql", "Map %u defined in `terrain_swap_defaults` does not exist, skipped.", mapId);
+ TC_LOG_ERROR("sql.sql", "TerrainSwapMap %u defined in `terrain_worldmap` does not exist, skipped.", mapId);
continue;
}
- uint32 terrainSwap = fields[1].GetUInt32();
-
- if (!sMapStore.LookupEntry(terrainSwap))
+ if (!sWorldMapAreaStore.LookupEntry(worldMapArea))
{
- TC_LOG_ERROR("sql.sql", "TerrainSwapMap %u defined in `terrain_swap_defaults` does not exist, skipped.", terrainSwap);
+ TC_LOG_ERROR("sql.sql", "WorldMapArea %u defined in `terrain_worldmap` does not exist, skipped.", worldMapArea);
continue;
}
- _terrainMapDefaultStore[mapId].push_back(terrainSwap);
+ TerrainSwapInfo* terrainSwapInfo = &_terrainSwapInfoById[mapId];
+ terrainSwapInfo->Id = mapId;
+ terrainSwapInfo->UiWorldMapAreaIDSwaps.push_back(worldMapArea);
++count;
} while (result->NextRow());
- TC_LOG_INFO("server.loading", ">> Loaded %u terrain swap defaults in %u ms.", count, GetMSTimeDiffToNow(oldMSTime));
+ TC_LOG_INFO("server.loading", ">> Loaded %u terrain world maps in %u ms.", count, GetMSTimeDiffToNow(oldMSTime));
}
-void ObjectMgr::LoadTerrainPhaseInfo()
+void ObjectMgr::LoadTerrainSwapDefaults()
{
- _terrainPhaseInfoStore.clear();
-
uint32 oldMSTime = getMSTime();
// 0 1
- QueryResult result = WorldDatabase.Query("SELECT Id, TerrainSwapMap FROM `terrain_phase_info`");
+ QueryResult result = WorldDatabase.Query("SELECT MapId, TerrainSwapMap FROM `terrain_swap_defaults`");
if (!result)
{
- TC_LOG_INFO("server.loading", ">> Loaded 0 terrain phase infos. DB table `terrain_phase_info` is empty.");
+ TC_LOG_INFO("server.loading", ">> Loaded 0 terrain swap defaults. DB table `terrain_swap_defaults` is empty.");
return;
}
@@ -9458,92 +9541,130 @@ void ObjectMgr::LoadTerrainPhaseInfo()
{
Field* fields = result->Fetch();
- uint32 phaseId = fields[0].GetUInt32();
+ uint32 mapId = fields[0].GetUInt32();
- if (!sPhaseStore.LookupEntry(phaseId))
+ if (!sMapStore.LookupEntry(mapId))
{
- TC_LOG_ERROR("sql.sql", "Phase %u defined in `terrain_phase_info` does not exist, skipped.", phaseId);
+ TC_LOG_ERROR("sql.sql", "Map %u defined in `terrain_swap_defaults` does not exist, skipped.", mapId);
continue;
}
uint32 terrainSwap = fields[1].GetUInt32();
- _terrainPhaseInfoStore[phaseId].push_back(terrainSwap);
+ if (!sMapStore.LookupEntry(terrainSwap))
+ {
+ TC_LOG_ERROR("sql.sql", "TerrainSwapMap %u defined in `terrain_swap_defaults` does not exist, skipped.", terrainSwap);
+ continue;
+ }
+
+ TerrainSwapInfo* terrainSwapInfo = &_terrainSwapInfoById[terrainSwap];
+ terrainSwapInfo->Id = terrainSwap;
+ _terrainSwapInfoByMap[mapId].push_back(terrainSwapInfo);
++count;
- }
- while (result->NextRow());
+ } while (result->NextRow());
- TC_LOG_INFO("server.loading", ">> Loaded %u terrain phase infos in %u ms.", count, GetMSTimeDiffToNow(oldMSTime));
+ TC_LOG_INFO("server.loading", ">> Loaded %u terrain swap defaults in %u ms.", count, GetMSTimeDiffToNow(oldMSTime));
}
-void ObjectMgr::LoadTerrainWorldMaps()
+void ObjectMgr::LoadAreaPhases()
{
- _terrainWorldMapStore.clear();
-
uint32 oldMSTime = getMSTime();
- // 0 1
- QueryResult result = WorldDatabase.Query("SELECT TerrainSwapMap, WorldMapArea FROM `terrain_worldmap`");
+ // 0 1
+ QueryResult result = WorldDatabase.Query("SELECT AreaId, PhaseId FROM `phase_area`");
if (!result)
{
- TC_LOG_INFO("server.loading", ">> Loaded 0 terrain world maps. DB table `terrain_worldmap` is empty.");
+ TC_LOG_INFO("server.loading", ">> Loaded 0 phase areas. DB table `phase_area` is empty.");
return;
}
+ auto getOrCreatePhaseIfMissing = [this](uint32 phaseId)
+ {
+ PhaseInfoStruct* phaseInfo = &_phaseInfoById[phaseId];
+ phaseInfo->Id = phaseId;
+ return phaseInfo;
+ };
+
uint32 count = 0;
do
{
Field* fields = result->Fetch();
-
- uint32 mapId = fields[0].GetUInt32();
-
- if (!sMapStore.LookupEntry(mapId))
+ uint32 area = fields[0].GetUInt32();
+ uint32 phaseId = fields[1].GetUInt32();
+ if (!sAreaTableStore.LookupEntry(area))
{
- TC_LOG_ERROR("sql.sql", "TerrainSwapMap %u defined in `terrain_worldmap` does not exist, skipped.", mapId);
+ TC_LOG_ERROR("sql.sql", "Area %u defined in `phase_area` does not exist, skipped.", area);
continue;
}
- uint32 worldMapArea = fields[1].GetUInt32();
+ if (!sPhaseStore.LookupEntry(phaseId))
+ {
+ TC_LOG_ERROR("sql.sql", "Phase %u defined in `phase_area` does not exist, skipped.", phaseId);
+ continue;
+ }
- _terrainWorldMapStore[mapId].push_back(worldMapArea);
+ PhaseInfoStruct* phase = getOrCreatePhaseIfMissing(phaseId);
+ phase->Areas.insert(area);
+ _phaseInfoByArea[area].emplace_back(phase);
++count;
} while (result->NextRow());
- TC_LOG_INFO("server.loading", ">> Loaded %u terrain world maps in %u ms.", count, GetMSTimeDiffToNow(oldMSTime));
-}
-
-void ObjectMgr::LoadAreaPhases()
-{
- _phases.clear();
+ for (auto itr = _phaseInfoByArea.begin(); itr != _phaseInfoByArea.end(); ++itr)
+ {
+ for (PhaseAreaInfo& phase : itr->second)
+ {
+ uint32 parentAreaId = itr->first;
+ do
+ {
+ AreaTableEntry const* area = sAreaTableStore.LookupEntry(parentAreaId);
+ if (!area)
+ break;
- uint32 oldMSTime = getMSTime();
+ parentAreaId = area->ParentAreaID;
+ if (!parentAreaId)
+ break;
- // 0 1
- QueryResult result = WorldDatabase.Query("SELECT AreaId, PhaseId FROM `phase_area`");
+ if (std::vector<PhaseAreaInfo>* parentAreaPhases = Trinity::Containers::MapGetValuePtr(_phaseInfoByArea, parentAreaId))
+ for (PhaseAreaInfo& parentAreaPhase : *parentAreaPhases)
+ if (parentAreaPhase.PhaseInfo->Id == phase.PhaseInfo->Id)
+ parentAreaPhase.SubAreaExclusions.insert(itr->first);
- if (!result)
- {
- TC_LOG_INFO("server.loading", ">> Loaded 0 phase areas. DB table `phase_area` is empty.");
- return;
+ } while (true);
+ }
}
- uint32 count = 0;
- do
+ TC_LOG_INFO("server.loading", ">> Loaded %u phase areas in %u ms.", count, GetMSTimeDiffToNow(oldMSTime));
+}
+
+bool PhaseInfoStruct::IsAllowedInArea(uint32 areaId) const
+{
+ return std::any_of(Areas.begin(), Areas.end(), [areaId](uint32 areaToCheck)
{
- Field* fields = result->Fetch();
+ return DB2Manager::IsInArea(areaId, areaToCheck);
+ });
+}
- PhaseInfoStruct phase;
- uint32 area = fields[0].GetUInt32();
- phase.Id = fields[1].GetUInt32();
- _phases[area].push_back(phase);
+PhaseInfoStruct const* ObjectMgr::GetPhaseInfo(uint32 phaseId) const
+{
+ return Trinity::Containers::MapGetValuePtr(_phaseInfoById, phaseId);
+}
- ++count;
- } while (result->NextRow());
+std::vector<PhaseAreaInfo> const* ObjectMgr::GetPhasesForArea(uint32 areaId) const
+{
+ return Trinity::Containers::MapGetValuePtr(_phaseInfoByArea, areaId);
+}
- TC_LOG_INFO("server.loading", ">> Loaded %u phase areas in %u ms.", count, GetMSTimeDiffToNow(oldMSTime));
+TerrainSwapInfo const* ObjectMgr::GetTerrainSwapInfo(uint32 terrainSwapId) const
+{
+ return Trinity::Containers::MapGetValuePtr(_terrainSwapInfoById, terrainSwapId);
+}
+
+std::vector<TerrainSwapInfo*> const* ObjectMgr::GetTerrainSwapsForMap(uint32 mapId) const
+{
+ return Trinity::Containers::MapGetValuePtr(_terrainSwapInfoByMap, mapId);
}
GameObjectTemplate const* ObjectMgr::GetGameObjectTemplate(uint32 entry) const