mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2026-01-14 17:49:10 +00:00
fix(Core/Movement): (#7008)
- Get zone/area IDs from vmap data in the liquid update - Add new method Map::getFullVMapDataForPosition to get area info and liquid info in a single vmap lookup - Adjust GetZoneId/GetAreaId on WorldObject to always return these cached fields. - Clean up liquid state handling on Unit and Player - Implemented getting area id from gameobject spawns. - Removed old core related to getting movement flags dependent on environment. - Movement flags are now processed more precisely and dynamically. Original source: TrinityCore. - Closes #5086 - Updates #2208.
This commit is contained in:
@@ -950,8 +950,8 @@ WorldObject::WorldObject(bool isWorldObject) : WorldLocation(),
|
||||
elunaEvents(nullptr),
|
||||
#endif
|
||||
LastUsedScriptID(0), m_name(""), m_isActive(false), m_isVisibilityDistanceOverride(false), m_isWorldObject(isWorldObject), m_zoneScript(nullptr),
|
||||
m_staticFloorZ(INVALID_HEIGHT), m_transport(nullptr), m_currMap(nullptr), m_InstanceId(0),
|
||||
m_phaseMask(PHASEMASK_NORMAL), m_useCombinedPhases(true), m_notifyflags(0), m_executed_notifies(0)
|
||||
_zoneId(0), _areaId(0), _floorZ(INVALID_HEIGHT), _outdoors(false), _liquidData(), _updatePositionData(false), m_transport(nullptr),
|
||||
m_currMap(nullptr), m_InstanceId(0), m_phaseMask(PHASEMASK_NORMAL), m_useCombinedPhases(true), m_notifyflags(0), m_executed_notifies(0)
|
||||
{
|
||||
m_serverSideVisibility.SetValue(SERVERSIDE_VISIBILITY_GHOST, GHOST_VISIBILITY_ALIVE | GHOST_VISIBILITY_GHOST);
|
||||
m_serverSideVisibilityDetect.SetValue(SERVERSIDE_VISIBILITY_GHOST, GHOST_VISIBILITY_ALIVE);
|
||||
@@ -1040,19 +1040,51 @@ void WorldObject::_Create(ObjectGuid::LowType guidlow, HighGuid guidhigh, uint32
|
||||
SetPhaseMask(phaseMask, false);
|
||||
}
|
||||
|
||||
uint32 WorldObject::GetZoneId(bool /*forceRecalc*/) const
|
||||
void WorldObject::SetPositionDataUpdate()
|
||||
{
|
||||
return GetBaseMap()->GetZoneId(m_positionX, m_positionY, m_positionZ);
|
||||
_updatePositionData = true;
|
||||
|
||||
// Calls immediately for charmed units
|
||||
if (GetTypeId() == TYPEID_UNIT && ToUnit()->IsCharmedOwnedByPlayerOrPlayer())
|
||||
UpdatePositionData();
|
||||
}
|
||||
|
||||
uint32 WorldObject::GetAreaId(bool /*forceRecalc*/) const
|
||||
void WorldObject::UpdatePositionData()
|
||||
{
|
||||
return GetBaseMap()->GetAreaId(m_positionX, m_positionY, m_positionZ);
|
||||
_updatePositionData = false;
|
||||
|
||||
PositionFullTerrainStatus data;
|
||||
GetMap()->GetFullTerrainStatusForPosition(GetPhaseMask(), GetPositionX(), GetPositionY(), GetPositionZ(), GetCollisionHeight(), data);
|
||||
ProcessPositionDataChanged(data);
|
||||
}
|
||||
|
||||
void WorldObject::GetZoneAndAreaId(uint32& zoneid, uint32& areaid, bool /*forceRecalc*/) const
|
||||
void WorldObject::ProcessPositionDataChanged(PositionFullTerrainStatus const& data)
|
||||
{
|
||||
GetBaseMap()->GetZoneAndAreaId(zoneid, areaid, m_positionX, m_positionY, m_positionZ);
|
||||
_zoneId = _areaId = data.areaId;
|
||||
|
||||
if (AreaTableEntry const* area = sAreaTableStore.LookupEntry(_areaId))
|
||||
if (area->zone)
|
||||
_zoneId = area->zone;
|
||||
|
||||
_outdoors = data.outdoors;
|
||||
_floorZ = data.floorZ;
|
||||
_liquidData = data.liquidInfo;
|
||||
}
|
||||
|
||||
void WorldObject::AddToWorld()
|
||||
{
|
||||
Object::AddToWorld();
|
||||
GetMap()->GetZoneAndAreaId(GetPhaseMask(), _zoneId, _areaId, GetPositionX(), GetPositionY(), GetPositionZ());
|
||||
}
|
||||
|
||||
void WorldObject::RemoveFromWorld()
|
||||
{
|
||||
if (!IsInWorld())
|
||||
return;
|
||||
|
||||
DestroyForNearbyPlayers();
|
||||
|
||||
Object::RemoveFromWorld();
|
||||
}
|
||||
|
||||
InstanceScript* WorldObject::GetInstanceScript()
|
||||
@@ -1470,7 +1502,7 @@ void WorldObject::UpdateAllowedPositionZ(float x, float y, float& z, float* grou
|
||||
|
||||
if (max_z > INVALID_HEIGHT)
|
||||
{
|
||||
if (canSwim && unit->GetMap()->IsInWater(x, y, max_z - Z_OFFSET_FIND_HEIGHT))
|
||||
if (canSwim && unit->GetMap()->IsInWater(unit->GetPhaseMask(), x, y, max_z - Z_OFFSET_FIND_HEIGHT, unit->GetCollisionHeight()))
|
||||
{
|
||||
// do not allow creatures to walk on
|
||||
// water level while swimming
|
||||
@@ -2137,12 +2169,6 @@ void WorldObject::ResetMap()
|
||||
//m_InstanceId = 0;
|
||||
}
|
||||
|
||||
Map const* WorldObject::GetBaseMap() const
|
||||
{
|
||||
ASSERT(m_currMap);
|
||||
return m_currMap->GetParent();
|
||||
}
|
||||
|
||||
void WorldObject::AddObjectToRemoveList()
|
||||
{
|
||||
ASSERT(m_uint32Values);
|
||||
@@ -2307,7 +2333,7 @@ void WorldObject::SetZoneScript()
|
||||
m_zoneScript = (ZoneScript*)map->ToInstanceMap()->GetInstanceScript();
|
||||
else if (!map->IsBattlegroundOrArena())
|
||||
{
|
||||
uint32 zoneId = GetZoneId(true);
|
||||
uint32 zoneId = GetZoneId();
|
||||
if (Battlefield* bf = sBattlefieldMgr->GetBattlefieldToZoneId(zoneId))
|
||||
m_zoneScript = bf;
|
||||
else
|
||||
@@ -3031,10 +3057,54 @@ float WorldObject::GetMapWaterOrGroundLevel(float x, float y, float z, float* gr
|
||||
|
||||
float WorldObject::GetFloorZ() const
|
||||
{
|
||||
if (!IsInWorld())
|
||||
return m_staticFloorZ;
|
||||
if (_updatePositionData)
|
||||
const_cast<WorldObject*>(this)->UpdatePositionData();
|
||||
|
||||
return std::max<float>(m_staticFloorZ, GetMap()->GetGameObjectFloor(GetPhaseMask(), GetPositionX(), GetPositionY(), GetPositionZ() + std::max(GetCollisionHeight(), Z_OFFSET_FIND_HEIGHT)));
|
||||
if (!IsInWorld())
|
||||
return _floorZ;
|
||||
|
||||
return std::max<float>(_floorZ, GetMap()->GetGameObjectFloor(GetPhaseMask(), GetPositionX(), GetPositionY(), GetPositionZ() + std::max(GetCollisionHeight(), Z_OFFSET_FIND_HEIGHT)));
|
||||
}
|
||||
|
||||
uint32 WorldObject::GetZoneId() const
|
||||
{
|
||||
if (_updatePositionData)
|
||||
const_cast<WorldObject*>(this)->UpdatePositionData();
|
||||
|
||||
return _zoneId;
|
||||
}
|
||||
|
||||
uint32 WorldObject::GetAreaId() const
|
||||
{
|
||||
if (_updatePositionData)
|
||||
const_cast<WorldObject*>(this)->UpdatePositionData();
|
||||
|
||||
return _areaId;
|
||||
}
|
||||
|
||||
void WorldObject::GetZoneAndAreaId(uint32& zoneid, uint32& areaid) const
|
||||
{
|
||||
if (_updatePositionData)
|
||||
const_cast<WorldObject*>(this)->UpdatePositionData();
|
||||
|
||||
zoneid = _zoneId;
|
||||
areaid = _areaId;
|
||||
}
|
||||
|
||||
bool WorldObject::IsOutdoors() const
|
||||
{
|
||||
if (_updatePositionData)
|
||||
const_cast<WorldObject*>(this)->UpdatePositionData();
|
||||
|
||||
return _outdoors;
|
||||
}
|
||||
|
||||
LiquidData const& WorldObject::GetLiquidData() const
|
||||
{
|
||||
if (_updatePositionData)
|
||||
const_cast<WorldObject*>(this)->UpdatePositionData();
|
||||
|
||||
return _liquidData;
|
||||
}
|
||||
|
||||
void WorldObject::AddAllowedLooter(ObjectGuid guid)
|
||||
|
||||
Reference in New Issue
Block a user