summaryrefslogtreecommitdiff
path: root/src/server/game/Maps
diff options
context:
space:
mode:
Diffstat (limited to 'src/server/game/Maps')
-rw-r--r--src/server/game/Maps/AreaBoundary.cpp10
-rw-r--r--src/server/game/Maps/AreaBoundary.h10
-rw-r--r--src/server/game/Maps/AreaDefines.h10
-rw-r--r--src/server/game/Maps/Map.cpp275
-rw-r--r--src/server/game/Maps/Map.h55
-rw-r--r--src/server/game/Maps/MapInstanced.cpp10
-rw-r--r--src/server/game/Maps/MapInstanced.h10
-rw-r--r--src/server/game/Maps/MapMgr.cpp12
-rw-r--r--src/server/game/Maps/MapMgr.h10
-rw-r--r--src/server/game/Maps/MapRefMgr.h10
-rw-r--r--src/server/game/Maps/MapReference.h10
-rw-r--r--src/server/game/Maps/MapUpdater.cpp10
-rw-r--r--src/server/game/Maps/MapUpdater.h10
-rw-r--r--src/server/game/Maps/TransportMgr.cpp52
-rw-r--r--src/server/game/Maps/TransportMgr.h12
-rw-r--r--src/server/game/Maps/ZoneScript.h10
16 files changed, 293 insertions, 223 deletions
diff --git a/src/server/game/Maps/AreaBoundary.cpp b/src/server/game/Maps/AreaBoundary.cpp
index e5b1848761..80bacdc841 100644
--- a/src/server/game/Maps/AreaBoundary.cpp
+++ b/src/server/game/Maps/AreaBoundary.cpp
@@ -1,14 +1,14 @@
/*
* This file is part of the AzerothCore 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 Affero General Public License as published by the
- * Free Software Foundation; either version 3 of the License, or (at your
- * option) any later version.
+ * 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 Affero General Public License for
+ * 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
diff --git a/src/server/game/Maps/AreaBoundary.h b/src/server/game/Maps/AreaBoundary.h
index 48a5e66713..392bfef22d 100644
--- a/src/server/game/Maps/AreaBoundary.h
+++ b/src/server/game/Maps/AreaBoundary.h
@@ -1,14 +1,14 @@
/*
* This file is part of the AzerothCore 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 Affero General Public License as published by the
- * Free Software Foundation; either version 3 of the License, or (at your
- * option) any later version.
+ * 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 Affero General Public License for
+ * 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
diff --git a/src/server/game/Maps/AreaDefines.h b/src/server/game/Maps/AreaDefines.h
index a7af304579..1730cd09d4 100644
--- a/src/server/game/Maps/AreaDefines.h
+++ b/src/server/game/Maps/AreaDefines.h
@@ -1,14 +1,14 @@
/*
* This file is part of the AzerothCore 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 Affero General Public License as published by the
- * Free Software Foundation; either version 3 of the License, or (at your
- * option) any later version.
+ * 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 Affero General Public License for
+ * 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
diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp
index d8dde935e5..0ea47ff8ab 100644
--- a/src/server/game/Maps/Map.cpp
+++ b/src/server/game/Maps/Map.cpp
@@ -1,14 +1,14 @@
/*
* This file is part of the AzerothCore 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 Affero General Public License as published by the
- * Free Software Foundation; either version 3 of the License, or (at your
- * option) any later version.
+ * 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 Affero General Public License for
+ * 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
@@ -43,16 +43,21 @@
#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()
{
// UnloadAll must be called before deleting the map
+ // Kill all scheduled events without executing them, since the map and its objects are being destroyed.
+ // This prevents events from running on invalid or deleted objects during map destruction.
+ Events.KillAllEvents(false);
+
sScriptMgr->OnDestroyMap(this);
if (!m_scriptSchedule.empty())
@@ -74,6 +79,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 +274,6 @@ bool Map::AddPlayerToMap(Player* player)
SendInitTransports(player);
SendInitSelf(player);
- SendZoneDynamicInfo(player);
player->UpdateObjectVisibility(false);
@@ -416,12 +421,12 @@ void Map::UpdatePlayerZoneStats(uint32 oldZone, uint32 newZone)
if (oldZone != MAP_INVALID_ZONE)
{
uint32& oldZoneCount = _zonePlayerCountMap[oldZone];
- if (!oldZoneCount)
- LOG_ERROR("maps", "A player left zone {} (went to {}) - but there were no players in the zone!", oldZone, newZone);
- else
+ if (oldZoneCount)
--oldZoneCount;
}
- ++_zonePlayerCountMap[newZone];
+
+ if (newZone != MAP_INVALID_ZONE)
+ ++_zonePlayerCountMap[newZone];
}
void Map::Update(const uint32 t_diff, const uint32 s_diff, bool /*thread*/)
@@ -446,7 +451,7 @@ void Map::Update(const uint32 t_diff, const uint32 s_diff, bool /*thread*/)
}
}
- _creatureRespawnScheduler.Update(t_diff);
+ Events.Update(t_diff);
if (!t_diff)
{
@@ -500,6 +505,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);
@@ -694,8 +700,8 @@ struct ResetNotifier
void Map::RemovePlayerFromMap(Player* player, bool remove)
{
- // Before leaving map, update zone/area for stats
- player->UpdateZone(MAP_INVALID_ZONE, 0);
+ UpdatePlayerZoneStats(player->GetZoneId(), MAP_INVALID_ZONE);
+
player->getHostileRefMgr().deleteReferences(true); // pussywizard: multithreading crashfix
player->RemoveFromWorld();
@@ -723,8 +729,6 @@ void Map::RemoveFromMap(T* obj, bool remove)
obj->RemoveFromWorld();
obj->RemoveFromGrid();
- if (obj->IsFarVisible())
- RemoveWorldObjectFromFarVisibleMap(obj);
obj->ResetMap();
@@ -1097,7 +1101,7 @@ float Map::GetWaterOrGroundLevel(uint32 phasemask, float x, float y, float z, fl
if (ground)
*ground = ground_z;
- LiquidData const& liquidData = const_cast<Map*>(this)->GetLiquidData(phasemask, x, y, ground_z, collisionHeight, MAP_ALL_LIQUIDS);
+ LiquidData const& liquidData = const_cast<Map*>(this)->GetLiquidData(phasemask, x, y, ground_z, collisionHeight, {});
switch (liquidData.Status)
{
case LIQUID_MAP_ABOVE_WATER:
@@ -1198,27 +1202,18 @@ static inline bool IsInWMOInterior(uint32 mogpFlags)
bool Map::GetAreaInfo(uint32 phaseMask, float x, float y, float z, uint32& flags, int32& adtId, int32& rootId, int32& groupId) const
{
- float vmap_z = z;
- float dynamic_z = z;
float check_z = z;
VMAP::IVMapMgr* vmgr = VMAP::VMapFactory::createOrGetVMapMgr();
- uint32 vflags;
- int32 vadtId;
- int32 vrootId;
- int32 vgroupId;
- uint32 dflags;
- int32 dadtId;
- int32 drootId;
- int32 dgroupId;
-
- bool hasVmapAreaInfo = vmgr->GetAreaInfo(GetId(), x, y, vmap_z, vflags, vadtId, vrootId, vgroupId);
- bool hasDynamicAreaInfo = _dynamicTree.GetAreaInfo(x, y, dynamic_z, phaseMask, dflags, dadtId, drootId, dgroupId);
- auto useVmap = [&]() { check_z = vmap_z; flags = vflags; adtId = vadtId; rootId = vrootId; groupId = vgroupId; };
- auto useDyn = [&]() { check_z = dynamic_z; flags = dflags; adtId = dadtId; rootId = drootId; groupId = dgroupId; };
+ VMAP::AreaAndLiquidData vdata;
+ VMAP::AreaAndLiquidData ddata;
+ bool hasVmapAreaInfo = vmgr->GetAreaAndLiquidData(GetId(), x, y, z, {}, vdata) && vdata.areaInfo.has_value();
+ bool hasDynamicAreaInfo = _dynamicTree.GetAreaAndLiquidData(x, y, z, phaseMask, {}, ddata) && ddata.areaInfo.has_value();
+ auto useVmap = [&] { check_z = vdata.floorZ; groupId = vdata.areaInfo->groupId; adtId = vdata.areaInfo->adtId; rootId = vdata.areaInfo->rootId; flags = vdata.areaInfo->mogpFlags; };
+ auto useDyn = [&] { check_z = ddata.floorZ; groupId = ddata.areaInfo->groupId; adtId = ddata.areaInfo->adtId; rootId = ddata.areaInfo->rootId; flags = ddata.areaInfo->mogpFlags; };
if (hasVmapAreaInfo)
{
- if (hasDynamicAreaInfo && dynamic_z > vmap_z)
+ if (hasDynamicAreaInfo && ddata.floorZ > vdata.floorZ)
useDyn();
else
useVmap();
@@ -1299,32 +1294,30 @@ void Map::GetZoneAndAreaId(uint32 phaseMask, uint32& zoneid, uint32& areaid, flo
zoneid = area->zone;
}
-LiquidData const Map::GetLiquidData(uint32 phaseMask, float x, float y, float z, float collisionHeight, uint8 ReqLiquidType)
+LiquidData const Map::GetLiquidData(uint32 phaseMask, float x, float y, float z, float collisionHeight, Optional<uint8> ReqLiquidType)
{
LiquidData liquidData;
+ liquidData.Status = LIQUID_MAP_NO_WATER;
VMAP::IVMapMgr* vmgr = VMAP::VMapFactory::createOrGetVMapMgr();
- float liquid_level = INVALID_HEIGHT;
- float ground_level = INVALID_HEIGHT;
- uint32 liquid_type = 0;
- uint32 mogpFlags = 0;
+ VMAP::AreaAndLiquidData vmapData;
bool useGridLiquid = true;
- if (vmgr->GetLiquidLevel(GetId(), x, y, z, ReqLiquidType, liquid_level, ground_level, liquid_type, mogpFlags))
+ if (vmgr->GetAreaAndLiquidData(GetId(), x, y, z, ReqLiquidType, vmapData) && vmapData.liquidInfo)
{
- useGridLiquid = !IsInWMOInterior(mogpFlags);
- LOG_DEBUG("maps", "GetLiquidStatus(): vmap liquid level: {} ground: {} type: {}", liquid_level, ground_level, liquid_type);
+ useGridLiquid = !vmapData.areaInfo || !IsInWMOInterior(vmapData.areaInfo->mogpFlags);
+ LOG_DEBUG("maps", "GetLiquidStatus(): vmap liquid level: {} ground: {} type: {}", vmapData.liquidInfo->level, vmapData.floorZ, vmapData.liquidInfo->type);
// Check water level and ground level
- if (liquid_level > ground_level && G3D::fuzzyGe(z, ground_level - GROUND_HEIGHT_TOLERANCE))
+ if (vmapData.liquidInfo->level > vmapData.floorZ && G3D::fuzzyGe(z, vmapData.floorZ - GROUND_HEIGHT_TOLERANCE))
{
// hardcoded in client like this
- if (GetId() == MAP_OUTLAND && liquid_type == 2)
- liquid_type = 15;
+ if (GetId() == MAP_OUTLAND && vmapData.liquidInfo->type == 2)
+ vmapData.liquidInfo->type = 15;
uint32 liquidFlagType = 0;
- if (LiquidTypeEntry const* liq = sLiquidTypeStore.LookupEntry(liquid_type))
+ if (LiquidTypeEntry const* liq = sLiquidTypeStore.LookupEntry(vmapData.liquidInfo->type))
liquidFlagType = liq->Type;
- if (liquid_type && liquid_type < 21)
+ if (vmapData.liquidInfo->type && vmapData.liquidInfo->type < 21)
{
if (AreaTableEntry const* area = sAreaTableStore.LookupEntry(GetAreaId(phaseMask, x, y, z)))
{
@@ -1338,19 +1331,19 @@ LiquidData const Map::GetLiquidData(uint32 phaseMask, float x, float y, float z,
if (LiquidTypeEntry const* liq = sLiquidTypeStore.LookupEntry(overrideLiquid))
{
- liquid_type = overrideLiquid;
+ vmapData.liquidInfo->type = overrideLiquid;
liquidFlagType = liq->Type;
}
}
}
- liquidData.Level = liquid_level;
- liquidData.DepthLevel = ground_level;
- liquidData.Entry = liquid_type;
+ liquidData.Level = vmapData.liquidInfo->level;
+ liquidData.DepthLevel = vmapData.floorZ;
+ liquidData.Entry = vmapData.liquidInfo->type;
liquidData.Flags = 1 << liquidFlagType;
}
- float delta = liquid_level - z;
+ float delta = vmapData.liquidInfo->level - z;
// Get position delta
if (delta > collisionHeight)
@@ -1369,7 +1362,7 @@ LiquidData const Map::GetLiquidData(uint32 phaseMask, float x, float y, float z,
{
LiquidData const& map_data = gmap->GetLiquidData(x, y, z, collisionHeight, ReqLiquidType);
// Not override LIQUID_MAP_ABOVE_WATER with LIQUID_MAP_NO_WATER:
- if (map_data.Status != LIQUID_MAP_NO_WATER && (map_data.Level > ground_level))
+ if (map_data.Status != LIQUID_MAP_NO_WATER && (map_data.Level > vmapData.floorZ))
{
// hardcoded in client like this
uint32 liquidEntry = map_data.Entry;
@@ -1385,7 +1378,7 @@ LiquidData const Map::GetLiquidData(uint32 phaseMask, float x, float y, float z,
return liquidData;
}
-void Map::GetFullTerrainStatusForPosition(uint32 /*phaseMask*/, float x, float y, float z, float collisionHeight, PositionFullTerrainStatus& data, uint8 reqLiquidType)
+void Map::GetFullTerrainStatusForPosition(uint32 /*phaseMask*/, float x, float y, float z, float collisionHeight, PositionFullTerrainStatus& data, Optional<uint8> reqLiquidType)
{
GridTerrainData* gmap = GetGridTerrainData(x, y);
@@ -1600,7 +1593,7 @@ float Map::GetHeight(uint32 phasemask, float x, float y, float z, bool vmap/*=tr
bool Map::IsInWater(uint32 phaseMask, float x, float y, float pZ, float collisionHeight) const
{
- LiquidData const& liquidData = const_cast<Map*>(this)->GetLiquidData(phaseMask, x, y, pZ, collisionHeight, MAP_ALL_LIQUIDS);
+ LiquidData const& liquidData = const_cast<Map*>(this)->GetLiquidData(phaseMask, x, y, pZ, collisionHeight, {});
return (liquidData.Status & MAP_LIQUID_STATUS_SWIMMING) != 0;
}
@@ -1691,7 +1684,7 @@ void Map::SendInitTransports(Player* player)
WorldPacket packet;
transData.BuildPacket(packet);
- player->GetSession()->SendPacket(&packet);
+ player->SendDirectMessage(&packet);
}
void Map::SendRemoveTransports(Player* player)
@@ -1710,7 +1703,7 @@ void Map::SendRemoveTransports(Player* player)
WorldPacket packet;
transData.BuildPacket(packet);
- player->GetSession()->SendPacket(&packet);
+ player->SendDirectMessage(&packet);
}
void Map::SendObjectUpdates()
@@ -1730,7 +1723,7 @@ void Map::SendObjectUpdates()
for (UpdateDataMapType::iterator iter = update_players.begin(); iter != update_players.end(); ++iter)
{
iter->second.BuildPacket(packet);
- iter->first->GetSession()->SendPacket(&packet);
+ iter->first->SendDirectMessage(&packet);
packet.clear(); // clean the string
}
}
@@ -1850,7 +1843,7 @@ uint32 Map::GetPlayersCountExceptGMs() const
void Map::SendToPlayers(WorldPacket const* data) const
{
for (MapRefMgr::const_iterator itr = m_mapRefMgr.begin(); itr != m_mapRefMgr.end(); ++itr)
- itr->GetSource()->GetSession()->SendPacket(data);
+ itr->GetSource()->SendDirectMessage(data);
}
template bool Map::AddToMap(Corpse*, bool);
@@ -2055,7 +2048,7 @@ bool InstanceMap::AddPlayerToMap(Player* player)
data << uint32(60000);
data << uint32(instance_data ? instance_data->GetCompletedEncounterMask() : 0);
data << uint8(0);
- player->GetSession()->SendPacket(&data);
+ player->SendDirectMessage(&data);
player->SetPendingBind(mapSave->GetInstanceId(), 60000);
}
}
@@ -2118,7 +2111,7 @@ void InstanceMap::CreateInstanceScript(bool load, std::string data, uint32 compl
if (instance_data)
isOtherAI = true;
- // if Eluna AI was fetched succesfully we should not call CreateInstanceData nor set the unused scriptID
+ // if ALE AI was fetched succesfully we should not call CreateInstanceData nor set the unused scriptID
if (!isOtherAI)
{
InstanceTemplate const* mInstance = sObjectMgr->GetInstanceTemplate(GetId());
@@ -2132,7 +2125,7 @@ void InstanceMap::CreateInstanceScript(bool load, std::string data, uint32 compl
if (!instance_data)
return;
- // use mangos behavior if we are dealing with Eluna AI
+ // use mangos behavior if we are dealing with ALE AI
// initialize should then be called only if load is false
if (!isOtherAI || !load)
{
@@ -2227,7 +2220,7 @@ void InstanceMap::PermBindAllPlayers()
{
WorldPacket data(SMSG_INSTANCE_SAVE_CREATED, 4);
data << uint32(0);
- player->GetSession()->SendPacket(&data);
+ player->SendDirectMessage(&data);
sInstanceSaveMgr->PlayerBindToInstance(player->GetGUID(), save, true, player);
}
@@ -2356,27 +2349,27 @@ void BattlegroundMap::RemoveAllPlayers()
player->TeleportTo(player->GetEntryPoint());
}
-Corpse* Map::GetCorpse(ObjectGuid const guid)
+Corpse* Map::GetCorpse(ObjectGuid const& guid)
{
return _objectsStore.Find<Corpse>(guid);
}
-Creature* Map::GetCreature(ObjectGuid const guid)
+Creature* Map::GetCreature(ObjectGuid const& guid)
{
return _objectsStore.Find<Creature>(guid);
}
-GameObject* Map::GetGameObject(ObjectGuid const guid)
+GameObject* Map::GetGameObject(ObjectGuid const& guid)
{
return _objectsStore.Find<GameObject>(guid);
}
-Pet* Map::GetPet(ObjectGuid const guid)
+Pet* Map::GetPet(ObjectGuid const& guid)
{
return dynamic_cast<Pet*>(_objectsStore.Find<Creature>(guid));
}
-Transport* Map::GetTransport(ObjectGuid guid)
+Transport* Map::GetTransport(ObjectGuid const& guid)
{
if (guid.GetHigh() != HighGuid::Mo_Transport && guid.GetHigh() != HighGuid::Transport)
return nullptr;
@@ -2385,7 +2378,7 @@ Transport* Map::GetTransport(ObjectGuid guid)
return go ? go->ToTransport() : nullptr;
}
-DynamicObject* Map::GetDynamicObject(ObjectGuid guid)
+DynamicObject* Map::GetDynamicObject(ObjectGuid const& guid)
{
return _objectsStore.Find<DynamicObject>(guid);
}
@@ -2677,7 +2670,7 @@ void Map::RemoveCorpse(Corpse* corpse)
_corpseBones.erase(corpse);
}
-Corpse* Map::ConvertCorpseToBones(ObjectGuid const ownerGuid, bool insignia /*= false*/)
+Corpse* Map::ConvertCorpseToBones(ObjectGuid const& ownerGuid, bool insignia /*= false*/)
{
Corpse* corpse = GetCorpseByPlayer(ownerGuid);
if (!corpse)
@@ -2758,18 +2751,46 @@ void Map::RemoveOldCorpses()
void Map::ScheduleCreatureRespawn(ObjectGuid creatureGuid, Milliseconds respawnTimer, Position pos)
{
- _creatureRespawnScheduler.Schedule(respawnTimer, [this, creatureGuid, pos](TaskContext)
+ Events.AddEventAtOffset([this, creatureGuid, pos]()
{
if (Creature* creature = GetCreature(creatureGuid))
creature->Respawn();
else
SummonCreature(creatureGuid.GetEntry(), pos);
- });
+ }, respawnTimer);
+}
+
+/// 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(Player* player)
+void Map::SendZoneDynamicInfo(uint32 zoneId, Player* player) const
{
- uint32 zoneId = player->GetZoneId();
ZoneDynamicInfoMap::const_iterator itr = _zoneDynamicInfo.find(zoneId);
if (itr == _zoneDynamicInfo.end())
return;
@@ -2777,15 +2798,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);
@@ -2793,6 +2810,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();
@@ -2810,67 +2862,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)
diff --git a/src/server/game/Maps/Map.h b/src/server/game/Maps/Map.h
index c875e4eaa9..21226c54a9 100644
--- a/src/server/game/Maps/Map.h
+++ b/src/server/game/Maps/Map.h
@@ -1,14 +1,14 @@
/*
* This file is part of the AzerothCore 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 Affero General Public License as published by the
- * Free Software Foundation; either version 3 of the License, or (at your
- * option) any later version.
+ * 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 Affero General Public License for
+ * 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
@@ -23,6 +23,7 @@
#include "DataMap.h"
#include "Define.h"
#include "DynamicTree.h"
+#include "EventProcessor.h"
#include "GameObjectModel.h"
#include "GridDefines.h"
#include "GridRefMgr.h"
@@ -33,7 +34,6 @@
#include "PathGenerator.h"
#include "Position.h"
#include "SharedDefines.h"
-#include "TaskScheduler.h"
#include "Timer.h"
#include "GridTerrainData.h"
#include <bitset>
@@ -47,6 +47,7 @@ class InstanceScript;
class Group;
class InstanceSave;
class Object;
+class Weather;
class WorldObject;
class TempSummon;
class Player;
@@ -62,6 +63,7 @@ class Transport;
class StaticTransport;
class MotionTransport;
class PathGenerator;
+class WorldSession;
enum WeatherState : uint32;
@@ -132,6 +134,7 @@ struct ZoneDynamicInfo
ZoneDynamicInfo();
uint32 MusicId;
+ std::unique_ptr<Weather> DefaultWeather;
WeatherState WeatherId;
float WeatherGrade;
uint32 OverrideLightId;
@@ -169,7 +172,7 @@ public:
// currently unused for normal maps
bool CanUnload(uint32 diff)
{
- if (!m_unloadTimer)
+ if (!m_unloadTimer || Events.HasEvents())
return false;
if (m_unloadTimer <= diff)
@@ -240,8 +243,8 @@ public:
[[nodiscard]] float GetMinHeight(float x, float y) const;
Transport* GetTransportForPos(uint32 phase, float x, float y, float z, WorldObject* worldobject = nullptr);
- void GetFullTerrainStatusForPosition(uint32 phaseMask, float x, float y, float z, float collisionHeight, PositionFullTerrainStatus& data, uint8 reqLiquidType = MAP_ALL_LIQUIDS);
- LiquidData const GetLiquidData(uint32 phaseMask, float x, float y, float z, float collisionHeight, uint8 ReqLiquidType);
+ void GetFullTerrainStatusForPosition(uint32 phaseMask, float x, float y, float z, float collisionHeight, PositionFullTerrainStatus& data, Optional<uint8> reqLiquidType = {});
+ LiquidData const GetLiquidData(uint32 phaseMask, float x, float y, float z, float collisionHeight, Optional<uint8> ReqLiquidType);
[[nodiscard]] bool GetAreaInfo(uint32 phaseMask, float x, float y, float z, uint32& mogpflags, int32& adtId, int32& rootId, int32& groupId) const;
[[nodiscard]] uint32 GetAreaId(uint32 phaseMask, float x, float y, float z) const;
@@ -335,12 +338,12 @@ public:
GameObject* SummonGameObject(uint32 entry, Position const& pos, float rotation0 = 0.0f, float rotation1 = 0.0f, float rotation2 = 0.0f, float rotation3 = 0.0f, uint32 respawnTime = 100, bool checkTransport = true);
void SummonCreatureGroup(uint8 group, std::list<TempSummon*>* list = nullptr);
- Corpse* GetCorpse(ObjectGuid const guid);
- Creature* GetCreature(ObjectGuid const guid);
- GameObject* GetGameObject(ObjectGuid const guid);
- Transport* GetTransport(ObjectGuid const guid);
- DynamicObject* GetDynamicObject(ObjectGuid const guid);
- Pet* GetPet(ObjectGuid const guid);
+ Corpse* GetCorpse(ObjectGuid const& guid);
+ Creature* GetCreature(ObjectGuid const& guid);
+ GameObject* GetGameObject(ObjectGuid const& guid);
+ Transport* GetTransport(ObjectGuid const& guid);
+ DynamicObject* GetDynamicObject(ObjectGuid const& guid);
+ Pet* GetPet(ObjectGuid const& guid);
MapStoredObjectTypesContainer& GetObjectsStore() { return _objectsStore; }
@@ -427,7 +430,7 @@ public:
void UpdatePlayerZoneStats(uint32 oldZone, uint32 newZone);
[[nodiscard]] uint32 ApplyDynamicModeRespawnScaling(WorldObject const* obj, uint32 respawnDelay) const;
- TaskScheduler _creatureRespawnScheduler;
+ EventProcessor Events;
void ScheduleCreatureRespawn(ObjectGuid /*creatureGuid*/, Milliseconds /*respawnTimer*/, Position pos = Position());
@@ -435,20 +438,27 @@ public:
void DeleteCorpseData();
void AddCorpse(Corpse* corpse);
void RemoveCorpse(Corpse* corpse);
- Corpse* ConvertCorpseToBones(ObjectGuid const ownerGuid, bool insignia = false);
+ Corpse* ConvertCorpseToBones(ObjectGuid const& ownerGuid, bool insignia = false);
void RemoveOldCorpses();
static void DeleteRespawnTimesInDB(uint16 mapId, uint32 instanceId);
+ bool SendZoneMessage(uint32 zone, WorldPacket const* packet, WorldSession const* self = nullptr, TeamId teamId = TEAM_NEUTRAL) const;
+ void SendZoneText(uint32 zoneId, char const* text, WorldSession const* self = nullptr, TeamId teamId = TEAM_NEUTRAL) const;
+
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 SendInitSelf(Player* player);
+ void UpdateWeather(uint32 const diff);
void UpdateExpiredCorpses(uint32 const diff);
void PlayDirectSoundToMap(uint32 soundId, uint32 zoneId = 0);
void SetZoneMusic(uint32 zoneId, uint32 musicId);
+ Weather* GetOrGenerateZoneDefaultWeather(uint32 zoneId);
void SetZoneWeather(uint32 zoneId, WeatherState weatherId, float weatherGrade);
void SetZoneOverrideLight(uint32 zoneId, uint32 lightId, Milliseconds fadeInTime);
@@ -504,6 +514,14 @@ public:
void RemoveWorldObjectFromZoneWideVisibleMap(uint32 zoneId, WorldObject* obj);
ZoneWideVisibleWorldObjectsSet const* GetZoneWideVisibleWorldObjectsForZone(uint32 zoneId) const;
+ [[nodiscard]] uint32 GetPlayerCountInZone(uint32 zoneId) const
+ {
+ if (auto const& it = _zonePlayerCountMap.find(zoneId); it != _zonePlayerCountMap.end())
+ return it->second;
+
+ return 0;
+ };
+
private:
template<class T> void InitializeObject(T* obj);
@@ -584,6 +602,7 @@ private:
std::unordered_map<uint32, uint32> _zonePlayerCountMap;
ZoneDynamicInfoMap _zoneDynamicInfo;
+ IntervalTimer _weatherUpdateTimer;
uint32 _defaultLight;
IntervalTimer _corpseUpdateTimer;
diff --git a/src/server/game/Maps/MapInstanced.cpp b/src/server/game/Maps/MapInstanced.cpp
index 9d8172a733..cbe0a3a17e 100644
--- a/src/server/game/Maps/MapInstanced.cpp
+++ b/src/server/game/Maps/MapInstanced.cpp
@@ -1,14 +1,14 @@
/*
* This file is part of the AzerothCore 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 Affero General Public License as published by the
- * Free Software Foundation; either version 3 of the License, or (at your
- * option) any later version.
+ * 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 Affero General Public License for
+ * 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
diff --git a/src/server/game/Maps/MapInstanced.h b/src/server/game/Maps/MapInstanced.h
index e50057c9e5..75601434cd 100644
--- a/src/server/game/Maps/MapInstanced.h
+++ b/src/server/game/Maps/MapInstanced.h
@@ -1,14 +1,14 @@
/*
* This file is part of the AzerothCore 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 Affero General Public License as published by the
- * Free Software Foundation; either version 3 of the License, or (at your
- * option) any later version.
+ * 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 Affero General Public License for
+ * 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
diff --git a/src/server/game/Maps/MapMgr.cpp b/src/server/game/Maps/MapMgr.cpp
index e113c93d27..94044f7997 100644
--- a/src/server/game/Maps/MapMgr.cpp
+++ b/src/server/game/Maps/MapMgr.cpp
@@ -1,14 +1,14 @@
/*
* This file is part of the AzerothCore 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 Affero General Public License as published by the
- * Free Software Foundation; either version 3 of the License, or (at your
- * option) any later version.
+ * 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 Affero General Public License for
+ * 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
@@ -205,7 +205,7 @@ Map::EnterState MapMgr::PlayerCannotEnter(uint32 mapid, Player* player, bool log
if (!corpseMap)
{
WorldPacket data(SMSG_CORPSE_NOT_IN_INSTANCE, 0);
- player->GetSession()->SendPacket(&data);
+ player->SendDirectMessage(&data);
LOG_DEBUG("maps", "MAP: Player '{}' does not have a corpse in instance '{}' and cannot enter.", player->GetName(), mapName);
return Map::CANNOT_ENTER_CORPSE_IN_DIFFERENT_INSTANCE;
}
diff --git a/src/server/game/Maps/MapMgr.h b/src/server/game/Maps/MapMgr.h
index 2872ddd7c8..c2336707e4 100644
--- a/src/server/game/Maps/MapMgr.h
+++ b/src/server/game/Maps/MapMgr.h
@@ -1,14 +1,14 @@
/*
* This file is part of the AzerothCore 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 Affero General Public License as published by the
- * Free Software Foundation; either version 3 of the License, or (at your
- * option) any later version.
+ * 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 Affero General Public License for
+ * 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
diff --git a/src/server/game/Maps/MapRefMgr.h b/src/server/game/Maps/MapRefMgr.h
index ddedb076d9..cb5f6486f1 100644
--- a/src/server/game/Maps/MapRefMgr.h
+++ b/src/server/game/Maps/MapRefMgr.h
@@ -1,14 +1,14 @@
/*
* This file is part of the AzerothCore 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 Affero General Public License as published by the
- * Free Software Foundation; either version 3 of the License, or (at your
- * option) any later version.
+ * 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 Affero General Public License for
+ * 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
diff --git a/src/server/game/Maps/MapReference.h b/src/server/game/Maps/MapReference.h
index 002771c76a..82c47a71ee 100644
--- a/src/server/game/Maps/MapReference.h
+++ b/src/server/game/Maps/MapReference.h
@@ -1,14 +1,14 @@
/*
* This file is part of the AzerothCore 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 Affero General Public License as published by the
- * Free Software Foundation; either version 3 of the License, or (at your
- * option) any later version.
+ * 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 Affero General Public License for
+ * 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
diff --git a/src/server/game/Maps/MapUpdater.cpp b/src/server/game/Maps/MapUpdater.cpp
index ea5fe96025..d2ad9e6708 100644
--- a/src/server/game/Maps/MapUpdater.cpp
+++ b/src/server/game/Maps/MapUpdater.cpp
@@ -1,14 +1,14 @@
/*
* This file is part of the AzerothCore 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 Affero General Public License as published by the
- * Free Software Foundation; either version 3 of the License, or (at your
- * option) any later version.
+ * 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 Affero General Public License for
+ * 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
diff --git a/src/server/game/Maps/MapUpdater.h b/src/server/game/Maps/MapUpdater.h
index 9576e7e1f0..a2e9aaae45 100644
--- a/src/server/game/Maps/MapUpdater.h
+++ b/src/server/game/Maps/MapUpdater.h
@@ -1,14 +1,14 @@
/*
* This file is part of the AzerothCore 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 Affero General Public License as published by the
- * Free Software Foundation; either version 3 of the License, or (at your
- * option) any later version.
+ * 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 Affero General Public License for
+ * 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
diff --git a/src/server/game/Maps/TransportMgr.cpp b/src/server/game/Maps/TransportMgr.cpp
index f065ccf56a..00afdf2b64 100644
--- a/src/server/game/Maps/TransportMgr.cpp
+++ b/src/server/game/Maps/TransportMgr.cpp
@@ -1,14 +1,14 @@
/*
* This file is part of the AzerothCore 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 Affero General Public License as published by the
- * Free Software Foundation; either version 3 of the License, or (at your
- * option) any later version.
+ * 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 Affero General Public License for
+ * 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
@@ -448,31 +448,45 @@ void TransportMgr::SpawnContinentTransports()
LOG_INFO("server.loading", ">> Spawned {} continent motion transports in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
}
+ // Preloads Deeprun Tram to fix issues with Subway carts syncronization
+ /// @todo: This is a temporary workaround. Consider removing TransportMgr::PreloadGridsFromQuery() as part of fix.
+ /**
+ Takenbacon: "In the long run the most likely ideal fix would be to always spawn all transport types (and thus loading their grid) on map creation"
+ See https://github.com/azerothcore/azerothcore-wotlk/pull/23009 for more details.
+ */
+ PreloadGridsFromQuery("SELECT map, position_x, position_y FROM gameobject g JOIN gameobject_template t ON g.id = t.entry WHERE t.type = 11 AND g.map = 369", count);
+
if (sWorld->getBoolConfig(CONFIG_ENABLE_CONTINENT_TRANSPORT_PRELOADING))
{
// pussywizard: preload grids for continent static transports
- QueryResult result2 = WorldDatabase.Query("SELECT map, position_x, position_y FROM gameobject g JOIN gameobject_template t ON g.id = t.entry WHERE t.type = 11");
+ PreloadGridsFromQuery("SELECT map, position_x, position_y FROM gameobject g JOIN gameobject_template t ON g.id = t.entry WHERE t.type = 11 AND g.map != 369", count);
+ LOG_INFO("server.loading", ">> Preloaded grids for {} continent static transports in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
+ }
+}
- if (result2)
+void TransportMgr::PreloadGridsFromQuery(std::string const& query, uint32& count)
+{
+ if (QueryResult result = WorldDatabase.Query(query))
+ {
+ do
{
- do
- {
- Field* fields = result2->Fetch();
- uint16 mapId = fields[0].Get<uint16>();
- float x = fields[1].Get<float>();
- float y = fields[2].Get<float>();
+ Field* fields = result->Fetch();
+ uint16 mapId = fields[0].Get<uint16>();
+ float x = fields[1].Get<float>();
+ float y = fields[2].Get<float>();
- MapEntry const* mapEntry = sMapStore.LookupEntry(mapId);
- if (mapEntry && !mapEntry->Instanceable())
+ if (MapEntry const* mapEntry = sMapStore.LookupEntry(mapId))
+ {
+ if (!mapEntry->Instanceable())
+ {
if (Map* map = sMapMgr->CreateBaseMap(mapId))
{
map->LoadGrid(x, y);
++count;
}
- } while (result2->NextRow());
- }
-
- LOG_INFO("server.loading", ">> Preloaded grids for {} continent static transports in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
+ }
+ }
+ } while (result->NextRow());
}
}
diff --git a/src/server/game/Maps/TransportMgr.h b/src/server/game/Maps/TransportMgr.h
index 9767ab3359..73a5655fb0 100644
--- a/src/server/game/Maps/TransportMgr.h
+++ b/src/server/game/Maps/TransportMgr.h
@@ -1,14 +1,14 @@
/*
* This file is part of the AzerothCore 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 Affero General Public License as published by the
- * Free Software Foundation; either version 3 of the License, or (at your
- * option) any later version.
+ * 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 Affero General Public License for
+ * 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
@@ -158,6 +158,8 @@ private:
TransportInstanceMap _instanceTransports;
TransportAnimationContainer _transportAnimations;
+
+ void PreloadGridsFromQuery(std::string const& query, uint32& count);
};
#define sTransportMgr TransportMgr::instance()
diff --git a/src/server/game/Maps/ZoneScript.h b/src/server/game/Maps/ZoneScript.h
index c257115da0..3dd66ce290 100644
--- a/src/server/game/Maps/ZoneScript.h
+++ b/src/server/game/Maps/ZoneScript.h
@@ -1,14 +1,14 @@
/*
* This file is part of the AzerothCore 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 Affero General Public License as published by the
- * Free Software Foundation; either version 3 of the License, or (at your
- * option) any later version.
+ * 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 Affero General Public License for
+ * 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