Allow all sprites to use interpolated facings.
This commit is contained in:
@@ -24,7 +24,6 @@ namespace OpenRA.Graphics
|
|||||||
string Name { get; }
|
string Name { get; }
|
||||||
int Length { get; }
|
int Length { get; }
|
||||||
int Facings { get; }
|
int Facings { get; }
|
||||||
int InterpolatedFacings { get; }
|
|
||||||
int Tick { get; }
|
int Tick { get; }
|
||||||
int ZOffset { get; }
|
int ZOffset { get; }
|
||||||
int ShadowZOffset { get; }
|
int ShadowZOffset { get; }
|
||||||
|
|||||||
@@ -85,7 +85,6 @@ namespace OpenRA.Mods.Common.Graphics
|
|||||||
string ISpriteSequence.Name => throw exception;
|
string ISpriteSequence.Name => throw exception;
|
||||||
int ISpriteSequence.Length => throw exception;
|
int ISpriteSequence.Length => throw exception;
|
||||||
int ISpriteSequence.Facings => throw exception;
|
int ISpriteSequence.Facings => throw exception;
|
||||||
int ISpriteSequence.InterpolatedFacings => throw exception;
|
|
||||||
int ISpriteSequence.Tick => throw exception;
|
int ISpriteSequence.Tick => throw exception;
|
||||||
int ISpriteSequence.ZOffset => throw exception;
|
int ISpriteSequence.ZOffset => throw exception;
|
||||||
int ISpriteSequence.ShadowZOffset => throw exception;
|
int ISpriteSequence.ShadowZOffset => throw exception;
|
||||||
@@ -144,13 +143,12 @@ namespace OpenRA.Mods.Common.Graphics
|
|||||||
|
|
||||||
[Desc("The amount of directions the unit faces. Use negative values to rotate counter-clockwise.")]
|
[Desc("The amount of directions the unit faces. Use negative values to rotate counter-clockwise.")]
|
||||||
static readonly SpriteSequenceField<int> Facings = new SpriteSequenceField<int>(nameof(Facings), 1);
|
static readonly SpriteSequenceField<int> Facings = new SpriteSequenceField<int>(nameof(Facings), 1);
|
||||||
int ISpriteSequence.Facings => facings;
|
int ISpriteSequence.Facings => interpolatedFacings ?? facings;
|
||||||
protected int facings;
|
protected int facings;
|
||||||
|
|
||||||
[Desc("The amount of directions the unit faces. Use negative values to rotate counter-clockwise.")]
|
[Desc("The amount of directions the unit faces. Use negative values to rotate counter-clockwise.")]
|
||||||
static readonly SpriteSequenceField<int> InterpolatedFacings = new SpriteSequenceField<int>(nameof(InterpolatedFacings), 1);
|
static readonly SpriteSequenceField<int?> InterpolatedFacings = new SpriteSequenceField<int?>(nameof(InterpolatedFacings), null);
|
||||||
int ISpriteSequence.InterpolatedFacings => interpolatedFacings;
|
protected int? interpolatedFacings;
|
||||||
protected int interpolatedFacings;
|
|
||||||
|
|
||||||
[Desc("Time (in milliseconds at default game speed) to wait until playing the next frame in the animation.")]
|
[Desc("Time (in milliseconds at default game speed) to wait until playing the next frame in the animation.")]
|
||||||
static readonly SpriteSequenceField<int> Tick = new SpriteSequenceField<int>(nameof(Tick), 40);
|
static readonly SpriteSequenceField<int> Tick = new SpriteSequenceField<int>(nameof(Tick), 40);
|
||||||
@@ -282,10 +280,9 @@ namespace OpenRA.Mods.Common.Graphics
|
|||||||
var zRamp = LoadField(ZRamp, data, defaults);
|
var zRamp = LoadField(ZRamp, data, defaults);
|
||||||
|
|
||||||
facings = LoadField(Facings, data, defaults);
|
facings = LoadField(Facings, data, defaults);
|
||||||
interpolatedFacings = LoadField(InterpolatedFacings.Key, -1, data, defaults);
|
interpolatedFacings = LoadField(InterpolatedFacings, data, defaults);
|
||||||
if (interpolatedFacings != -1 && (interpolatedFacings <= 1 || interpolatedFacings <= Math.Abs(facings) || interpolatedFacings > 1024
|
if (interpolatedFacings != null && (interpolatedFacings <= 1 || interpolatedFacings <= Math.Abs(facings) || interpolatedFacings > 1024 || !Exts.IsPowerOf2(interpolatedFacings.Value)))
|
||||||
|| !Exts.IsPowerOf2(interpolatedFacings)))
|
throw new YamlException($"Sequence {image}.{sequence}: InterpolatedFacings must be greater than Facings, within the range of 2 to 1024, and a power of 2.");
|
||||||
throw new YamlException($"InterpolatedFacings must be greater than Facings, within the range of 2 to 1024, and a power of 2.");
|
|
||||||
|
|
||||||
if (facings < 0)
|
if (facings < 0)
|
||||||
{
|
{
|
||||||
@@ -508,10 +505,8 @@ namespace OpenRA.Mods.Common.Graphics
|
|||||||
public (Sprite, WAngle) GetSpriteWithRotation(int frame, WAngle facing)
|
public (Sprite, WAngle) GetSpriteWithRotation(int frame, WAngle facing)
|
||||||
{
|
{
|
||||||
var rotation = WAngle.Zero;
|
var rotation = WAngle.Zero;
|
||||||
|
if (interpolatedFacings != null)
|
||||||
// Note: Error checking is not done here as it is done on load
|
rotation = Util.GetInterpolatedFacingRotation(facing, Math.Abs(facings), interpolatedFacings.Value);
|
||||||
if (interpolatedFacings != -1)
|
|
||||||
rotation = Util.GetInterpolatedFacing(facing, Math.Abs(facings), interpolatedFacings);
|
|
||||||
|
|
||||||
return (GetSprite(start, frame, facing), rotation);
|
return (GetSprite(start, frame, facing), rotation);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,14 +23,13 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
[Desc("Defines sequence to derive facings from.")]
|
[Desc("Defines sequence to derive facings from.")]
|
||||||
public readonly string Sequence = "idle";
|
public readonly string Sequence = "idle";
|
||||||
|
|
||||||
public int QuantizedBodyFacings(ActorInfo ai, SequenceProvider sequenceProvider, string race)
|
public int QuantizedBodyFacings(ActorInfo ai, SequenceProvider sequences, string faction)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(Sequence))
|
if (string.IsNullOrEmpty(Sequence))
|
||||||
throw new InvalidOperationException("Actor " + ai.Name + " is missing sequence to quantize facings from.");
|
throw new InvalidOperationException($"Actor {ai.Name} is missing sequence to quantize facings from.");
|
||||||
|
|
||||||
var rsi = ai.TraitInfo<RenderSpritesInfo>();
|
var rsi = ai.TraitInfo<RenderSpritesInfo>();
|
||||||
var seq = sequenceProvider.GetSequence(rsi.GetImage(ai, race), Sequence);
|
return sequences.GetSequence(rsi.GetImage(ai, faction), Sequence).Facings;
|
||||||
return seq.InterpolatedFacings == -1 ? seq.Facings : seq.InterpolatedFacings;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override object Create(ActorInitializer init) { return new QuantizeFacingsFromSequence(this); }
|
public override object Create(ActorInitializer init) { return new QuantizeFacingsFromSequence(this); }
|
||||||
|
|||||||
@@ -84,16 +84,17 @@ namespace OpenRA.Mods.Common
|
|||||||
return new WAngle(a % step - step / 2);
|
return new WAngle(a % step - step / 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static WAngle GetInterpolatedFacing(WAngle facing, int facings, int interpolatedFacings)
|
/// <summary>Returns the angle that the closest facing sprite should be rotated by to achieve the closest interpolated facing.</summary>
|
||||||
|
public static WAngle GetInterpolatedFacingRotation(WAngle facing, int facings, int interpolatedFacings)
|
||||||
{
|
{
|
||||||
var step = 1024 / interpolatedFacings;
|
var step = 1024 / interpolatedFacings;
|
||||||
return new WAngle(AngleDiffToStep(facing, facings).Angle / step * step);
|
return new WAngle(AngleDiffToStep(facing, facings).Angle / step * step);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Rounds the given facing value to the nearest quantized step.</summary>
|
/// <summary>Rounds the given facing value to the nearest quantized facing.</summary>
|
||||||
public static WAngle QuantizeFacing(WAngle facing, int steps)
|
public static WAngle QuantizeFacing(WAngle facing, int facings)
|
||||||
{
|
{
|
||||||
return new WAngle(IndexFacing(facing, steps) * (1024 / steps));
|
return new WAngle(IndexFacing(facing, facings) * (1024 / facings));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Wraps an arbitrary integer facing value into the range 0 - 255</summary>
|
/// <summary>Wraps an arbitrary integer facing value into the range 0 - 255</summary>
|
||||||
|
|||||||
Reference in New Issue
Block a user