From 6fc90de3b52bcee2b1c35c2924c5de05b8fe01c9 Mon Sep 17 00:00:00 2001 From: Shauren Date: Sat, 8 Oct 2022 23:48:04 +0200 Subject: [PATCH] Core/WorldStates: Allow multiple map ids for world states --- .../world/4.3.4/2022_10_08_01_world.sql | 1 + .../World/WorldStates/WorldStateDefines.h | 4 +- .../game/World/WorldStates/WorldStateMgr.cpp | 48 +++++++++++++++---- 3 files changed, 41 insertions(+), 12 deletions(-) create mode 100755 sql/updates/world/4.3.4/2022_10_08_01_world.sql diff --git a/sql/updates/world/4.3.4/2022_10_08_01_world.sql b/sql/updates/world/4.3.4/2022_10_08_01_world.sql new file mode 100755 index 0000000000..983ff2092a --- /dev/null +++ b/sql/updates/world/4.3.4/2022_10_08_01_world.sql @@ -0,0 +1 @@ +ALTER TABLE `world_state` CHANGE `MapID` `MapIDs` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL; diff --git a/src/server/game/World/WorldStates/WorldStateDefines.h b/src/server/game/World/WorldStates/WorldStateDefines.h index 3b85a36d1e..97966fb5ce 100644 --- a/src/server/game/World/WorldStates/WorldStateDefines.h +++ b/src/server/game/World/WorldStates/WorldStateDefines.h @@ -19,8 +19,8 @@ #define WorldStateDefines_h__ #include "Define.h" -#include "Optional.h" #include +#include struct WorldStateTemplate { @@ -28,7 +28,7 @@ struct WorldStateTemplate int32 DefaultValue = 0; uint32 ScriptId = 0; - Optional MapId; + std::unordered_set MapIds; }; using WorldStateValueContainer = std::unordered_map; diff --git a/src/server/game/World/WorldStates/WorldStateMgr.cpp b/src/server/game/World/WorldStates/WorldStateMgr.cpp index 321a7255c4..09b90e8d50 100644 --- a/src/server/game/World/WorldStates/WorldStateMgr.cpp +++ b/src/server/game/World/WorldStates/WorldStateMgr.cpp @@ -36,8 +36,8 @@ void WorldStateMgr::LoadFromDB() { uint32 oldMSTime = getMSTime(); - // 0 1 2 3 - QueryResult result = WorldDatabase.Query("SELECT ID, DefaultValue, MapID, ScriptName FROM world_state"); + // 0 1 2 3 + QueryResult result = WorldDatabase.Query("SELECT ID, DefaultValue, MapIDs, ScriptName FROM world_state"); if (!result) return; @@ -49,13 +49,41 @@ void WorldStateMgr::LoadFromDB() WorldStateTemplate& worldState = _worldStateTemplates[id]; worldState.Id = id; worldState.DefaultValue = fields[1].GetInt32(); - if (!fields[2].IsNull()) - worldState.MapId = fields[2].GetUInt32(); + + Tokenizer tokens(fields[2].GetString(), ' '); + uint8 i = 0; + for (Tokenizer::const_iterator itr = tokens.begin(); itr != tokens.end(); ++itr, ++i) + { + uint32 mapId = atoul(*itr); + if (!mapId) + { + TC_LOG_ERROR("sql.sql", "Table `world_state` contains a world state %u with non-integer MapID (%s), map ignored", + id, *itr); + continue; + } + + if (!sMapStore.LookupEntry(mapId)) + { + TC_LOG_ERROR("sql.sql", "Table `world_state` contains a world state %u with invalid MapID (%u), map ignored", + id, mapId); + continue; + } + + worldState.MapIds.insert(mapId); + } + + if (i > 0 && worldState.MapIds.empty()) + { + TC_LOG_ERROR("sql.sql", "Table `world_state` contains a world state %u with nonempty MapIDs but no valid map id was found, ignored", + id); + continue; + } worldState.ScriptId = sObjectMgr->GetScriptId(fields[3].GetString()); - if (worldState.MapId) - _worldStatesByMap[*worldState.MapId][id] = worldState.DefaultValue; + if (!worldState.MapIds.empty()) + for (uint32 mapId : worldState.MapIds) + _worldStatesByMap[mapId][id] = worldState.DefaultValue; else _realmWorldStateValues[id] = worldState.DefaultValue; @@ -72,7 +100,7 @@ WorldStateTemplate const* WorldStateMgr::GetWorldStateTemplate(int32 worldStateI int32 WorldStateMgr::GetValue(int32 worldStateId, Map const* map) const { WorldStateTemplate const* worldStateTemplate = GetWorldStateTemplate(worldStateId); - if (!worldStateTemplate || !worldStateTemplate->MapId) + if (!worldStateTemplate || worldStateTemplate->MapIds.empty()) { if (int32 const* value = Trinity::Containers::MapGetValuePtr(_realmWorldStateValues, worldStateId)) return *value; @@ -80,7 +108,7 @@ int32 WorldStateMgr::GetValue(int32 worldStateId, Map const* map) const return 0; } - if (map->GetId() != worldStateTemplate->MapId) + if (worldStateTemplate->MapIds.find(map->GetId()) == worldStateTemplate->MapIds.end()) return 0; return map->GetWorldStateValue(worldStateId); @@ -89,7 +117,7 @@ int32 WorldStateMgr::GetValue(int32 worldStateId, Map const* map) const void WorldStateMgr::SetValue(int32 worldStateId, int32 value, Map* map) { WorldStateTemplate const* worldStateTemplate = GetWorldStateTemplate(worldStateId); - if (!worldStateTemplate || !worldStateTemplate->MapId) + if (!worldStateTemplate || worldStateTemplate->MapIds.empty()) { auto itr = _realmWorldStateValues.try_emplace(worldStateId, 0).first; int32 oldValue = itr->second; @@ -106,7 +134,7 @@ void WorldStateMgr::SetValue(int32 worldStateId, int32 value, Map* map) return; } - if (map->GetId() != worldStateTemplate->MapId) + if (worldStateTemplate->MapIds.find(map->GetId()) == worldStateTemplate->MapIds.end()) return; map->SetWorldStateValue(worldStateId, value);