Merge branch 'azerothcore:master' into Playerbot

This commit is contained in:
bash
2025-09-29 20:09:38 +02:00
committed by GitHub
33 changed files with 315 additions and 422 deletions

View File

@@ -43,10 +43,11 @@
#include "Vehicle.h"
#include "VMapMgr2.h"
#include "Weather.h"
#include "WeatherMgr.h"
#define MAP_INVALID_ZONE 0xFFFFFFFF
ZoneDynamicInfo::ZoneDynamicInfo() : MusicId(0), WeatherId(WEATHER_STATE_FINE),
ZoneDynamicInfo::ZoneDynamicInfo() : MusicId(0), DefaultWeather(nullptr), WeatherId(WEATHER_STATE_FINE),
WeatherGrade(0.0f), OverrideLightId(0), LightFadeInTime(0) { }
Map::~Map()
@@ -74,6 +75,7 @@ Map::Map(uint32 id, uint32 InstanceId, uint8 SpawnMode, Map* _parent) :
//lets initialize visibility distance for map
Map::InitVisibilityDistance();
_weatherUpdateTimer.SetInterval(1 * IN_MILLISECONDS);
_corpseUpdateTimer.SetInterval(20 * MINUTE * IN_MILLISECONDS);
}
@@ -268,7 +270,6 @@ bool Map::AddPlayerToMap(Player* player)
SendInitTransports(player);
SendInitSelf(player);
SendZoneDynamicInfo(player);
player->UpdateObjectVisibility(false);
@@ -500,6 +501,7 @@ void Map::Update(const uint32 t_diff, const uint32 s_diff, bool /*thread*/)
HandleDelayedVisibility();
UpdateWeather(t_diff);
UpdateExpiredCorpses(t_diff);
sScriptMgr->OnMapUpdate(this, t_diff);
@@ -2773,9 +2775,37 @@ void Map::ScheduleCreatureRespawn(ObjectGuid creatureGuid, Milliseconds respawnT
});
}
void Map::SendZoneDynamicInfo(Player* player)
/// 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, TeamId teamId) const
{
bool foundPlayerToSend = false;
for (MapReference const& ref : GetPlayers())
{
Player* player = ref.GetSource();
if (player->IsInWorld() &&
player->GetZoneId() == zone &&
player->GetSession() != self &&
(teamId == TEAM_NEUTRAL || player->GetTeamId() == teamId))
{
player->SendDirectMessage(packet);
foundPlayerToSend = true;
}
}
return foundPlayerToSend;
}
/// Send a System Message to all players in the zone (except self if mentioned)
void Map::SendZoneText(uint32 zoneId, char const* text, WorldSession const* self, TeamId teamId) const
{
WorldPacket data;
ChatHandler::BuildChatPacket(data, CHAT_MSG_SYSTEM, LANG_UNIVERSAL, nullptr, nullptr, text);
SendZoneMessage(zoneId, &data, self, teamId);
}
void Map::SendZoneDynamicInfo(uint32 zoneId, Player* player) const
{
uint32 zoneId = player->GetZoneId();
ZoneDynamicInfoMap::const_iterator itr = _zoneDynamicInfo.find(zoneId);
if (itr == _zoneDynamicInfo.end())
return;
@@ -2783,15 +2813,11 @@ void Map::SendZoneDynamicInfo(Player* player)
if (uint32 music = itr->second.MusicId)
player->SendDirectMessage(WorldPackets::Misc::PlayMusic(music).Write());
if (WeatherState weatherId = itr->second.WeatherId)
{
WorldPackets::Misc::Weather weather(weatherId, itr->second.WeatherGrade);
player->SendDirectMessage(weather.Write());
}
SendZoneWeather(itr->second, player);
if (uint32 overrideLight = itr->second.OverrideLightId)
{
WorldPacket data(SMSG_OVERRIDE_LIGHT, 4 + 4 + 1);
WorldPacket data(SMSG_OVERRIDE_LIGHT, 4 + 4 + 4);
data << uint32(_defaultLight);
data << uint32(overrideLight);
data << uint32(itr->second.LightFadeInTime);
@@ -2799,6 +2825,41 @@ void Map::SendZoneDynamicInfo(Player* player)
}
}
void Map::SendZoneWeather(uint32 zoneId, Player* player) const
{
ZoneDynamicInfoMap::const_iterator itr = _zoneDynamicInfo.find(zoneId);
if (itr == _zoneDynamicInfo.end())
return;
SendZoneWeather(itr->second, player);
}
void Map::SendZoneWeather(ZoneDynamicInfo const& zoneDynamicInfo, Player* player) const
{
if (WeatherState weatherId = zoneDynamicInfo.WeatherId)
{
WorldPackets::Misc::Weather weather(weatherId, zoneDynamicInfo.WeatherGrade);
player->SendDirectMessage(weather.Write());
}
else if (zoneDynamicInfo.DefaultWeather)
zoneDynamicInfo.DefaultWeather->SendWeatherUpdateToPlayer(player);
else
Weather::SendFineWeatherUpdateToPlayer(player);
}
void Map::UpdateWeather(uint32 const diff)
{
_weatherUpdateTimer.Update(diff);
if (!_weatherUpdateTimer.Passed())
return;
for (auto&& zoneInfo : _zoneDynamicInfo)
if (zoneInfo.second.DefaultWeather && !zoneInfo.second.DefaultWeather->Update(_weatherUpdateTimer.GetInterval()))
zoneInfo.second.DefaultWeather.reset();
_weatherUpdateTimer.Reset();
}
void Map::PlayDirectSoundToMap(uint32 soundId, uint32 zoneId)
{
Map::PlayerList const& players = GetPlayers();
@@ -2816,67 +2877,50 @@ void Map::PlayDirectSoundToMap(uint32 soundId, uint32 zoneId)
void Map::SetZoneMusic(uint32 zoneId, uint32 musicId)
{
if (_zoneDynamicInfo.find(zoneId) == _zoneDynamicInfo.end())
_zoneDynamicInfo.insert(ZoneDynamicInfoMap::value_type(zoneId, ZoneDynamicInfo()));
_zoneDynamicInfo[zoneId].MusicId = musicId;
Map::PlayerList const& players = GetPlayers();
if (!players.IsEmpty())
{
WorldPackets::Misc::PlayMusic playMusic(musicId);
playMusic.Write();
WorldPackets::Misc::PlayMusic playMusic(musicId);
SendZoneMessage(zoneId, WorldPackets::Misc::PlayMusic(musicId).Write());
}
for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
if (Player* player = itr->GetSource())
if (player->GetZoneId() == zoneId)
player->SendDirectMessage(playMusic.GetRawPacket());
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<Weather>(this, zoneId, weatherData);
info.DefaultWeather->ReGenerate();
info.DefaultWeather->UpdateWeather();
}
return info.DefaultWeather.get();
}
void Map::SetZoneWeather(uint32 zoneId, WeatherState weatherId, float weatherGrade)
{
if (_zoneDynamicInfo.find(zoneId) == _zoneDynamicInfo.end())
_zoneDynamicInfo.insert(ZoneDynamicInfoMap::value_type(zoneId, ZoneDynamicInfo()));
ZoneDynamicInfo& info = _zoneDynamicInfo[zoneId];
info.WeatherId = weatherId;
info.WeatherGrade = weatherGrade;
Map::PlayerList const& players = GetPlayers();
if (!players.IsEmpty())
{
WorldPackets::Misc::Weather weather(weatherId, weatherGrade);
for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
if (Player* player = itr->GetSource())
if (player->GetZoneId() == zoneId)
player->SendDirectMessage(weather.Write());
}
SendZoneMessage(zoneId, WorldPackets::Misc::Weather(weatherId, weatherGrade).Write());
}
void Map::SetZoneOverrideLight(uint32 zoneId, uint32 lightId, Milliseconds fadeInTime)
{
if (_zoneDynamicInfo.find(zoneId) == _zoneDynamicInfo.end())
_zoneDynamicInfo.insert(ZoneDynamicInfoMap::value_type(zoneId, ZoneDynamicInfo()));
ZoneDynamicInfo& info = _zoneDynamicInfo[zoneId];
info.OverrideLightId = lightId;
info.LightFadeInTime = static_cast<uint32>(fadeInTime.count());
Map::PlayerList const& players = GetPlayers();
if (!players.IsEmpty())
{
WorldPacket data(SMSG_OVERRIDE_LIGHT, 4 + 4 + 4);
data << uint32(_defaultLight);
data << uint32(lightId);
data << uint32(static_cast<uint32>(fadeInTime.count()));
for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
if (Player* player = itr->GetSource())
if (player->GetZoneId() == zoneId)
player->SendDirectMessage(&data);
}
WorldPacket data(SMSG_OVERRIDE_LIGHT, 4 + 4 + 4);
data << uint32(_defaultLight);
data << uint32(lightId);
data << uint32(static_cast<uint32>(fadeInTime.count()));
SendZoneMessage(zoneId, &data);
}
void Map::DoForAllPlayers(std::function<void(Player*)> exec)