Core/Movement: FormationMovementGenerator

Port From (https://github.com/TrinityCore/TrinityCore/commit/84df2c57a385df4503fc1f8ff5dfdf445ea2e31f)
This commit is contained in:
hondacrx
2020-05-07 14:34:16 -04:00
parent c9a91fa62f
commit 415d6d84ba
7 changed files with 198 additions and 30 deletions
@@ -27,25 +27,26 @@ namespace Framework.Constants
public enum MovementGeneratorType
{
Idle = 0, // IdleMovement
Random = 1, // RandomMovement
Waypoint = 2, // WaypointMovement
Idle = 0, // IdleMovement
Random = 1, // RandomMovement
Waypoint = 2, // WaypointMovement
MaxDB = 3, // *** this and below motion types can't be set in DB.
Confused = 4, // ConfusedMovementGenerator
Chase = 5, // TargetedMovementGenerator
Home = 6, // HomeMovementGenerator
Flight = 7, // WaypointMovementGenerator
Point = 8, // PointMovementGenerator
Fleeing = 9, // FleeingMovementGenerator
Distract = 10, // IdleMovementGenerator
Assistance = 11, // PointMovementGenerator
AssistanceDistract = 12, // IdleMovementGenerator
TimedFleeing = 13, // FleeingMovementGenerator
MaxDB = 3, // *** this and below motion types can't be set in DB.
Confused = 4, // ConfusedMovementGenerator
Chase = 5, // TargetedMovementGenerator
Home = 6, // HomeMovementGenerator
Flight = 7, // WaypointMovementGenerator
Point = 8, // PointMovementGenerator
Fleeing = 9, // FleeingMovementGenerator
Distract = 10, // IdleMovementGenerator
Assistance = 11, // PointMovementGenerator
AssistanceDistract = 12, // IdleMovementGenerator
TimedFleeing = 13, // FleeingMovementGenerator
Follow = 14,
Rotate = 15,
Effect = 16,
SplineChain = 17,
SplineChain = 17, // SplineChainMovementGenerator
Formation = 18, // FormationMovementGenerator
Max
}
@@ -222,13 +222,16 @@ namespace Game.Entities
m_Formed = !dismiss;
}
public void LeaderMoveTo(float x, float y, float z)
public void LeaderMoveTo(Position destination, uint id = 0, uint moveType = 0, bool orientation = false)
{
//! 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 (!m_leader)
return;
float x = destination.GetPositionX();
float y = destination.GetPositionY();
float z = destination.GetPositionZ();
float pathangle = (float)Math.Atan2(m_leader.GetPositionY() - y, m_leader.GetPositionX() - x);
foreach (var pair in m_members)
@@ -254,12 +257,9 @@ namespace Game.Entities
if (!member.IsFlying())
member.UpdateGroundPositionZ(dx, dy, ref dz);
if (member.IsWithinDist(m_leader, dist + 5.0f))
member.SetUnitMovementFlags(m_leader.GetUnitMovementFlags());
else
member.SetWalk(false);
Position point = new Position(dx, dy, dz, destination.GetOrientation());
member.GetMotionMaster().MovePoint(0, dx, dy, dz);
member.GetMotionMaster().MoveFormation(id, point, moveType, !member.IsWithinDist(m_leader, dist + 5.0f), orientation);
member.SetHomePosition(dx, dy, dz, pathangle);
}
}
@@ -0,0 +1,160 @@
/*
* Copyright (C) 2012-2020 CypherCore <http://github.com/CypherCore>
*
* 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 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 more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using Framework.Constants;
using Game.Entities;
namespace Game.Movement
{
public class FormationMovementGenerator : MovementGeneratorMedium<Creature>
{
public FormationMovementGenerator(uint id, Position destination, uint moveType, bool run, bool orientation)
{
_movementId = id;
_destination = destination;
_moveType = moveType;
_run = run;
_orientation = orientation;
}
public override void DoInitialize(Creature owner)
{
owner.AddUnitState(UnitState.Roaming);
if (owner.HasUnitState(UnitState.NotMove) || owner.IsMovementPreventedByCasting())
{
_interrupt = true;
owner.StopMoving();
return;
}
owner.AddUnitState(UnitState.RoamingMove);
MoveSplineInit init = new MoveSplineInit(owner);
init.MoveTo(_destination.GetPositionX(), _destination.GetPositionY(), _destination.GetPositionZ());
if (_orientation)
init.SetFacing(_destination.GetOrientation());
switch (_moveType)
{
case 2: // WAYPOINT_MOVE_TYPE_LAND
init.SetAnimation(AnimType.ToGround);
break;
case 3: // WAYPOINT_MOVE_TYPE_TAKEOFF
init.SetAnimation(AnimType.ToFly);
break;
case 1: // WAYPOINT_MOVE_TYPE_RUN
init.SetWalk(false);
break;
case 0: // WAYPOINT_MOVE_TYPE_WALK
init.SetWalk(true);
break;
}
if (_run)
init.SetWalk(false);
init.Launch();
}
public override void DoReset(Creature owner)
{
owner.StopMoving();
DoInitialize(owner);
}
public override bool DoUpdate(Creature owner, uint diff)
{
if (!owner)
return false;
if (owner.HasUnitState(UnitState.NotMove) || owner.IsMovementPreventedByCasting())
{
_interrupt = true;
owner.StopMoving();
return true;
}
if ((_interrupt && owner.MoveSpline.Finalized()) || (_recalculateSpeed && !owner.MoveSpline.Finalized()))
{
_recalculateSpeed = false;
_interrupt = false;
owner.AddUnitState(UnitState.RoamingMove);
MoveSplineInit init = new MoveSplineInit(owner);
init.MoveTo(_destination.GetPositionX(), _destination.GetPositionY(), _destination.GetPositionZ());
if (_orientation)
init.SetFacing(_destination.GetOrientation());
switch (_moveType)
{
case 2: // WAYPOINT_MOVE_TYPE_LAND
init.SetAnimation(AnimType.ToGround);
break;
case 3: // WAYPOINT_MOVE_TYPE_TAKEOFF
init.SetAnimation(AnimType.ToFly);
break;
case 1: // WAYPOINT_MOVE_TYPE_RUN
init.SetWalk(false);
break;
case 0: // WAYPOINT_MOVE_TYPE_WALK
init.SetWalk(true);
break;
}
if (_run)
init.SetWalk(false);
init.Launch();
}
return !owner.MoveSpline.Finalized();
}
public override void DoFinalize(Creature owner)
{
owner.ClearUnitState(UnitState.Roaming | UnitState.RoamingMove);
if (owner.MoveSpline.Finalized())
MovementInform(owner);
}
public override void UnitSpeedChanged()
{
_recalculateSpeed = true;
}
public override MovementGeneratorType GetMovementGeneratorType()
{
return MovementGeneratorType.Formation;
}
void MovementInform(Creature owner)
{
if (owner.GetAI() != null)
owner.GetAI().MovementInform(MovementGeneratorType.Formation, _movementId);
}
uint _movementId;
Position _destination;
uint _moveType;
bool _run;
bool _orientation;
bool _recalculateSpeed;
bool _interrupt;
}
}
@@ -69,7 +69,7 @@ namespace Game.Movement
Creature creature = owner.ToCreature();
if (creature != null)
if (creature.GetFormation() != null && creature.GetFormation().GetLeader() == creature)
creature.GetFormation().LeaderMoveTo(_destination.GetPositionX(), _destination.GetPositionY(), _destination.GetPositionZ());
creature.GetFormation().LeaderMoveTo(_destination, _movementId);
}
public override void DoReset(T owner)
@@ -110,7 +110,7 @@ namespace Game.Movement
Creature creature = owner.ToCreature();
if (creature != null)
if (creature.GetFormation() != null && creature.GetFormation().GetLeader() == creature)
creature.GetFormation().LeaderMoveTo(_destination.GetPositionX(), _destination.GetPositionY(), _destination.GetPositionZ());
creature.GetFormation().LeaderMoveTo(_destination, _movementId);
}
return !owner.MoveSpline.Finalized();
@@ -118,7 +118,7 @@ namespace Game.Movement
// Call for creature group update
if (owner.GetFormation() != null && owner.GetFormation().GetLeader() == owner)
owner.GetFormation().LeaderMoveTo(position.GetPositionX(), position.GetPositionY(), position.GetPositionZ());
owner.GetFormation().LeaderMoveTo(position);
}
public override MovementGeneratorType GetMovementGeneratorType()
@@ -187,7 +187,7 @@ namespace Game.Movement
creature.AddUnitState(UnitState.RoamingMove);
Position formationDest = new Position(node.x, node.y, node.z, 0.0f);
Position formationDest = new Position(node.x, node.y, node.z, (node.orientation != 0 && node.delay != 0) ? node.orientation : 0.0f);
MoveSplineInit init = new MoveSplineInit(creature);
//! If creature is on transport, we assume waypoints set in DB are already transport offsets
@@ -196,7 +196,11 @@ namespace Game.Movement
init.DisableTransportPathTransformations();
ITransport trans = creature.GetDirectTransport();
if (trans != null)
trans.CalculatePassengerPosition(ref formationDest.posX, ref formationDest.posY, ref formationDest.posZ, ref formationDest.Orientation);
{
float orientation = formationDest.GetOrientation();
trans.CalculatePassengerPosition(ref formationDest.posX, ref formationDest.posY, ref formationDest.posZ, ref orientation);
formationDest.SetOrientation(orientation);
}
}
//! Do not use formationDest here, MoveTo requires transport offsets due to DisableTransportPathTransformations() call
@@ -227,10 +231,7 @@ namespace Game.Movement
//Call for creature group update
if (creature.GetFormation() != null && creature.GetFormation().GetLeader() == creature)
{
creature.SetWalk(node.moveType != WaypointMoveType.Run);
creature.GetFormation().LeaderMoveTo(formationDest.posX, formationDest.posY, formationDest.posZ);
}
creature.GetFormation().LeaderMoveTo(formationDest, node.id, (uint)node.moveType, (node.orientation != 0 && node.delay != 0) ? true : false);
return true;
}
+6
View File
@@ -607,6 +607,12 @@ namespace Game.Movement
StartMovement(new RotateMovementGenerator(time, direction), MovementSlot.Active);
}
public void MoveFormation(uint id, Position destination, uint moveType, bool forceRun = false, bool forceOrientation = false)
{
if (_owner.GetTypeId() == TypeId.Unit)
StartMovement(new FormationMovementGenerator(id, destination, moveType, forceRun, forceOrientation), MovementSlot.Active);
}
void Pop()
{
if (Empty())