Core/Movement: Fixed creature hover

Port From (https://github.com/TrinityCore/TrinityCore/commit/2e2b29861878fda2d27156c71a1d8ed7dbe0b4fe)
This commit is contained in:
hondacrx
2021-08-24 11:10:59 -04:00
parent 1c5bb258d5
commit 89058fec83
9 changed files with 59 additions and 90 deletions
+4 -7
View File
@@ -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;
+23 -42
View File
@@ -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;
}
} }
} }
+1 -1
View File
@@ -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);
+6 -10
View File
@@ -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();
+1 -4
View File
@@ -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());
-12
View File
@@ -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
{ {
+3 -3
View File
@@ -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);