#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.Linq; using OpenRA.Mods.Common.Traits; using OpenRA.Traits; namespace OpenRA.Mods.D2k.Traits { public class LaysTerrainInfo : ITraitInfo, Requires { [Desc("The terrain template to place. If the template is PickAny, then " + "the actor footprint will be filled with this tile.")] public readonly ushort Template = 0; [Desc("The terrain types that this template will be placed on")] public readonly string[] TerrainTypes = { }; [Desc("Offset relative to the actor TopLeft. Not used if the template is PickAny")] public readonly CVec Offset = CVec.Zero; public object Create(ActorInitializer init) { return new LaysTerrain(init.Self, this); } } public class LaysTerrain : INotifyAddedToWorld { readonly LaysTerrainInfo info; readonly BuildableTerrainLayer layer; readonly BuildingInfluence bi; readonly TerrainTemplateInfo template; public LaysTerrain(Actor self, LaysTerrainInfo info) { this.info = info; layer = self.World.WorldActor.Trait(); bi = self.World.WorldActor.Trait(); template = self.World.TileSet.Templates[info.Template]; } public void AddedToWorld(Actor self) { var map = self.World.Map; if (template.PickAny) { // Fill the footprint with random variants foreach (var c in FootprintUtils.Tiles(self)) { // Only place on allowed terrain types if (!info.TerrainTypes.Contains(map.GetTerrainInfo(c).Type)) continue; // Don't place under other buildings or custom terrain if (bi.GetBuildingAt(c) != self || map.CustomTerrain[c] != byte.MaxValue) continue; var index = Game.CosmeticRandom.Next(template.TilesCount); layer.AddTile(c, new TerrainTile(template.Id, (byte)index)); } return; } var origin = self.Location + info.Offset; for (var i = 0; i < template.TilesCount; i++) { var c = origin + new CVec(i % template.Size.X, i / template.Size.X); // Only place on allowed terrain types if (!info.TerrainTypes.Contains(map.GetTerrainInfo(c).Type)) continue; // Don't place under other buildings or custom terrain if (bi.GetBuildingAt(c) != self || map.CustomTerrain[c] != byte.MaxValue) continue; layer.AddTile(c, new TerrainTile(template.Id, (byte)i)); } } } }