diff --git a/OpenRA.Mods.D2k/Traits/Buildings/D2kBuilding.cs b/OpenRA.Mods.D2k/Traits/Buildings/D2kBuilding.cs index db11c721fe..2093ce47f2 100644 --- a/OpenRA.Mods.D2k/Traits/Buildings/D2kBuilding.cs +++ b/OpenRA.Mods.D2k/Traits/Buildings/D2kBuilding.cs @@ -36,17 +36,27 @@ namespace OpenRA.Mods.D2k.Traits.Buildings [Desc("Inflict damage down to the DamageThreshold when the actor gets created on damaging terrain.")] public readonly bool StartOnThreshold = true; + [Desc("The terrain template to place when adding a concrete foundation. " + + "If the template is PickAny, then the actor footprint will be filled with this tile.")] + public readonly ushort ConcreteTemplate = 88; + + [Desc("List of required prerequisites to place a terrain template.")] + public readonly string[] ConcretePrerequisites = { }; + public override object Create(ActorInitializer init) { return new D2kBuilding(init, this); } } public class D2kBuilding : Building, ITick, INotifyCreated { readonly D2kBuildingInfo info; + + BuildableTerrainLayer layer; IHealth health; int safeTiles; int totalTiles; int damageThreshold; int damageTicks; + TechTree techTree; public D2kBuilding(ActorInitializer init, D2kBuildingInfo info) : base(init, info) @@ -57,12 +67,51 @@ namespace OpenRA.Mods.D2k.Traits.Buildings void INotifyCreated.Created(Actor self) { health = self.TraitOrDefault(); + layer = self.World.WorldActor.TraitOrDefault(); + techTree = self.Owner.PlayerActor.TraitOrDefault(); } protected override void AddedToWorld(Actor self) { base.AddedToWorld(self); + if (layer != null && (!info.ConcretePrerequisites.Any() || techTree == null || techTree.HasPrerequisites(info.ConcretePrerequisites))) + { + var map = self.World.Map; + var template = map.Rules.TileSet.Templates[info.ConcreteTemplate]; + if (template.PickAny) + { + // Fill the footprint with random variants + foreach (var c in info.Tiles(self.Location)) + { + if (!map.Contains(c) || map.CustomTerrain[c] != byte.MaxValue) + continue; + + // Don't place under other buildings + if (self.World.ActorMap.GetActorsAt(c).Any(a => a != self && a.TraitOrDefault() != null)) + continue; + + var index = Game.CosmeticRandom.Next(template.TilesCount); + layer.AddTile(c, new TerrainTile(template.Id, (byte)index)); + } + } + else + { + for (var i = 0; i < template.TilesCount; i++) + { + var c = self.Location + new CVec(i % template.Size.X, i / template.Size.X); + if (!map.Contains(c) || map.CustomTerrain[c] != byte.MaxValue) + continue; + + // Don't place under other buildings + if (self.World.ActorMap.GetActorsAt(c).Any(a => a != self && a.TraitOrDefault() != null)) + continue; + + layer.AddTile(c, new TerrainTile(template.Id, (byte)i)); + } + } + } + if (health == null) return; diff --git a/mods/d2k/rules/defaults.yaml b/mods/d2k/rules/defaults.yaml index 385bdfa594..b36d9bcda0 100644 --- a/mods/d2k/rules/defaults.yaml +++ b/mods/d2k/rules/defaults.yaml @@ -409,6 +409,7 @@ Footprint: x TerrainTypes: Rock, Concrete BuildSounds: BUILD1.WAV + ConcretePrerequisites: global-auto-concrete D2kActorPreviewPlaceBuildingPreview: RequiresPrerequisites: !global-auto-concrete OverridePalette: placebuilding @@ -448,13 +449,6 @@ SellSounds: BUILD1.WAV Guardable: Range: 3c0 - GrantConditionOnPrerequisite@AUTOCONCRETE: - Condition: auto-concrete - Prerequisites: global-auto-concrete - LaysTerrain: - RequiresCondition: auto-concrete - TerrainTypes: Rock - Template: 88 ThrowsShrapnel: Weapons: Debris, Debris2, Debris3, Debris4 Pieces: 2, 5 diff --git a/mods/d2k/rules/structures.yaml b/mods/d2k/rules/structures.yaml index a542e25efe..54b86ab740 100644 --- a/mods/d2k/rules/structures.yaml +++ b/mods/d2k/rules/structures.yaml @@ -9,9 +9,6 @@ RequiresBuildableArea: AreaTypes: building Adjacent: 4 - LaysTerrain: - Template: 88 - TerrainTypes: Rock Tooltip: Name: Concrete GenericName: Structure @@ -63,9 +60,7 @@ construction_yard: Footprint: xxx xxx === Dimensions: 3,3 LocalCenterOffset: 0,-512,0 - LaysTerrain: - -RequiresCondition: - -GrantConditionOnPrerequisite@AUTOCONCRETE: + -ConcretePrerequisites: WithBuildingBib: Selectable: Bounds: 96,64