Convert AnimationWithOffset to world coords.

Animations (via Actor.CenterPosition) now
understand Altitude, so there is potential for
mis-positioned animations if any existing altitude
hacks were missed.
This commit is contained in:
Paul Chote
2013-05-14 21:02:46 +12:00
parent fb17654ea0
commit fe716e76a7
16 changed files with 64 additions and 66 deletions

View File

@@ -15,21 +15,20 @@ namespace OpenRA.Graphics
{
public class AnimationWithOffset
{
public Animation Animation;
public Func<WorldRenderer, float2> OffsetFunc;
public Func<bool> DisableFunc;
public int ZOffset;
public readonly Animation Animation;
public readonly Func<WVec> OffsetFunc;
public readonly Func<bool> DisableFunc;
public readonly int ZOffset;
public AnimationWithOffset(Animation a)
: this(a, null, null)
{
}
public AnimationWithOffset(Animation a, Func<WVec> offset, Func<bool> disable)
: this(a, offset, disable, 0) { }
public AnimationWithOffset(Animation a, Func<WorldRenderer, float2> o, Func<bool> d)
public AnimationWithOffset(Animation a, Func<WVec> offset, Func<bool> disable, int zOffset)
{
this.Animation = a;
this.OffsetFunc = o;
this.DisableFunc = d;
this.OffsetFunc = offset;
this.DisableFunc = disable;
this.ZOffset = zOffset;
}
public Renderable Image(Actor self, WorldRenderer wr, PaletteReference pal)
@@ -39,17 +38,16 @@ namespace OpenRA.Graphics
public Renderable Image(Actor self, WorldRenderer wr, PaletteReference pal, float scale)
{
var p = self.CenterLocation;
var offset = p.ToFloat2();
var p = self.CenterPosition;
if (OffsetFunc != null)
offset += OffsetFunc(wr);
p += OffsetFunc();
return new Renderable(Animation.Image, offset, pal, p.Y, ZOffset, scale);
return new Renderable(Animation.Image, p, ZOffset, pal, scale);
}
public static implicit operator AnimationWithOffset(Animation a)
{
return new AnimationWithOffset(a);
return new AnimationWithOffset(a, null, null, 0);
}
}
}

View File

@@ -29,13 +29,11 @@ namespace OpenRA.Graphics
public struct Renderable
{
readonly Sprite Sprite;
readonly WPos Pos;
readonly float Scale;
// TODO: Fix Parachute and WithShadow so these can be made private
public readonly WPos Pos;
public readonly float Scale;
public readonly PaletteReference Palette;
public readonly int ZOffset;
readonly Sprite Sprite;
public Renderable(Sprite sprite, WPos pos, int zOffset, PaletteReference palette, float scale)
{

View File

@@ -57,7 +57,8 @@ namespace OpenRA.Traits
public Animation anim
{
get { return anims[""].Animation; }
protected set { anims[""].Animation = value; }
protected set { anims[""] = new AnimationWithOffset(value,
anims[""].OffsetFunc, anims[""].DisableFunc, anims[""].ZOffset); }
}
public static string GetImage(ActorInfo actor)

View File

@@ -18,7 +18,9 @@ namespace OpenRA.Mods.Cnc
{
class RenderBuildingRefineryInfo : RenderBuildingInfo
{
public override object Create(ActorInitializer init) { return new RenderBuildingRefinery( init, this ); }
public readonly WVec Offset = new WVec(1365, 896, 0);
public override object Create(ActorInitializer init) { return new RenderBuildingRefinery(init, this); }
}
class RenderBuildingRefinery : RenderBuilding, INotifyBuildComplete, INotifySold, INotifyCapture
@@ -27,7 +29,7 @@ namespace OpenRA.Mods.Cnc
PlayerResources playerResources;
bool buildComplete;
public RenderBuildingRefinery(ActorInitializer init, RenderBuildingInfo info)
public RenderBuildingRefinery(ActorInitializer init, RenderBuildingRefineryInfo info)
: base(init, info)
{
playerResources = init.self.Owner.PlayerActor.Trait<PlayerResources>();
@@ -38,9 +40,7 @@ namespace OpenRA.Mods.Cnc
? (59 * playerResources.Ore) / (10 * playerResources.OreCapacity)
: 0);
var offset = new float2(-32,-21);
anims.Add("lights", new AnimationWithOffset( lights, wr => offset, () => !buildComplete )
{ ZOffset = 24 });
anims.Add("lights", new AnimationWithOffset(lights, () => info.Offset, () => !buildComplete, 24));
}
public void BuildingComplete( Actor self )

View File

@@ -34,8 +34,12 @@ namespace OpenRA.Mods.RA.Render
var wake = new Animation(anim.Name);
wake.Play("left-wake");
Func<WorldRenderer, float2> offset = wr => new float2(((anims["wake"].Animation.CurrentSequence.Name == "left-wake") ? 1 : -1),2);
anims.Add( "wake", new AnimationWithOffset( wake, offset, () => false ) { ZOffset = -2 } );
var leftOffset = new WVec(43, 86, 0);
var rightOffset = new WVec(-43, 86, 0);
anims.Add("wake", new AnimationWithOffset(wake,
() => anims["wake"].Animation.CurrentSequence.Name == "left-wake" ? leftOffset : rightOffset,
() => false, -2));
}
public override void Tick(Actor self)

View File

@@ -15,17 +15,20 @@ namespace OpenRA.Mods.Cnc
{
class WithFireInfo : ITraitInfo, Requires<RenderSimpleInfo>
{
public object Create(ActorInitializer init) { return new WithFire(init.self); }
public readonly WVec Offset = new WVec(299,-640,0);
public object Create(ActorInitializer init) { return new WithFire(init.self, this); }
}
class WithFire
{
public WithFire(Actor self)
public WithFire(Actor self, WithFireInfo info)
{
var rs = self.Trait<RenderSimple>();
var roof = new Animation(rs.GetImage(self));
roof.PlayThen("fire-start", () => roof.PlayRepeating("fire-loop"));
rs.anims.Add( "fire", new AnimationWithOffset( roof, wr => new float2(7,-15), null ) { ZOffset = 24 } );
rs.anims.Add("fire", new AnimationWithOffset(roof, () => info.Offset, null, 24));
}
}
}

View File

@@ -25,7 +25,7 @@ namespace OpenRA.Mods.Cnc
var rs = self.Trait<RenderSimple>();
var roof = new Animation(rs.GetImage(self), () => self.Trait<IFacing>().Facing);
roof.Play("roof");
rs.anims.Add( "roof", new AnimationWithOffset( roof ) { ZOffset = 24 } );
rs.anims.Add("roof", new AnimationWithOffset(roof, null, null, 24));
}
}
}

View File

@@ -18,6 +18,7 @@ namespace OpenRA.Mods.RA
public readonly string Anim = "1";
public readonly int Damage = 1;
public readonly int Interval = 8;
public readonly WVec Offset = new WVec(0,0,128);
public object Create(ActorInitializer init) { return new Burns(init.self, this); }
}
@@ -30,11 +31,11 @@ namespace OpenRA.Mods.RA
public Burns(Actor self, BurnsInfo info)
{
Info = info;
var rs = self.Trait<RenderSimple>();
var anim = new Animation("fire", () => 0);
anim.PlayRepeating(Info.Anim);
rs.anims.Add("fire",
new AnimationWithOffset(anim, wr => new float2(0, -3), null));
self.Trait<RenderSimple>().anims.Add("fire",
new AnimationWithOffset(anim, () => info.Offset, null));
}
public void Tick(Actor self)

View File

@@ -49,9 +49,7 @@ namespace OpenRA.Mods.RA.Render
: base(init, info)
{
roof = new Animation(GetImage(init.self));
var offset = new AnimationWithOffset( roof ) { ZOffset = 24 };
offset.DisableFunc = () => !buildComplete;
anims.Add("roof", offset);
anims.Add("roof", new AnimationWithOffset(roof, null, () => !buildComplete, 24));
}
public void BuildingComplete( Actor self )

View File

@@ -45,9 +45,9 @@ namespace OpenRA.Mods.RA.Render
var muzzleFlash = new Animation(render.GetImage(self), getFacing);
muzzleFlash.Play("muzzle");
muzzleFlashes.Add("muzzle{0}".F(muzzleFlashes.Count), new AnimationWithOffset(
muzzleFlash,
wr => wr.ScreenPxOffset(a.MuzzleOffset(self, barrel)),
muzzleFlashes.Add("muzzle{0}".F(muzzleFlashes.Count),
new AnimationWithOffset(muzzleFlash,
() => a.MuzzleOffset(self, barrel),
() => !isShowing));
}
}

View File

@@ -32,10 +32,9 @@ namespace OpenRA.Mods.RA.Render
rotorAnim = new Animation(rs.GetImage(self));
rotorAnim.PlayRepeating("rotor");
rs.anims.Add(info.Id, new AnimationWithOffset(
rotorAnim,
wr => wr.ScreenPxOffset(rs.LocalToWorld(info.Offset.Rotate(rs.QuantizeOrientation(self, self.Orientation)))),
null ) { ZOffset = 1 } );
rs.anims.Add(info.Id, new AnimationWithOffset(rotorAnim,
() => rs.LocalToWorld(info.Offset.Rotate(rs.QuantizeOrientation(self, self.Orientation))),
null, 1));
}
public void Tick(Actor self)

View File

@@ -28,11 +28,13 @@ namespace OpenRA.Mods.RA.Render
/* rude hack */
var visualOffset = ((move is Helicopter || move is Mobile) && move.Altitude > 0)
? Math.Abs((self.ActorID + Game.LocalTick) / 5 % 4 - 1) - 1 : 0;
? (int)Math.Abs((self.ActorID + Game.LocalTick) / 5 % 4 - 1) - 1 : 0;
var shadowSprites = r.Select(a => a.WithPalette(wr.Palette("shadow")));
var flyingSprites = (move.Altitude <= 0) ? r
: r.Select(a => a.WithPxOffset(new float2(0, -(move.Altitude + visualOffset))).WithZOffset(move.Altitude + a.ZOffset));
var shadowSprites = r.Select(a => a.WithPalette(wr.Palette("shadow"))
.WithPos(a.Pos - new WVec(0, 0, a.Pos.Z)).WithZOffset(-24));
var flyingSprites = (move.Altitude <= 0) ? r :
r.Select(a => a.WithPos(a.Pos - new WVec(0,0,43*visualOffset)));
return shadowSprites.Concat(flyingSprites);
}

View File

@@ -28,8 +28,7 @@ namespace OpenRA.Mods.RA.Render
var rs = self.Trait<RenderSimple>();
anim = new Animation("smoke_m");
rs.anims.Add("smoke", new AnimationWithOffset(
anim, null, () => !isSmoking));
rs.anims.Add("smoke", new AnimationWithOffset(anim, null, () => !isSmoking));
}
public void Damaged(Actor self, AttackInfo e)

View File

@@ -32,10 +32,9 @@ namespace OpenRA.Mods.RA.Render
var rs = self.Trait<RenderSimple>();
var spinner = new Animation(rs.GetImage(self));
spinner.PlayRepeating(info.Sequence);
rs.anims.Add("spinner_{0}".F(info.Sequence), new AnimationWithOffset(
spinner,
wr => wr.ScreenPxOffset(rs.LocalToWorld(info.Offset.Rotate(rs.QuantizeOrientation(self, self.Orientation)))),
null ) { ZOffset = 1 } );
rs.anims.Add("spinner_{0}".F(info.Sequence), new AnimationWithOffset(spinner,
() => rs.LocalToWorld(info.Offset.Rotate(rs.QuantizeOrientation(self, self.Orientation))),
null, 1));
}
}
}

View File

@@ -53,20 +53,16 @@ namespace OpenRA.Mods.RA.Render
anim = new Animation(rs.GetImage(self), () => t.turretFacing);
anim.Play(info.Sequence);
rs.anims.Add("turret_{0}".F(info.Turret), new AnimationWithOffset(
anim,
wr => TurretPosition(self, wr),
null) { ZOffset = 1 });
anim, () => TurretOffset(self), null, 24));
}
int2 TurretPosition(Actor self, WorldRenderer wr)
WVec TurretOffset(Actor self)
{
var recoil = arms.Aggregate(WRange.Zero, (a,b) => a + b.Recoil);
var localOffset = new WVec(-recoil, WRange.Zero, WRange.Zero);
var bodyOrientation = rs.QuantizeOrientation(self, self.Orientation);
var turretOrientation = rs.QuantizeOrientation(self, t.LocalOrientation(self));
var worldPos = t.Position(self) + rs.LocalToWorld(localOffset.Rotate(turretOrientation).Rotate(bodyOrientation));
return wr.ScreenPxOffset(worldPos);
return t.Position(self) + rs.LocalToWorld(localOffset.Rotate(turretOrientation).Rotate(bodyOrientation));
}
public void Tick(Actor self)

View File

@@ -71,7 +71,7 @@ namespace OpenRA.Mods.RA
var anim = new Animation(rs.GetImage(self), () => (int)facing);
anim.PlayRepeating(info.Anim);
rs.anims.Add(info.Anim, new AnimationWithOffset(anim, wr => wr.ScreenPxOffset(pos), null));
rs.anims.Add(info.Anim, new AnimationWithOffset(anim, () => pos, null));
}
public void Tick(Actor self)