Core/Movement: Fixed creature hover
Port From (https://github.com/TrinityCore/TrinityCore/commit/2e2b29861878fda2d27156c71a1d8ed7dbe0b4fe)
This commit is contained in:
@@ -201,6 +201,7 @@ namespace Game.Entities
|
|||||||
transport.CalculatePassengerPosition(ref x, ref y, ref z, ref o);
|
transport.CalculatePassengerPosition(ref x, ref y, ref z, ref o);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UpdateAllowedPositionZ(x, y, ref z);
|
||||||
SetHomePosition(x, y, z, o);
|
SetHomePosition(x, y, z, o);
|
||||||
GetMap().CreatureRelocation(this, x, y, z, o);
|
GetMap().CreatureRelocation(this, x, y, z, o);
|
||||||
}
|
}
|
||||||
@@ -897,11 +898,7 @@ namespace Game.Entities
|
|||||||
LoadCreaturesAddon();
|
LoadCreaturesAddon();
|
||||||
|
|
||||||
//! Need to be called after LoadCreaturesAddon - MOVEMENTFLAG_HOVER is set there
|
//! Need to be called after LoadCreaturesAddon - MOVEMENTFLAG_HOVER is set there
|
||||||
if (HasUnitMovementFlag(MovementFlag.Hover))
|
posZ += GetHoverOffset();
|
||||||
{
|
|
||||||
//! Relocate again with updated Z coord
|
|
||||||
posZ += m_unitData.HoverHeight;
|
|
||||||
}
|
|
||||||
|
|
||||||
LastUsedScriptID = GetScriptId();
|
LastUsedScriptID = GetScriptId();
|
||||||
|
|
||||||
@@ -2825,7 +2822,7 @@ namespace Game.Entities
|
|||||||
// Set the movement flags if the creature is in that mode. (Only fly if actually in air, only swim if in water, etc)
|
// Set the movement flags if the creature is in that mode. (Only fly if actually in air, only swim if in water, etc)
|
||||||
float ground = GetFloorZ();
|
float ground = GetFloorZ();
|
||||||
|
|
||||||
bool isInAir = (MathFunctions.fuzzyGt(GetPositionZMinusOffset(), ground + MapConst.GroundHeightTolerance) || MathFunctions.fuzzyLt(GetPositionZMinusOffset(), ground - MapConst.GroundHeightTolerance)); // Can be underground too, prevent the falling
|
bool isInAir = (MathFunctions.fuzzyGt(GetPositionZ(), ground + MapConst.GroundHeightTolerance) || MathFunctions.fuzzyLt(GetPositionZ(), ground - MapConst.GroundHeightTolerance)); // Can be underground too, prevent the falling
|
||||||
|
|
||||||
if (GetCreatureTemplate().InhabitType.HasAnyFlag(InhabitType.Air) && isInAir && !IsFalling())
|
if (GetCreatureTemplate().InhabitType.HasAnyFlag(InhabitType.Air) && isInAir && !IsFalling())
|
||||||
{
|
{
|
||||||
@@ -3138,7 +3135,7 @@ namespace Game.Entities
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
//We should set first home position, because then AI calls home movement
|
//We should set first home position, because then AI calls home movement
|
||||||
SetHomePosition(data.spawnPoint);
|
SetHomePosition(this);
|
||||||
|
|
||||||
m_deathState = DeathState.Alive;
|
m_deathState = DeathState.Alive;
|
||||||
|
|
||||||
|
|||||||
@@ -2095,7 +2095,9 @@ namespace Game.Entities
|
|||||||
|
|
||||||
public void UpdateGroundPositionZ(float x, float y, ref float z)
|
public void UpdateGroundPositionZ(float x, float y, ref float z)
|
||||||
{
|
{
|
||||||
z = GetMapHeight(x, y, z);
|
float newZ = GetMapHeight(x, y, z);
|
||||||
|
if (newZ > MapConst.InvalidHeight)
|
||||||
|
z = newZ + (IsUnit() ? ToUnit().GetHoverOffset() : 0.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UpdateAllowedPositionZ(float x, float y, ref float z)
|
public void UpdateAllowedPositionZ(float x, float y, ref float z)
|
||||||
@@ -2104,65 +2106,44 @@ namespace Game.Entities
|
|||||||
if (GetTransport())
|
if (GetTransport())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
switch (GetTypeId())
|
Unit unit = ToUnit();
|
||||||
|
if (unit != null)
|
||||||
{
|
{
|
||||||
case TypeId.Unit:
|
if (!unit.CanFly())
|
||||||
{
|
{
|
||||||
// non fly unit don't must be in air
|
bool canSwim = unit.CanSwim();
|
||||||
// non swim unit must be at ground (mostly speedup, because it don't must be in water and water level check less fast
|
float groundZ = z;
|
||||||
if (!ToCreature().CanFly())
|
float max_z;
|
||||||
{
|
if (canSwim)
|
||||||
bool canSwim = ToCreature().CanSwim();
|
max_z = GetMapWaterOrGroundLevel(x, y, z, ref groundZ);
|
||||||
float ground_z = z;
|
else
|
||||||
float max_z = canSwim
|
max_z = groundZ = GetMapHeight(x, y, z);
|
||||||
? GetMapWaterOrGroundLevel(x, y, z, ref ground_z)
|
|
||||||
: (ground_z = GetMapHeight(x, y, z));
|
|
||||||
if (max_z > MapConst.InvalidHeight)
|
if (max_z > MapConst.InvalidHeight)
|
||||||
{
|
{
|
||||||
|
// hovering units cannot go below their hover height
|
||||||
|
float hoverOffset = unit.GetHoverOffset();
|
||||||
|
max_z += hoverOffset;
|
||||||
|
groundZ += hoverOffset;
|
||||||
|
|
||||||
if (z > max_z)
|
if (z > max_z)
|
||||||
z = max_z;
|
z = max_z;
|
||||||
else if (z < ground_z)
|
else if (z < groundZ)
|
||||||
z = ground_z;
|
z = groundZ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
float ground_z = GetMapHeight(x, y, z);
|
float ground_z = GetMapHeight(x, y, z) + unit.GetHoverOffset();
|
||||||
if (MathF.Abs(z - ground_z) < GetCollisionHeight())
|
if (z < ground_z)
|
||||||
z = ground_z;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case TypeId.Player:
|
|
||||||
{
|
|
||||||
// for server controlled moves playr work same as creature (but it can always swim)
|
|
||||||
if (!ToPlayer().CanFly())
|
|
||||||
{
|
|
||||||
float ground_z = z;
|
|
||||||
float max_z = GetMapWaterOrGroundLevel(x, y, z, ref ground_z);
|
|
||||||
if (max_z > MapConst.InvalidHeight)
|
|
||||||
{
|
|
||||||
if (z > max_z)
|
|
||||||
z = max_z;
|
|
||||||
else if (z < ground_z)
|
|
||||||
z = ground_z;
|
z = ground_z;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
|
||||||
float ground_z = GetMapHeight(x, y, z);
|
|
||||||
if (MathF.Abs(z - ground_z) < GetCollisionHeight())
|
|
||||||
z = ground_z;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
{
|
{
|
||||||
float ground_z = GetMapHeight(x, y, z);
|
float ground_z = GetMapHeight(x, y, z);
|
||||||
if (ground_z > MapConst.InvalidHeight)
|
if (ground_z > MapConst.InvalidHeight)
|
||||||
z = ground_z;
|
z = ground_z;
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1531,7 +1531,7 @@ namespace Game.Entities
|
|||||||
|
|
||||||
float dx = GetPositionX() - obj.GetPositionX();
|
float dx = GetPositionX() - obj.GetPositionX();
|
||||||
float dy = GetPositionY() - obj.GetPositionY();
|
float dy = GetPositionY() - obj.GetPositionY();
|
||||||
float dz = GetPositionZMinusOffset() - obj.GetPositionZMinusOffset();
|
float dz = GetPositionZ() - obj.GetPositionZ();
|
||||||
float distsq = (dx * dx) + (dy * dy) + (dz * dz);
|
float distsq = (dx * dx) + (dy * dy) + (dz * dz);
|
||||||
|
|
||||||
float maxdist = GetMeleeRange(obj) + GetTotalAuraModifier(AuraType.ModAutoAttackRange);
|
float maxdist = GetMeleeRange(obj) + GetTotalAuraModifier(AuraType.ModAutoAttackRange);
|
||||||
|
|||||||
@@ -198,7 +198,7 @@ namespace Game.Entities
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
MoveSplineInit init = new(this);
|
MoveSplineInit init = new(this);
|
||||||
init.MoveTo(GetPositionX(), GetPositionY(), GetPositionZMinusOffset(), false);
|
init.MoveTo(GetPositionX(), GetPositionY(), GetPositionZ(), false);
|
||||||
init.SetFacing(ori);
|
init.SetFacing(ori);
|
||||||
init.Launch();
|
init.Launch();
|
||||||
}
|
}
|
||||||
@@ -616,6 +616,11 @@ namespace Game.Entities
|
|||||||
GetVehicleKit().RelocatePassengers();
|
GetVehicleKit().RelocatePassengers();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public float GetHoverOffset()
|
||||||
|
{
|
||||||
|
return HasUnitMovementFlag(MovementFlag.Hover) ? m_unitData.HoverHeight : 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
public bool IsWithinBoundaryRadius(Unit obj)
|
public bool IsWithinBoundaryRadius(Unit obj)
|
||||||
{
|
{
|
||||||
if (!obj || !IsInMap(obj) || !IsInPhase(obj))
|
if (!obj || !IsInMap(obj) || !IsInPhase(obj))
|
||||||
@@ -1577,15 +1582,6 @@ namespace Game.Entities
|
|||||||
SendMessageToSet(data, true);
|
SendMessageToSet(data, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public float GetPositionZMinusOffset()
|
|
||||||
{
|
|
||||||
float offset = 0.0f;
|
|
||||||
if (HasUnitMovementFlag(MovementFlag.Hover))
|
|
||||||
offset = m_unitData.HoverHeight;
|
|
||||||
|
|
||||||
return GetPositionZ() - offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Unit GetUnitBeingMoved()
|
public Unit GetUnitBeingMoved()
|
||||||
{
|
{
|
||||||
Player player = ToPlayer();
|
Player player = ToPlayer();
|
||||||
|
|||||||
@@ -264,10 +264,7 @@ namespace Game
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
float z = loc.GetPositionZ();
|
float z = loc.GetPositionZ() + GetPlayer().GetHoverOffset();
|
||||||
if (GetPlayer().HasUnitMovementFlag(MovementFlag.Hover))
|
|
||||||
z += GetPlayer().m_unitData.HoverHeight;
|
|
||||||
|
|
||||||
GetPlayer().Relocate(loc.GetPositionX(), loc.GetPositionY(), z, loc.GetOrientation());
|
GetPlayer().Relocate(loc.GetPositionX(), loc.GetPositionY(), z, loc.GetOrientation());
|
||||||
GetPlayer().SetFallInformation(0, GetPlayer().GetPositionZ());
|
GetPlayer().SetFallInformation(0, GetPlayer().GetPositionZ());
|
||||||
|
|
||||||
|
|||||||
@@ -1016,12 +1016,6 @@ namespace Game.Maps
|
|||||||
var oldcell = player.GetCurrentCell();
|
var oldcell = player.GetCurrentCell();
|
||||||
var newcell = new Cell(x, y);
|
var newcell = new Cell(x, y);
|
||||||
|
|
||||||
//! If hovering, always increase our server-side Z position
|
|
||||||
//! Client automatically projects correct position based on Z coord sent in monster move
|
|
||||||
//! and HoverHeight sent in object updates
|
|
||||||
if (player.HasUnitMovementFlag(MovementFlag.Hover))
|
|
||||||
z += player.m_unitData.HoverHeight;
|
|
||||||
|
|
||||||
player.Relocate(x, y, z, orientation);
|
player.Relocate(x, y, z, orientation);
|
||||||
if (player.IsVehicle())
|
if (player.IsVehicle())
|
||||||
player.GetVehicleKit().RelocatePassengers();
|
player.GetVehicleKit().RelocatePassengers();
|
||||||
@@ -1052,12 +1046,6 @@ namespace Game.Maps
|
|||||||
if (!respawnRelocationOnFail && GetGrid(new_cell.GetGridX(), new_cell.GetGridY()) == null)
|
if (!respawnRelocationOnFail && GetGrid(new_cell.GetGridX(), new_cell.GetGridY()) == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
//! If hovering, always increase our server-side Z position
|
|
||||||
//! Client automatically projects correct position based on Z coord sent in monster move
|
|
||||||
//! and HoverHeight sent in object updates
|
|
||||||
if (creature.HasUnitMovementFlag(MovementFlag.Hover))
|
|
||||||
z += creature.m_unitData.HoverHeight;
|
|
||||||
|
|
||||||
Cell old_cell = creature.GetCurrentCell();
|
Cell old_cell = creature.GetCurrentCell();
|
||||||
// delay creature move for grid/cell to grid/cell moves
|
// delay creature move for grid/cell to grid/cell moves
|
||||||
if (old_cell.DiffCell(new_cell) || old_cell.DiffGrid(new_cell))
|
if (old_cell.DiffCell(new_cell) || old_cell.DiffGrid(new_cell))
|
||||||
|
|||||||
@@ -67,6 +67,7 @@ namespace Game.AI
|
|||||||
owner.GetHomePosition(out x, out y, out z, out o);
|
owner.GetHomePosition(out x, out y, out z, out o);
|
||||||
init.SetFacing(o);
|
init.SetFacing(o);
|
||||||
}
|
}
|
||||||
|
owner.UpdateAllowedPositionZ(x, y, ref z);
|
||||||
init.MoveTo(x, y, z);
|
init.MoveTo(x, y, z);
|
||||||
init.SetWalk(false);
|
init.SetWalk(false);
|
||||||
init.Launch();
|
init.Launch();
|
||||||
|
|||||||
@@ -141,30 +141,39 @@ namespace Game.Movement
|
|||||||
float x, y, z;
|
float x, y, z;
|
||||||
if (updateDestination || _path == null)
|
if (updateDestination || _path == null)
|
||||||
{
|
{
|
||||||
|
float size = owner.GetCombatReach();
|
||||||
|
float hoverDiff = owner.GetHoverOffset() - GetTarget().GetHoverOffset();
|
||||||
if (_offset == 0)
|
if (_offset == 0)
|
||||||
{
|
{
|
||||||
if (GetTarget().IsWithinDistInMap(owner, SharedConst.ContactDistance))
|
if (GetTarget().IsWithinDistInMap(owner, SharedConst.ContactDistance))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// to nearest contact position
|
// to nearest contact position
|
||||||
GetTarget().GetContactPoint(owner, out x, out y, out z);
|
if (hoverDiff != 0f)
|
||||||
|
size = size > hoverDiff ? MathF.Sqrt(size * size - hoverDiff * hoverDiff) : 0.0f;
|
||||||
|
|
||||||
|
GetTarget().GetNearPoint(owner, out x, out y, out z, size, SharedConst.ContactDistance, GetTarget().GetAngle(owner));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
float distance = _offset + 1.0f;
|
float distance = _offset + 1.0f;
|
||||||
float size = owner.GetCombatReach();
|
|
||||||
|
|
||||||
if (owner.IsPet() && GetTarget().GetTypeId() == TypeId.Player)
|
if (owner.IsPet() && GetTarget().GetTypeId() == TypeId.Player)
|
||||||
{
|
{
|
||||||
distance = 1.0f;
|
distance = 1.0f;
|
||||||
size = 1.0f;
|
size = 1.0f;
|
||||||
}
|
}
|
||||||
|
else if (hoverDiff != 0)
|
||||||
|
size = size > hoverDiff ? MathF.Sqrt(size * size - hoverDiff * hoverDiff) : 0.0f;
|
||||||
|
|
||||||
if (GetTarget().IsWithinDistInMap(owner, distance))
|
if (GetTarget().IsWithinDistInMap(owner, distance))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
GetTarget().GetClosePoint(out x, out y, out z, size, _offset, _angle);
|
GetTarget().GetClosePoint(out x, out y, out z, size, _offset, _angle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (owner.IsHovering())
|
||||||
|
owner.UpdateAllowedPositionZ(x, y, ref z);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -286,7 +286,7 @@ namespace Game.Movement
|
|||||||
{
|
{
|
||||||
// we are already close enough. We just need to turn toward the target without changing position.
|
// we are already close enough. We just need to turn toward the target without changing position.
|
||||||
MoveSplineInit init = new(_owner);
|
MoveSplineInit init = new(_owner);
|
||||||
init.MoveTo(_owner.GetPositionX(), _owner.GetPositionY(), _owner.GetPositionZMinusOffset());
|
init.MoveTo(_owner.GetPositionX(), _owner.GetPositionY(), _owner.GetPositionZ());
|
||||||
init.SetFacing(target);
|
init.SetFacing(target);
|
||||||
init.Launch();
|
init.Launch();
|
||||||
StartMovement(new EffectMovementGenerator(id), MovementSlot.Active);
|
StartMovement(new EffectMovementGenerator(id), MovementSlot.Active);
|
||||||
@@ -440,7 +440,7 @@ namespace Game.Movement
|
|||||||
if (_owner.IsFlying())
|
if (_owner.IsFlying())
|
||||||
point.Z = z;
|
point.Z = z;
|
||||||
else
|
else
|
||||||
point.Z = _owner.GetMapHeight(point.X, point.Y, z);
|
point.Z = _owner.GetMapHeight(point.X, point.Y, z) + _owner.GetHoverOffset();
|
||||||
|
|
||||||
init.args.path[i] = point;
|
init.args.path[i] = point;
|
||||||
}
|
}
|
||||||
@@ -536,7 +536,7 @@ namespace Game.Movement
|
|||||||
}
|
}
|
||||||
|
|
||||||
MoveSplineInit init = new(_owner);
|
MoveSplineInit init = new(_owner);
|
||||||
init.MoveTo(_owner.GetPositionX(), _owner.GetPositionY(), tz, false);
|
init.MoveTo(_owner.GetPositionX(), _owner.GetPositionY(), tz + _owner.GetHoverOffset(), false);
|
||||||
init.SetFall();
|
init.SetFall();
|
||||||
init.Launch();
|
init.Launch();
|
||||||
StartMovement(new EffectMovementGenerator(id), MovementSlot.Controlled);
|
StartMovement(new EffectMovementGenerator(id), MovementSlot.Controlled);
|
||||||
|
|||||||
Reference in New Issue
Block a user