aboutsummaryrefslogtreecommitdiff
path: root/src/server/game/World
diff options
context:
space:
mode:
authorShauren <shauren.trinity@gmail.com>2022-06-25 22:48:27 +0200
committerShauren <shauren.trinity@gmail.com>2022-06-25 22:48:27 +0200
commit737d94d7efe0b6c308ac1bf3692b6aa2e43f5adb (patch)
tree678898e6b8d3834f53c39567242a36f547d2fa77 /src/server/game/World
parente708bd28d1056e83b99b11094b9056ce2e5864a9 (diff)
Core/World: implement database support for default map and realm wide world states
Co-Authored-By: Shauren <shauren.trinity@gmail.com>
Diffstat (limited to 'src/server/game/World')
-rw-r--r--src/server/game/World/World.cpp4
-rw-r--r--src/server/game/World/WorldStates/WorldStateDefines.h36
-rw-r--r--src/server/game/World/WorldStates/WorldStateMgr.cpp137
-rw-r--r--src/server/game/World/WorldStates/WorldStateMgr.h50
4 files changed, 227 insertions, 0 deletions
diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp
index 5a3ef8104f3..94b36940189 100644
--- a/src/server/game/World/World.cpp
+++ b/src/server/game/World/World.cpp
@@ -100,6 +100,7 @@
#include "WhoListStorage.h"
#include "WorldSession.h"
#include "WorldSocket.h"
+#include "WorldStateMgr.h"
#include <boost/algorithm/string.hpp>
@@ -2241,6 +2242,9 @@ void World::SetInitialWorldSettings()
TC_LOG_INFO("server.loading", "Loading Creature Formations...");
sFormationMgr->LoadCreatureFormations();
+ TC_LOG_INFO("server.loading", "Loading World State templates...");
+ sWorldStateMgr->LoadFromDB();
+
TC_LOG_INFO("server.loading", "Loading World States..."); // must be loaded before battleground, outdoor PvP and conditions
LoadWorldStates();
diff --git a/src/server/game/World/WorldStates/WorldStateDefines.h b/src/server/game/World/WorldStates/WorldStateDefines.h
new file mode 100644
index 00000000000..3b85a36d1e4
--- /dev/null
+++ b/src/server/game/World/WorldStates/WorldStateDefines.h
@@ -0,0 +1,36 @@
+/*
+ * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef WorldStateDefines_h__
+#define WorldStateDefines_h__
+
+#include "Define.h"
+#include "Optional.h"
+#include <unordered_map>
+
+struct WorldStateTemplate
+{
+ int32 Id = 0;
+ int32 DefaultValue = 0;
+ uint32 ScriptId = 0;
+
+ Optional<uint32> MapId;
+};
+
+using WorldStateValueContainer = std::unordered_map<int32 /*worldStateId*/, int32 /*value*/>;
+
+#endif // WorldStateDefines_h__
diff --git a/src/server/game/World/WorldStates/WorldStateMgr.cpp b/src/server/game/World/WorldStates/WorldStateMgr.cpp
new file mode 100644
index 00000000000..b9ed79f951a
--- /dev/null
+++ b/src/server/game/World/WorldStates/WorldStateMgr.cpp
@@ -0,0 +1,137 @@
+/*
+ * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "WorldStateMgr.h"
+#include "Containers.h"
+#include "DatabaseEnv.h"
+#include "Log.h"
+#include "Map.h"
+#include "ObjectMgr.h"
+#include "ScriptMgr.h"
+#include "World.h"
+#include "WorldStatePackets.h"
+
+namespace
+{
+std::unordered_map<int32, WorldStateTemplate> _worldStateTemplates;
+WorldStateValueContainer _realmWorldStateValues;
+std::unordered_map<uint32, WorldStateValueContainer> _worldStatesByMap;
+}
+
+void WorldStateMgr::LoadFromDB()
+{
+ uint32 oldMSTime = getMSTime();
+
+ // 0 1 2 3
+ QueryResult result = WorldDatabase.Query("SELECT ID, DefaultValue, MapID, ScriptName FROM world_state");
+ if (!result)
+ return;
+
+ do
+ {
+ Field* fields = result->Fetch();
+
+ int32 id = fields[0].GetInt32();
+ WorldStateTemplate& worldState = _worldStateTemplates[id];
+ worldState.Id = id;
+ worldState.DefaultValue = fields[1].GetInt32();
+ if (!fields[2].IsNull())
+ worldState.MapId = fields[2].GetUInt32();
+
+ worldState.ScriptId = sObjectMgr->GetScriptId(fields[3].GetString());
+
+ if (worldState.MapId)
+ _worldStatesByMap[*worldState.MapId][id] = worldState.DefaultValue;
+ else
+ _realmWorldStateValues[id] = worldState.DefaultValue;
+
+ } while (result->NextRow());
+
+ TC_LOG_INFO("server.loading", ">> Loaded " SZFMTD " world state templates %u ms", _worldStateTemplates.size(), GetMSTimeDiffToNow(oldMSTime));
+}
+
+WorldStateTemplate const* WorldStateMgr::GetWorldStateTemplate(int32 worldStateId) const
+{
+ return Trinity::Containers::MapGetValuePtr(_worldStateTemplates, worldStateId);
+}
+
+int32 WorldStateMgr::GetValue(int32 worldStateId, Map const* map) const
+{
+ WorldStateTemplate const* worldStateTemplate = GetWorldStateTemplate(worldStateId);
+ if (!worldStateTemplate || !worldStateTemplate->MapId)
+ {
+ if (int32 const* value = Trinity::Containers::MapGetValuePtr(_realmWorldStateValues, worldStateId))
+ return *value;
+
+ return 0;
+ }
+
+ if (map->GetId() != worldStateTemplate->MapId)
+ return 0;
+
+ return map->GetWorldStateValue(worldStateId);
+}
+
+void WorldStateMgr::SetValue(int32 worldStateId, int32 value, Map* map)
+{
+ WorldStateTemplate const* worldStateTemplate = GetWorldStateTemplate(worldStateId);
+ if (!worldStateTemplate || !worldStateTemplate->MapId)
+ {
+ auto itr = _realmWorldStateValues.try_emplace(worldStateId, 0).first;
+ int32 oldValue = itr->second;
+ itr->second = value;
+
+ if (worldStateTemplate)
+ sScriptMgr->OnWorldStateValueChange(worldStateTemplate, oldValue, value, nullptr);
+
+ // Broadcast update to all players on the server
+ WorldPackets::WorldState::UpdateWorldState updateWorldState;
+ updateWorldState.VariableID = worldStateId;
+ updateWorldState.Value = value;
+ sWorld->SendGlobalMessage(updateWorldState.Write());
+ return;
+ }
+
+ if (map->GetId() != worldStateTemplate->MapId)
+ return;
+
+ map->SetWorldStateValue(worldStateId, value);
+}
+
+WorldStateValueContainer WorldStateMgr::GetInitialWorldStatesForMap(Map const* map) const
+{
+ WorldStateValueContainer initialValues;
+ if (WorldStateValueContainer const* valuesTemplate = Trinity::Containers::MapGetValuePtr(_worldStatesByMap, map->GetId()))
+ initialValues = *valuesTemplate;
+
+ return initialValues;
+}
+
+void WorldStateMgr::FillInitialWorldStates(WorldPackets::WorldState::InitWorldStates& initWorldStates, Map const* map) const
+{
+ for (auto const& [worldStateId, value] : _realmWorldStateValues)
+ initWorldStates.Worldstates.emplace_back(worldStateId, value);
+
+ for (auto const& [worldStateId, value] : map->GetWorldStateValues())
+ initWorldStates.Worldstates.emplace_back(worldStateId, value);
+}
+
+WorldStateMgr* WorldStateMgr::instance()
+{
+ static WorldStateMgr instance;
+ return &instance;
+}
diff --git a/src/server/game/World/WorldStates/WorldStateMgr.h b/src/server/game/World/WorldStates/WorldStateMgr.h
new file mode 100644
index 00000000000..18ce38afd2f
--- /dev/null
+++ b/src/server/game/World/WorldStates/WorldStateMgr.h
@@ -0,0 +1,50 @@
+/*
+ * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef WorldStateMgr_h__
+#define WorldStateMgr_h__
+
+#include "Define.h"
+#include "WorldStateDefines.h"
+
+class Map;
+
+namespace WorldPackets::WorldState
+{
+ class InitWorldStates;
+}
+
+class TC_GAME_API WorldStateMgr
+{
+public:
+ static WorldStateMgr* instance();
+
+ void LoadFromDB();
+
+ WorldStateTemplate const* GetWorldStateTemplate(int32 worldStateId) const;
+
+ int32 GetValue(int32 worldStateId, Map const* map) const;
+ void SetValue(int32 worldStateId, int32 value, Map* map);
+
+ WorldStateValueContainer GetInitialWorldStatesForMap(Map const* map) const;
+
+ void FillInitialWorldStates(WorldPackets::WorldState::InitWorldStates& initWorldStates, Map const* map) const;
+};
+
+#define sWorldStateMgr WorldStateMgr::instance()
+
+#endif