diff --git a/sql/updates/world/4.3.4/2021_06_13_02_world.sql b/sql/updates/world/4.3.4/2021_06_13_02_world.sql new file mode 100644 index 00000000000..022e0b0198e --- /dev/null +++ b/sql/updates/world/4.3.4/2021_06_13_02_world.sql @@ -0,0 +1,15 @@ +DROP TABLE IF EXISTS `world_states`; +CREATE TABLE `world_states` ( + `ID` INT(5) UNSIGNED NOT NULL, + `DefaultValue` INT(8) NOT NULL DEFAULT 0, + `MapID` INT(4) UNSIGNED NULL DEFAULT NULL, + `Comment` varchar(255) NULL, + PRIMARY KEY (`ID`) +); + +INSERT INTO `world_states` (`ID`, `DefaultValue`, `MapID`, `Comment`) VALUES +(5644, 0, 669, 'Blackwing Descent - Omnotron Defense System - Achieve-a-tron'), +(5645, 0, 669, 'Blackwing Descent - Omnotron Defense System - Achieve-a-tron'), +(5646, 0, 669, 'Blackwing Descent - Omnotron Defense System - Achieve-a-tron'), +(5647, 0, 669, 'Blackwing Descent - Omnotron Defense System - Achieve-a-tron'), +(5117, 0, 670, 'Grim Batol - Erudax - Don\'t need to Break Eggs to Make an Omelet'); diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 0caa8ad14ca..26ab0dc1064 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -112,6 +112,7 @@ #include "World.h" #include "WorldPacket.h" #include "WorldSession.h" +#include "WorldStateMgr.h" #include "WorldStatePackets.h" #include @@ -9204,6 +9205,9 @@ void Player::SendInitWorldStates(uint32 zoneId, uint32 areaId) break; } + // insert realm wide world states + sWorldStateMgr->AppendRealmWorldStates(packet.Worldstates); + // insert map world states if (Map* map = GetMap()) map->AppendWorldStates(packet.Worldstates); diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp index cfb9e78ebca..8d34e512615 100644 --- a/src/server/game/Maps/Map.cpp +++ b/src/server/game/Maps/Map.cpp @@ -49,6 +49,7 @@ #include "Weather.h" #include "WeatherMgr.h" #include "World.h" +#include "WorldStateMgr.h" #include "WorldStatePackets.h" #include #include @@ -367,6 +368,8 @@ i_scriptLock(false), _respawnCheckTimer(0) MMAP::MMapFactory::createOrGetMMapManager()->loadMapInstance(sWorld->GetDataPath(), GetId(), i_InstanceId); sScriptMgr->OnCreateMap(this); + + sWorldStateMgr->FillDefaultWorldStatesForMap(_worldStates, id); } void Map::InitVisibilityDistance() diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index 6435a0c22c4..bdf8b92273d 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -88,6 +88,7 @@ #include "WeatherMgr.h" #include "WhoListStorage.h" #include "WorldSession.h" +#include "WorldStateMgr.h" #include "WorldSocket.h" #include @@ -2122,6 +2123,9 @@ void World::SetInitialWorldSettings() TC_LOG_INFO("server.loading", "Loading World States..."); // must be loaded before battleground, outdoor PvP and conditions LoadWorldStates(); + TC_LOG_INFO("server.loading", "Loading Map default and Realm wide World States..."); + sWorldStateMgr->LoadFromDB(); + sObjectMgr->LoadPhases(); TC_LOG_INFO("server.loading", "Loading Conditions..."); diff --git a/src/server/game/World/WorldStates/WorldStateMgr.cpp b/src/server/game/World/WorldStates/WorldStateMgr.cpp new file mode 100644 index 00000000000..b214493cc45 --- /dev/null +++ b/src/server/game/World/WorldStates/WorldStateMgr.cpp @@ -0,0 +1,97 @@ +/* + * 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 . + */ + +#include "WorldStateMgr.h" +#include "DatabaseEnv.h" +#include "Log.h" +#include "World.h" +#include "WorldStatePackets.h" + +void WorldStateMgr::LoadFromDB() +{ + uint32 oldMSTime = getMSTime(); + + _mapWorldStates.clear(); + _realmWorldStates.clear(); + + // 0 1 2 + QueryResult result = WorldDatabase.Query("SELECT ID, DefaultValue, MapID FROM world_states"); + if (!result) + return; + + uint32 worldStatesCount = 0; + do + { + Field* fields = result->Fetch(); + + uint32 id = fields[0].GetUInt32(); + uint32 defaultValue = fields[1].GetInt32(); + Optional mapId; + if (!fields[2].IsNull()) + fields[2].GetUInt32(); + + if (mapId.has_value()) + _mapWorldStates[*mapId][id] = defaultValue; + else + _realmWorldStates[id] = defaultValue; + + ++worldStatesCount; + + } while (result->NextRow()); + + TC_LOG_INFO("server.loading", ">> Loaded %u map and realm world states %u ms", worldStatesCount, GetMSTimeDiffToNow(oldMSTime)); +} + +void WorldStateMgr::FillDefaultWorldStatesForMap(WorldStateDataMap& worldStates, uint32 mapId) +{ + std::unordered_map::const_iterator itr = _mapWorldStates.find(mapId); + if (itr != _mapWorldStates.end()) + worldStates = itr->second; +} + +void WorldStateMgr::AppendRealmWorldStates(std::vector& worldStates) +{ + for (std::pair& worldState : _realmWorldStates) + worldStates.emplace_back(worldState.first, worldState.second); +} + +void WorldStateMgr::SetRealmWorldStateValue(uint32 worldStateId, int32 value) +{ + _realmWorldStates[worldStateId] = value; + + // Broadcast update to all players on the server + WorldPackets::WorldState::UpdateWorldState packet; + packet.VariableID = worldStateId; + packet.Value = value; + packet.Write(); + sWorld->SendGlobalMessage(packet.GetRawPacket()); +} + +int32 WorldStateMgr::GetRealmWorldStateValue(uint32 worldStateId) const +{ + auto itr = _realmWorldStates.find(worldStateId); + if (itr != _realmWorldStates.end()) + return itr->second; + + return 0; +} + +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..e0c16beec65 --- /dev/null +++ b/src/server/game/World/WorldStates/WorldStateMgr.h @@ -0,0 +1,57 @@ +/* +* 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 . +*/ + + +#ifndef WorldStateMgr_h__ +#define WorldStateMgr_h__ + +#include "Define.h" +#include "Optional.h" +#include +#include + +namespace WorldPackets +{ + namespace WorldState + { + struct WorldStateInfo; + } +} + +typedef std::unordered_map WorldStateDataMap; + +class TC_GAME_API WorldStateMgr +{ +public: + static WorldStateMgr* instance(); + + void LoadFromDB(); + + void FillDefaultWorldStatesForMap(WorldStateDataMap& worldStates, uint32 mapId); + void AppendRealmWorldStates(std::vector& worldStates); + + void SetRealmWorldStateValue(uint32 worldStateId, int32 value); + int32 GetRealmWorldStateValue(uint32 worldStateId) const; + +private: + std::unordered_map _mapWorldStates; + std::unordered_map _realmWorldStates; +}; + +#define sWorldStateMgr WorldStateMgr::instance() + +#endif diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingDescent/instance_blackwing_descent.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingDescent/instance_blackwing_descent.cpp index e0400bbdd8a..9e7c57c1368 100644 --- a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingDescent/instance_blackwing_descent.cpp +++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingDescent/instance_blackwing_descent.cpp @@ -128,10 +128,6 @@ class instance_blackwing_descent : public InstanceMapScript SetBossNumber(EncounterCount); LoadObjectData(creatureData, gameobjectData); LoadDoorData(doorData); - instance->SetWorldState(WORLD_STATE_ID_STATIC_SHOCK, 0, false); - instance->SetWorldState(WORLD_STATE_ID_POISON_BOMB, 0, false); - instance->SetWorldState(WORLD_STATE_ID_ARCANE_ANNIHILATOR, 0, false); - instance->SetWorldState(WORLD_STATE_ID_FLAMETHROWER, 0, false); _deadDwarfSpiritsLeft = 0; _deadDwarfSpiritsRight = 0; _atramedesIntroState = NOT_STARTED; diff --git a/src/server/scripts/EasternKingdoms/GrimBatol/instance_grim_batol.cpp b/src/server/scripts/EasternKingdoms/GrimBatol/instance_grim_batol.cpp index 83b8686a5b7..90f83f000f7 100644 --- a/src/server/scripts/EasternKingdoms/GrimBatol/instance_grim_batol.cpp +++ b/src/server/scripts/EasternKingdoms/GrimBatol/instance_grim_batol.cpp @@ -60,7 +60,6 @@ class instance_grim_batol : public InstanceMapScript SetHeaders(DataHeader); SetBossNumber(EncounterCount); LoadObjectData(creatureData, nullptr); - instance->SetWorldState(WORLD_STATE_ID_DONT_NEED_TO_BREAK_EGGS, 0, false); _initialized = false; _destroyedNets = 0; _batteredRedDrakeState = STATE_EMPRISONED;