Allow voxel-based aircraft to pitch and roll.

This commit is contained in:
Paul Chote
2020-06-21 10:33:21 +01:00
committed by tovl
parent 43717a89b5
commit 6dcde3af72
5 changed files with 71 additions and 12 deletions

View File

@@ -36,6 +36,16 @@ namespace OpenRA
public static bool operator !=(WRot me, WRot other) { return !(me == other); }
public WRot WithRoll(WAngle roll)
{
return new WRot(roll, Pitch, Yaw);
}
public WRot WithPitch(WAngle pitch)
{
return new WRot(Roll, pitch, Yaw);
}
public WRot WithYaw(WAngle yaw)
{
return new WRot(Roll, Pitch, yaw);

View File

@@ -60,16 +60,29 @@ namespace OpenRA.Mods.Common.Activities
this.minRange = minRange;
}
public static void FlyTick(Actor self, Aircraft aircraft, WAngle desiredFacing, WDist desiredAltitude, WVec moveOverride, WAngle? turnSpeedOverride = null)
public static void FlyTick(Actor self, Aircraft aircraft, WAngle desiredFacing, WDist desiredAltitude, WVec moveOverride, bool idleTurn = false)
{
var dat = self.World.Map.DistanceAboveTerrain(aircraft.CenterPosition);
var move = aircraft.Info.CanSlide ? aircraft.FlyStep(desiredFacing) : aircraft.FlyStep(aircraft.Facing);
if (moveOverride != WVec.Zero)
move = moveOverride;
var turnSpeed = turnSpeedOverride ?? aircraft.TurnSpeed;
var oldFacing = aircraft.Facing;
var turnSpeed = idleTurn ? aircraft.IdleTurnSpeed ?? aircraft.TurnSpeed : aircraft.TurnSpeed;
aircraft.Facing = Util.TickFacing(aircraft.Facing, desiredFacing, turnSpeed);
var roll = idleTurn ? aircraft.Info.IdleRoll ?? aircraft.Info.Roll : aircraft.Info.Roll;
if (roll != WAngle.Zero)
{
var desiredRoll = aircraft.Facing == desiredFacing ? WAngle.Zero :
new WAngle(roll.Angle * Util.GetTurnDirection(aircraft.Facing, oldFacing));
aircraft.Roll = Util.TickFacing(aircraft.Roll, desiredRoll, aircraft.Info.RollSpeed);
}
if (aircraft.Info.Pitch != WAngle.Zero)
aircraft.Pitch = Util.TickFacing(aircraft.Pitch, aircraft.Info.Pitch, aircraft.Info.PitchSpeed);
// Note: we assume that if move.Z is not zero, it's intentional and we want to move in that vertical direction instead of towards desiredAltitude.
// If that is not desired, the place that calls this should make sure moveOverride.Z is zero.
if (dat != desiredAltitude || move.Z != 0)
@@ -83,18 +96,18 @@ namespace OpenRA.Mods.Common.Activities
aircraft.SetPosition(self, aircraft.CenterPosition + move);
}
public static void FlyTick(Actor self, Aircraft aircraft, WAngle desiredFacing, WDist desiredAltitude, WAngle? turnSpeedOverride = null)
public static void FlyTick(Actor self, Aircraft aircraft, WAngle desiredFacing, WDist desiredAltitude, bool idleTurn = false)
{
FlyTick(self, aircraft, desiredFacing, desiredAltitude, WVec.Zero, turnSpeedOverride);
FlyTick(self, aircraft, desiredFacing, desiredAltitude, WVec.Zero, idleTurn);
}
// Should only be used for vertical-only movement, usually VTOL take-off or land. Terrain-induced altitude changes should always be handled by FlyTick.
public static bool VerticalTakeOffOrLandTick(Actor self, Aircraft aircraft, WAngle desiredFacing, WDist desiredAltitude, WAngle? turnSpeedOverride = null)
public static bool VerticalTakeOffOrLandTick(Actor self, Aircraft aircraft, WAngle desiredFacing, WDist desiredAltitude, bool idleTurn = false)
{
var dat = self.World.Map.DistanceAboveTerrain(aircraft.CenterPosition);
var move = WVec.Zero;
var turnSpeed = turnSpeedOverride ?? aircraft.TurnSpeed;
var turnSpeed = idleTurn ? aircraft.IdleTurnSpeed ?? aircraft.TurnSpeed : aircraft.TurnSpeed;
aircraft.Facing = Util.TickFacing(aircraft.Facing, desiredFacing, turnSpeed);
if (dat != desiredAltitude)

View File

@@ -20,16 +20,16 @@ namespace OpenRA.Mods.Common.Activities
{
readonly Aircraft aircraft;
readonly INotifyIdle[] tickIdles;
readonly WAngle turnSpeed;
readonly bool idleTurn;
int remainingTicks;
public FlyIdle(Actor self, int ticks = -1, bool tickIdle = true)
public FlyIdle(Actor self, int ticks = -1, bool idleTurn = true)
{
aircraft = self.Trait<Aircraft>();
turnSpeed = aircraft.IdleTurnSpeed ?? aircraft.TurnSpeed;
remainingTicks = ticks;
this.idleTurn = idleTurn;
if (tickIdle)
if (idleTurn)
tickIdles = self.TraitsImplementing<INotifyIdle>().ToArray();
}
@@ -55,7 +55,7 @@ namespace OpenRA.Mods.Common.Activities
// We can't possibly turn this fast
var desiredFacing = aircraft.Facing + new WAngle(256);
Fly.FlyTick(self, aircraft, desiredFacing, aircraft.Info.CruiseAltitude, move, turnSpeed);
Fly.FlyTick(self, aircraft, desiredFacing, aircraft.Info.CruiseAltitude, move, idleTurn);
}
return false;

View File

@@ -58,7 +58,7 @@ namespace OpenRA.Mods.Common.Activities
// Fly to the target and wait for it to be locked for pickup
// These activities will be cancelled and replaced by Land once the target has been locked
QueueChild(new Fly(self, Target.FromActor(cargo)));
QueueChild(new FlyIdle(self, tickIdle: false));
QueueChild(new FlyIdle(self, idleTurn: false));
}
}

View File

@@ -56,6 +56,21 @@ namespace OpenRA.Mods.Common.Traits
public readonly int Speed = 1;
[Desc("Body pitch when flying forwards. Only relevant for voxel aircraft.")]
public readonly WAngle Pitch = WAngle.Zero;
[Desc("Pitch steps to apply each tick when starting/stopping.")]
public readonly WAngle PitchSpeed = WAngle.Zero;
[Desc("Body roll when turning. Only relevant for voxel aircraft.")]
public readonly WAngle Roll = WAngle.Zero;
[Desc("Body roll to apply when aircraft flies in circles while idle. Defaults to Roll if undefined. Only relevant for voxel aircraft.")]
public readonly WAngle? IdleRoll = null;
[Desc("Roll steps to apply each tick when turning.")]
public readonly WAngle RollSpeed = WAngle.Zero;
[Desc("Minimum altitude where this aircraft is considered airborne.")]
public readonly int MinAirborneAltitude = 1;
@@ -217,6 +232,18 @@ namespace OpenRA.Mods.Common.Traits
set { orientation = orientation.WithYaw(value); }
}
public WAngle Pitch
{
get { return orientation.Pitch; }
set { orientation = orientation.WithPitch(value); }
}
public WAngle Roll
{
get { return orientation.Roll; }
set { orientation = orientation.WithRoll(value); }
}
public WRot Orientation { get { return orientation; } }
[Sync]
@@ -389,6 +416,15 @@ namespace OpenRA.Mods.Common.Traits
CurrentMovementTypes = newMovementTypes;
if (!CurrentMovementTypes.HasFlag(MovementType.Horizontal))
{
if (Info.Roll != WAngle.Zero && Roll != WAngle.Zero)
Roll = Util.TickFacing(Roll, WAngle.Zero, Info.RollSpeed);
if (Info.Pitch != WAngle.Zero && Pitch != WAngle.Zero)
Pitch = Util.TickFacing(Pitch, WAngle.Zero, Info.PitchSpeed);
}
Repulse();
}