diff options
Diffstat (limited to 'src/server/game/Globals/ObjectMgr.cpp')
-rw-r--r-- | src/server/game/Globals/ObjectMgr.cpp | 265 |
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 |