33constexpr int32 WORLDSTATE_ANY_MAP = -1;
34std::unordered_map<int32, WorldStateTemplate> _worldStateTemplates;
36std::unordered_map<int32, WorldStateValueContainer> _worldStatesByMap;
50 Field* fields = result->Fetch();
63 TC_LOG_ERROR(
"sql.sql",
"Table `world_state` contains a world state {} with non-integer MapID ({}), map ignored",
68 if (!
sMapStore.LookupEntry(*mapId) && mapId != WORLDSTATE_ANY_MAP)
70 TC_LOG_ERROR(
"sql.sql",
"Table `world_state` contains a world state {} with invalid MapID ({}), map ignored",
75 worldState.
MapIds.insert(*mapId);
78 if (!mapIds.empty() && worldState.
MapIds.empty())
80 TC_LOG_ERROR(
"sql.sql",
"Table `world_state` contains a world state {} with nonempty MapIDs ({}) but no valid map id was found, ignored",
86 if (!worldState.
MapIds.empty())
93 TC_LOG_ERROR(
"sql.sql",
"Table `world_state` contains a world state {} with non-integer AreaID ({}), area ignored",
101 TC_LOG_ERROR(
"sql.sql",
"Table `world_state` contains a world state {} with invalid AreaID ({}), area ignored",
108 TC_LOG_ERROR(
"sql.sql",
"Table `world_state` contains a world state {} with AreaID ({}) not on any of required maps, area ignored",
113 worldState.
AreaIds.insert(*areaId);
116 if (!areaIds.empty() && worldState.
AreaIds.empty())
118 TC_LOG_ERROR(
"sql.sql",
"Table `world_state` contains a world state {} with nonempty AreaIDs ({}) but no valid area id was found, ignored",
123 else if (!areaIds.empty())
125 TC_LOG_ERROR(
"sql.sql",
"Table `world_state` contains a world state {} with nonempty AreaIDs ({}) but is a realm wide world state, area requirement ignored",
131 if (!worldState.
MapIds.empty())
139 }
while (result->NextRow());
146 uint32 savedValueCount = 0;
151 Field* fields = result->Fetch();
156 TC_LOG_ERROR(
"sql.sql",
"Table `world_state_value` contains a value for unknown world state {}, ignored", worldStateId);
162 if (!worldState->
MapIds.empty())
165 _worldStatesByMap[mapId][worldStateId] = value;
168 _realmWorldStateValues[worldStateId] = value;
172 while (result->NextRow());
186 if (!worldStateTemplate || worldStateTemplate->
MapIds.empty())
194 if (!map || (!worldStateTemplate->
MapIds.count(map->
GetId()) && !worldStateTemplate->
MapIds.count(WORLDSTATE_ANY_MAP)))
203 if (!worldStateTemplate || worldStateTemplate->
MapIds.empty())
205 auto [itr, inserted] = _realmWorldStateValues.try_emplace(worldStateId, 0);
206 int32 oldValue = itr->second;
207 if (oldValue == value && !inserted)
212 if (worldStateTemplate)
213 sScriptMgr->OnWorldStateValueChange(worldStateTemplate, oldValue, value,
nullptr);
218 updateWorldState.
Value = value;
219 updateWorldState.
Hidden = hidden;
220 sWorld->SendGlobalMessage(updateWorldState.
Write());
224 if (!map || (!worldStateTemplate->
MapIds.count(map->
GetId()) && !worldStateTemplate->
MapIds.count(WORLDSTATE_ANY_MAP)))
243 SetValue(worldStateId, value, hidden, map);
251 initialValues.insert(valuesTemplate->begin(), valuesTemplate->end());
254 initialValues.insert(valuesTemplate->begin(), valuesTemplate->end());
256 return initialValues;
261 for (
auto const& [worldStateId, value] : _realmWorldStateValues)
262 initWorldStates.
Worldstates.emplace_back(worldStateId, value);
267 if (worldStateTemplate && !worldStateTemplate->
AreaIds.empty())
269 bool isInAllowedArea = std::any_of(worldStateTemplate->
AreaIds.begin(), worldStateTemplate->
AreaIds.end(),
270 [=](
uint32 requiredAreaId) { return DB2Manager::IsInArea(playerAreaId, requiredAreaId); });
271 if (!isInAllowedArea)
275 initWorldStates.
Worldstates.emplace_back(worldStateId, value);
DB2Storage< MapEntry > sMapStore("Map.db2", &MapLoadInfo::Instance)
DB2Storage< AreaTableEntry > sAreaTableStore("AreaTable.db2", &AreaTableLoadInfo::Instance)
std::shared_ptr< ResultSet > QueryResult
DatabaseWorkerPool< CharacterDatabaseConnection > CharacterDatabase
Accessor to the character database.
DatabaseWorkerPool< WorldDatabaseConnection > WorldDatabase
Accessor to the world database.
#define TC_LOG_ERROR(filterType__,...)
#define TC_LOG_INFO(filterType__,...)
std::optional< T > Optional
Optional helper class to wrap optional values within.
uint32 GetMSTimeDiffToNow(uint32 oldMSTime)
std::unordered_map< int32, int32 > WorldStateValueContainer
Class used to access individual fields of database query result.
std::string_view GetStringView() const
WorldStateValueContainer const & GetWorldStateValues() const
void SetWorldStateValue(int32 worldStateId, int32 value, bool hidden)
int32 GetWorldStateValue(int32 worldStateId) const
void setInt32(const uint8 index, const int32 value)
std::vector< WorldStateInfo > Worldstates
WorldPacket const * Write() override
void SetValue(int32 worldStateId, int32 value, bool hidden, Map *map)
WorldStateTemplate const * GetWorldStateTemplate(int32 worldStateId) const
void SetValueAndSaveInDb(int32 worldStateId, int32 value, bool hidden, Map *map)
void SaveValueInDb(int32 worldStateId, int32 value)
void FillInitialWorldStates(WorldPackets::WorldState::InitWorldStates &initWorldStates, Map const *map, uint32 playerAreaId) const
static WorldStateMgr * instance()
int32 GetValue(int32 worldStateId, Map const *map) const
WorldStateValueContainer GetInitialWorldStatesForMap(Map const *map) const
auto MapGetValuePtr(M &map, typename M::key_type const &key)
TC_COMMON_API std::vector< std::string_view > Tokenize(std::string_view str, char sep, bool keepEmpty)
std::unordered_set< uint32 > AreaIds
std::unordered_set< uint32 > MapIds