diff --git a/OpenRA.Mods.Cnc/Traits/TransformsNearResources.cs b/OpenRA.Mods.Cnc/Traits/TransformsNearResources.cs new file mode 100644 index 0000000000..078e7cd08f --- /dev/null +++ b/OpenRA.Mods.Cnc/Traits/TransformsNearResources.cs @@ -0,0 +1,102 @@ +#region Copyright & License Information +/* + * Copyright 2007-2020 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, either version 3 of + * the License, or (at your option) any later version. For more + * information, see COPYING. + */ +#endregion + +using OpenRA.Mods.Common.Activities; +using OpenRA.Mods.Common.Traits; +using OpenRA.Traits; + +namespace OpenRA.Mods.Cnc.Traits +{ + [Desc("Replace with another actor when a resource spawns adjacent.")] + public class TransformsNearResourcesInfo : TraitInfo + { + [FieldLoader.Require] + [ActorReference] + public readonly string IntoActor = null; + + public readonly CVec Offset = CVec.Zero; + + [Desc("Don't render the make animation.")] + public readonly bool SkipMakeAnims = false; + + [FieldLoader.Require] + [Desc("Resource type which triggers the transformation.")] + public readonly string Type = null; + + [Desc("Resource density threshold which is required.")] + public readonly int Density = 1; + + [Desc("This many adjacent resource tiles are required.")] + public readonly int Adjacency = 1; + + [Desc("The range of time (in ticks) until the transformation starts.")] + public readonly int[] Delay = { 1000, 3000 }; + + public override object Create(ActorInitializer init) { return new TransformsNearResources(init.Self, this); } + } + + public class TransformsNearResources : ITick + { + readonly TransformsNearResourcesInfo info; + readonly ResourceLayer resourceLayer; + int delay; + + public TransformsNearResources(Actor self, TransformsNearResourcesInfo info) + { + resourceLayer = self.World.WorldActor.Trait(); + delay = Common.Util.RandomDelay(self.World, info.Delay); + this.info = info; + } + + void ITick.Tick(Actor self) + { + if (delay < 0) + return; + + var adjacent = 0; + foreach (var direction in CVec.Directions) + { + var location = self.Location + direction; + + var resource = resourceLayer.GetResourceType(location); + if (resource == null || resource.Info.Type != info.Type) + continue; + + var density = resourceLayer.GetResourceDensity(location); + if (density < info.Density) + continue; + + if (++adjacent < info.Adjacency) + continue; + + delay--; + break; + } + + if (delay < 0) + Transform(self); + } + + void Transform(Actor self) + { + var transform = new Transform(self, info.IntoActor); + + var facing = self.TraitOrDefault(); + if (facing != null) + transform.Facing = facing.Facing; + + transform.SkipMakeAnims = info.SkipMakeAnims; + transform.Offset = info.Offset; + + self.QueueActivity(false, transform); + } + } +} diff --git a/mods/cnc/rules/trees.yaml b/mods/cnc/rules/trees.yaml index 371bce46a8..4feb3e42a6 100644 --- a/mods/cnc/rules/trees.yaml +++ b/mods/cnc/rules/trees.yaml @@ -101,6 +101,21 @@ T03: SpawnActorOnDeath: Actor: T03.Husk +T03.Transformable: + Inherits: ^Tree + RenderSprites: + Image: t03 + MapEditorData: + ExcludeTilesets: DESERT + SpawnActorOnDeath: + Actor: T03.Husk + TransformsNearResources: + Type: Tiberium + IntoActor: split2 + Offset: 0,1 + EditorOnlyTooltip: + Name: (Tree that can transform into a Blossom Tree) + T03.Husk: Inherits: ^TreeHusk MapEditorData: @@ -238,6 +253,21 @@ T13: SpawnActorOnDeath: Actor: T13.Husk +T13.Transformable: + Inherits: ^Tree + RenderSprites: + Image: t13 + MapEditorData: + ExcludeTilesets: DESERT + SpawnActorOnDeath: + Actor: T13.Husk + TransformsNearResources: + Type: Tiberium + IntoActor: split3 + Offset: 0,1 + EditorOnlyTooltip: + Name: (Tree that can transform into a Blossom Tree) + T13.Husk: Inherits: ^TreeHusk Building: diff --git a/mods/cnc/sequences/decorations.yaml b/mods/cnc/sequences/decorations.yaml index c3cbef301a..dbf41e7c4f 100644 --- a/mods/cnc/sequences/decorations.yaml +++ b/mods/cnc/sequences/decorations.yaml @@ -6,6 +6,7 @@ split2: DESERT: TEMPERAT make: Length: 30 + Tick: 120 active: Start: 30 Length: 24 @@ -18,6 +19,7 @@ split3: UseTilesetExtension: true make: Length: 30 + Tick: 120 active: Start: 30 Length: 24