diff --git a/sql/updates/world/2014_10_31_00_world.sql b/sql/updates/world/2014_10_31_00_world.sql new file mode 100644 index 00000000000..7bee8bc3bab --- /dev/null +++ b/sql/updates/world/2014_10_31_00_world.sql @@ -0,0 +1,44 @@ +DROP TABLE IF EXISTS `terrain_phase_info`; +DROP TABLE IF EXISTS `terrain_map_info`; +DROP TABLE IF EXISTS `terrain_swap_defaults`; +DROP TABLE IF EXISTS `terrain_worldmap`; + +CREATE TABLE `terrain_phase_info`( + `Id` INT(10) unsigned NOT NULL, + `TerrainSwapMap` INT(10) unsigned NOT NULL, + `Comment` VARCHAR(255), + PRIMARY KEY (`Id`, `TerrainSwapMap`) +); + +CREATE TABLE `terrain_swap_defaults`( + `MapId` INT(10) unsigned NOT NULL, + `TerrainSwapMap` INT(10) unsigned NOT NULL, + `Comment` VARCHAR(255), + PRIMARY KEY (`MapId`, `TerrainSwapMap`) +); + +CREATE TABLE `terrain_worldmap`( + `TerrainSwapMap` INT(10) unsigned NOT NULL, + `WorldMapArea` INT(10) unsigned NOT NULL, + `Comment` VARCHAR(255), + PRIMARY KEY (`TerrainSwapMap`, `WorldMapArea`) +); + +INSERT INTO `terrain_phase_info` (Id, TerrainSwapMap, Comment) VALUES +(182, 655, 'Quest Zone-Specific 07'), +(186, 656, 'Quest Zone-Specific 11'); + +INSERT INTO `terrain_worldmap` (TerrainSwapMap, WorldMapArea, Comment) VALUES +(638, 545, 'Gilneas'), +(655, 678, 'Gilneas_terrain1'), +(719, 683, 'Hyjal_terrain1'), +(656, 679, 'Gilneas_terrain2'); + +INSERT INTO `terrain_swap_defaults` (MapId, TerrainSwapMap, Comment) VALUES +(1, 719, 'Mount Hyjal default terrain'), +(654, 638, 'Gilneas default terrain'); + +DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=25 AND `SourceEntry`=719; +INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES +(25, 0, 719, 0, 0, 8, 0, 25372, 0, 0, 1, 0, 0, '', 'Hyjal terrain swap if Aessina''s Miracle quest is not rewarded'); + diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp index 89e2cf166ea..7e33d73c903 100644 --- a/src/server/game/Entities/Object/Object.cpp +++ b/src/server/game/Entities/Object/Object.cpp @@ -2934,6 +2934,11 @@ void WorldObject::RebuildTerrainSwaps() for (uint32 swap : swaps) { + // only add terrain swaps for current map + MapEntry const* mapEntry = sMapStore.LookupEntry(swap); + if (!mapEntry || mapEntry->rootPhaseMap != GetMapId()) + continue; + conditions = sConditionMgr->GetConditionsForNotGroupedEntry(CONDITION_SOURCE_TYPE_TERRAIN_SWAP, swap); if (sConditionMgr->IsObjectMeetToConditions(this, conditions)) @@ -2941,14 +2946,38 @@ void WorldObject::RebuildTerrainSwaps() } } - // get default terrain swaps, id is 0 - std::list& swaps = sObjectMgr->GetPhaseTerrainSwaps(0); + // get default terrain swaps, only for current map always + std::list& mapSwaps = sObjectMgr->GetDefaultTerrainSwaps(GetMapId()); - for (uint32 swap : swaps) + for (uint32 swap : mapSwaps) { conditions = sConditionMgr->GetConditionsForNotGroupedEntry(CONDITION_SOURCE_TYPE_TERRAIN_SWAP, swap); if (sConditionMgr->IsObjectMeetToConditions(this, conditions)) _terrainSwaps.insert(swap); } + if (GetTypeId() == TYPEID_PLAYER) + RebuildWorldMapAreaSwaps(); +} + +void WorldObject::RebuildWorldMapAreaSwaps() +{ + // Clear all world map area swaps, will be rebuilt below + _worldMapAreaSwaps.clear(); + + // get ALL default terrain swaps, if we are using it (condition is true) + // send the worldmaparea for it, to see swapped worldmaparea in client from other maps too, not just from our current + TerrainPhaseInfo defaults = sObjectMgr->GetDefaultTerrainSwapStore(); + for (TerrainPhaseInfo::const_iterator itr = defaults.begin(); itr != defaults.end(); ++itr) + { + for (uint32 swap : itr->second) + { + ConditionList conditions = sConditionMgr->GetConditionsForNotGroupedEntry(CONDITION_SOURCE_TYPE_TERRAIN_SWAP, swap); + if (sConditionMgr->IsObjectMeetToConditions(this, conditions)) + { + for (uint32 map : sObjectMgr->GetTerrainWorldMaps(swap)) + _worldMapAreaSwaps.insert(map); + } + } + } } diff --git a/src/server/game/Entities/Object/Object.h b/src/server/game/Entities/Object/Object.h index 71f1cc69dfe..f245f3e0e97 100644 --- a/src/server/game/Entities/Object/Object.h +++ b/src/server/game/Entities/Object/Object.h @@ -596,16 +596,18 @@ class WorldObject : public Object, public WorldLocation void CopyPhaseFrom(WorldObject* obj, bool update = false); void ClearPhases(bool update = false); void RebuildTerrainSwaps(); + void RebuildWorldMapAreaSwaps(); uint32 GetPhaseMask() const { return m_phaseMask; } bool IsInPhase(uint32 phase) const { return _phases.find(phase) != _phases.end(); } bool IsInPhase(WorldObject const* obj) const; bool IsInTerrainSwap(uint32 terrainSwap) const { return _terrainSwaps.find(terrainSwap) != _terrainSwaps.end(); } std::set const& GetPhases() const { return _phases; } std::set const& GetTerrainSwaps() const { return _terrainSwaps; } - int GetDBPhase() { return _dbPhase; } + std::set const& GetWorldMapAreaSwaps() const { return _worldMapAreaSwaps; } + int32 GetDBPhase() { return _dbPhase; } // if negative it is used as PhaseGroupId - void SetDBPhase(int p) { _dbPhase = p; } + void SetDBPhase(int32 p) { _dbPhase = p; } uint32 GetZoneId() const; uint32 GetAreaId() const; @@ -778,7 +780,8 @@ class WorldObject : public Object, public WorldLocation uint32 m_phaseMask; // in area phase state std::set _phases; std::set _terrainSwaps; - int _dbPhase; + std::set _worldMapAreaSwaps; + int32 _dbPhase; uint16 m_notifyflags; uint16 m_executed_notifies; diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index ccbb844de4a..274ba31cbee 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -16185,7 +16185,7 @@ void Player::SendQuestUpdate(uint32 questId) } UpdateForQuestWorldObjects(); - RebuildTerrainSwaps(); + SendUpdatePhasing(); } QuestGiverStatus Player::GetQuestDialogStatus(Object* questgiver) @@ -27993,18 +27993,9 @@ void Player::SendUpdatePhasing() if (!IsInWorld()) return; - RebuildTerrainSwaps(); // to set default maps swaps + RebuildTerrainSwaps(); // to set default map swaps - std::set worldAreaSwaps; - - for (uint32 terrain : GetTerrainSwaps()) - { - for (uint32 map : sObjectMgr->GetMapTerrainSwaps(terrain)) - { - worldAreaSwaps.insert(map); - } - } - GetSession()->SendSetPhaseShift(GetPhases(), GetTerrainSwaps(), worldAreaSwaps); + GetSession()->SendSetPhaseShift(GetPhases(), GetTerrainSwaps(), GetWorldMapAreaSwaps()); } void Player::SendSupercededSpell(uint32 oldSpell, uint32 newSpell) diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index 09643797a00..3f794e516fd 100644 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -9258,18 +9258,18 @@ void ObjectMgr::LoadFactionChangeTitles() TC_LOG_INFO("server.loading", ">> Loaded %u faction change title pairs in %u ms", count, GetMSTimeDiffToNow(oldMSTime)); } -void ObjectMgr::LoadTerrainMapInfo() +void ObjectMgr::LoadTerrainSwapDefaults() { - _terrainMapInfoStore.clear(); + _terrainMapDefaultStore.clear(); uint32 oldMSTime = getMSTime(); // 0 1 - QueryResult result = WorldDatabase.Query("SELECT MapId, TerrainSwapMap FROM `terrain_map_info`"); + QueryResult result = WorldDatabase.Query("SELECT MapId, TerrainSwapMap FROM `terrain_swap_defaults`"); if (!result) { - TC_LOG_INFO("server.loading", ">> Loaded 0 terrain area infos. DB table `terrain_map_info` is empty."); + TC_LOG_INFO("server.loading", ">> Loaded 0 terrain swap defaults. DB table `terrain_swap_defaults` is empty."); return; } @@ -9283,18 +9283,25 @@ void ObjectMgr::LoadTerrainMapInfo() MapEntry const* map = sMapStore.LookupEntry(mapId); if (!map) { - TC_LOG_ERROR("sql.sql", "Map %u defined in `terrain_map_info` does not exist, skipped.", mapId); + TC_LOG_ERROR("sql.sql", "Map %u defined in `terrain_swap_defaults` does not exist, skipped.", mapId); continue; } uint32 terrainSwap = fields[1].GetUInt32(); - _terrainMapInfoStore[mapId].push_back(terrainSwap); + map = sMapStore.LookupEntry(terrainSwap); + if (!map) + { + TC_LOG_ERROR("sql.sql", "TerrainSwapMap %u defined in `terrain_swap_defaults` does not exist, skipped.", terrainSwap); + continue; + } + + _terrainMapDefaultStore[mapId].push_back(terrainSwap); ++count; } while (result->NextRow()); - TC_LOG_INFO("server.loading", ">> Loaded %u terrain map 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::LoadTerrainPhaseInfo() @@ -9319,16 +9326,13 @@ void ObjectMgr::LoadTerrainPhaseInfo() uint32 phaseId = fields[0].GetUInt32(); - // 0 is kept for default map swaps - if (phaseId) + PhaseEntry const* phase = sPhaseStore.LookupEntry(phaseId); + if (!phase) { - PhaseEntry const* phase = sPhaseStore.LookupEntry(phaseId); - if (!phase) - { - TC_LOG_ERROR("sql.sql", "Phase %u defined in `terrain_phase_info` does not exist, skipped.", phaseId); - continue; - } + TC_LOG_ERROR("sql.sql", "Phase %u defined in `terrain_phase_info` does not exist, skipped.", phaseId); + continue; } + uint32 terrainSwap = fields[1].GetUInt32(); _terrainPhaseInfoStore[phaseId].push_back(terrainSwap); @@ -9340,6 +9344,44 @@ void ObjectMgr::LoadTerrainPhaseInfo() TC_LOG_INFO("server.loading", ">> Loaded %u terrain phase infos in %u ms.", count, GetMSTimeDiffToNow(oldMSTime)); } +void ObjectMgr::LoadTerrainWorldMaps() +{ + _terrainWorldMapStore.clear(); + + uint32 oldMSTime = getMSTime(); + + // 0 1 + QueryResult result = WorldDatabase.Query("SELECT TerrainSwapMap, WorldMapArea FROM `terrain_worldmap`"); + + if (!result) + { + TC_LOG_INFO("server.loading", ">> Loaded 0 terrain world maps. DB table `terrain_worldmap` is empty."); + return; + } + + uint32 count = 0; + do + { + Field* fields = result->Fetch(); + + uint32 mapId = fields[0].GetUInt32(); + + if (!sMapStore.LookupEntry(mapId)) + { + TC_LOG_ERROR("sql.sql", "TerrainSwapMap %u defined in `terrain_worldmap` does not exist, skipped.", mapId); + continue; + } + + uint32 worldMapArea = fields[1].GetUInt32(); + + _terrainWorldMapStore[mapId].push_back(worldMapArea); + + ++count; + } while (result->NextRow()); + + TC_LOG_INFO("server.loading", ">> Loaded %u terrain world maps in %u ms.", count, GetMSTimeDiffToNow(oldMSTime)); +} + GameObjectTemplate const* ObjectMgr::GetGameObjectTemplate(uint32 entry) { GameObjectTemplateContainer::const_iterator itr = _gameObjectTemplateStore.find(entry); diff --git a/src/server/game/Globals/ObjectMgr.h b/src/server/game/Globals/ObjectMgr.h index 12e358d3c05..8de6896e014 100644 --- a/src/server/game/Globals/ObjectMgr.h +++ b/src/server/game/Globals/ObjectMgr.h @@ -1029,7 +1029,8 @@ class ObjectMgr void AddSpellToTrainer(uint32 entry, uint32 spell, uint32 spellCost, uint32 reqSkill, uint32 reqSkillValue, uint32 reqLevel); void LoadTerrainPhaseInfo(); - void LoadTerrainMapInfo(); + void LoadTerrainSwapDefaults(); + void LoadTerrainWorldMaps(); std::string GeneratePetName(uint32 entry); uint32 GetBaseXP(uint8 level); @@ -1287,7 +1288,9 @@ class ObjectMgr } std::list& GetPhaseTerrainSwaps(uint32 phaseid) { return _terrainPhaseInfoStore[phaseid]; } - std::list& GetMapTerrainSwaps(uint32 mapid) { return _terrainMapInfoStore[mapid]; } + std::list& GetDefaultTerrainSwaps(uint32 mapid) { return _terrainMapDefaultStore[mapid]; } + std::list& GetTerrainWorldMaps(uint32 terrainId) { return _terrainWorldMapStore[terrainId]; } + TerrainPhaseInfo& GetDefaultTerrainSwapStore() { return _terrainMapDefaultStore; } // for wintergrasp only GraveYardContainer GraveYardStore; @@ -1405,7 +1408,8 @@ class ObjectMgr InstanceTemplateContainer _instanceTemplateStore; TerrainPhaseInfo _terrainPhaseInfoStore; - TerrainPhaseInfo _terrainMapInfoStore; + TerrainPhaseInfo _terrainMapDefaultStore; + TerrainPhaseInfo _terrainWorldMapStore; private: void LoadScripts(ScriptsType type); diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index 22a5e138d1f..d0dbe6a87a1 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -1733,8 +1733,11 @@ void World::SetInitialWorldSettings() TC_LOG_INFO("server.loading", "Loading Terrain Phase definitions..."); sObjectMgr->LoadTerrainPhaseInfo(); - TC_LOG_INFO("server.loading", "Loading Terrain Map definitions..."); - sObjectMgr->LoadTerrainMapInfo(); + TC_LOG_INFO("server.loading", "Loading Terrain Swap Default definitions..."); + sObjectMgr->LoadTerrainSwapDefaults(); + + TC_LOG_INFO("server.loading", "Loading Terrain World Map definitions..."); + sObjectMgr->LoadTerrainWorldMaps(); TC_LOG_INFO("server.loading", "Loading Conditions..."); sConditionMgr->LoadConditions();