Merge pull request #3450 from pchote/offset-sprites

Allow sequences to define sprite offsets
This commit is contained in:
Matthias Mailänder
2013-06-20 09:46:39 -07:00
29 changed files with 191 additions and 196 deletions

View File

@@ -52,19 +52,14 @@ namespace OpenRA.Graphics
readonly int zOffset; readonly int zOffset;
readonly PaletteReference palette; readonly PaletteReference palette;
readonly float scale; readonly float scale;
readonly float2 pxCenter;
public SpriteRenderable(Sprite sprite, WPos pos, int zOffset, PaletteReference palette, float scale) public SpriteRenderable(Sprite sprite, WPos pos, int zOffset, PaletteReference palette, float scale)
: this(sprite, pos, zOffset, palette, scale, 0.5f*scale*sprite.size) {}
public SpriteRenderable(Sprite sprite, WPos pos, int zOffset, PaletteReference palette, float scale, float2 pxCenter)
{ {
this.sprite = sprite; this.sprite = sprite;
this.pos = pos; this.pos = pos;
this.zOffset = zOffset; this.zOffset = zOffset;
this.palette = palette; this.palette = palette;
this.scale = scale; this.scale = scale;
this.pxCenter = pxCenter;
} }
// Provided for legacy support only - Don't use for new things! // Provided for legacy support only - Don't use for new things!
@@ -84,12 +79,12 @@ namespace OpenRA.Graphics
public void BeforeRender(WorldRenderer wr) {} public void BeforeRender(WorldRenderer wr) {}
public void Render(WorldRenderer wr) public void Render(WorldRenderer wr)
{ {
sprite.DrawAt(wr.ScreenPxPosition(pos) - pxCenter, palette, scale); sprite.DrawAt(wr.ScreenPxPosition(pos) - 0.5f*scale*sprite.size, palette, scale);
} }
public void RenderDebugGeometry(WorldRenderer wr) public void RenderDebugGeometry(WorldRenderer wr)
{ {
var offset = wr.ScreenPxPosition(pos) - pxCenter; var offset = wr.ScreenPxPosition(pos) - 0.5f*scale*sprite.size + sprite.offset;
Game.Renderer.WorldLineRenderer.DrawRect(offset, offset + sprite.size, Color.Red); Game.Renderer.WorldLineRenderer.DrawRect(offset, offset + sprite.size, Color.Red);
} }
} }

View File

@@ -11,6 +11,7 @@
using System; using System;
using System.Xml; using System.Xml;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using OpenRA.FileFormats; using OpenRA.FileFormats;
namespace OpenRA.Graphics namespace OpenRA.Graphics
@@ -34,10 +35,18 @@ namespace OpenRA.Graphics
var srcOverride = info.Value; var srcOverride = info.Value;
Name = name; Name = name;
var d = info.NodesDict; var d = info.NodesDict;
var offset = float2.Zero;
sprites = Game.modData.SpriteLoader.LoadAllSprites(srcOverride ?? unit);
start = int.Parse(d["Start"].Value); start = int.Parse(d["Start"].Value);
if (d.ContainsKey("Offset"))
offset = FieldLoader.GetValue<float2>("Offset", d["Offset"].Value);
// Apply offset to each sprite in the sequence
// Different sequences may apply different offsets to the same frame
sprites = Game.modData.SpriteLoader.LoadAllSprites(srcOverride ?? unit).Select(
s => new Sprite(s.sheet, s.bounds, s.offset + offset, s.channel)).ToArray();
if (!d.ContainsKey("Length")) if (!d.ContainsKey("Length"))
length = 1; length = 1;
else if (d["Length"].Value == "*") else if (d["Length"].Value == "*")

View File

@@ -34,7 +34,7 @@ namespace OpenRA.Traits
RenderSimpleInfo Info; RenderSimpleInfo Info;
public RenderSimple(Actor self, Func<int> baseFacing) public RenderSimple(Actor self, Func<int> baseFacing)
: base(self, baseFacing) : base(self)
{ {
anims.Add("", new Animation(GetImage(self), baseFacing)); anims.Add("", new Animation(GetImage(self), baseFacing));
Info = self.Info.Traits.Get<RenderSimpleInfo>(); Info = self.Info.Traits.Get<RenderSimpleInfo>();
@@ -55,13 +55,9 @@ namespace OpenRA.Traits
.FirstOrDefault(); .FirstOrDefault();
} }
protected virtual string NormalizeSequence(Actor self, string baseSequence) public string NormalizeSequence(Actor self, string baseSequence)
{ {
string damageState = self.GetDamageState() >= DamageState.Heavy ? "damaged-" : ""; return NormalizeSequence(anim, self.GetDamageState(), baseSequence);
if (anim.HasSequence(damageState + baseSequence))
return damageState + baseSequence;
else
return baseSequence;
} }
public void PlayCustomAnim(Actor self, string name) public void PlayCustomAnim(Actor self, string name)

View File

@@ -54,14 +54,11 @@ namespace OpenRA.Traits
bool initializePalette = true; bool initializePalette = true;
protected PaletteReference palette; protected PaletteReference palette;
public RenderSprites(Actor self, Func<int> baseFacing) public RenderSprites(Actor self)
{ {
Info = self.Info.Traits.Get<RenderSpritesInfo>(); Info = self.Info.Traits.Get<RenderSpritesInfo>();
} }
public RenderSprites(Actor self)
: this(self, MakeFacingFunc(self)) {}
public static string GetImage(ActorInfo actor) public static string GetImage(ActorInfo actor)
{ {
var Info = actor.Traits.Get<RenderSpritesInfo>(); var Info = actor.Traits.Get<RenderSpritesInfo>();
@@ -103,5 +100,21 @@ namespace OpenRA.Traits
a.Animation.Tick(); a.Animation.Tick();
} }
public static string NormalizeSequence(Animation anim, DamageState state, string baseSequence)
{
var states = new Pair<DamageState, string>[]
{
Pair.New(DamageState.Critical, "critical-"),
Pair.New(DamageState.Heavy, "damaged-"),
Pair.New(DamageState.Medium, "scratched-"),
Pair.New(DamageState.Light, "scuffed-")
};
foreach (var s in states)
if (state >= s.First && anim.HasSequence(s.Second+baseSequence))
return s.Second+baseSequence;
return baseSequence;
}
} }
} }

View File

@@ -85,7 +85,6 @@
<Compile Include="ProductionAirdrop.cs" /> <Compile Include="ProductionAirdrop.cs" />
<Compile Include="ProductionQueueFromSelection.cs" /> <Compile Include="ProductionQueueFromSelection.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="RenderBuildingRefinery.cs" />
<Compile Include="WithCargo.cs" /> <Compile Include="WithCargo.cs" />
<Compile Include="RenderGunboat.cs" /> <Compile Include="RenderGunboat.cs" />
<Compile Include="SpawnViceroid.cs" /> <Compile Include="SpawnViceroid.cs" />

View File

@@ -1,67 +0,0 @@
#region Copyright & License Information
/*
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation. For more information,
* see COPYING.
*/
#endregion
using System.Collections.Generic;
using System.Linq;
using OpenRA.Graphics;
using OpenRA.Traits;
using OpenRA.Mods.RA.Render;
namespace OpenRA.Mods.Cnc
{
class RenderBuildingRefineryInfo : RenderBuildingInfo
{
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
{
public Animation lights;
PlayerResources playerResources;
bool buildComplete;
public RenderBuildingRefinery(ActorInitializer init, RenderBuildingRefineryInfo info)
: base(init, info)
{
playerResources = init.self.Owner.PlayerActor.Trait<PlayerResources>();
lights = new Animation(GetImage(init.self));
lights.PlayFetchIndex("lights",
() => playerResources.OreCapacity != 0
? (59 * playerResources.Ore) / (10 * playerResources.OreCapacity)
: 0);
anims.Add("lights", new AnimationWithOffset(lights, () => info.Offset, () => !buildComplete, 1024));
}
public void BuildingComplete( Actor self )
{
buildComplete = true;
}
public override void DamageStateChanged(Actor self, AttackInfo e)
{
if (lights.CurrentSequence != null)
lights.ReplaceAnim(NormalizeSequence(self, "lights"));
base.DamageStateChanged(self, e);
}
public void OnCapture (Actor self, Actor captor, Player oldOwner, Player newOwner)
{
playerResources = newOwner.PlayerActor.Trait<PlayerResources>();
}
public void Selling(Actor self) { anims.Remove("lights"); }
public void Sold(Actor self) { }
}
}

View File

@@ -10,66 +10,55 @@
using System; using System;
using System.Linq; using System.Linq;
using OpenRA.FileFormats;
using OpenRA.Graphics; using OpenRA.Graphics;
using OpenRA.Traits; using OpenRA.Traits;
namespace OpenRA.Mods.RA.Render namespace OpenRA.Mods.RA.Render
{ {
class RenderGunboatInfo : RenderSimpleInfo class RenderGunboatInfo : RenderSpritesInfo, Requires<IBodyOrientationInfo>
{ {
public override object Create(ActorInitializer init) { return new RenderGunboat(init.self); } [Desc("Turreted 'Turret' key to display")]
public readonly string Turret = "primary";
public override object Create(ActorInitializer init) { return new RenderGunboat(init.self, this); }
} }
class RenderGunboat : RenderSimple, INotifyDamageStateChanged class RenderGunboat : RenderSprites, INotifyDamageStateChanged
{ {
IFacing facing; Animation left, right;
string lastDir = "left";
string lastDamage = "";
static Func<int> TurretFacingFunc(Actor self) public RenderGunboat(Actor self, RenderGunboatInfo info)
: base(self)
{ {
return () => self.HasTrait<Turreted>() ? self.TraitsImplementing<Turreted>().First().turretFacing : 0; var name = GetImage(self);
} var facing = self.Trait<IFacing>();
var turret = self.TraitsImplementing<Turreted>()
.First(t => t.Name == info.Turret);
public RenderGunboat(Actor self) left = new Animation(name, () => turret.turretFacing);
: base(self, TurretFacingFunc(self)) left.Play("left");
{ anims.Add("left", new AnimationWithOffset(left, null, () => facing.Facing > 128, 0));
facing = self.Trait<IFacing>();
anim.Play("left");
var wake = new Animation(anim.Name); right = new Animation(name, () => turret.turretFacing);
wake.Play("left-wake"); right.Play("right");
anims.Add("right", new AnimationWithOffset(right, null, () => facing.Facing <= 128, 0));
var leftOffset = new WVec(43, 86, 0); var leftWake = new Animation(name);
var rightOffset = new WVec(-43, 86, 0); leftWake.Play("wake-left");
anims.Add("wake", new AnimationWithOffset(wake, anims.Add("wake-left", new AnimationWithOffset(leftWake, null, () => facing.Facing > 128, -87));
() => anims["wake"].Animation.CurrentSequence.Name == "left-wake" ? leftOffset : rightOffset,
() => false, -87));
self.Trait<IBodyOrientation>().QuantizedFacings = anim.CurrentSequence.Facings; var rightWake = new Animation(name);
} rightWake.Play("wake-right");
anims.Add("wake-right", new AnimationWithOffset(rightWake, null, () => facing.Facing <= 128, -87));
public override void Tick(Actor self) self.Trait<IBodyOrientation>().QuantizedFacings = 2;
{
var dir = (facing.Facing > 128) ? "right" : "left";
if (dir != lastDir)
{
anim.ReplaceAnim(dir+lastDamage);
anims["wake"].Animation.ReplaceAnim(dir+"-wake");
lastDir = dir;
}
base.Tick(self);
} }
public void DamageStateChanged(Actor self, AttackInfo e) public void DamageStateChanged(Actor self, AttackInfo e)
{ {
if (e.DamageState >= DamageState.Critical) left.ReplaceAnim(NormalizeSequence(left, e.DamageState, "left"));
lastDamage = "-critical"; right.ReplaceAnim(NormalizeSequence(right, e.DamageState, "right"));
else if (e.DamageState >= DamageState.Heavy)
lastDamage = "-damaged";
else if (e.DamageState < DamageState.Heavy)
lastDamage = "";
anim.ReplaceAnim(lastDir+lastDamage);
} }
} }
} }

View File

@@ -15,8 +15,6 @@ namespace OpenRA.Mods.Cnc
{ {
class WithFireInfo : ITraitInfo, Requires<RenderSpritesInfo> class WithFireInfo : ITraitInfo, Requires<RenderSpritesInfo>
{ {
public readonly WVec Offset = new WVec(299,-640,0);
public object Create(ActorInitializer init) { return new WithFire(init.self, this); } public object Create(ActorInitializer init) { return new WithFire(init.self, this); }
} }
@@ -27,8 +25,7 @@ namespace OpenRA.Mods.Cnc
var rs = self.Trait<RenderSprites>(); var rs = self.Trait<RenderSprites>();
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, null, null, 1024));
rs.anims.Add("fire", new AnimationWithOffset(roof, () => info.Offset, null, 1024));
} }
} }
} }

View File

@@ -18,7 +18,6 @@ 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); }
} }
@@ -34,8 +33,7 @@ namespace OpenRA.Mods.RA
var anim = new Animation("fire", () => 0); var anim = new Animation("fire", () => 0);
anim.PlayRepeating(Info.Anim); anim.PlayRepeating(Info.Anim);
self.Trait<RenderSprites>().anims.Add("fire", self.Trait<RenderSprites>().anims.Add("fire", anim);
new AnimationWithOffset(anim, () => info.Offset, null));
} }
public void Tick(Actor self) public void Tick(Actor self)

View File

@@ -17,14 +17,12 @@ namespace OpenRA.Mods.RA.Effects
{ {
class GpsSatellite : IEffect class GpsSatellite : IEffect
{ {
float2 Origin;
WPos Pos; WPos Pos;
Animation Anim = new Animation("sputnik"); Animation Anim = new Animation("sputnik");
public GpsSatellite(WPos pos, float2 spriteOrigin) public GpsSatellite(WPos pos)
{ {
Pos = pos; Pos = pos;
Origin = spriteOrigin;
Anim.PlayRepeating("idle"); Anim.PlayRepeating("idle");
} }
@@ -39,7 +37,7 @@ namespace OpenRA.Mods.RA.Effects
public IEnumerable<IRenderable> Render(WorldRenderer wr) public IEnumerable<IRenderable> Render(WorldRenderer wr)
{ {
yield return new SpriteRenderable(Anim.Image, Pos, 0, wr.Palette("effect"), 1f, Origin); yield return new SpriteRenderable(Anim.Image, Pos, 0, wr.Palette("effect"), 1f);
} }
} }
} }

View File

@@ -56,7 +56,7 @@ namespace OpenRA.Mods.RA.Effects
var pos = cachedLocation.CenterPosition; var pos = cachedLocation.CenterPosition;
var palette = wr.Palette(palettePrefix+building.Owner.InternalName); var palette = wr.Palette(palettePrefix+building.Owner.InternalName);
yield return new SpriteRenderable(circles.Image, pos, 0, palette, 1f); yield return new SpriteRenderable(circles.Image, pos, 0, palette, 1f);
yield return new SpriteRenderable(flag.Image, pos, 0, palette, 1f, new int2(1, 17)); yield return new SpriteRenderable(flag.Image, pos, 0, palette, 1f);
} }
} }
} }

View File

@@ -19,7 +19,6 @@ namespace OpenRA.Mods.RA.Effects
{ {
int frame = 0; int frame = 0;
Animation doors = new Animation("atek"); Animation doors = new Animation("atek");
float2 doorOrigin = new float2(16,24);
WPos pos; WPos pos;
public SatelliteLaunch(Actor a) public SatelliteLaunch(Actor a)
@@ -35,12 +34,12 @@ namespace OpenRA.Mods.RA.Effects
doors.Tick(); doors.Tick();
if (++frame == 19) if (++frame == 19)
world.AddFrameEndTask(w => w.Add(new GpsSatellite(pos, doorOrigin))); world.AddFrameEndTask(w => w.Add(new GpsSatellite(pos)));
} }
public IEnumerable<IRenderable> Render(WorldRenderer wr) public IEnumerable<IRenderable> Render(WorldRenderer wr)
{ {
yield return new SpriteRenderable(doors.Image, pos, 0, wr.Palette("effect"), 1f, doorOrigin); yield return new SpriteRenderable(doors.Image, pos, 0, wr.Palette("effect"), 1f);
} }
} }
} }

View File

@@ -453,6 +453,7 @@
<Compile Include="Render\WithVoxelBarrel.cs" /> <Compile Include="Render\WithVoxelBarrel.cs" />
<Compile Include="Render\WithVoxelWalkerBody.cs" /> <Compile Include="Render\WithVoxelWalkerBody.cs" />
<Compile Include="Widgets\Logic\CreditsLogic.cs" /> <Compile Include="Widgets\Logic\CreditsLogic.cs" />
<Compile Include="Render\WithResources.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\OpenRA.FileFormats\OpenRA.FileFormats.csproj"> <ProjectReference Include="..\OpenRA.FileFormats\OpenRA.FileFormats.csproj">

View File

@@ -24,15 +24,8 @@ namespace OpenRA.Mods.RA.Render
{ {
public readonly bool HasMakeAnimation = true; public readonly bool HasMakeAnimation = true;
[Desc("Artwork offset in world (not local) coordinates")]
public readonly WVec Origin = WVec.Zero;
public override object Create(ActorInitializer init) { return new RenderBuilding(init, this);} public override object Create(ActorInitializer init) { return new RenderBuilding(init, this);}
public override IEnumerable<IRenderable> RenderPreview(ActorInfo building, PaletteReference pr)
{
return base.RenderPreview(building, pr).Select(a => a.WithPos(a.Pos + Origin));
}
public void Render(WorldRenderer wr, World w, ActorInfo ai, PPos centerLocation) public void Render(WorldRenderer wr, World w, ActorInfo ai, PPos centerLocation)
{ {
if (!ai.Traits.Get<BuildingInfo>().RequiresBaseProvider) if (!ai.Traits.Get<BuildingInfo>().RequiresBaseProvider)
@@ -45,16 +38,14 @@ namespace OpenRA.Mods.RA.Render
public class RenderBuilding : RenderSimple, INotifyDamageStateChanged, IRenderModifier public class RenderBuilding : RenderSimple, INotifyDamageStateChanged, IRenderModifier
{ {
readonly RenderBuildingInfo Info;
public RenderBuilding(ActorInitializer init, RenderBuildingInfo info) public RenderBuilding(ActorInitializer init, RenderBuildingInfo info)
: this(init, info, () => 0) { } : this(init, info, () => 0) { }
public RenderBuilding(ActorInitializer init, RenderBuildingInfo info, Func<int> baseFacing) public RenderBuilding(ActorInitializer init, RenderBuildingInfo info, Func<int> baseFacing)
: base(init.self, baseFacing) : base(init.self, baseFacing)
{ {
Info = info;
var self = init.self; var self = init.self;
// Work around a bogus crash // Work around a bogus crash
anim.PlayRepeating( NormalizeSequence(self, "idle") ); anim.PlayRepeating( NormalizeSequence(self, "idle") );
self.Trait<IBodyOrientation>().QuantizedFacings = anim.CurrentSequence.Facings; self.Trait<IBodyOrientation>().QuantizedFacings = anim.CurrentSequence.Facings;
@@ -71,10 +62,9 @@ namespace OpenRA.Mods.RA.Render
var disabled = self.IsDisabled(); var disabled = self.IsDisabled();
foreach (var a in r) foreach (var a in r)
{ {
var ret = a.WithPos(a.Pos + Info.Origin); yield return a;
yield return ret;
if (disabled) if (disabled)
yield return ret.WithPalette(wr.Palette("disabled")).WithZOffset(1); yield return a.WithPalette(wr.Palette("disabled")).WithZOffset(1);
} }
} }
@@ -94,7 +84,7 @@ namespace OpenRA.Mods.RA.Render
public void PlayCustomAnimRepeating(Actor self, string name) public void PlayCustomAnimRepeating(Actor self, string name)
{ {
anim.PlayThen(NormalizeSequence(self, name), anim.PlayThen(NormalizeSequence(self, name),
() => { PlayCustomAnimRepeating(self, name); }); () => PlayCustomAnimRepeating(self, name));
} }
public void PlayCustomAnimBackwards(Actor self, string name, Action a) public void PlayCustomAnimBackwards(Actor self, string name, Action a)
@@ -110,10 +100,8 @@ namespace OpenRA.Mods.RA.Render
public virtual void DamageStateChanged(Actor self, AttackInfo e) public virtual void DamageStateChanged(Actor self, AttackInfo e)
{ {
if (e.DamageState >= DamageState.Heavy && e.PreviousDamageState < DamageState.Heavy) if (anim.CurrentSequence != null)
anim.ReplaceAnim("damaged-idle"); anim.ReplaceAnim(NormalizeSequence(self, "idle"));
else if (e.DamageState < DamageState.Heavy)
anim.ReplaceAnim("idle");
} }
} }
} }

View File

@@ -14,20 +14,17 @@ namespace OpenRA.Mods.RA.Render
{ {
class RenderBuildingSiloInfo : RenderBuildingInfo class RenderBuildingSiloInfo : RenderBuildingInfo
{ {
public readonly int FillSteps = 49;
public override object Create(ActorInitializer init) { return new RenderBuildingSilo(init, this); } public override object Create(ActorInitializer init) { return new RenderBuildingSilo(init, this); }
} }
class RenderBuildingSilo : RenderBuilding, INotifyBuildComplete, INotifyCapture class RenderBuildingSilo : RenderBuilding, INotifyBuildComplete, INotifyCapture
{ {
PlayerResources playerResources; PlayerResources playerResources;
readonly RenderBuildingSiloInfo Info;
public RenderBuildingSilo( ActorInitializer init, RenderBuildingSiloInfo info ) public RenderBuildingSilo( ActorInitializer init, RenderBuildingSiloInfo info )
: base(init, info) : base(init, info)
{ {
playerResources = init.self.Owner.PlayerActor.Trait<PlayerResources>(); playerResources = init.self.Owner.PlayerActor.Trait<PlayerResources>();
Info = info;
} }
public void BuildingComplete(Actor self) public void BuildingComplete(Actor self)
@@ -35,7 +32,7 @@ namespace OpenRA.Mods.RA.Render
var animation = (self.GetDamageState() >= DamageState.Heavy) ? "damaged-idle" : "idle"; var animation = (self.GetDamageState() >= DamageState.Heavy) ? "damaged-idle" : "idle";
anim.PlayFetchIndex(animation, anim.PlayFetchIndex(animation,
() => playerResources.OreCapacity != 0 () => playerResources.OreCapacity != 0
? (Info.FillSteps * playerResources.Ore) / (10 * playerResources.OreCapacity) ? ((10 * anim.CurrentSequence.Length - 1) * playerResources.Ore) / (10 * playerResources.OreCapacity)
: 0); : 0);
} }

View File

@@ -37,16 +37,7 @@ namespace OpenRA.Mods.RA.Render
public override void DamageStateChanged(Actor self, AttackInfo e) public override void DamageStateChanged(Actor self, AttackInfo e)
{ {
if (e.DamageState == DamageState.Medium && anim.HasSequence("scratched-idle")) anim.PlayFetchIndex(NormalizeSequence(anim, e.DamageState, "idle"), () => adjacentWalls);
seqName = "scratched-idle";
else if (e.DamageState <= DamageState.Medium)
seqName = "idle";
else if (e.DamageState == DamageState.Critical && anim.HasSequence("critical-idle"))
seqName = "critical-idle";
else if (e.DamageState <= DamageState.Critical)
seqName = "damaged-idle";
anim.PlayFetchIndex(seqName, () => adjacentWalls);
} }
bool hasTicked = false; bool hasTicked = false;

View File

@@ -34,7 +34,7 @@ namespace OpenRA.Mods.RA.Render
var anim = new Animation(RenderSprites.GetImage(building), () => 0); var anim = new Animation(RenderSprites.GetImage(building), () => 0);
anim.PlayRepeating("idle-top"); anim.PlayRepeating("idle-top");
yield return new SpriteRenderable(anim.Image, WPos.Zero + Origin, 0, pr, 1f); yield return new SpriteRenderable(anim.Image, WPos.Zero, 0, pr, 1f);
} }
} }

View File

@@ -0,0 +1,70 @@
#region Copyright & License Information
/*
* Copyright 2007-2013 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation. For more information,
* see COPYING.
*/
#endregion
using System.Collections.Generic;
using System.Linq;
using OpenRA.FileFormats;
using OpenRA.Graphics;
using OpenRA.Traits;
namespace OpenRA.Mods.RA.Render
{
class WithResourcesInfo : ITraitInfo, Requires<RenderSimpleInfo>
{
[Desc("Sequence name to use")]
public readonly string Sequence = "resources";
public object Create(ActorInitializer init) { return new WithResources(init.self, this); }
}
class WithResources : INotifyBuildComplete, INotifySold, INotifyCapture, INotifyDamageStateChanged
{
WithResourcesInfo info;
Animation anim;
RenderSimple rs;
PlayerResources playerResources;
bool buildComplete;
public WithResources(Actor self, WithResourcesInfo info)
{
this.info = info;
rs = self.Trait<RenderSimple>();
playerResources = self.Owner.PlayerActor.Trait<PlayerResources>();
anim = new Animation(rs.GetImage(self));
anim.PlayFetchIndex(info.Sequence,
() => playerResources.OreCapacity != 0
? ((10 * anim.CurrentSequence.Length - 1) * playerResources.Ore) / (10 * playerResources.OreCapacity)
: 0);
rs.anims.Add("resources_{0}".F(info.Sequence), new AnimationWithOffset(
anim, null, () => !buildComplete, 1024));
}
public void BuildingComplete( Actor self )
{
buildComplete = true;
}
public void DamageStateChanged(Actor self, AttackInfo e)
{
if (anim.CurrentSequence != null)
anim.ReplaceAnim(rs.NormalizeSequence(self, info.Sequence));
}
public void OnCapture (Actor self, Actor captor, Player oldOwner, Player newOwner)
{
playerResources = newOwner.PlayerActor.Trait<PlayerResources>();
}
public void Selling(Actor self) { rs.anims.Remove("resources_{0}".F(info.Sequence)); }
public void Sold(Actor self) { }
}
}

View File

@@ -24,6 +24,8 @@ BOAT:
LocalOffset: 213,-180,0, 213,128,0, 213,0,0 LocalOffset: 213,-180,0, 213,128,0, 213,0,0
AttackTurreted: AttackTurreted:
RenderGunboat: RenderGunboat:
Selectable:
Bounds: 42,24
AutoTarget: AutoTarget:
AllowMovement: false AllowMovement: false
WithSmoke: WithSmoke:

View File

@@ -134,8 +134,7 @@ PROC:
InitialActivity: FindResources InitialActivity: FindResources
SpawnOffset: 1,2 SpawnOffset: 1,2
Facing: 64 Facing: 64
-RenderBuilding: WithResources:
RenderBuildingRefinery:
SILO: SILO:
Inherits: ^Building Inherits: ^Building
@@ -161,7 +160,7 @@ SILO:
Range: 4 Range: 4
RenderBuildingSilo: RenderBuildingSilo:
StoresOre: StoresOre:
PipCount: 24 PipCount: 10
PipColor: Green PipColor: Green
Capacity: 2400 Capacity: 2400
Selectable: Selectable:

View File

@@ -12,22 +12,26 @@ boat:
left: left:
Start: 0 Start: 0
Facings: 32 Facings: 32
left-damaged: damaged-left:
Start: 32 Start: 32
left-critical: Facings: 32
critical-left:
Start: 64 Start: 64
left-wake: wake Facings: 32
wake-left: wake
Start: 6 Start: 6
Length: 6 Length: 6
Offset: 1,2
right: right:
Start: 96 Start: 96
Facings: 32 Facings: 32
right-damaged: damaged-right:
Start: 128 Start: 128
Facings: 32 Facings: 32
right-critical: critical-right:
Start: 160 Start: 160
Facings: 32 Facings: 32
right-wake: wake wake-right: wake
Start: 0 Start: 0
Length: 6 Length: 6
Offset: -1,2

View File

@@ -482,9 +482,11 @@ v19.husk:
fire-start: flmspt fire-start: flmspt
Start: 0 Start: 0
Length: * Length: *
Offset: 7,-15
fire-loop: flmspt fire-loop: flmspt
Start: 50 Start: 50
Length: * Length: *
Offset: 7,-15
v20: v20:
idle: idle:

View File

@@ -7,9 +7,11 @@ fire:
1: fire1 1: fire1
Start: 0 Start: 0
Length: * Length: *
Offset: 0,-3
2: fire2 2: fire2
Start: 0 Start: 0
Length: * Length: *
Offset: 0,-3
120mm: 120mm:
idle: idle:
@@ -145,6 +147,7 @@ rallypoint:
flag:flagfly flag:flagfly
Start: 0 Start: 0
Length: * Length: *
Offset: 10,-5
circles:fpls circles:fpls
Start: 0 Start: 0
Length: * Length: *

View File

@@ -54,12 +54,14 @@ proc:
Start: 0 Start: 0
Length: * Length: *
Tick: 80 Tick: 80
lights: proctwr resources: proctwr
Start: 0 Start: 0
Length: 6 Length: 6
damaged-lights: proctwr Offset: -32,-21
damaged-resources: proctwr
Start: 6 Start: 6
Length: 6 Length: 6
Offset: -32,-21
silo: silo:
idle: idle:

View File

@@ -168,7 +168,6 @@
Range: 4 Range: 4
-RenderBuilding: -RenderBuilding:
RenderBuildingSilo: RenderBuildingSilo:
FillSteps: 39
StoresOre: StoresOre:
PipColor: green PipColor: green
PipCount: 5 PipCount: 5

View File

@@ -1143,6 +1143,7 @@ rallypoint:
flag:flagfly flag:flagfly
Start: 0 Start: 0
Length: * Length: *
Offset: 11,-5
circles:fpls circles:fpls
Start: 0 Start: 0
Length: * Length: *
@@ -1259,15 +1260,19 @@ fire:
1: fire2 1: fire2
Start: 0 Start: 0
Length: * Length: *
Offset: 0,-3
2: fire2 2: fire2
Start: 0 Start: 0
Length: * Length: *
Offset: 0,-3
3: fire3 3: fire3
Start: 0 Start: 0
Length: * Length: *
Offset: 0,-3
4: fire 4: fire
Start: 0 Start: 0
Length: * Length: *
Offset: 0,-3
smoke_m: smoke_m:
idle: minifire idle: minifire

View File

@@ -1009,7 +1009,6 @@ SILO:
RevealsShroud: RevealsShroud:
Range: 4 Range: 4
RenderBuildingSilo: RenderBuildingSilo:
FillSteps: 89
StoresOre: StoresOre:
PipCount: 5 PipCount: 5
Capacity: 1500 Capacity: 1500

View File

@@ -95,6 +95,7 @@ rallypoint:
flag:flagfly flag:flagfly
Start: 0 Start: 0
Length: * Length: *
Offset: 11,-5
circles:fpls circles:fpls
Start: 0 Start: 0
Length: * Length: *
@@ -174,6 +175,7 @@ sputnik:
idle: idle:
Start: 0 Start: 0
Length: * Length: *
Offset: -4,0
dd-crnr: dd-crnr:
idle: idle:
@@ -319,15 +321,19 @@ fire:
1: fire1 1: fire1
Start: 0 Start: 0
Length: * Length: *
Offset: 0,-3
2: fire2 2: fire2
Start: 0 Start: 0
Length: * Length: *
Offset: 0,-3
3: fire3 3: fire3
Start: 0 Start: 0
Length: * Length: *
Offset: 0,-3
4: fire4 4: fire4
Start: 0 Start: 0
Length: * Length: *
Offset: 0,-3
rank: rank:
rank: rank:

View File

@@ -148,6 +148,7 @@ atek:
active: sputdoor active: sputdoor
Start: 0 Start: 0
Length: * Length: *
Offset: -4,0
stek: stek:
idle: idle: