From 9c20de7d9863d1637ff1dc6568c8eb377ab2d977 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Mail=C3=A4nder?= Date: Sat, 18 Apr 2015 09:46:09 +0200 Subject: [PATCH 1/6] readonly and don't sync cosmetic traits --- .../Traits/Render/RenderBuildingWarFactory.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/OpenRA.Mods.Common/Traits/Render/RenderBuildingWarFactory.cs b/OpenRA.Mods.Common/Traits/Render/RenderBuildingWarFactory.cs index 498764b8da..a8c53111c6 100644 --- a/OpenRA.Mods.Common/Traits/Render/RenderBuildingWarFactory.cs +++ b/OpenRA.Mods.Common/Traits/Render/RenderBuildingWarFactory.cs @@ -35,11 +35,11 @@ namespace OpenRA.Mods.Common.Traits } } - class RenderBuildingWarFactory : RenderBuilding, INotifyBuildComplete, ITick, INotifyProduction, INotifySold, ISync + class RenderBuildingWarFactory : RenderBuilding, INotifyBuildComplete, ITick, INotifyProduction, INotifySold { - Animation roof; - [Sync] bool isOpen; - [Sync] CPos openExit; + readonly Animation roof; + bool isOpen; + CPos openExit; bool buildComplete; public RenderBuildingWarFactory(ActorInitializer init, RenderBuildingInfo info) From 9a37e77d1ae308083dbc210bdff3559694e774fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Mail=C3=A4nder?= Date: Mon, 20 Apr 2015 21:20:06 +0200 Subject: [PATCH 2/6] fix the weapon factory door opening animation --- OpenRA.Mods.Common/OpenRA.Mods.Common.csproj | 1 + .../Render/WithProductionDoorOverlay.cs | 91 +++++++++++++++++++ mods/ts/rules/gdi-structures.yaml | 5 +- mods/ts/rules/nod-structures.yaml | 5 +- mods/ts/sequences/structures.yaml | 48 ++++++---- 5 files changed, 126 insertions(+), 24 deletions(-) create mode 100644 OpenRA.Mods.Common/Traits/Render/WithProductionDoorOverlay.cs diff --git a/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj b/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj index c617cbea48..49d839cb9a 100644 --- a/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj +++ b/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj @@ -405,6 +405,7 @@ + diff --git a/OpenRA.Mods.Common/Traits/Render/WithProductionDoorOverlay.cs b/OpenRA.Mods.Common/Traits/Render/WithProductionDoorOverlay.cs new file mode 100644 index 0000000000..85f95d526c --- /dev/null +++ b/OpenRA.Mods.Common/Traits/Render/WithProductionDoorOverlay.cs @@ -0,0 +1,91 @@ +#region Copyright & License Information +/* + * Copyright 2007-2015 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.Mods.Common.Graphics; +using OpenRA.Mods.Common.Traits; +using OpenRA.Traits; + +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 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); + + var bi = init.Actor.Traits.Get(); + var offset = FootprintUtils.CenterOffset(init.World, bi).Y + 512; // Additional 512 units move from center -> top of cell + yield return new SpriteActorPreview(anim, WVec.Zero, offset, p, rs.Scale); + } + } + + class WithProductionDoorOverlay : INotifyBuildComplete, ITick, INotifyProduction, INotifySold, INotifyDamageStateChanged + { + readonly WithProductionDoorOverlayInfo info; + readonly RenderSprites renderSprites; + readonly Animation door; + + bool isOpen; + CPos openExit; + bool buildComplete; + + public WithProductionDoorOverlay(Actor self, WithProductionDoorOverlayInfo info) + { + this.info = info; + renderSprites = self.Trait(); + door = new Animation(self.World, renderSprites.GetImage(self)); + door.Play(RenderSprites.NormalizeSequence(door, self.GetDamageState(), info.Sequence)); + + var buildingInfo = self.Info.Traits.Get(); + + var offset = FootprintUtils.CenterOffset(self.World, buildingInfo).Y + 512; + renderSprites.Add("door_overlay_{0}".F(info.Sequence), new AnimationWithOffset(door, null, () => !buildComplete, offset)); + } + + public void BuildingComplete(Actor self) + { + buildComplete = true; + } + + 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))); + } + } + + public void DamageStateChanged(Actor self, AttackInfo e) + { + if (door.CurrentSequence != null) + door.ReplaceAnim(RenderSprites.NormalizeSequence(door, e.DamageState, door.CurrentSequence.Name)); + } + + public void UnitProduced(Actor self, Actor other, CPos exit) + { + door.PlayThen(RenderSprites.NormalizeSequence(door, self.GetDamageState(), info.BuildSequence), () => { isOpen = true; openExit = exit; }); + } + + public void Selling(Actor self) { buildComplete = false; } + public void Sold(Actor self) { } + } +} diff --git a/mods/ts/rules/gdi-structures.yaml b/mods/ts/rules/gdi-structures.yaml index 6ecf481663..a3138fcf3e 100644 --- a/mods/ts/rules/gdi-structures.yaml +++ b/mods/ts/rules/gdi-structures.yaml @@ -123,8 +123,6 @@ GAWEAP: HP: 1000 RevealsShroud: Range: 4c0 - -RenderBuilding: - RenderBuildingWarFactory: RallyPoint: RallyPoint: 6,1 Exit@1: @@ -134,6 +132,9 @@ GAWEAP: Produces: Vehicle PrimaryBuilding: ProductionBar: + WithIdleOverlay@ROOF: + Sequence: idle-roof + WithProductionDoorOverlay@DOOR: WithProductionOverlay@WHITELIGHTS: Sequence: production-lights-white WithProductionOverlay@REDLIGHTS: diff --git a/mods/ts/rules/nod-structures.yaml b/mods/ts/rules/nod-structures.yaml index 15118349d8..71aa3ad2e4 100644 --- a/mods/ts/rules/nod-structures.yaml +++ b/mods/ts/rules/nod-structures.yaml @@ -130,8 +130,6 @@ NAWEAP: HP: 1000 RevealsShroud: Range: 4c0 - -RenderBuilding: - RenderBuildingWarFactory: RallyPoint: RallyPoint: 6,1 Exit@1: @@ -141,6 +139,9 @@ NAWEAP: Produces: Vehicle PrimaryBuilding: ProductionBar: + WithIdleOverlay@ROOF: + Sequence: idle-roof + WithProductionDoorOverlay@DOOR: WithProductionOverlay@LIGHTS: Sequence: production-lights WithIdleOverlay@BIB: diff --git a/mods/ts/sequences/structures.yaml b/mods/ts/sequences/structures.yaml index 7deb008378..0ba1da08d2 100644 --- a/mods/ts/sequences/structures.yaml +++ b/mods/ts/sequences/structures.yaml @@ -136,12 +136,17 @@ gaweap: Defaults: Offset: -12, -42 UseTilesetCode: true - idle: - ShadowStart: 3 - damaged-idle: + idle: gtweap_1 + ShadowStart: 2 + damaged-idle: gtweap_1 Start: 1 - ShadowStart: 4 - dead: + ShadowStart: 3 + idle-roof: gtweap_2 + ShadowStart: 2 + damaged-idle-roof: gtweap_2 + Start: 1 + ShadowStart: 3 + dead: gtweap Start: 2 ShadowStart: 5 Tick: 400 @@ -171,14 +176,14 @@ gaweap: Length: 4 Tick: 80 ZOffset: 2048 - build-top: gtweap_d + build-door: gtweap_d Length: 9 ShadowStart: 9 - damaged-build-top: gtweap_d + damaged-build-door: gtweap_d Length: 9 ShadowStart: 9 - idle-top: gtweap_2 - damaged-idle-top: gtweap_2 + idle-door: gtweap_d + damaged-idle-door: gtweap_d Start: 1 make: gtweapmk Length: 20 @@ -195,7 +200,6 @@ gaweap: icon: weapicon Offset: 0, 0 UseTilesetCode: false -# TODO: gtweap_1 & gtweap_a & gtweap_b & gtweap_c are unused napowr: Defaults: @@ -289,12 +293,17 @@ naweap: Defaults: Offset: -12, -42 UseTilesetCode: true - idle: - ShadowStart: 3 - damaged-idle: + idle: ntweap_1 + ShadowStart: 2 + damaged-idle: ntweap_1 Start: 1 - ShadowStart: 4 - dead: + ShadowStart: 3 + idle-roof: ntweap_2 + ShadowStart: 2 + damaged-idle-roof: ntweap_2 + Start: 1 + ShadowStart: 3 + dead: ntweap Start: 2 ShadowStart: 5 Tick: 400 @@ -307,15 +316,15 @@ naweap: Length: 16 Tick: 100 ZOffset: 2048 - build-top: ntweap_b + build-door: ntweap_b Length: 10 ShadowStart: 10 - damaged-build-top: ntweap_b + damaged-build-door: ntweap_b Start: 10 Length: 10 ShadowStart: 20 - idle-top: ntweap_2 - damaged-idle-top: ntweap_2 + idle-door: ntweap_b + damaged-idle-door: ntweap_b Start: 1 make: ntweapmk Length: 22 @@ -329,7 +338,6 @@ naweap: icon: nwepicon Offset: 0, 0 UseTilesetCode: false -# TODO: ntweap_1 & ntweap_b & ntweap_c are unused naradr: Defaults: From 8c8b9b1cc38c9edaf40b8c8742f22f77ef1be3d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Mail=C3=A4nder?= Date: Sat, 25 Apr 2015 08:00:45 +0200 Subject: [PATCH 3/6] deprecate RenderBuildingWarFactory --- OpenRA.Mods.Common/OpenRA.Mods.Common.csproj | 1 - .../Traits/Render/RenderBuildingWarFactory.cs | 96 ------------------- mods/cnc/rules/structures.yaml | 5 +- mods/d2k/rules/structures.yaml | 3 +- mods/ra/rules/fakes.yaml | 5 +- mods/ra/rules/structures.yaml | 5 +- 6 files changed, 10 insertions(+), 105 deletions(-) delete mode 100644 OpenRA.Mods.Common/Traits/Render/RenderBuildingWarFactory.cs diff --git a/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj b/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj index 49d839cb9a..42336b5898 100644 --- a/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj +++ b/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj @@ -370,7 +370,6 @@ - diff --git a/OpenRA.Mods.Common/Traits/Render/RenderBuildingWarFactory.cs b/OpenRA.Mods.Common/Traits/Render/RenderBuildingWarFactory.cs deleted file mode 100644 index a8c53111c6..0000000000 --- a/OpenRA.Mods.Common/Traits/Render/RenderBuildingWarFactory.cs +++ /dev/null @@ -1,96 +0,0 @@ -#region Copyright & License Information -/* - * Copyright 2007-2015 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.Mods.Common.Graphics; -using OpenRA.Traits; - -namespace OpenRA.Mods.Common.Traits -{ - class RenderBuildingWarFactoryInfo : RenderBuildingInfo - { - public override object Create(ActorInitializer init) { return new RenderBuildingWarFactory(init, this); } - - public override IEnumerable RenderPreviewSprites(ActorPreviewInitializer init, RenderSpritesInfo rs, string image, int facings, PaletteReference p) - { - foreach (var orig in base.RenderPreviewSprites(init, rs, image, facings, p)) - yield return orig; - - // Show additional roof overlay - var anim = new Animation(init.World, image, () => 0); - anim.PlayRepeating("idle-top"); - - var bi = init.Actor.Traits.Get(); - var offset = FootprintUtils.CenterOffset(init.World, bi).Y + 512; - yield return new SpriteActorPreview(anim, WVec.Zero, offset, p, rs.Scale); - } - } - - class RenderBuildingWarFactory : RenderBuilding, INotifyBuildComplete, ITick, INotifyProduction, INotifySold - { - readonly Animation roof; - bool isOpen; - CPos openExit; - bool buildComplete; - - public RenderBuildingWarFactory(ActorInitializer init, RenderBuildingInfo info) - : base(init, info) - { - roof = new Animation(init.World, GetImage(init.Self)); - var bi = init.Self.Info.Traits.Get(); - - // Additional 512 units move from center -> top of cell - var offset = FootprintUtils.CenterOffset(init.World, bi).Y + 512; - Add("roof", new AnimationWithOffset(roof, null, - () => !buildComplete, offset)); - } - - public override void BuildingComplete(Actor self) - { - roof.Play(NormalizeSequence(self, - self.GetDamageState() > DamageState.Heavy ? "damaged-idle-top" : "idle-top")); - buildComplete = true; - } - - public override void Tick(Actor self) - { - base.Tick(self); - if (isOpen && !self.World.ActorMap.GetUnitsAt(openExit).Any(a => a != self)) - { - isOpen = false; - roof.PlayBackwardsThen(NormalizeSequence(self, "build-top"), - () => roof.Play(NormalizeSequence(self, "idle-top"))); - } - } - - public override void DamageStateChanged(Actor self, AttackInfo e) - { - if (roof.CurrentSequence != null) - { - if (e.DamageState >= DamageState.Heavy) - roof.ReplaceAnim("damaged-" + roof.CurrentSequence.Name); - else - roof.ReplaceAnim(roof.CurrentSequence.Name.Replace("damaged-", "")); - } - - base.DamageStateChanged(self, e); - } - - public void UnitProduced(Actor self, Actor other, CPos exit) - { - roof.PlayThen(NormalizeSequence(self, "build-top"), () => { isOpen = true; openExit = exit; }); - } - - public void Selling(Actor self) { Remove("roof"); } - public void Sold(Actor self) { } - } -} diff --git a/mods/cnc/rules/structures.yaml b/mods/cnc/rules/structures.yaml index 70b06a605f..f27dff3aa0 100644 --- a/mods/cnc/rules/structures.yaml +++ b/mods/cnc/rules/structures.yaml @@ -363,8 +363,9 @@ WEAP: RevealsShroud: Range: 4c0 Bib: - -RenderBuilding: - RenderBuildingWarFactory: + WithProductionDoorOverlay: + Sequence: idle-top + BuildSequence: build-top RallyPoint: RallyPoint: 0,3 Exit@1: diff --git a/mods/d2k/rules/structures.yaml b/mods/d2k/rules/structures.yaml index 0038aec005..cfe97627c2 100644 --- a/mods/d2k/rules/structures.yaml +++ b/mods/d2k/rules/structures.yaml @@ -200,8 +200,7 @@ refinery: DeliveryOffset: 2,2 DeliveringActor: carryall.reinforce Facing: 160 - -RenderBuilding: - RenderBuildingWarFactory: + RenderBuilding: Image: refinery.harkonnen RaceImages: atreides: refinery.atreides diff --git a/mods/ra/rules/fakes.yaml b/mods/ra/rules/fakes.yaml index 9d39c1e6f3..c24069c28c 100644 --- a/mods/ra/rules/fakes.yaml +++ b/mods/ra/rules/fakes.yaml @@ -37,9 +37,10 @@ WEAF: Footprint: xxx xxx Dimensions: 3,2 Bib: - -RenderBuilding: - RenderBuildingWarFactory: + RenderBuilding: Image: WEAP + WithIdleOverlay@ROOF: + Sequence: idle-top Valued: Cost: 200 diff --git a/mods/ra/rules/structures.yaml b/mods/ra/rules/structures.yaml index 0c634e1dff..c21635ae1c 100644 --- a/mods/ra/rules/structures.yaml +++ b/mods/ra/rules/structures.yaml @@ -761,8 +761,9 @@ WEAP: RevealsShroud: Range: 4c0 Bib: - -RenderBuilding: - RenderBuildingWarFactory: + WithProductionDoorOverlay: + Sequence: idle-top + BuildSequence: build-top RallyPoint: Exit@1: SpawnOffset: 213,-128,0 From b07d125d18e859bb15f3e6684241a72dee831702 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Mail=C3=A4nder?= Date: Sat, 25 Apr 2015 09:14:05 +0200 Subject: [PATCH 4/6] add an upgrade rule --- .../UtilityCommands/UpgradeRules.cs | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/OpenRA.Mods.Common/UtilityCommands/UpgradeRules.cs b/OpenRA.Mods.Common/UtilityCommands/UpgradeRules.cs index 0f55a7e5f1..448a73fbf8 100644 --- a/OpenRA.Mods.Common/UtilityCommands/UpgradeRules.cs +++ b/OpenRA.Mods.Common/UtilityCommands/UpgradeRules.cs @@ -836,6 +836,26 @@ namespace OpenRA.Mods.Common.UtilityCommands node.Key = "BlocksProjectiles"; } + if (engineVersion < 20150425) + { + if (depth == 0) + { + var warFact = node.Value.Nodes.FirstOrDefault(n => n.Key.StartsWith("RenderBuildingWarFactory")); + if (warFact != null) + { + warFact.Key = "RenderBuilding"; + + if (node.Value.Nodes.Any(w => w.Key == "-RenderBuilding")) + 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")); + node.Value.Nodes.Add(doorOverlay); + } + } + } + UpgradeActorRules(engineVersion, ref node.Value.Nodes, node, depth + 1); } } From 75624560d2a62c941b93b293683936e0b85d741a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Mail=C3=A4nder?= Date: Sat, 25 Apr 2015 09:17:05 +0200 Subject: [PATCH 5/6] remove trailing tabs --- mods/d2k/rules/starport.yaml | 2 +- mods/ts/rules/defaults.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mods/d2k/rules/starport.yaml b/mods/d2k/rules/starport.yaml index 90b7abae29..51db9ef7f2 100644 --- a/mods/d2k/rules/starport.yaml +++ b/mods/d2k/rules/starport.yaml @@ -83,7 +83,7 @@ combato.starport: Cost: 875 RenderUnit: Image: combato - + carryall.starport: Inherits: carryall Valued: diff --git a/mods/ts/rules/defaults.yaml b/mods/ts/rules/defaults.yaml index d9fd9790a9..e6835d98ae 100644 --- a/mods/ts/rules/defaults.yaml +++ b/mods/ts/rules/defaults.yaml @@ -486,7 +486,7 @@ UpgradeManager: MustBeDestroyed: -^Plane: +^Plane: Inherits: ^Helicopter -Helicopter: Plane: From 8f93d7b5d76a20174349830016a6ada05cb27ee4 Mon Sep 17 00:00:00 2001 From: Paul Chote Date: Sat, 25 Apr 2015 21:53:31 +1200 Subject: [PATCH 6/6] Simplify and fix animation glitches. --- OpenRA.Game/Graphics/Animation.cs | 20 +++++++++++++- .../Render/WithProductionDoorOverlay.cs | 27 ++++++++----------- .../UtilityCommands/UpgradeRules.cs | 3 +-- mods/cnc/rules/structures.yaml | 3 +-- mods/cnc/sequences/structures.yaml | 3 --- mods/ra/rules/structures.yaml | 3 +-- mods/ra/sequences/structures.yaml | 3 --- mods/ts/sequences/structures.yaml | 6 ----- 8 files changed, 33 insertions(+), 35 deletions(-) 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