Files
OpenRA/OpenRA.Mods.RA/Buildings/LaysTerrain.cs
RoosterDragon 59b3cd154d Change indexes into tile arrays to be stored as bytes to save memory.
The index value needs only be big enough to handle all defined terrain types. This is a low number so we can save memory by defining it as a byte. This particularly saves memory for the CustomTerrain field in the Map class, which defines a cell layer for the map using tile indexes, so we can reduce the size of that layer 4x as a result.
2014-10-09 20:03:01 +01:00

88 lines
2.6 KiB
C#
Executable File

#region Copyright & License Information
/*
* Copyright 2007-2014 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.Traits;
namespace OpenRA.Mods.RA.Buildings
{
public class LaysTerrainInfo : ITraitInfo, Requires<BuildingInfo>
{
[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 TileTemplate template;
public LaysTerrain(Actor self, LaysTerrainInfo info)
{
this.info = info;
layer = self.World.WorldActor.Trait<BuildableTerrainLayer>();
bi = self.World.WorldActor.Trait<BuildingInfluence>();
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));
}
}
}
}