diff options
-rw-r--r-- | sql/updates/world/2015_10_25_00_world.sql | 2 | ||||
-rw-r--r-- | src/server/game/Conditions/ConditionMgr.cpp | 105 | ||||
-rw-r--r-- | src/server/game/Conditions/ConditionMgr.h | 2 | ||||
-rw-r--r-- | src/server/game/Entities/Object/Object.cpp | 114 | ||||
-rw-r--r-- | src/server/game/Globals/ObjectMgr.cpp | 17 | ||||
-rw-r--r-- | src/server/game/Globals/ObjectMgr.h | 50 |
6 files changed, 200 insertions, 90 deletions
diff --git a/sql/updates/world/2015_10_25_00_world.sql b/sql/updates/world/2015_10_25_00_world.sql new file mode 100644 index 00000000000..440e98db1a3 --- /dev/null +++ b/sql/updates/world/2015_10_25_00_world.sql @@ -0,0 +1,2 @@ +UPDATE `conditions` SET `SourceGroup`=`SourceEntry` WHERE `SourceTypeOrReferenceId`=26; +UPDATE `conditions` SET `SourceEntry`=0 WHERE `SourceTypeOrReferenceId`=26; diff --git a/src/server/game/Conditions/ConditionMgr.cpp b/src/server/game/Conditions/ConditionMgr.cpp index dd3f3244f5b..42511736154 100644 --- a/src/server/game/Conditions/ConditionMgr.cpp +++ b/src/server/game/Conditions/ConditionMgr.cpp @@ -814,7 +814,8 @@ bool ConditionMgr::CanHaveSourceGroupSet(ConditionSourceType sourceType) sourceType == CONDITION_SOURCE_TYPE_SPELL_IMPLICIT_TARGET || sourceType == CONDITION_SOURCE_TYPE_SPELL_CLICK_EVENT || sourceType == CONDITION_SOURCE_TYPE_SMART_EVENT || - sourceType == CONDITION_SOURCE_TYPE_NPC_VENDOR); + sourceType == CONDITION_SOURCE_TYPE_NPC_VENDOR || + sourceType == CONDITION_SOURCE_TYPE_PHASE); } bool ConditionMgr::CanHaveSourceIdSet(ConditionSourceType sourceType) @@ -934,6 +935,18 @@ void ConditionMgr::LoadConditions(bool isReload) TC_LOG_INFO("misc", "Re-Loading `gossip_menu_option` Table for Conditions!"); sObjectMgr->LoadGossipMenuItems(); sSpellMgr->UnloadSpellInfoImplicitTargetConditionLists(); + + TC_LOG_INFO("misc", "Re-Loading `terrain_phase_info` Table for Conditions!"); + sObjectMgr->LoadTerrainPhaseInfo(); + + TC_LOG_INFO("misc", "Re-Loading `terrain_swap_defaults` Table for Conditions!"); + sObjectMgr->LoadTerrainSwapDefaults(); + + TC_LOG_INFO("misc", "Re-Loading `terrain_worldmap` Table for Conditions!"); + sObjectMgr->LoadTerrainWorldMaps(); + + TC_LOG_INFO("misc", "Re-Loading `phase_area` Table for Conditions!"); + sObjectMgr->LoadAreaPhases(); } QueryResult result = WorldDatabase.Query("SELECT SourceTypeOrReferenceId, SourceGroup, SourceEntry, SourceId, ElseGroup, ConditionTypeOrReference, ConditionTarget, " @@ -1135,6 +1148,9 @@ void ConditionMgr::LoadConditions(bool isReload) ++count; continue; } + case CONDITION_SOURCE_TYPE_PHASE: + valid = addToPhases(cond); + break; default: break; } @@ -1151,6 +1167,17 @@ void ConditionMgr::LoadConditions(bool isReload) } continue; } + else if (cond->SourceType == CONDITION_SOURCE_TYPE_TERRAIN_SWAP) + { + if (!addToTerrainSwaps(cond)) + { + delete cond; + continue; + } + + ++count; + continue; + } //handle not grouped conditions //make sure we have a storage list for our SourceType @@ -1334,6 +1361,62 @@ bool ConditionMgr::addToSpellImplicitTargetConditions(Condition* cond) return true; } +static bool addToTerrainSwapStore(TerrainPhaseInfo& swaps, Condition* cond) +{ + bool added = false; + for (auto itr = swaps.begin(); itr != swaps.end(); ++itr) + for (auto it2 = itr->second.begin(); it2 != itr->second.end(); ++it2) + if (it2->Id == uint32(cond->SourceEntry)) + it2->Conditions.push_back(cond), added = true; + + return added; +} + +bool ConditionMgr::addToTerrainSwaps(Condition* cond) +{ + bool added = false; + added = addToTerrainSwapStore(sObjectMgr->GetPhaseTerrainSwapStoreForLoading(), cond); + added = addToTerrainSwapStore(sObjectMgr->GetDefaultTerrainSwapStoreForLoading(), cond) || added; + if (added) + return true; + + TC_LOG_ERROR("sql.sql", "%s No terrain swap with map %u exists.", cond->ToString().c_str(), cond->SourceEntry); + return false; +} + +bool ConditionMgr::addToPhases(Condition* cond) +{ + if (!cond->SourceEntry) + { + PhaseInfo& p = sObjectMgr->GetAreaPhasesForLoading(); + for (auto phaseItr = p.begin(); phaseItr != p.end(); ++phaseItr) + { + for (PhaseInfoStruct& phase : phaseItr->second) + { + if (phase.Id == cond->SourceGroup) + { + phase.Conditions.push_back(cond); + return true; + } + } + } + } + else if (std::vector<PhaseInfoStruct>* phases = sObjectMgr->GetPhasesForAreaForLoading(cond->SourceEntry)) + { + for (PhaseInfoStruct& phase : *phases) + { + if (phase.Id == cond->SourceGroup) + { + phase.Conditions.push_back(cond); + return true; + } + } + } + + TC_LOG_ERROR("sql.sql", "%s Area %u does not have phase %u.", cond->ToString().c_str(), cond->SourceGroup, cond->SourceEntry); + return false; +} + bool ConditionMgr::isSourceTypeValid(Condition* cond) { if (cond->SourceType == CONDITION_SOURCE_TYPE_NONE || cond->SourceType >= CONDITION_SOURCE_TYPE_MAX) @@ -1674,12 +1757,28 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond) } break; } + case CONDITION_SOURCE_TYPE_TERRAIN_SWAP: + { + if (!sMapStore.LookupEntry(cond->SourceEntry)) + { + TC_LOG_ERROR("sql.sql", "%s SourceEntry in `condition` table, does not exist in Map.dbc, ignoring.", cond->ToString().c_str()); + return false; + } + break; + } + case CONDITION_SOURCE_TYPE_PHASE: + { + if (cond->SourceEntry && !GetAreaEntryByAreaID(cond->SourceEntry)) + { + TC_LOG_ERROR("sql.sql", "%s SourceEntry in `condition` table, does not exist in AreaTable.dbc, ignoring.", cond->ToString().c_str()); + return false; + } + break; + } case CONDITION_SOURCE_TYPE_GOSSIP_MENU: case CONDITION_SOURCE_TYPE_GOSSIP_MENU_OPTION: case CONDITION_SOURCE_TYPE_SMART_EVENT: case CONDITION_SOURCE_TYPE_NONE: - case CONDITION_SOURCE_TYPE_TERRAIN_SWAP: - case CONDITION_SOURCE_TYPE_PHASE: default: break; } diff --git a/src/server/game/Conditions/ConditionMgr.h b/src/server/game/Conditions/ConditionMgr.h index 3549b1f2515..a9015af6e60 100644 --- a/src/server/game/Conditions/ConditionMgr.h +++ b/src/server/game/Conditions/ConditionMgr.h @@ -292,6 +292,8 @@ class ConditionMgr bool addToGossipMenus(Condition* cond); bool addToGossipMenuItems(Condition* cond); bool addToSpellImplicitTargetConditions(Condition* cond); + bool addToTerrainSwaps(Condition* cond); + bool addToPhases(Condition* cond); bool IsObjectMeetToConditionList(ConditionSourceInfo& sourceInfo, ConditionList const& conditions); static void LogUselessConditionValue(Condition* cond, uint8 index, uint32 value); diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp index 9a01eacbf7f..6318caf00b4 100644 --- a/src/server/game/Entities/Object/Object.cpp +++ b/src/server/game/Entities/Object/Object.cpp @@ -2807,26 +2807,25 @@ bool WorldObject::HasInPhaseList(uint32 phase) void WorldObject::UpdateAreaPhase() { bool updateNeeded = false; - PhaseInfo phases = sObjectMgr->GetAreaPhases(); + PhaseInfo const& phases = sObjectMgr->GetAreaPhases(); for (PhaseInfo::const_iterator itr = phases.begin(); itr != phases.end(); ++itr) { uint32 areaId = itr->first; - for (uint32 phaseId : itr->second) + for (PhaseInfoStruct const& phase : itr->second) { if (areaId == GetAreaId()) { - ConditionList conditions = sConditionMgr->GetConditionsForNotGroupedEntry(CONDITION_SOURCE_TYPE_PHASE, phaseId); - if (sConditionMgr->IsObjectMeetToConditions(this, conditions)) + if (sConditionMgr->IsObjectMeetToConditions(this, phase.Conditions)) { // add new phase if condition passed, true if it wasnt added before - bool up = SetInPhase(phaseId, false, true); + bool up = SetInPhase(phase.Id, false, true); if (!updateNeeded && up) updateNeeded = true; } else { // condition failed, remove phase, true if there was something removed - bool up = SetInPhase(phaseId, false, false); + bool up = SetInPhase(phase.Id, false, false); if (!updateNeeded && up) updateNeeded = true; } @@ -2834,7 +2833,7 @@ void WorldObject::UpdateAreaPhase() else { // not in area, remove phase, true if there was something removed - bool up = SetInPhase(phaseId, false, false); + bool up = SetInPhase(phase.Id, false, false); if (!updateNeeded && up) updateNeeded = true; } @@ -2866,7 +2865,6 @@ void WorldObject::UpdateAreaPhase() } // only update visibility and send packets if there was a change in the phase list - if (updateNeeded && GetTypeId() == TYPEID_PLAYER && IsInWorld()) ToPlayer()->GetSession()->SendSetPhaseShift(GetPhases(), GetTerrainSwaps(), GetWorldMapAreaSwaps()); @@ -2883,32 +2881,31 @@ bool WorldObject::SetInPhase(uint32 id, bool update, bool apply) { if (HasInPhaseList(id)) // do not run the updates if we are already in this phase return false; + _phases.insert(id); } else { - for (uint32 phaseId : sObjectMgr->GetPhasesForArea(GetAreaId())) - { - if (id == phaseId) - { - ConditionList conditions = sConditionMgr->GetConditionsForNotGroupedEntry(CONDITION_SOURCE_TYPE_PHASE, phaseId); - if (sConditionMgr->IsObjectMeetToConditions(this, conditions)) - { - // if area phase passes the condition we should not remove it (ie: if remove called from aura remove) - // this however breaks the .mod phase command, you wont be able to remove any area based phases with it - return false; - } - } - } + // if area phase passes the condition we should not remove it (ie: if remove called from aura remove) + // this however breaks the .mod phase command, you wont be able to remove any area based phases with it + if (std::vector<PhaseInfoStruct> const* phases = sObjectMgr->GetPhasesForArea(GetAreaId())) + for (PhaseInfoStruct const& phase : *phases) + if (id == phase.Id) + if (sConditionMgr->IsObjectMeetToConditions(this, phase.Conditions)) + return false; + if (!HasInPhaseList(id)) // do not run the updates if we are not in this phase return false; + _phases.erase(id); } } + RebuildTerrainSwaps(); if (update && IsInWorld()) UpdateObjectVisibility(); + return true; } @@ -3111,37 +3108,30 @@ void WorldObject::RebuildTerrainSwaps() // Clear all terrain swaps, will be rebuilt below // Reason for this is, multiple phases can have the same terrain swap, we should not remove the swap if another phase still use it _terrainSwaps.clear(); - ConditionList conditions; // Check all applied phases for terrain swap and add it only once for (uint32 phaseId : _phases) { - std::list<uint32>& swaps = sObjectMgr->GetPhaseTerrainSwaps(phaseId); - - for (uint32 swap : swaps) + if (std::vector<PhaseInfoStruct> const* swaps = sObjectMgr->GetPhaseTerrainSwaps(phaseId)) { - // only add terrain swaps for current map - MapEntry const* mapEntry = sMapStore.LookupEntry(swap); - if (!mapEntry || mapEntry->ParentMapID != int32(GetMapId())) - continue; - - conditions = sConditionMgr->GetConditionsForNotGroupedEntry(CONDITION_SOURCE_TYPE_TERRAIN_SWAP, swap); + for (PhaseInfoStruct const& swap : *swaps) + { + // only add terrain swaps for current map + MapEntry const* mapEntry = sMapStore.LookupEntry(swap.Id); + if (!mapEntry || mapEntry->ParentMapID != int32(GetMapId())) + continue; - if (sConditionMgr->IsObjectMeetToConditions(this, conditions)) - _terrainSwaps.insert(swap); + if (sConditionMgr->IsObjectMeetToConditions(this, swap.Conditions)) + _terrainSwaps.insert(swap.Id); + } } } // get default terrain swaps, only for current map always - std::list<uint32>& mapSwaps = sObjectMgr->GetDefaultTerrainSwaps(GetMapId()); - - for (uint32 swap : mapSwaps) - { - conditions = sConditionMgr->GetConditionsForNotGroupedEntry(CONDITION_SOURCE_TYPE_TERRAIN_SWAP, swap); - - if (sConditionMgr->IsObjectMeetToConditions(this, conditions)) - _terrainSwaps.insert(swap); - } + if (std::vector<PhaseInfoStruct> const* mapSwaps = sObjectMgr->GetDefaultTerrainSwaps(GetMapId())) + for (PhaseInfoStruct const& swap : *mapSwaps) + if (sConditionMgr->IsObjectMeetToConditions(this, swap.Conditions)) + _terrainSwaps.insert(swap.Id); // online players have a game client with world map display if (GetTypeId() == TYPEID_PLAYER) @@ -3155,36 +3145,20 @@ void WorldObject::RebuildWorldMapAreaSwaps() // 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(); + TerrainPhaseInfo const& 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); - } - } - } + for (PhaseInfoStruct const& swap : itr->second) + if (std::vector<uint32> const* uiMapSwaps = sObjectMgr->GetTerrainWorldMaps(swap.Id)) + if (sConditionMgr->IsObjectMeetToConditions(this, swap.Conditions)) + for (uint32 worldMapAreaId : *uiMapSwaps) + _worldMapAreaSwaps.insert(worldMapAreaId); // Check all applied phases for world map area swaps for (uint32 phaseId : _phases) - { - std::list<uint32>& swaps = sObjectMgr->GetPhaseTerrainSwaps(phaseId); - - for (uint32 swap : swaps) - { - // add world map swaps for ANY map - - ConditionList conditions = sConditionMgr->GetConditionsForNotGroupedEntry(CONDITION_SOURCE_TYPE_TERRAIN_SWAP, swap); - - if (sConditionMgr->IsObjectMeetToConditions(this, conditions)) - { - for (uint32 map : sObjectMgr->GetTerrainWorldMaps(swap)) - _worldMapAreaSwaps.insert(map); - } - } - } + if (std::vector<PhaseInfoStruct> const* swaps = sObjectMgr->GetPhaseTerrainSwaps(phaseId)) + for (PhaseInfoStruct const& swap : *swaps) + if (std::vector<uint32> const* uiMapSwaps = sObjectMgr->GetTerrainWorldMaps(swap.Id)) + if (sConditionMgr->IsObjectMeetToConditions(this, swap.Conditions)) + for (uint32 worldMapAreaId : *uiMapSwaps) + _worldMapAreaSwaps.insert(worldMapAreaId); } diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index 5e5ec3be6eb..3e418f08880 100644 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -8873,8 +8873,7 @@ void ObjectMgr::LoadTerrainSwapDefaults() uint32 mapId = fields[0].GetUInt32(); - MapEntry const* map = sMapStore.LookupEntry(mapId); - if (!map) + if (!sMapStore.LookupEntry(mapId)) { TC_LOG_ERROR("sql.sql", "Map %u defined in `terrain_swap_defaults` does not exist, skipped.", mapId); continue; @@ -8882,14 +8881,15 @@ void ObjectMgr::LoadTerrainSwapDefaults() uint32 terrainSwap = fields[1].GetUInt32(); - map = sMapStore.LookupEntry(terrainSwap); - if (!map) + if (!sMapStore.LookupEntry(terrainSwap)) { TC_LOG_ERROR("sql.sql", "TerrainSwapMap %u defined in `terrain_swap_defaults` does not exist, skipped.", terrainSwap); continue; } - _terrainMapDefaultStore[mapId].push_back(terrainSwap); + PhaseInfoStruct defaultSwap; + defaultSwap.Id = terrainSwap; + _terrainMapDefaultStore[mapId].push_back(defaultSwap); ++count; } while (result->NextRow()); @@ -8926,7 +8926,8 @@ void ObjectMgr::LoadTerrainPhaseInfo() continue; } - uint32 terrainSwap = fields[1].GetUInt32(); + PhaseInfoStruct terrainSwap; + terrainSwap.Id = fields[1].GetUInt32(); _terrainPhaseInfoStore[phaseId].push_back(terrainSwap); @@ -8995,9 +8996,9 @@ void ObjectMgr::LoadAreaPhases() { Field* fields = result->Fetch(); + PhaseInfoStruct phase; uint32 area = fields[0].GetUInt32(); - uint32 phase = fields[1].GetUInt32(); - + phase.Id = fields[1].GetUInt32(); _phases[area].push_back(phase); ++count; diff --git a/src/server/game/Globals/ObjectMgr.h b/src/server/game/Globals/ObjectMgr.h index 62791734b72..ad51d77a9bd 100644 --- a/src/server/game/Globals/ObjectMgr.h +++ b/src/server/game/Globals/ObjectMgr.h @@ -681,8 +681,15 @@ struct DungeonEncounter typedef std::list<DungeonEncounter const*> DungeonEncounterList; typedef std::unordered_map<uint64, DungeonEncounterList> DungeonEncounterContainer; -typedef std::unordered_map<uint32, std::list<uint32>> TerrainPhaseInfo; -typedef std::unordered_map<uint32, std::list<uint32>> PhaseInfo; +struct PhaseInfoStruct +{ + uint32 Id; + ConditionList Conditions; +}; + +typedef std::unordered_map<uint32, std::vector<PhaseInfoStruct>> TerrainPhaseInfo; // terrain swap +typedef std::unordered_map<uint32, std::vector<uint32>> TerrainUIPhaseInfo; // worldmaparea swap +typedef std::unordered_map<uint32, std::vector<PhaseInfoStruct>> PhaseInfo; // phase class PlayerDumpReader; @@ -1293,12 +1300,37 @@ class ObjectMgr return _gossipMenuItemsStore.equal_range(uiMenuId); } - std::list<uint32>& GetPhaseTerrainSwaps(uint32 phaseid) { return _terrainPhaseInfoStore[phaseid]; } - std::list<uint32>& GetDefaultTerrainSwaps(uint32 mapid) { return _terrainMapDefaultStore[mapid]; } - std::list<uint32>& GetTerrainWorldMaps(uint32 terrainId) { return _terrainWorldMapStore[terrainId]; } - TerrainPhaseInfo& GetDefaultTerrainSwapStore() { return _terrainMapDefaultStore; } - std::list<uint32>& GetPhasesForArea(uint32 area) { return _phases[area]; } - PhaseInfo& GetAreaPhases() { return _phases; } + std::vector<PhaseInfoStruct> const* GetPhaseTerrainSwaps(uint32 phaseid) const + { + auto itr = _terrainPhaseInfoStore.find(phaseid); + return itr != _terrainPhaseInfoStore.end() ? &itr->second : nullptr; + } + std::vector<PhaseInfoStruct> const* GetDefaultTerrainSwaps(uint32 mapid) const + { + auto itr = _terrainMapDefaultStore.find(mapid); + return itr != _terrainMapDefaultStore.end() ? &itr->second : nullptr; + } + std::vector<uint32> const* GetTerrainWorldMaps(uint32 terrainId) const + { + auto itr = _terrainWorldMapStore.find(terrainId); + return itr != _terrainWorldMapStore.end() ? &itr->second : nullptr; + } + std::vector<PhaseInfoStruct> const* GetPhasesForArea(uint32 area) const + { + auto itr = _phases.find(area); + return itr != _phases.end() ? &itr->second : nullptr; + } + TerrainPhaseInfo const& GetDefaultTerrainSwapStore() const { return _terrainMapDefaultStore; } + PhaseInfo const& GetAreaPhases() const { return _phases; } + // condition loading helpers + std::vector<PhaseInfoStruct>* GetPhasesForAreaForLoading(uint32 area) + { + auto itr = _phases.find(area); + return itr != _phases.end() ? &itr->second : nullptr; + } + TerrainPhaseInfo& GetPhaseTerrainSwapStoreForLoading() { return _terrainPhaseInfoStore; } + TerrainPhaseInfo& GetDefaultTerrainSwapStoreForLoading() { return _terrainMapDefaultStore; } + PhaseInfo& GetAreaPhasesForLoading() { return _phases; } // for wintergrasp only GraveYardContainer GraveYardStore; @@ -1440,7 +1472,7 @@ class ObjectMgr TerrainPhaseInfo _terrainPhaseInfoStore; TerrainPhaseInfo _terrainMapDefaultStore; - TerrainPhaseInfo _terrainWorldMapStore; + TerrainUIPhaseInfo _terrainWorldMapStore; PhaseInfo _phases; private: |