mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2026-01-17 10:55:43 +00:00
@@ -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 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 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 distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
@@ -54,10 +54,6 @@ 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())
|
||||
@@ -451,7 +447,7 @@ void Map::Update(const uint32 t_diff, const uint32 s_diff, bool /*thread*/)
|
||||
}
|
||||
}
|
||||
|
||||
Events.Update(t_diff);
|
||||
_creatureRespawnScheduler.Update(t_diff);
|
||||
|
||||
if (!t_diff)
|
||||
{
|
||||
@@ -1101,7 +1097,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, {});
|
||||
LiquidData const& liquidData = const_cast<Map*>(this)->GetLiquidData(phasemask, x, y, ground_z, collisionHeight, MAP_ALL_LIQUIDS);
|
||||
switch (liquidData.Status)
|
||||
{
|
||||
case LIQUID_MAP_ABOVE_WATER:
|
||||
@@ -1202,18 +1198,27 @@ 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();
|
||||
VMAP::AreaAndLiquidData vdata;
|
||||
VMAP::AreaAndLiquidData ddata;
|
||||
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; };
|
||||
|
||||
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 && ddata.floorZ > vdata.floorZ)
|
||||
if (hasDynamicAreaInfo && dynamic_z > vmap_z)
|
||||
useDyn();
|
||||
else
|
||||
useVmap();
|
||||
@@ -1294,30 +1299,32 @@ 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, Optional<uint8> ReqLiquidType)
|
||||
LiquidData const Map::GetLiquidData(uint32 phaseMask, float x, float y, float z, float collisionHeight, uint8 ReqLiquidType)
|
||||
{
|
||||
LiquidData liquidData;
|
||||
liquidData.Status = LIQUID_MAP_NO_WATER;
|
||||
|
||||
VMAP::IVMapMgr* vmgr = VMAP::VMapFactory::createOrGetVMapMgr();
|
||||
VMAP::AreaAndLiquidData vmapData;
|
||||
float liquid_level = INVALID_HEIGHT;
|
||||
float ground_level = INVALID_HEIGHT;
|
||||
uint32 liquid_type = 0;
|
||||
uint32 mogpFlags = 0;
|
||||
bool useGridLiquid = true;
|
||||
if (vmgr->GetAreaAndLiquidData(GetId(), x, y, z, ReqLiquidType, vmapData) && vmapData.liquidInfo)
|
||||
if (vmgr->GetLiquidLevel(GetId(), x, y, z, ReqLiquidType, liquid_level, ground_level, liquid_type, mogpFlags))
|
||||
{
|
||||
useGridLiquid = !vmapData.areaInfo || !IsInWMOInterior(vmapData.areaInfo->mogpFlags);
|
||||
LOG_DEBUG("maps", "GetLiquidStatus(): vmap liquid level: {} ground: {} type: {}", vmapData.liquidInfo->level, vmapData.floorZ, vmapData.liquidInfo->type);
|
||||
useGridLiquid = !IsInWMOInterior(mogpFlags);
|
||||
LOG_DEBUG("maps", "GetLiquidStatus(): vmap liquid level: {} ground: {} type: {}", liquid_level, ground_level, liquid_type);
|
||||
// Check water level and ground level
|
||||
if (vmapData.liquidInfo->level > vmapData.floorZ && G3D::fuzzyGe(z, vmapData.floorZ - GROUND_HEIGHT_TOLERANCE))
|
||||
if (liquid_level > ground_level && G3D::fuzzyGe(z, ground_level - GROUND_HEIGHT_TOLERANCE))
|
||||
{
|
||||
// hardcoded in client like this
|
||||
if (GetId() == MAP_OUTLAND && vmapData.liquidInfo->type == 2)
|
||||
vmapData.liquidInfo->type = 15;
|
||||
if (GetId() == MAP_OUTLAND && liquid_type == 2)
|
||||
liquid_type = 15;
|
||||
|
||||
uint32 liquidFlagType = 0;
|
||||
if (LiquidTypeEntry const* liq = sLiquidTypeStore.LookupEntry(vmapData.liquidInfo->type))
|
||||
if (LiquidTypeEntry const* liq = sLiquidTypeStore.LookupEntry(liquid_type))
|
||||
liquidFlagType = liq->Type;
|
||||
|
||||
if (vmapData.liquidInfo->type && vmapData.liquidInfo->type < 21)
|
||||
if (liquid_type && liquid_type < 21)
|
||||
{
|
||||
if (AreaTableEntry const* area = sAreaTableStore.LookupEntry(GetAreaId(phaseMask, x, y, z)))
|
||||
{
|
||||
@@ -1331,19 +1338,19 @@ LiquidData const Map::GetLiquidData(uint32 phaseMask, float x, float y, float z,
|
||||
|
||||
if (LiquidTypeEntry const* liq = sLiquidTypeStore.LookupEntry(overrideLiquid))
|
||||
{
|
||||
vmapData.liquidInfo->type = overrideLiquid;
|
||||
liquid_type = overrideLiquid;
|
||||
liquidFlagType = liq->Type;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
liquidData.Level = vmapData.liquidInfo->level;
|
||||
liquidData.DepthLevel = vmapData.floorZ;
|
||||
liquidData.Entry = vmapData.liquidInfo->type;
|
||||
liquidData.Level = liquid_level;
|
||||
liquidData.DepthLevel = ground_level;
|
||||
liquidData.Entry = liquid_type;
|
||||
liquidData.Flags = 1 << liquidFlagType;
|
||||
}
|
||||
|
||||
float delta = vmapData.liquidInfo->level - z;
|
||||
float delta = liquid_level - z;
|
||||
|
||||
// Get position delta
|
||||
if (delta > collisionHeight)
|
||||
@@ -1362,7 +1369,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 > vmapData.floorZ))
|
||||
if (map_data.Status != LIQUID_MAP_NO_WATER && (map_data.Level > ground_level))
|
||||
{
|
||||
// hardcoded in client like this
|
||||
uint32 liquidEntry = map_data.Entry;
|
||||
@@ -1378,7 +1385,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, Optional<uint8> reqLiquidType)
|
||||
void Map::GetFullTerrainStatusForPosition(uint32 /*phaseMask*/, float x, float y, float z, float collisionHeight, PositionFullTerrainStatus& data, uint8 reqLiquidType)
|
||||
{
|
||||
GridTerrainData* gmap = GetGridTerrainData(x, y);
|
||||
|
||||
@@ -1593,7 +1600,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, {});
|
||||
LiquidData const& liquidData = const_cast<Map*>(this)->GetLiquidData(phaseMask, x, y, pZ, collisionHeight, MAP_ALL_LIQUIDS);
|
||||
return (liquidData.Status & MAP_LIQUID_STATUS_SWIMMING) != 0;
|
||||
}
|
||||
|
||||
@@ -2757,13 +2764,13 @@ void Map::RemoveOldCorpses()
|
||||
|
||||
void Map::ScheduleCreatureRespawn(ObjectGuid creatureGuid, Milliseconds respawnTimer, Position pos)
|
||||
{
|
||||
Events.AddEventAtOffset([this, creatureGuid, pos]()
|
||||
_creatureRespawnScheduler.Schedule(respawnTimer, [this, creatureGuid, pos](TaskContext)
|
||||
{
|
||||
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)
|
||||
|
||||
Reference in New Issue
Block a user