Core/Movement: Formation Rewrite

Port From (https://github.com/TrinityCore/TrinityCore/commit/924116f0461f5e1e03a026129b81dfe23faa20e4)
This commit is contained in:
hondacrx
2022-02-17 16:18:54 -05:00
parent d9b9739999
commit 266284247c
8 changed files with 168 additions and 123 deletions
+2 -2
View File
@@ -130,7 +130,7 @@ namespace Game.Entities
return m_formation.IsLeader(this);
}
public void SignalFormationMovement(Position destination, uint id = 0, WaypointMoveType moveType = 0, bool orientation = false)
public void SignalFormationMovement()
{
if (m_formation == null)
return;
@@ -138,7 +138,7 @@ namespace Game.Entities
if (!m_formation.IsLeader(this))
return;
m_formation.LeaderMoveTo(destination, id, moveType, orientation);
m_formation.LeaderStartedMoving();
}
public bool IsFormationLeaderMoveAllowed()
@@ -274,51 +274,23 @@ namespace Game.Entities
_formed = !dismiss;
}
public void LeaderMoveTo(Position destination, uint id = 0, WaypointMoveType moveType = 0, bool orientation = false)
public void LeaderStartedMoving()
{
//! To do: This should probably get its own movement generator or use WaypointMovementGenerator.
//! If the leader's path is known, member's path can be plotted as well using formation offsets.
if (_leader == null)
return;
Position pos = new(destination);
float pathangle = (float)Math.Atan2(_leader.GetPositionY() - pos.GetPositionY(), _leader.GetPositionX() - pos.GetPositionX());
foreach (var pair in _members)
{
Creature member = pair.Key;
if (member == _leader || !member.IsAlive() || member.IsEngaged() || !pair.Value.GroupAI.HasAnyFlag((uint)GroupAIFlags.IdleInFormation))
continue;
if (pair.Value.LeaderWaypointIDs[0] != 0)
{
for (var i = 0; i < 2; ++i)
{
if (_leader.GetCurrentWaypointInfo().nodeId == pair.Value.LeaderWaypointIDs[i])
{
pair.Value.FollowAngle = MathF.PI * 2f - pair.Value.FollowAngle;
break;
}
}
}
float angle = pair.Value.FollowAngle;
float angle = pair.Value.FollowAngle + MathF.PI; // for some reason, someone thought it was a great idea to invert relativ angles...
float dist = pair.Value.FollowDist;
float dx = pos.GetPositionX() + MathF.Cos(angle + pathangle) * dist;
float dy = pos.GetPositionY() + MathF.Sin(angle + pathangle) * dist;
float dz = pos.GetPositionZ();
GridDefines.NormalizeMapCoord(ref dx);
GridDefines.NormalizeMapCoord(ref dy);
if (!member.IsFlying())
member.UpdateGroundPositionZ(dx, dy, ref dz);
member.SetHomePosition(dx, dy, dz, pathangle);
Position point = new(dx, dy, dz, destination.GetOrientation());
member.GetMotionMaster().MoveFormation(id, point, moveType, !member.IsWithinDist(_leader, dist + 5.0f), orientation);
var moveGen = member.GetMotionMaster().GetMovementGenerator(movement => { return movement.GetMovementGeneratorType() == MovementGeneratorType.Formation; }, MovementSlot.Default);
if (moveGen == null)
member.GetMotionMaster().MoveFormation(_leader, dist, angle, pair.Value.LeaderWaypointIDs[0], pair.Value.LeaderWaypointIDs[1]);
}
}