Add TurnsWhileMoving to Mobile

This commit is contained in:
dnqbob
2023-04-07 01:46:35 +08:00
committed by abcdefg30
parent a65bb17d68
commit 69441a4fee
2 changed files with 32 additions and 19 deletions

View File

@@ -21,12 +21,12 @@ namespace OpenRA.Mods.Common.Activities
{ {
public class Move : Activity public class Move : Activity
{ {
public WAngle ActorFacingModifier;
readonly Mobile mobile; readonly Mobile mobile;
readonly WDist nearEnough; readonly WDist nearEnough;
readonly Func<BlockedByActor, List<CPos>> getPath; readonly Func<BlockedByActor, List<CPos>> getPath;
readonly Actor ignoreActor; readonly Actor ignoreActor;
readonly Color? targetLineColor; readonly Color? targetLineColor;
WAngle actorFacingModifier;
static readonly BlockedByActor[] PathSearchOrder = static readonly BlockedByActor[] PathSearchOrder =
{ {
@@ -162,13 +162,13 @@ namespace OpenRA.Mods.Common.Activities
if (mobile.Info.CanMoveBackward && self.World.WorldTick - startTicks < mobile.Info.BackwardDuration && Math.Abs(firstFacing.Angle - mobile.Facing.Angle) > 256) if (mobile.Info.CanMoveBackward && self.World.WorldTick - startTicks < mobile.Info.BackwardDuration && Math.Abs(firstFacing.Angle - mobile.Facing.Angle) > 256)
{ {
actorFacingModifier = new WAngle(512); ActorFacingModifier = new WAngle(512);
firstFacing += actorFacingModifier; firstFacing += ActorFacingModifier;
} }
else else
actorFacingModifier = WAngle.Zero; ActorFacingModifier = WAngle.Zero;
if (firstFacing != mobile.Facing) if (!mobile.Info.TurnsWhileMoving && firstFacing != mobile.Facing)
{ {
path.Add(nextCell.Value.Cell); path.Add(nextCell.Value.Cell);
QueueChild(new Turn(self, firstFacing)); QueueChild(new Turn(self, firstFacing));
@@ -192,7 +192,7 @@ namespace OpenRA.Mods.Common.Activities
toTerrainOrientation = WRot.SLerp(map.TerrainOrientation(mobile.FromCell), map.TerrainOrientation(mobile.ToCell), 1, 2); toTerrainOrientation = WRot.SLerp(map.TerrainOrientation(mobile.FromCell), map.TerrainOrientation(mobile.ToCell), 1, 2);
var movingOnGroundLayer = mobile.FromCell.Layer == 0 && mobile.ToCell.Layer == 0; var movingOnGroundLayer = mobile.FromCell.Layer == 0 && mobile.ToCell.Layer == 0;
QueueChild(new MoveFirstHalf(this, from, to, mobile.Facing, mobile.Facing, null, toTerrainOrientation, margin, carryoverProgress, movingOnGroundLayer)); QueueChild(new MoveFirstHalf(this, from, to, mobile.Facing, firstFacing, null, toTerrainOrientation, margin, carryoverProgress, false, movingOnGroundLayer));
carryoverProgress = 0; carryoverProgress = 0;
return false; return false;
} }
@@ -368,11 +368,13 @@ namespace OpenRA.Mods.Common.Activities
protected readonly WAngle ArcToAngle; protected readonly WAngle ArcToAngle;
protected readonly int Distance; protected readonly int Distance;
protected readonly bool MovingOnGroundLayer; protected readonly bool MovingOnGroundLayer;
protected readonly bool TurnsWhileMoving;
readonly int terrainOrientationMargin; readonly int terrainOrientationMargin;
protected int progress; protected int progress;
public MovePart(Move move, WPos from, WPos to, WAngle fromFacing, WAngle toFacing, public MovePart(Move move, WPos from, WPos to, WAngle fromFacing, WAngle toFacing,
WRot? fromTerrainOrientation, WRot? toTerrainOrientation, int terrainOrientationMargin, int carryoverProgress, bool movingOnGroundLayer) WRot? fromTerrainOrientation, WRot? toTerrainOrientation, int terrainOrientationMargin,
int carryoverProgress, bool shouldArc, bool movingOnGroundLayer)
{ {
Move = move; Move = move;
From = from; From = from;
@@ -388,9 +390,10 @@ namespace OpenRA.Mods.Common.Activities
IsInterruptible = false; // See comments in Move.Cancel() IsInterruptible = false; // See comments in Move.Cancel()
TurnsWhileMoving = move.mobile.Info.TurnsWhileMoving;
// Calculate an elliptical arc that joins from and to // Calculate an elliptical arc that joins from and to
var delta = (fromFacing - toFacing).Angle; if (shouldArc)
if (delta != 0 && delta != 512)
{ {
// The center of rotation is where the normal vectors cross // The center of rotation is where the normal vectors cross
var u = new WVec(1024, 0, 0).Rotate(WRot.FromYaw(fromFacing)); var u = new WVec(1024, 0, 0).Rotate(WRot.FromYaw(fromFacing));
@@ -427,7 +430,9 @@ namespace OpenRA.Mods.Common.Activities
if (progress >= Distance) if (progress >= Distance)
{ {
mobile.SetCenterPosition(self, To); mobile.SetCenterPosition(self, To);
mobile.Facing = ToFacing; mobile.Facing = TurnsWhileMoving
? Util.TickFacing(mobile.Facing, ToFacing, mobile.TurnSpeed)
: ToFacing;
Move.lastMovePartCompletedTick = self.World.WorldTick; Move.lastMovePartCompletedTick = self.World.WorldTick;
Queue(OnComplete(self, mobile, Move)); Queue(OnComplete(self, mobile, Move));
@@ -466,7 +471,10 @@ namespace OpenRA.Mods.Common.Activities
mobile.SetTerrainRampOrientation(orientation); mobile.SetTerrainRampOrientation(orientation);
} }
mobile.Facing = WAngle.Lerp(FromFacing, ToFacing, progress, Distance); mobile.Facing = TurnsWhileMoving
? Util.TickFacing(mobile.Facing, ToFacing, mobile.TurnSpeed)
: WAngle.Lerp(FromFacing, ToFacing, progress, Distance);
return false; return false;
} }
@@ -481,17 +489,17 @@ namespace OpenRA.Mods.Common.Activities
class MoveFirstHalf : MovePart class MoveFirstHalf : MovePart
{ {
public MoveFirstHalf(Move move, WPos from, WPos to, WAngle fromFacing, WAngle toFacing, public MoveFirstHalf(Move move, WPos from, WPos to, WAngle fromFacing, WAngle toFacing,
WRot? fromTerrainOrientation, WRot? toTerrainOrientation, int terrainOrientationMargin, int carryoverProgress, bool movingOnGroundLayer) WRot? fromTerrainOrientation, WRot? toTerrainOrientation, int terrainOrientationMargin, int carryoverProgress, bool shouldArc, bool movingOnGroundLayer)
: base(move, from, to, fromFacing, toFacing, fromTerrainOrientation, toTerrainOrientation, terrainOrientationMargin, carryoverProgress, movingOnGroundLayer) { } : base(move, from, to, fromFacing, toFacing, fromTerrainOrientation, toTerrainOrientation, terrainOrientationMargin, carryoverProgress, shouldArc, movingOnGroundLayer) { }
bool IsTurn(Actor self, Mobile mobile, CPos nextCell, Map map) bool IsTurn(Actor self, Mobile mobile, CPos nextCell, Map map)
{ {
// Some actors with a limited number of sprite facings should never move along curved trajectories. // Some actors with a limited number of sprite facings should never move along curved trajectories.
if (mobile.Info.AlwaysTurnInPlace) if (mobile.Info.AlwaysTurnInPlace || TurnsWhileMoving)
return false; return false;
// When Backwards duration runs out, let the Move activity do the turn. // When Backwards duration runs out, let the Move activity do the turn.
if (Move.actorFacingModifier != WAngle.Zero && self.World.WorldTick - Move.startTicks >= mobile.Info.BackwardDuration) if (Move.ActorFacingModifier != WAngle.Zero && self.World.WorldTick - Move.startTicks >= mobile.Info.BackwardDuration)
return false; return false;
// Tight U-turns should be done in place instead of making silly looking loops. // Tight U-turns should be done in place instead of making silly looking loops.
@@ -523,11 +531,12 @@ namespace OpenRA.Mods.Common.Activities
Util.BetweenCells(self.World, mobile.FromCell, mobile.ToCell) + (fromSubcellOffset + toSubcellOffset) / 2, Util.BetweenCells(self.World, mobile.FromCell, mobile.ToCell) + (fromSubcellOffset + toSubcellOffset) / 2,
Util.BetweenCells(self.World, mobile.ToCell, nextCell.Value.Cell) + (toSubcellOffset + nextSubcellOffset) / 2, Util.BetweenCells(self.World, mobile.ToCell, nextCell.Value.Cell) + (toSubcellOffset + nextSubcellOffset) / 2,
mobile.Facing, mobile.Facing,
map.FacingBetween(mobile.ToCell, nextCell.Value.Cell, mobile.Facing) + Move.actorFacingModifier, map.FacingBetween(mobile.ToCell, nextCell.Value.Cell, mobile.Facing) + Move.ActorFacingModifier,
ToTerrainOrientation, ToTerrainOrientation,
nextToTerrainOrientation, nextToTerrainOrientation,
margin, margin,
progress - Distance, progress - Distance,
true,
mobile.ToCell.Layer == 0 && nextCell.Value.Cell.Layer == 0); mobile.ToCell.Layer == 0 && nextCell.Value.Cell.Layer == 0);
mobile.FinishedMoving(self); mobile.FinishedMoving(self);
@@ -546,11 +555,12 @@ namespace OpenRA.Mods.Common.Activities
Util.BetweenCells(self.World, mobile.FromCell, mobile.ToCell) + (fromSubcellOffset + toSubcellOffset) / 2, Util.BetweenCells(self.World, mobile.FromCell, mobile.ToCell) + (fromSubcellOffset + toSubcellOffset) / 2,
toPos + toSubcellOffset, toPos + toSubcellOffset,
mobile.Facing, mobile.Facing,
mobile.Facing, TurnsWhileMoving ? map.FacingBetween(mobile.FromCell, mobile.ToCell, mobile.Facing) + Move.ActorFacingModifier : mobile.Facing,
ToTerrainOrientation, ToTerrainOrientation,
null, null,
mobile.Info.TerrainOrientationAdjustmentMargin.Length, mobile.Info.TerrainOrientationAdjustmentMargin.Length,
progress - Distance, progress - Distance,
false,
MovingOnGroundLayer); MovingOnGroundLayer);
mobile.EnteringCell(self); mobile.EnteringCell(self);
@@ -562,8 +572,8 @@ namespace OpenRA.Mods.Common.Activities
class MoveSecondHalf : MovePart class MoveSecondHalf : MovePart
{ {
public MoveSecondHalf(Move move, WPos from, WPos to, WAngle fromFacing, WAngle toFacing, public MoveSecondHalf(Move move, WPos from, WPos to, WAngle fromFacing, WAngle toFacing,
WRot? fromTerrainOrientation, WRot? toTerrainOrientation, int terrainOrientationMargin, int carryoverProgress, bool movingOnGroundLayer) WRot? fromTerrainOrientation, WRot? toTerrainOrientation, int terrainOrientationMargin, int carryoverProgress, bool shouldArc, bool movingOnGroundLayer)
: base(move, from, to, fromFacing, toFacing, fromTerrainOrientation, toTerrainOrientation, terrainOrientationMargin, carryoverProgress, movingOnGroundLayer) { } : base(move, from, to, fromFacing, toFacing, fromTerrainOrientation, toTerrainOrientation, terrainOrientationMargin, carryoverProgress, shouldArc, movingOnGroundLayer) { }
protected override MovePart OnComplete(Actor self, Mobile mobile, Move parent) protected override MovePart OnComplete(Actor self, Mobile mobile, Move parent)
{ {

View File

@@ -40,6 +40,9 @@ namespace OpenRA.Mods.Common.Traits
[Desc("If set to true, this unit will always turn in place instead of following a curved trajectory (like infantry).")] [Desc("If set to true, this unit will always turn in place instead of following a curved trajectory (like infantry).")]
public readonly bool AlwaysTurnInPlace = false; public readonly bool AlwaysTurnInPlace = false;
[Desc("If set to true, this unit won't stop to turn, it will turn while moving instead.")]
public readonly bool TurnsWhileMoving = false;
[CursorReference] [CursorReference]
[Desc("Cursor to display when a move order can be issued at target location.")] [Desc("Cursor to display when a move order can be issued at target location.")]
public readonly string Cursor = "move"; public readonly string Cursor = "move";