Core/Conditions: Phase condition changes

* SourceGroup defines which phase should the condition affect

* SourceEntry limits the area of the phase (alternatively 0 means all areas)
This commit is contained in:
Aokromes committed 2015-11-01 19:11:52 +01:00
1 parent 2a0df059f3
commit c58f540348
5 files changed
+198 -89

No files matched your search

+102 -3
View File
@@ -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
@@ -1313,6 +1340,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)
@@ -1655,12 +1738,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;
}
@@ -273,6 +273,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);
+44 -70
View File
@@ -2607,26 +2607,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;
}
@@ -2634,7 +2633,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;
}
@@ -2666,7 +2665,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());
@@ -2683,32 +2681,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;
}
@@ -2904,37 +2901,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->rootPhaseMap != int32(GetMapId()))
continue;
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;
conditions = sConditionMgr->GetConditionsForNotGroupedEntry(CONDITION_SOURCE_TYPE_TERRAIN_SWAP, swap);
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)
@@ -2948,36 +2938,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);
}
+9 -7
View File
@@ -9387,8 +9387,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;
@@ -9396,14 +9395,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());
@@ -9440,7 +9440,8 @@ void ObjectMgr::LoadTerrainPhaseInfo()
continue;
}
uint32 terrainSwap = fields[1].GetUInt32();
PhaseInfoStruct terrainSwap;
terrainSwap.Id = fields[1].GetUInt32();
_terrainPhaseInfoStore[phaseId].push_back(terrainSwap);
@@ -9509,9 +9510,10 @@ 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;
+41 -9
View File
@@ -677,8 +677,15 @@ struct HotfixInfo
typedef std::vector<HotfixInfo> HotfixData;
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;
@@ -1301,12 +1308,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;
@@ -1425,7 +1457,7 @@ class ObjectMgr
TerrainPhaseInfo _terrainPhaseInfoStore;
TerrainPhaseInfo _terrainMapDefaultStore;
TerrainPhaseInfo _terrainWorldMapStore;
TerrainUIPhaseInfo _terrainWorldMapStore;
PhaseInfo _phases;
private: