From c1cba4ecc18c162be45445bc1f64077c56d804ff Mon Sep 17 00:00:00 2001 From: reaperrr Date: Sun, 19 Nov 2017 17:10:29 +0100 Subject: [PATCH] Make Gate more independent from Building and pausable-conditional Replace Gate IsDisabled checks with IsTraitDisabled/Paused checks --- OpenRA.Mods.Common/Traits/Buildings/Gate.cs | 46 ++++++++++------- .../Traits/Render/WithGateSpriteBody.cs | 2 +- .../UtilityCommands/UpgradeRules.cs | 49 +++++++++++++++++++ mods/ra/rules/defaults.yaml | 10 ++-- mods/ra/rules/structures.yaml | 4 +- mods/ts/rules/defaults.yaml | 19 ++++--- 6 files changed, 93 insertions(+), 37 deletions(-) diff --git a/OpenRA.Mods.Common/Traits/Buildings/Gate.cs b/OpenRA.Mods.Common/Traits/Buildings/Gate.cs index 1806b4156f..61ce1b23de 100644 --- a/OpenRA.Mods.Common/Traits/Buildings/Gate.cs +++ b/OpenRA.Mods.Common/Traits/Buildings/Gate.cs @@ -16,7 +16,7 @@ using OpenRA.Traits; namespace OpenRA.Mods.Common.Traits { [Desc("Will open and be passable for actors that appear friendly when there are no enemies in range.")] - public class GateInfo : BuildingInfo, IBlocksProjectilesInfo + public class GateInfo : PausableConditionalTraitInfo, IBlocksProjectilesInfo, Requires { public readonly string OpeningSound = null; public readonly string ClosingSound = null; @@ -33,11 +33,13 @@ namespace OpenRA.Mods.Common.Traits public override object Create(ActorInitializer init) { return new Gate(init, this); } } - public class Gate : Building, ITick, ITemporaryBlocker, IBlocksProjectiles, INotifyBlockingMove, ISync + public class Gate : PausableConditionalTrait, ITick, ITemporaryBlocker, IBlocksProjectiles, + INotifyAddedToWorld, INotifyRemovedFromWorld, INotifyBlockingMove, ISync { - readonly GateInfo info; readonly Actor self; + readonly Building building; IEnumerable blockedPositions; + public readonly IEnumerable Footprint; public readonly int OpenPosition; [Sync] public int Position { get; private set; } @@ -45,16 +47,18 @@ namespace OpenRA.Mods.Common.Traits int remainingOpenTime; public Gate(ActorInitializer init, GateInfo info) - : base(init, info) + : base(info) { - this.info = info; self = init.Self; - OpenPosition = info.TransitionDelay; + OpenPosition = Info.TransitionDelay; + building = self.Trait(); + blockedPositions = building.Info.Tiles(self.Location); + Footprint = blockedPositions; } void ITick.Tick(Actor self) { - if (self.IsDisabled() || Locked || !BuildComplete) + if (IsTraitDisabled || IsTraitPaused || building.Locked || !building.BuildComplete) return; if (desiredPosition < Position) @@ -62,8 +66,8 @@ namespace OpenRA.Mods.Common.Traits // Gate was fully open if (Position == OpenPosition) { - Game.Sound.Play(SoundType.World, info.ClosingSound, self.CenterPosition); - self.World.ActorMap.AddInfluence(self, this); + Game.Sound.Play(SoundType.World, Info.ClosingSound, self.CenterPosition); + self.World.ActorMap.AddInfluence(self, building); } Position--; @@ -72,22 +76,22 @@ namespace OpenRA.Mods.Common.Traits { // Gate was fully closed if (Position == 0) - Game.Sound.Play(SoundType.World, info.OpeningSound, self.CenterPosition); + Game.Sound.Play(SoundType.World, Info.OpeningSound, self.CenterPosition); Position++; // Gate is now fully open if (Position == OpenPosition) { - self.World.ActorMap.RemoveInfluence(self, this); - remainingOpenTime = info.CloseDelay; + self.World.ActorMap.RemoveInfluence(self, building); + remainingOpenTime = Info.CloseDelay; } } if (Position == OpenPosition) { if (IsBlocked()) - remainingOpenTime = info.CloseDelay; + remainingOpenTime = Info.CloseDelay; else if (--remainingOpenTime <= 0) desiredPosition = 0; } @@ -109,15 +113,19 @@ namespace OpenRA.Mods.Common.Traits desiredPosition = OpenPosition; } - bool CanRemoveBlockage(Actor self, Actor blocking) + void INotifyAddedToWorld.AddedToWorld(Actor self) { - return !self.IsDisabled() && BuildComplete && blocking.AppearsFriendlyTo(self); + blockedPositions = Footprint; } - protected override void AddedToWorld(Actor self) + void INotifyRemovedFromWorld.RemovedFromWorld(Actor self) { - base.AddedToWorld(self); - blockedPositions = Info.Tiles(self.Location); + blockedPositions = Enumerable.Empty(); + } + + bool CanRemoveBlockage(Actor self, Actor blocking) + { + return !IsTraitDisabled && !IsTraitPaused && building.BuildComplete && !building.Locked && blocking.AppearsFriendlyTo(self); } bool IsBlocked() @@ -129,7 +137,7 @@ namespace OpenRA.Mods.Common.Traits { get { - return new WDist(info.BlocksProjectilesHeight.Length * (OpenPosition - Position) / OpenPosition); + return new WDist(Info.BlocksProjectilesHeight.Length * (OpenPosition - Position) / OpenPosition); } } } diff --git a/OpenRA.Mods.Common/Traits/Render/WithGateSpriteBody.cs b/OpenRA.Mods.Common/Traits/Render/WithGateSpriteBody.cs index fcdc12a4ec..dbb3c2bcbd 100644 --- a/OpenRA.Mods.Common/Traits/Render/WithGateSpriteBody.cs +++ b/OpenRA.Mods.Common/Traits/Render/WithGateSpriteBody.cs @@ -96,7 +96,7 @@ namespace OpenRA.Mods.Common.Traits.Render void UpdateNeighbours(Actor self) { - var footprint = gate.Info.Tiles(self.Location).ToArray(); + var footprint = gate.Footprint.ToArray(); var adjacent = Util.ExpandFootprint(footprint, true).Except(footprint) .Where(self.World.Map.Contains).ToList(); diff --git a/OpenRA.Mods.Common/UtilityCommands/UpgradeRules.cs b/OpenRA.Mods.Common/UtilityCommands/UpgradeRules.cs index e720a2e60b..0d4bdc08d5 100644 --- a/OpenRA.Mods.Common/UtilityCommands/UpgradeRules.cs +++ b/OpenRA.Mods.Common/UtilityCommands/UpgradeRules.cs @@ -1498,6 +1498,55 @@ namespace OpenRA.Mods.Common.UtilityCommands } } + // Made Gate not inherit Building + if (engineVersion < 20171119) + { + var gate = node.Value.Nodes.FirstOrDefault(n => n.Key == "Gate"); + if (gate != null) + { + var openSound = gate.Value.Nodes.FirstOrDefault(n => n.Key == "OpeningSound"); + var closeSound = gate.Value.Nodes.FirstOrDefault(n => n.Key == "ClosingSound"); + var closeDelay = gate.Value.Nodes.FirstOrDefault(n => n.Key == "CloseDelay"); + var transitDelay = gate.Value.Nodes.FirstOrDefault(n => n.Key == "TransitionDelay"); + var blockHeight = gate.Value.Nodes.FirstOrDefault(n => n.Key == "BlocksProjectilesHeight"); + + gate.Key = "Building"; + var newGate = new MiniYamlNode("Gate", ""); + + if (openSound != null) + { + newGate.Value.Nodes.Add(openSound); + gate.Value.Nodes.Remove(openSound); + } + + if (closeSound != null) + { + newGate.Value.Nodes.Add(closeSound); + gate.Value.Nodes.Remove(closeSound); + } + + if (closeDelay != null) + { + newGate.Value.Nodes.Add(closeDelay); + gate.Value.Nodes.Remove(closeDelay); + } + + if (transitDelay != null) + { + newGate.Value.Nodes.Add(transitDelay); + gate.Value.Nodes.Remove(transitDelay); + } + + if (blockHeight != null) + { + newGate.Value.Nodes.Add(blockHeight); + gate.Value.Nodes.Remove(blockHeight); + } + + node.Value.Nodes.Add(newGate); + } + } + UpgradeActorRules(modData, engineVersion, ref node.Value.Nodes, node, depth + 1); } diff --git a/mods/ra/rules/defaults.yaml b/mods/ra/rules/defaults.yaml index befe14f1d8..1a23f02cf6 100644 --- a/mods/ra/rules/defaults.yaml +++ b/mods/ra/rules/defaults.yaml @@ -707,22 +707,22 @@ Type: Heavy LineBuildNode: Types: concrete, gate - -Building: -WithSpriteBody: WithGateSpriteBody: Tooltip: Name: Gate - Gate: - BlocksProjectilesHeight: 0 + Building: BuildSounds: place2.aud - OpeningSound: cashturn.aud - ClosingSound: cashturn.aud TerrainTypes: Clear, Road RequiresBuildableArea: AreaTypes: building Adjacent: 4 EditorTilesetFilter: Categories: Wall + Gate: + OpeningSound: cashturn.aud + ClosingSound: cashturn.aud + BlocksProjectilesHeight: 0 ^TechBuilding: Inherits: ^BasicBuilding diff --git a/mods/ra/rules/structures.yaml b/mods/ra/rules/structures.yaml index 22e99e8f43..7438380cd9 100644 --- a/mods/ra/rules/structures.yaml +++ b/mods/ra/rules/structures.yaml @@ -1912,7 +1912,7 @@ VGATE: Type: Rectangle TopLeft: -512, -1536 BottomRight: 512, 1536 - Gate: + Building: Footprint: x x x Dimensions: 1,3 WithGateSpriteBody: @@ -1929,7 +1929,7 @@ HGATE: Type: Rectangle TopLeft: -1536, -512 BottomRight: 1536, 512 - Gate: + Building: Footprint: xxx Dimensions: 3,1 WithGateSpriteBody: diff --git a/mods/ts/rules/defaults.yaml b/mods/ts/rules/defaults.yaml index 1c4daa33a4..2e900df8a6 100644 --- a/mods/ts/rules/defaults.yaml +++ b/mods/ts/rules/defaults.yaml @@ -307,7 +307,7 @@ Dimensions: 1,1 Footprint: x BuildSounds: place2.aud - TerrainTypes: Clear, Road, DirtRoad, Rough + TerrainTypes: Clear, Rough, Road, DirtRoad, Green, Sand, Pavement RequiresBuildableArea: AreaTypes: building Adjacent: 4 @@ -1128,6 +1128,7 @@ ^Gate: Inherits: ^Building + Inherits@EMPDISABLE: ^EmpDisable Huntable: Valued: Cost: 250 @@ -1137,7 +1138,6 @@ Type: Heavy LineBuildNode: Types: wall, gate - -Building: -Capturable: -GivesBuildableArea: -MustBeDestroyed: @@ -1145,12 +1145,6 @@ WithGateSpriteBody: OpenSequence: open Tooltip: - Gate: - BuildSounds: place2.aud - OpeningSound: gateup1.aud - ClosingSound: gatedwn1.aud - TerrainTypes: Clear, Rough, Road, DirtRoad, Green, Sand, Pavement - BlocksProjectilesHeight: 768 Buildable: Description: Automated barrier that opens for allied units. HitShape: @@ -1161,12 +1155,17 @@ VerticalTopOffset: 768 EditorTilesetFilter: Categories: Wall + Gate: + OpeningSound: gateup1.aud + ClosingSound: gatedwn1.aud + BlocksProjectilesHeight: 768 + PauseOnCondition: empdisable ^Gate_A: Inherits: ^Gate Inherits@shape: ^3x1Shape Health: - Gate: + Building: Dimensions: 3,1 Footprint: xxx WithGateSpriteBody: @@ -1178,7 +1177,7 @@ Inherits: ^Gate Inherits@shape: ^1x3Shape Health: - Gate: + Building: Dimensions: 1,3 Footprint: x x x WithGateSpriteBody: