diff --git a/OpenRA.Game/Graphics/Animation.cs b/OpenRA.Game/Graphics/Animation.cs index fcd3325bea..f2f51e4918 100644 --- a/OpenRA.Game/Graphics/Animation.cs +++ b/OpenRA.Game/Graphics/Animation.cs @@ -47,7 +47,7 @@ namespace OpenRA.Graphics this.facingFunc = facingFunc; } - int CurrentFrame { get { return backwards ? CurrentSequence.Start + CurrentSequence.Length - frame - 1 : frame; } } + public int CurrentFrame { get { return backwards ? CurrentSequence.Start + CurrentSequence.Length - frame - 1 : frame; } } public Sprite Image { get { return CurrentSequence.GetSprite(CurrentFrame, facingFunc()); } } public IEnumerable Render(WPos pos, WVec offset, int zOffset, PaletteReference palette, float scale) @@ -139,6 +139,24 @@ namespace OpenRA.Graphics tickFunc = () => frame = func(); } + public void PlayFetchDirection(string sequenceName, Func direction) + { + tickAlways = false; + CurrentSequence = sequenceProvider.GetSequence(name, sequenceName); + timeUntilNextFrame = CurrentSequence != null ? CurrentSequence.Tick : defaultTick; + + frame = 0; + tickFunc = () => + { + var d = direction(); + if (d > 0 && ++frame >= CurrentSequence.Length) + frame = 0; + + if (d < 0 && --frame < 0) + frame = CurrentSequence.Length - 1; + }; + } + int timeUntilNextFrame; Action tickFunc; diff --git a/OpenRA.Mods.Common/Traits/Render/WithProductionDoorOverlay.cs b/OpenRA.Mods.Common/Traits/Render/WithProductionDoorOverlay.cs index 85f95d526c..40c56daba9 100644 --- a/OpenRA.Mods.Common/Traits/Render/WithProductionDoorOverlay.cs +++ b/OpenRA.Mods.Common/Traits/Render/WithProductionDoorOverlay.cs @@ -20,15 +20,14 @@ namespace OpenRA.Mods.TS.Traits [Desc("Play an animation when a unit exits or blocks the exit after production finished.")] class WithProductionDoorOverlayInfo : ITraitInfo, IRenderActorPreviewSpritesInfo, Requires, Requires, Requires { - public readonly string Sequence = "idle-door"; - public readonly string BuildSequence = "build-door"; + public readonly string Sequence = "build-door"; public object Create(ActorInitializer init) { return new WithProductionDoorOverlay(init.Self, this); } public IEnumerable RenderPreviewSprites(ActorPreviewInitializer init, RenderSpritesInfo rs, string image, int facings, PaletteReference p) { var anim = new Animation(init.World, image, () => 0); - anim.PlayRepeating(Sequence); + anim.PlayFetchIndex(Sequence, () => 0); var bi = init.Actor.Traits.Get(); var offset = FootprintUtils.CenterOffset(init.World, bi).Y + 512; // Additional 512 units move from center -> top of cell @@ -38,20 +37,19 @@ namespace OpenRA.Mods.TS.Traits class WithProductionDoorOverlay : INotifyBuildComplete, ITick, INotifyProduction, INotifySold, INotifyDamageStateChanged { - readonly WithProductionDoorOverlayInfo info; - readonly RenderSprites renderSprites; readonly Animation door; - bool isOpen; + int desiredFrame; + CPos openExit; bool buildComplete; public WithProductionDoorOverlay(Actor self, WithProductionDoorOverlayInfo info) { - this.info = info; - renderSprites = self.Trait(); + var renderSprites = self.Trait(); door = new Animation(self.World, renderSprites.GetImage(self)); - door.Play(RenderSprites.NormalizeSequence(door, self.GetDamageState(), info.Sequence)); + door.PlayFetchDirection(RenderSprites.NormalizeSequence(door, self.GetDamageState(), info.Sequence), + () => desiredFrame - door.CurrentFrame); var buildingInfo = self.Info.Traits.Get(); @@ -66,12 +64,8 @@ namespace OpenRA.Mods.TS.Traits public void Tick(Actor self) { - if (isOpen && !self.World.ActorMap.GetUnitsAt(openExit).Any(a => a != self)) - { - isOpen = false; - door.PlayBackwardsThen(RenderSprites.NormalizeSequence(door, self.GetDamageState(), info.BuildSequence), - () => door.Play(RenderSprites.NormalizeSequence(door, self.GetDamageState(), info.Sequence))); - } + if (desiredFrame > 0 && !self.World.ActorMap.GetUnitsAt(openExit).Any(a => a != self)) + desiredFrame = 0; } public void DamageStateChanged(Actor self, AttackInfo e) @@ -82,7 +76,8 @@ namespace OpenRA.Mods.TS.Traits public void UnitProduced(Actor self, Actor other, CPos exit) { - door.PlayThen(RenderSprites.NormalizeSequence(door, self.GetDamageState(), info.BuildSequence), () => { isOpen = true; openExit = exit; }); + openExit = exit; + desiredFrame = door.CurrentSequence.Length - 1; } public void Selling(Actor self) { buildComplete = false; } diff --git a/OpenRA.Mods.Common/UtilityCommands/UpgradeRules.cs b/OpenRA.Mods.Common/UtilityCommands/UpgradeRules.cs index 448a73fbf8..1f5f80ce24 100644 --- a/OpenRA.Mods.Common/UtilityCommands/UpgradeRules.cs +++ b/OpenRA.Mods.Common/UtilityCommands/UpgradeRules.cs @@ -849,8 +849,7 @@ namespace OpenRA.Mods.Common.UtilityCommands node.Value.Nodes.RemoveAll(p => p.Key == "-RenderBuilding"); var doorOverlay = new MiniYamlNode("WithProductionDoorOverlay", ""); - doorOverlay.Value.Nodes.Add(new MiniYamlNode("Sequence", "idle-top")); - doorOverlay.Value.Nodes.Add(new MiniYamlNode("BuildSequence", "build-top")); + doorOverlay.Value.Nodes.Add(new MiniYamlNode("Sequence", "build-top")); node.Value.Nodes.Add(doorOverlay); } } diff --git a/mods/cnc/rules/structures.yaml b/mods/cnc/rules/structures.yaml index f27dff3aa0..4cae60fd46 100644 --- a/mods/cnc/rules/structures.yaml +++ b/mods/cnc/rules/structures.yaml @@ -364,8 +364,7 @@ WEAP: Range: 4c0 Bib: WithProductionDoorOverlay: - Sequence: idle-top - BuildSequence: build-top + Sequence: build-top RallyPoint: RallyPoint: 0,3 Exit@1: diff --git a/mods/cnc/sequences/structures.yaml b/mods/cnc/sequences/structures.yaml index 730103a8e1..2a33aff6c9 100644 --- a/mods/cnc/sequences/structures.yaml +++ b/mods/cnc/sequences/structures.yaml @@ -147,9 +147,6 @@ weap: damaged-build-top: weap2 Start: 10 Length: 10 - idle-top: weap2 - damaged-idle-top: weap2 - Start: 4 make: weapmake Length: * Tick: 80 diff --git a/mods/ra/rules/structures.yaml b/mods/ra/rules/structures.yaml index c21635ae1c..8514dc97f2 100644 --- a/mods/ra/rules/structures.yaml +++ b/mods/ra/rules/structures.yaml @@ -762,8 +762,7 @@ WEAP: Range: 4c0 Bib: WithProductionDoorOverlay: - Sequence: idle-top - BuildSequence: build-top + Sequence: build-top RallyPoint: Exit@1: SpawnOffset: 213,-128,0 diff --git a/mods/ra/sequences/structures.yaml b/mods/ra/sequences/structures.yaml index cfef2780a6..5c95b58876 100644 --- a/mods/ra/sequences/structures.yaml +++ b/mods/ra/sequences/structures.yaml @@ -236,9 +236,6 @@ weap: damaged-build-top: weap2 Start: 4 Length: 4 - idle-top: weap2 - damaged-idle-top: weap2 - Start: 4 bib: bib2 Length: * UseTilesetExtension: true diff --git a/mods/ts/sequences/structures.yaml b/mods/ts/sequences/structures.yaml index 0ba1da08d2..e55672301a 100644 --- a/mods/ts/sequences/structures.yaml +++ b/mods/ts/sequences/structures.yaml @@ -182,9 +182,6 @@ gaweap: damaged-build-door: gtweap_d Length: 9 ShadowStart: 9 - idle-door: gtweap_d - damaged-idle-door: gtweap_d - Start: 1 make: gtweapmk Length: 20 Tick: 80 @@ -323,9 +320,6 @@ naweap: Start: 10 Length: 10 ShadowStart: 20 - idle-door: ntweap_b - damaged-idle-door: ntweap_b - Start: 1 make: ntweapmk Length: 22 Tick: 80