aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sql/updates/world/2015_10_25_00_world.sql2
-rw-r--r--src/server/game/Conditions/ConditionMgr.cpp105
-rw-r--r--src/server/game/Conditions/ConditionMgr.h2
-rw-r--r--src/server/game/Entities/Object/Object.cpp114
-rw-r--r--src/server/game/Globals/ObjectMgr.cpp17
-rw-r--r--src/server/game/Globals/ObjectMgr.h50
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: