From 5006264db873914125f92626252c87bec4b9af92 Mon Sep 17 00:00:00 2001 From: lee Date: Mon, 30 Sep 2024 01:22:55 +0800 Subject: [PATCH] [Core/Packet] Split SMSG_OVERRIDE_LIGHT to MiscPackets (#353) 1.Split SMSG_OVERRIDE_LIGHT to MiscPackets 2.Remove SMSG_WEATHER From scripts --- src/server/game/Entities/Player/Player.cpp | 23 +-- src/server/game/LuaEngine/GlobalMethods.h | 33 ---- src/server/game/LuaEngine/LuaFunctions.cpp | 4 - src/server/game/Maps/Map.cpp | 158 +++++++++++++----- src/server/game/Maps/Map.h | 41 +++-- .../game/Server/Packets/MiscPackets.cpp | 9 + src/server/game/Server/Packets/MiscPackets.h | 14 ++ .../game/Spells/Auras/SpellAuraEffects.cpp | 21 +-- src/server/game/Weather/Weather.cpp | 4 +- src/server/game/Weather/Weather.h | 4 +- src/server/game/Weather/WeatherMgr.cpp | 73 +------- src/server/game/Weather/WeatherMgr.h | 14 +- src/server/game/World/World.cpp | 7 - src/server/scripts/Commands/cs_misc.cpp | 5 +- .../RuinsOfAhnQiraj/boss_ossirian.cpp | 10 +- .../ThroneoftheFourWinds/boss_alakir.cpp | 21 ++- .../IcecrownCitadel/boss_the_lich_king.cpp | 32 +--- .../Nexus/EyeOfEternity/boss_malygos.cpp | 33 +--- 18 files changed, 215 insertions(+), 291 deletions(-) diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 3ec876eca..a1e0a9466 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -7957,11 +7957,7 @@ void Player::UpdateZone(uint32 newZone, uint32 newArea) // Let there be light! :3 if (m_zoneUpdateId == 876 || newZone == 876) // GM Island { - WorldPacket data(SMSG_OVERRIDE_LIGHT, 12); - data << uint32(newZone == 876 ? 500 : 0); - data << uint32(2488); - data << uint32(1); - SendDirectMessage(&data); + GetMap()->SetZoneOverrideLight(876, newZone == 876 ? 500 : 0, 2488, 1s); } } @@ -7979,19 +7975,10 @@ void Player::UpdateZone(uint32 newZone, uint32 newArea) if (!zone) return; - if (sWorld->getBoolConfig(CONFIG_WEATHER) && !HasAuraType(SPELL_AURA_FORCE_WEATHER)) - { - if (Weather* weather = WeatherMgr::FindWeather(zone->ID)) - weather->SendWeatherUpdateToPlayer(this); - else - { - if (!WeatherMgr::AddWeather(zone->ID)) - { - // send fine weather packet to remove old zone's weather - WeatherMgr::SendFineWeatherUpdateToPlayer(this); - } - } - } + if (sWorld->getBoolConfig(CONFIG_WEATHER)) + GetMap()->GetOrGenerateZoneDefaultWeather(newZone); + + GetMap()->SendZoneDynamicInfo(newZone, this); sScriptMgr->OnPlayerUpdateZone(this, newZone, newArea); diff --git a/src/server/game/LuaEngine/GlobalMethods.h b/src/server/game/LuaEngine/GlobalMethods.h index 034e4efa1..bbf68cc91 100644 --- a/src/server/game/LuaEngine/GlobalMethods.h +++ b/src/server/game/LuaEngine/GlobalMethods.h @@ -1016,38 +1016,5 @@ namespace LuaGlobalFunctions return 1; } - static int FindWeather(lua_State* L) - { - uint32 zoneId = luaL_checkunsigned(L, 1); - Weather* weather = WeatherMgr::FindWeather(zoneId); - sEluna->Push(L, weather); - return 1; - } - - static int AddWeather(lua_State* L) - { - uint32 zoneId = luaL_checkunsigned(L, 1); - Weather* weather = WeatherMgr::AddWeather(zoneId); - sEluna->Push(L, weather); - return 1; - } - - static int RemoveWeather(lua_State* L) - { - uint32 zoneId = luaL_checkunsigned(L, 1); - - WeatherMgr::RemoveWeather(zoneId); - return 0; - } - - static int SendFineWeatherToPlayer(lua_State* L) - { - Player* player = sEluna->CHECK_PLAYER(L, 1); - if (!player) - return 0; - - WeatherMgr::SendFineWeatherUpdateToPlayer(player); - return 0; - } } #endif diff --git a/src/server/game/LuaEngine/LuaFunctions.cpp b/src/server/game/LuaEngine/LuaFunctions.cpp index 052f7fde7..f2a5a19fc 100644 --- a/src/server/game/LuaEngine/LuaFunctions.cpp +++ b/src/server/game/LuaEngine/LuaFunctions.cpp @@ -95,10 +95,6 @@ void RegisterGlobals(lua_State* L) lua_register(L, "SaveAllPlayers", &LuaGlobalFunctions::SaveAllPlayers); // SaveAllPlayers() - Saves all players lua_register(L, "SendMail", &LuaGlobalFunctions::SendMail); // SendMail(subject, text, receiverLowGUID[, sender, stationary, delay, itemEntry, itemAmount, itemEntry2, itemAmount2...]) - Sends a mail to player with lowguid. use nil to use default values on optional arguments. Sender is an optional player object. UNDOCUMENTED lua_register(L, "AddTaxiPath", &LuaGlobalFunctions::AddTaxiPath); // AddTaxiPath(pathTable, mountA, mountH[, price, pathId]) - Adds a new taxi path. Returns the path's ID. Will replace an existing path if pathId provided and already used. path table structure: T = {{map, x, y, z[, actionFlag, delay, arrivalEvId, departEvId]}, {...}, ...} UDOCUMENTED - lua_register(L, "FindWeather", &LuaGlobalFunctions::FindWeather); // FindWeather(zoneId) - Finds the weather by zoneId and returns the weather - lua_register(L, "AddWeather", &LuaGlobalFunctions::AddWeather); // AddWeather(zoneId) - Adds weather to the following zone, also returns weather - lua_register(L, "RemoveWeather", &LuaGlobalFunctions::RemoveWeather); // RemoveWeather(zoneId) - Removes weather from a zone - lua_register(L, "SendFineWeatherToPlayer", &LuaGlobalFunctions::SendFineWeatherToPlayer); // SendFineWeatherToPlayer(player) - Sends WEATHER_STATE_FINE weather to the } ElunaRegister ObjectMethods[] = diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp index 5e230a9b4..e9d074e11 100644 --- a/src/server/game/Maps/Map.cpp +++ b/src/server/game/Maps/Map.cpp @@ -40,6 +40,8 @@ #include "Vehicle.h" #include "VMapFactory.h" #include "VMapManager2.h" +#include "Weather.h" +#include "WeatherMgr.h" #include "G3D/Plane.h" u_map_magic MapMagic = { {'M','A','P','S'} }; @@ -57,6 +59,9 @@ static uint16 const holetab_v[4] = { 0x000F, 0x00F0, 0x0F00, 0xF000 }; GridState* si_GridStates[MAX_GRID_STATE]; +ZoneDynamicInfo::ZoneDynamicInfo() : MusicId(0), DefaultWeather(nullptr), WeatherId(WEATHER_STATE_FINE), +Intensity(0.0f) { } + Map::~Map() { sBattlePetSpawnMgr->DepopulateMap(i_mapEntry->MapID); @@ -509,7 +514,6 @@ bool Map::AddPlayerToMap(Player* player) SendInitSelf(player); SendInitTransports(player); - SendZoneDynamicInfo(player); player->m_clientGUIDs.clear(); @@ -756,6 +760,16 @@ void Map::Update(const uint32 t_diff) i_scriptLock = false; } + _weatherUpdateTimer.Update(t_diff); + if (_weatherUpdateTimer.Passed()) + { + for (auto&& zoneInfo : _zoneDynamicInfo) + if (zoneInfo.second.DefaultWeather && !zoneInfo.second.DefaultWeather->Update(_weatherUpdateTimer.GetInterval())) + zoneInfo.second.DefaultWeather.reset(); + + _weatherUpdateTimer.Reset(); + } + MoveAllCreaturesInMoveList(); MoveAllGameObjectsInMoveList(); MoveAllDynamicObjectsInMoveList(); @@ -3184,6 +3198,27 @@ void Map::SendToPlayers(WorldPacket const* data) const itr->GetSource()->GetSession()->SendPacket(data); } +/// Send a packet to all players (or players selected team) in the zone (except self if mentioned) +bool Map::SendZoneMessage(uint32 zone, WorldPacket const* packet, WorldSession const* self, uint32 team) const +{ + bool foundPlayerToSend = false; + + for (MapReference const& ref : GetPlayers()) + { + Player* player = ref.GetSource(); + if (player->IsInWorld() && + player->GetZoneId() == zone && + player->GetSession() != self && + (team == 0 || player->GetTeam() == team)) + { + player->SendDirectMessage(packet); + foundPlayerToSend = true; + } + } + + return foundPlayerToSend; +} + bool Map::ActiveObjectsNearGrid(NGridType const& ngrid) const { CellCoord cell_min(ngrid.getX() * MAX_NUMBER_OF_CELLS, ngrid.getY() * MAX_NUMBER_OF_CELLS); @@ -4214,33 +4249,24 @@ void Map::RemoveOldCorpses() } } -void Map::SendZoneDynamicInfo(Player* player) +void Map::SendZoneDynamicInfo(uint32 zoneId, Player* player) const { - uint32 zoneId = GetZoneId(player->GetPhaseMask(), player->GetPositionX(), player->GetPositionY(), player->GetPositionZ()); - ZoneDynamicInfoMap::const_iterator itr = _zoneDynamicInfo.find(zoneId); - + auto itr = _zoneDynamicInfo.find(zoneId); if (itr == _zoneDynamicInfo.end()) return; if (uint32 music = itr->second.MusicId) player->SendDirectMessage(WorldPackets::Misc::PlayMusic(music).Write()); - if (uint32 weather = itr->second.WeatherId) - { - WorldPacket data(SMSG_WEATHER, 4 + 4 + 1); - data << uint32(weather); - data << float(itr->second.WeatherGrade); - data << uint8(0); - player->SendDirectMessage(&data); - } + SendZoneWeather(itr->second, player); - if (uint32 overrideLight = itr->second.OverrideLightId) + for (ZoneDynamicInfo::LightOverride const& lightOverride : itr->second.LightOverrides) { - WorldPacket data(SMSG_OVERRIDE_LIGHT, 4 + 4 + 1); - data << uint32(_defaultLight); - data << uint32(overrideLight); - data << uint32(itr->second.LightFadeInTime); - player->SendDirectMessage(&data); + WorldPackets::Misc::OverrideLight overrideLight; + overrideLight.AreaLightID = lightOverride.AreaLightId; + overrideLight.OverrideLightID = lightOverride.OverrideLightId; + overrideLight.TransitionMilliseconds = lightOverride.TransitionMilliseconds; + player->SendDirectMessage(overrideLight.Write()); } } @@ -4265,50 +4291,90 @@ void Map::SetZoneMusic(uint32 zoneId, uint32 musicId) } } -void Map::SetZoneWeather(uint32 zoneId, uint32 weatherId, float weatherGrade) +void Map::SendZoneWeather(uint32 zoneId, Player* player) const { - if (_zoneDynamicInfo.find(zoneId) == _zoneDynamicInfo.end()) - _zoneDynamicInfo.insert(ZoneDynamicInfoMap::value_type(zoneId, ZoneDynamicInfo())); + if (!player->HasAuraType(SPELL_AURA_FORCE_WEATHER)) + { + auto itr = _zoneDynamicInfo.find(zoneId); + if (itr == _zoneDynamicInfo.end()) + return; - ZoneDynamicInfo& info = _zoneDynamicInfo[zoneId]; - info.WeatherId = weatherId; - info.WeatherGrade = weatherGrade; - Map::PlayerList const& players = GetPlayers(); + SendZoneWeather(itr->second, player); + } +} - if (!players.isEmpty()) +void Map::SendZoneWeather(ZoneDynamicInfo const& zoneDynamicInfo, Player* player) const +{ + if (WeatherState weatherId = zoneDynamicInfo.WeatherId) { - WorldPacket data(SMSG_WEATHER, 4 + 4 + 1); - data << uint32(weatherId); - data << float(weatherGrade); - data << uint8(0); + WorldPackets::Misc::Weather weather(weatherId, zoneDynamicInfo.Intensity); + player->SendDirectMessage(weather.Write()); + } + else if (zoneDynamicInfo.DefaultWeather) + { + zoneDynamicInfo.DefaultWeather->SendWeatherUpdateToPlayer(player); + } + else + Weather::SendFineWeatherUpdateToPlayer(player); +} - for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr) - if (Player* player = itr->GetSource()) - if (player->GetZoneId() == zoneId) - player->SendDirectMessage(&data); +Weather* Map::GetOrGenerateZoneDefaultWeather(uint32 zoneId) +{ + WeatherData const* weatherData = WeatherMgr::GetWeatherData(zoneId); + if (!weatherData) + return nullptr; + + ZoneDynamicInfo& info = _zoneDynamicInfo[zoneId]; + if (!info.DefaultWeather) + { + info.DefaultWeather = std::make_unique(this, zoneId, weatherData); + info.DefaultWeather->ReGenerate(); + info.DefaultWeather->UpdateWeather(); } + + return info.DefaultWeather.get(); } -void Map::SetZoneOverrideLight(uint32 zoneId, uint32 lightId, uint32 fadeInTime) +void Map::SetZoneWeather(uint32 zoneId, WeatherState weatherId, float intensity) { - if (_zoneDynamicInfo.find(zoneId) == _zoneDynamicInfo.end()) - _zoneDynamicInfo.insert(ZoneDynamicInfoMap::value_type(zoneId, ZoneDynamicInfo())); + ZoneDynamicInfo& info = _zoneDynamicInfo[zoneId]; + info.WeatherId = weatherId; + info.Intensity = intensity; + SendZoneMessage(zoneId, WorldPackets::Misc::Weather(weatherId, intensity).Write()); +} + +void Map::SetZoneOverrideLight(uint32 zoneId, uint32 areaLightId, uint32 overrideLightId, Milliseconds transitionTime) +{ ZoneDynamicInfo& info = _zoneDynamicInfo[zoneId]; - info.OverrideLightId = lightId; - info.LightFadeInTime = fadeInTime; - Map::PlayerList const& players = GetPlayers(); + // client can support only one override for each light (zone independent) + info.LightOverrides.erase(std::remove_if(info.LightOverrides.begin(), info.LightOverrides.end(), [areaLightId](ZoneDynamicInfo::LightOverride const& lightOverride) + { + return lightOverride.AreaLightId == areaLightId; + }), info.LightOverrides.end()); + // set new override (if any) + if (overrideLightId) + { + ZoneDynamicInfo::LightOverride& lightOverride = info.LightOverrides.emplace_back(); + lightOverride.AreaLightId = areaLightId; + lightOverride.OverrideLightId = overrideLightId; + lightOverride.TransitionMilliseconds = static_cast(transitionTime.count()); + } + + Map::PlayerList const& players = GetPlayers(); if (!players.isEmpty()) { - WorldPacket data(SMSG_OVERRIDE_LIGHT, 4 + 4 + 1); - data << uint32(_defaultLight); - data << uint32(lightId); - data << uint32(fadeInTime); + WorldPackets::Misc::OverrideLight overrideLight; + overrideLight.AreaLightID = areaLightId; + overrideLight.OverrideLightID = overrideLightId; + overrideLight.TransitionMilliseconds = static_cast(transitionTime.count()); + overrideLight.Write(); for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr) if (Player* player = itr->GetSource()) if (player->GetZoneId() == zoneId) - player->SendDirectMessage(&data); + player->SendDirectMessage(overrideLight.GetRawPacket()); } } + diff --git a/src/server/game/Maps/Map.h b/src/server/game/Maps/Map.h index 351725cff..bb6a42fb2 100644 --- a/src/server/game/Maps/Map.h +++ b/src/server/game/Maps/Map.h @@ -1,5 +1,5 @@ /* -* This file is part of the Pandaria 5.4.8 Project. See THANKS file for Copyright information +* This file is part of the Legends of Azeroth Pandaria Project. See THANKS 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 @@ -37,12 +37,12 @@ #include class Unit; -class WorldPacket; + class InstanceScript; class Group; class InstanceSave; class Object; -class WorldObject; + class TempSummon; class Player; class ActivePoolData; @@ -55,6 +55,11 @@ class MapInstanced; class BattlegroundMap; class InstanceMap; class Transport; +class Weather; +class WorldObject; +class WorldPacket; +class WorldSession; +enum WeatherState : uint32; namespace Trinity { struct ObjectUpdater; } namespace VMAP { enum class ModelIgnoreFlags : uint32; } @@ -262,14 +267,21 @@ enum LevelRequirementVsMode struct ZoneDynamicInfo { - ZoneDynamicInfo() : MusicId(0), WeatherId(0), WeatherGrade(0.0f), - OverrideLightId(0), LightFadeInTime(0) { } + ZoneDynamicInfo(); uint32 MusicId; - uint32 WeatherId; - float WeatherGrade; - uint32 OverrideLightId; - uint32 LightFadeInTime; + + std::unique_ptr DefaultWeather; + WeatherState WeatherId; + float Intensity; + + struct LightOverride + { + uint32 AreaLightId; + uint32 OverrideLightId; + uint32 TransitionMilliseconds; + }; + std::vector LightOverrides; }; #if defined(__GNUC__) @@ -454,6 +466,7 @@ class TC_GAME_API Map : public GridRefManager void RemoveWorldObject(WorldObject* obj) { i_worldObjects.erase(obj); } void SendToPlayers(WorldPacket const* data) const; + bool SendZoneMessage(uint32 zone, WorldPacket const* packet, WorldSession const* self = nullptr, uint32 team = 0) const; typedef MapRefManager PlayerList; PlayerList const& GetPlayers() const { return m_mapRefManager; } @@ -588,11 +601,14 @@ class TC_GAME_API Map : public GridRefManager void SendInitTransports(Player* player); void SendRemoveTransports(Player* player); - void SendZoneDynamicInfo(Player* player); + void SendZoneDynamicInfo(uint32 zoneId, Player* player) const; + void SendZoneWeather(uint32 zoneId, Player* player) const; + void SendZoneWeather(ZoneDynamicInfo const& zoneDynamicInfo, Player* player) const; void SetZoneMusic(uint32 zoneId, uint32 musicId); - void SetZoneWeather(uint32 zoneId, uint32 weatherId, float weatherGrade); - void SetZoneOverrideLight(uint32 zoneId, uint32 lightId, uint32 fadeInTime); + Weather* GetOrGenerateZoneDefaultWeather(uint32 zoneId); + void SetZoneWeather(uint32 zoneId, WeatherState weatherId, float intensity); + void SetZoneOverrideLight(uint32 zoneId, uint32 areaLightId, uint32 overrideLightId, Milliseconds transitionTime); void SetMMapErrorReportEnabled(bool on) { m_mmapErrorReportEnabled = on; } @@ -809,6 +825,7 @@ class TC_GAME_API Map : public GridRefManager uint32 debugFlexPlayersCount; ZoneDynamicInfoMap _zoneDynamicInfo; + IntervalTimer _weatherUpdateTimer; uint32 _defaultLight; }; diff --git a/src/server/game/Server/Packets/MiscPackets.cpp b/src/server/game/Server/Packets/MiscPackets.cpp index c15678fae..170004e0c 100644 --- a/src/server/game/Server/Packets/MiscPackets.cpp +++ b/src/server/game/Server/Packets/MiscPackets.cpp @@ -188,4 +188,13 @@ WorldPacket const* WorldPackets::Misc::CorpseReclaimDelay::Write() void WorldPackets::Misc::FarSight::Read() { Enable = _worldPacket.ReadBit(); +} + +WorldPacket const* WorldPackets::Misc::OverrideLight::Write() +{ + _worldPacket << int32(AreaLightID); + _worldPacket << int32(OverrideLightID); + _worldPacket << int32(TransitionMilliseconds); + + return &_worldPacket; } \ No newline at end of file diff --git a/src/server/game/Server/Packets/MiscPackets.h b/src/server/game/Server/Packets/MiscPackets.h index d2848c5a5..c5fb51cef 100644 --- a/src/server/game/Server/Packets/MiscPackets.h +++ b/src/server/game/Server/Packets/MiscPackets.h @@ -207,6 +207,20 @@ namespace WorldPackets bool Enable = false; }; + + class OverrideLight final : public ServerPacket + { + public: + OverrideLight() : ServerPacket(SMSG_OVERRIDE_LIGHT, 4 + 4 + 4) { } + + WorldPacket const* Write() override; + + int32 AreaLightID = 0; + int32 TransitionMilliseconds = 0; + int32 OverrideLightID = 0; + }; + + } } diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp index 274e14e5b..8fd2ff7f2 100644 --- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp +++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp @@ -7070,26 +7070,9 @@ void AuraEffect::HandleAuraForceWeather(AuraApplication const* aurApp, uint8 mod return; if (apply) - { - WorldPacket data(SMSG_WEATHER, (4 + 4 + 1)); - - data << uint32(GetMiscValue()) << 1.0f << uint8(0); - target->GetSession()->SendPacket(&data); - } + target->SendDirectMessage(WorldPackets::Misc::Weather(WeatherState(GetMiscValue()), 1.0f).Write()); else - { - // send weather for current zone - if (Weather* weather = WeatherMgr::FindWeather(target->GetZoneId())) - weather->SendWeatherUpdateToPlayer(target); - else - { - if (!WeatherMgr::AddWeather(target->GetZoneId())) - { - // send fine weather packet to remove old weather - WeatherMgr::SendFineWeatherUpdateToPlayer(target); - } - } - } + target->GetMap()->SendZoneWeather(target->GetZoneId(), target); } void AuraEffect::HandleEnableAltPower(AuraApplication const* aurApp, uint8 mode, bool apply) const diff --git a/src/server/game/Weather/Weather.cpp b/src/server/game/Weather/Weather.cpp index b07afe5fe..ac16d4297 100644 --- a/src/server/game/Weather/Weather.cpp +++ b/src/server/game/Weather/Weather.cpp @@ -32,8 +32,8 @@ #include "Opcodes.h" /// Create the Weather object -Weather::Weather(uint32 zone, WeatherData const* weatherChances) - : m_zone(zone), m_weatherChances(weatherChances) +Weather::Weather(Map* map, uint32 zoneId, WeatherData const* weatherChances) + : m_map(map), m_zone(zoneId), m_weatherChances(weatherChances) { m_timer.SetInterval(sWorld->getIntConfig(CONFIG_INTERVAL_CHANGEWEATHER)); m_type = WEATHER_TYPE_FINE; diff --git a/src/server/game/Weather/Weather.h b/src/server/game/Weather/Weather.h index f9a95f6d4..967c809de 100644 --- a/src/server/game/Weather/Weather.h +++ b/src/server/game/Weather/Weather.h @@ -26,6 +26,7 @@ #include "SharedDefines.h" #include "Timer.h" +class Map; class Player; #define WEATHER_SEASONS 4 @@ -66,7 +67,7 @@ class TC_GAME_API Weather { public: - Weather(uint32 zone, WeatherData const* weatherChances); + Weather(Map* map, uint32 zoneId, WeatherData const* weatherChances); ~Weather() { }; bool Update(uint32 diff); @@ -84,6 +85,7 @@ class TC_GAME_API Weather private: WeatherState GetWeatherState() const; + Map* m_map; uint32 m_zone; WeatherType m_type; float m_grade; diff --git a/src/server/game/Weather/WeatherMgr.cpp b/src/server/game/Weather/WeatherMgr.cpp index 23232a8e3..adc6b9499 100644 --- a/src/server/game/Weather/WeatherMgr.cpp +++ b/src/server/game/Weather/WeatherMgr.cpp @@ -1,5 +1,5 @@ /* -* This file is part of the Pandaria 5.4.8 Project. See THANKS file for Copyright information +* This file is part of the Legends of Azeroth Pandaria Project. See THANKS 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 @@ -33,51 +33,12 @@ namespace WeatherMgr namespace { - typedef std::unordered_map> WeatherMap; - typedef std::unordered_map WeatherZoneMap; - - WeatherMap m_weathers; - WeatherZoneMap mWeatherZoneMap; - - WeatherData const* GetWeatherData(uint32 zone_id) - { - WeatherZoneMap::const_iterator itr = mWeatherZoneMap.find(zone_id); - return (itr != mWeatherZoneMap.end()) ? &itr->second : NULL; - } -} - -/// Find a Weather object by the given zoneid -Weather* FindWeather(uint32 id) -{ - WeatherMap::const_iterator itr = m_weathers.find(id); - return (itr != m_weathers.end()) ? itr->second.get() : 0; -} - -/// Remove a Weather object for the given zoneid -void RemoveWeather(uint32 id) -{ - // not called at the moment. Kept for completeness - WeatherMap::iterator itr = m_weathers.find(id); - - if (itr != m_weathers.end()) - m_weathers.erase(itr); + std::unordered_map _weatherData; } -/// Add a Weather object to the list -Weather* AddWeather(uint32 zone_id) +WeatherData const* GetWeatherData(uint32 zone_id) { - WeatherData const* weatherChances = GetWeatherData(zone_id); - - // zone does not have weather, ignore - if (!weatherChances) - return NULL; - - Weather* w = new Weather(zone_id, weatherChances); - m_weathers[w->GetZone()].reset(w); - w->ReGenerate(); - w->UpdateWeather(); - - return w; + return Trinity::Containers::MapGetValuePtr(_weatherData, zone_id); } void LoadWeatherData() @@ -105,7 +66,7 @@ void LoadWeatherData() uint32 zone_id = fields[0].GetUInt32(); - WeatherData& wzc = mWeatherZoneMap[zone_id]; + WeatherData& wzc = _weatherData[zone_id]; for (uint8 season = 0; season < WEATHER_SEASONS; ++season) { @@ -141,28 +102,4 @@ void LoadWeatherData() TC_LOG_INFO("server.loading", ">> Loaded %u weather definitions in %u ms", count, GetMSTimeDiffToNow(oldMSTime)); } -void SendFineWeatherUpdateToPlayer(Player* player) -{ - WorldPacket data(SMSG_WEATHER, (4+4+4)); - - data << (uint32)WEATHER_STATE_FINE << (float)0.0f << uint8(0); - player->GetSession()->SendPacket(&data); -} - -void Update(uint32 diff) -{ - ///- Send an update signal to Weather objects - WeatherMap::iterator itr, next; - for (itr = m_weathers.begin(); itr != m_weathers.end(); itr = next) - { - next = itr; - ++next; - - ///- and remove Weather objects for zones with no player - // As interval > WorldTick - if (!itr->second->Update(diff)) - m_weathers.erase(itr); - } -} - } // namespace diff --git a/src/server/game/Weather/WeatherMgr.h b/src/server/game/Weather/WeatherMgr.h index 1eabb90de..4e5c68197 100644 --- a/src/server/game/Weather/WeatherMgr.h +++ b/src/server/game/Weather/WeatherMgr.h @@ -1,5 +1,5 @@ /* -* This file is part of the Pandaria 5.4.8 Project. See THANKS file for Copyright information +* This file is part of the Legends of Azeroth Pandaria Project. See THANKS 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 @@ -26,18 +26,12 @@ class Weather; class Player; +struct WeatherData; namespace WeatherMgr { - void LoadWeatherData(); - - Weather* FindWeather(uint32 id); - Weather* AddWeather(uint32 zone_id); - void RemoveWeather(uint32 zone_id); - - void SendFineWeatherUpdateToPlayer(Player* player); - - void Update(uint32 diff); + TC_GAME_API void LoadWeatherData(); + TC_GAME_API WeatherData const* GetWeatherData(uint32 zone_id); } #endif diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index ecec55ec6..4d209ca3e 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -2625,13 +2625,6 @@ void World::Update(uint32 diff) UpdateSessions(diff); RecordTimeDiff("UpdateSessions"); - ///
  • Handle weather updates when the timer has passed - if (m_timers[WUPDATE_WEATHERS].Passed()) - { - m_timers[WUPDATE_WEATHERS].Reset(); - WeatherMgr::Update(uint32(m_timers[WUPDATE_WEATHERS].GetInterval())); - } - ///
  • Update uptime table if (m_timers[WUPDATE_UPTIME].Passed()) { diff --git a/src/server/scripts/Commands/cs_misc.cpp b/src/server/scripts/Commands/cs_misc.cpp index b2a4c0553..00f6fd14a 100644 --- a/src/server/scripts/Commands/cs_misc.cpp +++ b/src/server/scripts/Commands/cs_misc.cpp @@ -1598,10 +1598,7 @@ class misc_commandscript : public CommandScript Player* player = handler->GetSession()->GetPlayer(); uint32 zoneid = player->GetZoneId(); - Weather* weather = WeatherMgr::FindWeather(zoneid); - - if (!weather) - weather = WeatherMgr::AddWeather(zoneid); + Weather* weather = player->GetMap()->GetOrGenerateZoneDefaultWeather(zoneid); if (!weather) { handler->SendSysMessage(LANG_NO_WEATHER); diff --git a/src/server/scripts/Kalimdor/RuinsOfAhnQiraj/boss_ossirian.cpp b/src/server/scripts/Kalimdor/RuinsOfAhnQiraj/boss_ossirian.cpp index 2938f8da3..213ecb4c6 100644 --- a/src/server/scripts/Kalimdor/RuinsOfAhnQiraj/boss_ossirian.cpp +++ b/src/server/scripts/Kalimdor/RuinsOfAhnQiraj/boss_ossirian.cpp @@ -15,10 +15,11 @@ * with this program. If not, see . */ -#include "ScriptMgr.h" -#include "ScriptedCreature.h" #include "ruins_of_ahnqiraj.h" +#include "MiscPackets.h" #include "Player.h" +#include "ScriptMgr.h" +#include "ScriptedCreature.h" #include "SpellInfo.h" #include "WorldPacket.h" #include "Opcodes.h" @@ -142,9 +143,8 @@ class boss_ossirian : public CreatureScript if (!map->IsDungeon()) return; - WorldPacket data(SMSG_WEATHER, (4+4+4)); - data << uint32(WEATHER_STATE_HEAVY_SANDSTORM) << float(1) << uint8(0); - map->SendToPlayers(&data); + WorldPackets::Misc::Weather weather(WEATHER_STATE_HEAVY_SANDSTORM, 1.0f); + map->SendToPlayers(weather.Write()); for (uint8 i = 0; i < NUM_TORNADOS; ++i) { diff --git a/src/server/scripts/Kalimdor/ThroneoftheFourWinds/boss_alakir.cpp b/src/server/scripts/Kalimdor/ThroneoftheFourWinds/boss_alakir.cpp index 5a44115bb..27416be2b 100644 --- a/src/server/scripts/Kalimdor/ThroneoftheFourWinds/boss_alakir.cpp +++ b/src/server/scripts/Kalimdor/ThroneoftheFourWinds/boss_alakir.cpp @@ -1,5 +1,5 @@ /* -* This file is part of the Pandaria 5.4.8 Project. See THANKS file for Copyright information +* This file is part of the Legends of Azeroth Pandaria. See THANKS 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 @@ -711,15 +711,13 @@ class boss_alakir : public CreatureScript if (!players.isEmpty()) { - WorldPacket data(SMSG_WEATHER, 4 + 4 + 1); - data << uint32(weatherId); - data << float(weatherGrade); - data << uint8(0); + WorldPackets::Misc::Weather weather(WeatherState(weatherId), weatherGrade); + weather.Write(); for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr) if (Player* player = itr->GetSource()) if (player->GetZoneId() == zoneId) - player->SendDirectMessage(&data); + player->SendDirectMessage(weather.GetRawPacket()); } } @@ -729,15 +727,16 @@ class boss_alakir : public CreatureScript if (!players.isEmpty()) { - WorldPacket data(SMSG_OVERRIDE_LIGHT, 4 + 4 + 4); - data << uint32(lightId); - data << uint32(GetDefaultMapLight(instance->instance->GetId())); - data << uint32(fadeInTime); + WorldPackets::Misc::OverrideLight overrideLight; + overrideLight.AreaLightID = lightId; + overrideLight.OverrideLightID = GetDefaultMapLight(instance->instance->GetId()); + overrideLight.TransitionMilliseconds = static_cast(fadeInTime); + overrideLight.Write(); for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr) if (Player* player = itr->GetSource()) if (player->GetZoneId() == zoneId) - player->SendDirectMessage(&data); + player->SendDirectMessage(overrideLight.GetRawPacket()); } } }; diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp index 1a36072a1..d395b9718 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp @@ -348,8 +348,10 @@ enum EncounterActions enum MiscData { + LIGHT_DEFAULT = 2488, LIGHT_SNOWSTORM = 2490, LIGHT_SOULSTORM = 2508, + LIGHT_FOG = 2509, MUSIC_FROZEN_THRONE = 17457, MUSIC_SPECIAL = 17458, // Summon Shambling Horror, Remorseless Winter, Quake, Summon Val'kyr Periodic, Harvest Soul, Vile Spirits @@ -748,7 +750,7 @@ class boss_the_lich_king : public CreatureScript me->VisitNearbyGridObject(333.0f, worker); // Reset any light override - SendLightOverride(0, 5000); + me->GetMap()->SetZoneOverrideLight(AREA_ICECROWN_CITADEL, LIGHT_DEFAULT, 0, 5s); } bool CanAIAttack(Unit const* target) const override @@ -793,7 +795,7 @@ class boss_the_lich_king : public CreatureScript me->GetMap()->SetZoneMusic(AREA_ICECROWN_CITADEL, MUSIC_FINAL); break; case ACTION_RESTORE_LIGHT: - SendLightOverride(0, 5000); + me->GetMap()->SetZoneOverrideLight(AREA_ICECROWN_CITADEL, LIGHT_DEFAULT, 0, 5s); break; case ACTION_BREAK_FROSTMOURNE: me->InterruptNonMeleeSpells(false); @@ -987,8 +989,8 @@ class boss_the_lich_king : public CreatureScript { summon->CastSpell((Unit*)nullptr, SPELL_BROKEN_FROSTMOURNE, true); - SendLightOverride(LIGHT_SOULSTORM, 10000); - SendWeather(WEATHER_STATE_BLACKSNOW); + me->GetMap()->SetZoneOverrideLight(AREA_ICECROWN_CITADEL, LIGHT_DEFAULT, LIGHT_SOULSTORM, 10s); + me->GetMap()->SetZoneWeather(AREA_ICECROWN_CITADEL, WEATHER_STATE_BLACKSNOW, 0.5f); events.ScheduleEvent(EVENT_OUTRO_SOUL_BARRAGE, 5000, 0, PHASE_OUTRO); return; @@ -1048,8 +1050,8 @@ class boss_the_lich_king : public CreatureScript //default: if (spell->Id == SPELL_REMORSELESS_WINTER_1 || spell->Id == SPELL_REMORSELESS_WINTER_2) { - SendLightOverride(LIGHT_SNOWSTORM, 5000); - SendWeather(WEATHER_STATE_LIGHT_SNOW); + me->GetMap()->SetZoneOverrideLight(AREA_ICECROWN_CITADEL, LIGHT_DEFAULT, LIGHT_SNOWSTORM, 5s); + me->GetMap()->SetZoneWeather(AREA_ICECROWN_CITADEL, WEATHER_STATE_LIGHT_SNOW, 0.5f); summons.DespawnEntry(39137 /* Shadow Trap */); } // break; @@ -1435,24 +1437,6 @@ class boss_the_lich_king : public CreatureScript summon->AI()->DoAction(ACTION_START_ATTACK_2); }*/ - void SendLightOverride(uint32 overrideId, uint32 fadeInTime) const - { - WorldPacket data(SMSG_OVERRIDE_LIGHT, 12); - data << uint32(overrideId); // Light.dbc entry (override) - data << uint32(2488); // Light.dbc entry (map default) - data << uint32(fadeInTime); - SendPacketToPlayers(&data); - } - - void SendWeather(WeatherState weather) const - { - WorldPacket data(SMSG_WEATHER, 9); - data << uint32(weather); - data << float(0.5f); - data << uint8(0); - SendPacketToPlayers(&data); - } - // Send packet to all players in The Frozen Throne void SendPacketToPlayers(WorldPacket const* data) const { diff --git a/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp b/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp index f3059a7cd..d9de82a08 100644 --- a/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp +++ b/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp @@ -306,7 +306,7 @@ enum AreaIds enum MiscData { // Lights - LIGHT_GET_DEFAULT_FOR_MAP = 0, + LIGHT_DEFAULT = 1773, LIGHT_OBSCURE_SPACE = 1822, LIGHT_CHANGE_DIMENSIONS = 1823, LIGHT_ARCANE_RUNES = 1824, @@ -589,7 +589,7 @@ class boss_malygos : public CreatureScript if (instance) instance->SetBossState(DATA_MALYGOS_EVENT, FAIL); - SendLightOverride(LIGHT_GET_DEFAULT_FOR_MAP, 1*IN_MILLISECONDS); + me->GetMap()->SetZoneOverrideLight(AREA_EYE_OF_ETERNITY, LIGHT_DEFAULT, 0, 1s); if (_phase == PHASE_THREE) me->SetControlled(false, UNIT_STATE_ROOT); @@ -736,7 +736,7 @@ class boss_malygos : public CreatureScript me->OverrideInhabitType(INHABIT_AIR); me->UpdateMovementFlags(); me->SetFacingToObject(me->GetMap()->GetCreature(instance->GetGuidData(DATA_ALEXSTRASZA_BUNNY_GUID))); - SendLightOverride(LIGHT_ARCANE_RUNES, 5*IN_MILLISECONDS); + me->GetMap()->SetZoneOverrideLight(AREA_EYE_OF_ETERNITY, LIGHT_DEFAULT, LIGHT_ARCANE_RUNES, 5s); events.ScheduleEvent(EVENT_FLY_OUT_OF_PLATFORM, 18*IN_MILLISECONDS, 0, PHASE_TWO); break; case POINT_SURGE_OF_POWER_P_TWO: @@ -748,7 +748,7 @@ class boss_malygos : public CreatureScript } break; case POINT_DESTROY_PLATFORM_P_TWO: - SendLightOverride(LIGHT_OBSCURE_SPACE, 1*IN_MILLISECONDS); + me->GetMap()->SetZoneOverrideLight(AREA_EYE_OF_ETERNITY, LIGHT_DEFAULT, LIGHT_OBSCURE_SPACE, 1s); DoCast(me, SPELL_DESTROY_PLATFORM_CHANNEL); events.ScheduleEvent(EVENT_MOVE_TO_P_THREE_POINT, 11*IN_MILLISECONDS, 0, PHASE_TWO); break; @@ -940,7 +940,7 @@ class boss_malygos : public CreatureScript } break; case EVENT_LIGHT_DIMENSION_CHANGE: - SendLightOverride(LIGHT_CHANGE_DIMENSIONS, 2*IN_MILLISECONDS); + me->GetMap()->SetZoneOverrideLight(AREA_EYE_OF_ETERNITY, LIGHT_DEFAULT, LIGHT_CHANGE_DIMENSIONS, 2s); break; case EVENT_DELAY_MOVE_TO_DESTROY_P: me->GetMotionMaster()->MovePoint(POINT_DESTROY_PLATFORM_P_TWO, MalygosPositions[0]); @@ -950,7 +950,7 @@ class boss_malygos : public CreatureScript me->GetMotionMaster()->MovePoint(POINT_IDLE_P_THREE, MalygosPositions[4]); break; case EVENT_START_P_THREE: - SendLightOverride(LIGHT_OBSCURE_ARCANE_RUNES, 1*IN_MILLISECONDS); + me->GetMap()->SetZoneOverrideLight(AREA_EYE_OF_ETERNITY, LIGHT_DEFAULT, LIGHT_OBSCURE_ARCANE_RUNES, 1s); DoCast(me, SPELL_CLEAR_ALL_DEBUFFS); DoCast(me, SPELL_IMMUNE_CURSES); _canAttack = true; @@ -1037,27 +1037,6 @@ class boss_malygos : public CreatureScript } } - // Function that will change lights of map for all players on map. - void SendLightOverride(uint32 overrideId, uint32 fadeInTime) const - { - WorldPacket data(SMSG_OVERRIDE_LIGHT, 12); - data << uint32(overrideId); // Light.dbc entry (override) - data << uint32(1773); // Light.dbc entry (map default) - data << uint32(fadeInTime); - SendPacketToPlayers(&data); - } - - // Send packet to all players in Eye of Eternity - void SendPacketToPlayers(WorldPacket const* data) const - { - Map::PlayerList const& players = me->GetMap()->GetPlayers(); - if (!players.isEmpty()) - for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr) - if (Player* player = itr->GetSource()) - if (player->GetAreaId() == AREA_EYE_OF_ETERNITY) - player->GetSession()->SendPacket(data); - } - uint8 _phase; // Counter for phases used with a getter. uint8 _summonDeaths; // Keeps count of arcane trash. uint8 _preparingPulsesChecker; // In retail they use 2 preparing pulses with 7 sec CD, after they pass 2 seconds.