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 class AnimationWithOffset
{ {
public Animation Animation; public readonly Animation Animation;
public Func<WorldRenderer, float2> OffsetFunc; public readonly Func<WVec> OffsetFunc;
public Func<bool> DisableFunc; public readonly Func<bool> DisableFunc;
public int ZOffset; public readonly int ZOffset;
public AnimationWithOffset(Animation a) public AnimationWithOffset(Animation a, Func<WVec> offset, Func<bool> disable)
: this(a, null, null) : 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.Animation = a;
this.OffsetFunc = o; this.OffsetFunc = offset;
this.DisableFunc = d; this.DisableFunc = disable;
this.ZOffset = zOffset;
} }
public Renderable Image(Actor self, WorldRenderer wr, PaletteReference pal) 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) public Renderable Image(Actor self, WorldRenderer wr, PaletteReference pal, float scale)
{ {
var p = self.CenterLocation; var p = self.CenterPosition;
var offset = p.ToFloat2();
if (OffsetFunc != null) 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) 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 public struct Renderable
{ {
readonly Sprite Sprite; public readonly WPos Pos;
readonly WPos Pos; public readonly float Scale;
readonly float Scale;
// TODO: Fix Parachute and WithShadow so these can be made private
public readonly PaletteReference Palette; public readonly PaletteReference Palette;
public readonly int ZOffset; public readonly int ZOffset;
readonly Sprite Sprite;
public Renderable(Sprite sprite, WPos pos, int zOffset, PaletteReference palette, float scale) public Renderable(Sprite sprite, WPos pos, int zOffset, PaletteReference palette, float scale)
{ {

View File

@@ -57,7 +57,8 @@ namespace OpenRA.Traits
public Animation anim public Animation anim
{ {
get { return anims[""].Animation; } 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) public static string GetImage(ActorInfo actor)

View File

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

View File

@@ -34,8 +34,12 @@ namespace OpenRA.Mods.RA.Render
var wake = new Animation(anim.Name); var wake = new Animation(anim.Name);
wake.Play("left-wake"); 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) public override void Tick(Actor self)

View File

@@ -15,17 +15,20 @@ namespace OpenRA.Mods.Cnc
{ {
class WithFireInfo : ITraitInfo, Requires<RenderSimpleInfo> 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 class WithFire
{ {
public WithFire(Actor self) public WithFire(Actor self, WithFireInfo info)
{ {
var rs = self.Trait<RenderSimple>(); var rs = self.Trait<RenderSimple>();
var roof = new Animation(rs.GetImage(self)); var roof = new Animation(rs.GetImage(self));
roof.PlayThen("fire-start", () => roof.PlayRepeating("fire-loop")); 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 rs = self.Trait<RenderSimple>();
var roof = new Animation(rs.GetImage(self), () => self.Trait<IFacing>().Facing); var roof = new Animation(rs.GetImage(self), () => self.Trait<IFacing>().Facing);
roof.Play("roof"); 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 string Anim = "1";
public readonly int Damage = 1; public readonly int Damage = 1;
public readonly int Interval = 8; 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); } 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) public Burns(Actor self, BurnsInfo info)
{ {
Info = info; Info = info;
var rs = self.Trait<RenderSimple>();
var anim = new Animation("fire", () => 0); var anim = new Animation("fire", () => 0);
anim.PlayRepeating(Info.Anim); anim.PlayRepeating(Info.Anim);
rs.anims.Add("fire", self.Trait<RenderSimple>().anims.Add("fire",
new AnimationWithOffset(anim, wr => new float2(0, -3), null)); new AnimationWithOffset(anim, () => info.Offset, null));
} }
public void Tick(Actor self) public void Tick(Actor self)

View File

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

View File

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

View File

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

View File

@@ -28,11 +28,13 @@ namespace OpenRA.Mods.RA.Render
/* rude hack */ /* rude hack */
var visualOffset = ((move is Helicopter || move is Mobile) && move.Altitude > 0) 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 shadowSprites = r.Select(a => a.WithPalette(wr.Palette("shadow"))
var flyingSprites = (move.Altitude <= 0) ? r .WithPos(a.Pos - new WVec(0, 0, a.Pos.Z)).WithZOffset(-24));
: r.Select(a => a.WithPxOffset(new float2(0, -(move.Altitude + visualOffset))).WithZOffset(move.Altitude + a.ZOffset));
var flyingSprites = (move.Altitude <= 0) ? r :
r.Select(a => a.WithPos(a.Pos - new WVec(0,0,43*visualOffset)));
return shadowSprites.Concat(flyingSprites); return shadowSprites.Concat(flyingSprites);
} }

View File

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

View File

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

View File

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

View File

@@ -71,7 +71,7 @@ namespace OpenRA.Mods.RA
var anim = new Animation(rs.GetImage(self), () => (int)facing); var anim = new Animation(rs.GetImage(self), () => (int)facing);
anim.PlayRepeating(info.Anim); 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) public void Tick(Actor self)