Implement isometric selection boxes for TS structures.
This commit is contained in:
@@ -0,0 +1,168 @@
|
||||
#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 System;
|
||||
using OpenRA.Graphics;
|
||||
using OpenRA.Primitives;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.Common.Graphics
|
||||
{
|
||||
public struct IsometricSelectionBarsAnnotationRenderable : IRenderable, IFinalizedRenderable
|
||||
{
|
||||
const int BarWidth = 3;
|
||||
const int BarHeight = 4;
|
||||
const int BarStride = 5;
|
||||
|
||||
static readonly Color EmptyColor = Color.FromArgb(160, 30, 30, 30);
|
||||
static readonly Color DarkEmptyColor = Color.FromArgb(160, 15, 15, 15);
|
||||
static readonly Color DarkenColor = Color.FromArgb(24, 0, 0, 0);
|
||||
static readonly Color LightenColor = Color.FromArgb(24, 255, 255, 255);
|
||||
|
||||
readonly WPos pos;
|
||||
readonly Actor actor;
|
||||
readonly bool displayHealth;
|
||||
readonly bool displayExtra;
|
||||
readonly Polygon bounds;
|
||||
|
||||
public IsometricSelectionBarsAnnotationRenderable(Actor actor, Polygon bounds, bool displayHealth, bool displayExtra)
|
||||
: this(actor.CenterPosition, actor, bounds)
|
||||
{
|
||||
this.displayHealth = displayHealth;
|
||||
this.displayExtra = displayExtra;
|
||||
}
|
||||
|
||||
public IsometricSelectionBarsAnnotationRenderable(WPos pos, Actor actor, Polygon bounds)
|
||||
: this()
|
||||
{
|
||||
this.pos = pos;
|
||||
this.actor = actor;
|
||||
this.bounds = bounds;
|
||||
}
|
||||
|
||||
public WPos Pos { get { return pos; } }
|
||||
public bool DisplayHealth { get { return displayHealth; } }
|
||||
public bool DisplayExtra { get { return displayExtra; } }
|
||||
|
||||
public PaletteReference Palette { get { return null; } }
|
||||
public int ZOffset { get { return 0; } }
|
||||
public bool IsDecoration { get { return true; } }
|
||||
|
||||
public IRenderable WithPalette(PaletteReference newPalette) { return this; }
|
||||
public IRenderable WithZOffset(int newOffset) { return this; }
|
||||
public IRenderable OffsetBy(WVec vec) { return new IsometricSelectionBarsAnnotationRenderable(pos + vec, actor, bounds); }
|
||||
public IRenderable AsDecoration() { return this; }
|
||||
|
||||
void DrawExtraBars(WorldRenderer wr)
|
||||
{
|
||||
var i = 1;
|
||||
foreach (var extraBar in actor.TraitsImplementing<ISelectionBar>())
|
||||
{
|
||||
var value = extraBar.GetValue();
|
||||
if (value != 0 || extraBar.DisplayWhenEmpty)
|
||||
DrawBar(wr, extraBar.GetValue(), extraBar.GetColor(), i++);
|
||||
}
|
||||
}
|
||||
|
||||
void DrawBar(WorldRenderer wr, float value, Color barColor, int barNum, float? secondValue = null, Color? secondColor = null)
|
||||
{
|
||||
var darkColor = Color.FromArgb(barColor.A, barColor.R / 2, barColor.G / 2, barColor.B / 2);
|
||||
var barAspect = new float2(1f, 0.5f);
|
||||
var stepAspect = new float2(1f, -0.5f);
|
||||
|
||||
var offset = barNum * BarStride * barAspect - new float2(0, BarHeight + 1);
|
||||
var start = wr.Viewport.WorldToViewPx(bounds.Vertices[1]).ToFloat2() + offset;
|
||||
var end = wr.Viewport.WorldToViewPx(bounds.Vertices[0]).ToFloat2() + offset;
|
||||
|
||||
// HACK: Work around rounding errors that may cause a few-px offset in the end relative to the start
|
||||
// Force the bar to take a 45 degree angle
|
||||
end = new float2(end.X, start.Y - (end.X - start.X) / 2);
|
||||
|
||||
// Round the cut point to the nearest pixel to avoid potential off-by-one pixel offsets distorting the bar
|
||||
var cutX = (int)(float2.Lerp(start.X, end.X, value) + 0.5f);
|
||||
var cut = new float2(cutX, start.Y - (cutX - start.X) / 2);
|
||||
|
||||
var cr = Game.Renderer.RgbaColorRenderer;
|
||||
var da = BarWidth * barAspect;
|
||||
var db = new int2(0, BarHeight);
|
||||
var dc = da + db;
|
||||
|
||||
// Filled bar
|
||||
cr.FillRect(start + da, start + dc, cut + dc, cut + da, darkColor);
|
||||
cr.FillRect(start, start + da, start + dc, start + db, darkColor);
|
||||
cr.FillRect(start, start + da, cut + da, cut, barColor);
|
||||
|
||||
// Faint marks to break the monotony of the solid bar
|
||||
var dx = BarWidth;
|
||||
while (dx < cut.X - start.X)
|
||||
{
|
||||
var step = start + dx * stepAspect;
|
||||
cr.DrawLine(step, step + da, 1, DarkenColor);
|
||||
cr.DrawLine(step + da, step + dc, 1, LightenColor);
|
||||
dx += BarWidth;
|
||||
}
|
||||
|
||||
// Second bar (e.g. applied damage)
|
||||
if (secondValue.HasValue && secondColor.HasValue)
|
||||
{
|
||||
var secondCutX = (int)(float2.Lerp(start.X, end.X, secondValue.Value) + 0.5f);
|
||||
var secondCut = new float2(secondCutX, start.Y - (secondCutX - start.X) / 2);
|
||||
var darkSecond = Color.FromArgb(secondColor.Value.A, secondColor.Value.R / 2, secondColor.Value.G / 2, secondColor.Value.B / 2);
|
||||
|
||||
cr.FillRect(cut + da, cut + dc, secondCut + dc, secondCut + da, darkSecond);
|
||||
cr.FillRect(cut, cut + da, secondCut + da, secondCut, secondColor.Value);
|
||||
|
||||
value = secondValue.Value;
|
||||
cut = secondCut;
|
||||
}
|
||||
|
||||
// Empty bar
|
||||
if (value < 1)
|
||||
{
|
||||
cr.FillRect(cut + da, cut + dc, end + dc, end + da, DarkEmptyColor);
|
||||
cr.FillRect(cut, cut + da, end + da, end, EmptyColor);
|
||||
}
|
||||
}
|
||||
|
||||
Color GetHealthColor(IHealth health)
|
||||
{
|
||||
if (Game.Settings.Game.UsePlayerStanceColors)
|
||||
return actor.Owner.PlayerStanceColor(actor);
|
||||
|
||||
return health.DamageState == DamageState.Critical ? Color.Red :
|
||||
health.DamageState == DamageState.Heavy ? Color.Yellow : Color.LimeGreen;
|
||||
}
|
||||
|
||||
public IFinalizedRenderable PrepareRender(WorldRenderer wr) { return this; }
|
||||
public void Render(WorldRenderer wr)
|
||||
{
|
||||
if (!actor.IsInWorld || actor.IsDead)
|
||||
return;
|
||||
|
||||
var health = actor.TraitOrDefault<IHealth>();
|
||||
|
||||
if (DisplayHealth)
|
||||
{
|
||||
if (health == null || health.IsDead)
|
||||
return;
|
||||
|
||||
var displayValue = health.DisplayHP != health.HP ? (float?)health.DisplayHP / health.MaxHP : null;
|
||||
DrawBar(wr, (float)health.HP / health.MaxHP, GetHealthColor(health), 0, displayValue, Color.OrangeRed);
|
||||
}
|
||||
|
||||
if (DisplayExtra)
|
||||
DrawExtraBars(wr);
|
||||
}
|
||||
|
||||
public void RenderDebugGeometry(WorldRenderer wr) { }
|
||||
public Rectangle ScreenBounds(WorldRenderer wr) { return Rectangle.Empty; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
#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 System.Linq;
|
||||
using OpenRA.Graphics;
|
||||
using OpenRA.Primitives;
|
||||
|
||||
namespace OpenRA.Mods.Common.Graphics
|
||||
{
|
||||
public struct IsometricSelectionBoxAnnotationRenderable : IRenderable, IFinalizedRenderable
|
||||
{
|
||||
static readonly float2 TLOffset = new float2(-12, -6);
|
||||
static readonly float2 TROffset = new float2(12, -6);
|
||||
static readonly float2 TOffset = new float2(0, -13);
|
||||
static readonly float2[] Offsets =
|
||||
{
|
||||
-TROffset, -TLOffset, -TOffset,
|
||||
TROffset, -TOffset, -TLOffset,
|
||||
-TLOffset, TOffset, TROffset,
|
||||
TLOffset, TROffset, TOffset,
|
||||
-TROffset, TOffset, TLOffset,
|
||||
TLOffset, -TOffset, -TROffset
|
||||
};
|
||||
|
||||
readonly WPos pos;
|
||||
readonly Polygon bounds;
|
||||
readonly Color color;
|
||||
|
||||
public IsometricSelectionBoxAnnotationRenderable(Actor actor, Polygon bounds, Color color)
|
||||
{
|
||||
pos = actor.CenterPosition;
|
||||
this.bounds = bounds;
|
||||
this.color = color;
|
||||
}
|
||||
|
||||
public IsometricSelectionBoxAnnotationRenderable(WPos pos, Polygon bounds, Color color)
|
||||
{
|
||||
this.pos = pos;
|
||||
this.bounds = bounds;
|
||||
this.color = color;
|
||||
}
|
||||
|
||||
public WPos Pos { get { return pos; } }
|
||||
|
||||
public PaletteReference Palette { get { return null; } }
|
||||
public int ZOffset { get { return 0; } }
|
||||
public bool IsDecoration { get { return true; } }
|
||||
|
||||
public IRenderable WithPalette(PaletteReference newPalette) { return this; }
|
||||
public IRenderable WithZOffset(int newOffset) { return this; }
|
||||
public IRenderable OffsetBy(WVec vec) { return new IsometricSelectionBoxAnnotationRenderable(pos + vec, bounds, color); }
|
||||
public IRenderable AsDecoration() { return this; }
|
||||
|
||||
public IFinalizedRenderable PrepareRender(WorldRenderer wr) { return this; }
|
||||
|
||||
public void Render(WorldRenderer wr)
|
||||
{
|
||||
var screen = bounds.Vertices.Select(v => wr.Viewport.WorldToViewPx(v).ToFloat2()).ToArray();
|
||||
|
||||
var tl = new float2(-12, -6);
|
||||
var tr = new float2(12, -6);
|
||||
var t = new float2(0, -13);
|
||||
|
||||
var cr = Game.Renderer.RgbaColorRenderer;
|
||||
for (var i = 0; i < 6; i++)
|
||||
{
|
||||
cr.DrawLine(new float3[] { screen[i] + Offsets[3 * i], screen[i], screen[i] + Offsets[3 * i + 1] }, 1, color, true);
|
||||
cr.DrawLine(new float3[] { screen[i], screen[i] + Offsets[3 * i + 2] }, 1, color, true);
|
||||
}
|
||||
}
|
||||
|
||||
public void RenderDebugGeometry(WorldRenderer wr) { }
|
||||
public Rectangle ScreenBounds(WorldRenderer wr) { return Rectangle.Empty; }
|
||||
}
|
||||
}
|
||||
142
OpenRA.Mods.Common/Traits/IsometricSelectable.cs
Normal file
142
OpenRA.Mods.Common/Traits/IsometricSelectable.cs
Normal file
@@ -0,0 +1,142 @@
|
||||
#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 System;
|
||||
using System.Linq;
|
||||
using OpenRA.Graphics;
|
||||
using OpenRA.Primitives;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.Common.Traits
|
||||
{
|
||||
[Desc("This actor is selectable. Defines bounds of selectable area, selection class, selection priority and selection priority modifiers.")]
|
||||
public class IsometricSelectableInfo : ITraitInfo, IMouseBoundsInfo, ISelectableInfo, IRulesetLoaded, Requires<BuildingInfo>
|
||||
{
|
||||
[Desc("Defines a custom rectangle for mouse interaction with the actor.",
|
||||
"If null, the engine will guess an appropriate size based on the building's footprint.",
|
||||
"The first two numbers define the width and depth of the footprint rectangle.",
|
||||
"The (optional) second two numbers define an x and y offset from the actor center.")]
|
||||
public readonly int[] Bounds = null;
|
||||
|
||||
[Desc("Height above the footprint for the top of the interaction rectangle.")]
|
||||
public readonly int Height = 24;
|
||||
|
||||
[Desc("Defines a custom rectangle for Decorations (e.g. the selection box).",
|
||||
"If null, Bounds will be used instead.")]
|
||||
public readonly int[] DecorationBounds = null;
|
||||
|
||||
[Desc("Defines a custom height for Decorations (e.g. the selection box).",
|
||||
"If < 0, Height will be used instead.",
|
||||
"If Height is 0, this must be defined with a value greater than 0.")]
|
||||
public readonly int DecorationHeight = -1;
|
||||
|
||||
public readonly int Priority = 10;
|
||||
|
||||
[Desc("Allow selection priority to be modified using a hotkey.",
|
||||
"Valid values are None (priority is not affected by modifiers)",
|
||||
"Ctrl (priority is raised when Ctrl pressed) and",
|
||||
"Alt (priority is raised when Alt pressed).")]
|
||||
public readonly SelectionPriorityModifiers PriorityModifiers = SelectionPriorityModifiers.None;
|
||||
|
||||
[Desc("All units having the same selection class specified will be selected with select-by-type commands (e.g. double-click). ",
|
||||
"Defaults to the actor name when not defined or inherited.")]
|
||||
public readonly string Class = null;
|
||||
|
||||
[VoiceReference]
|
||||
public readonly string Voice = "Select";
|
||||
|
||||
public object Create(ActorInitializer init) { return new IsometricSelectable(init.Self, this); }
|
||||
|
||||
int ISelectableInfo.Priority { get { return Priority; } }
|
||||
SelectionPriorityModifiers ISelectableInfo.PriorityModifiers { get { return PriorityModifiers; } }
|
||||
string ISelectableInfo.Voice { get { return Voice; } }
|
||||
|
||||
public virtual void RulesetLoaded(Ruleset rules, ActorInfo ai)
|
||||
{
|
||||
var grid = Game.ModData.Manifest.Get<MapGrid>();
|
||||
if (grid.Type != MapGridType.RectangularIsometric)
|
||||
throw new YamlException("IsometricSelectable can only be used in mods that use the RectangularIsometric MapGrid type.");
|
||||
|
||||
if (Height == 0 && DecorationHeight <= 0)
|
||||
throw new YamlException("DecorationHeight must be defined and greater than 0 if Height is 0.");
|
||||
}
|
||||
}
|
||||
|
||||
public class IsometricSelectable : IMouseBounds, ISelectable
|
||||
{
|
||||
readonly IsometricSelectableInfo info;
|
||||
readonly string selectionClass = null;
|
||||
readonly BuildingInfo buildingInfo;
|
||||
|
||||
public IsometricSelectable(Actor self, IsometricSelectableInfo info)
|
||||
{
|
||||
this.info = info;
|
||||
selectionClass = string.IsNullOrEmpty(info.Class) ? self.Info.Name : info.Class;
|
||||
buildingInfo = self.Info.TraitInfo<BuildingInfo>();
|
||||
}
|
||||
|
||||
Polygon Bounds(Actor self, WorldRenderer wr, int[] bounds, int height)
|
||||
{
|
||||
int2 left, right, top, bottom;
|
||||
if (bounds != null)
|
||||
{
|
||||
var offset = bounds.Length >= 4 ? new int2(bounds[2], bounds[3]) : int2.Zero;
|
||||
var center = wr.ScreenPxPosition(self.CenterPosition) + offset;
|
||||
left = center - new int2(bounds[0] / 2, 0);
|
||||
right = left + new int2(bounds[0], 0);
|
||||
top = center - new int2(0, bounds[1] / 2);
|
||||
bottom = top + new int2(0, bounds[1]);
|
||||
}
|
||||
else
|
||||
{
|
||||
var xMin = int.MaxValue;
|
||||
var xMax = int.MinValue;
|
||||
var yMin = int.MaxValue;
|
||||
var yMax = int.MinValue;
|
||||
foreach (var c in buildingInfo.OccupiedTiles(self.Location))
|
||||
{
|
||||
xMin = Math.Min(xMin, c.X);
|
||||
xMax = Math.Max(xMax, c.X);
|
||||
yMin = Math.Min(yMin, c.Y);
|
||||
yMax = Math.Max(yMax, c.Y);
|
||||
}
|
||||
|
||||
left = wr.ScreenPxPosition(self.World.Map.CenterOfCell(new CPos(xMin, yMax)) - new WVec(768, 0, 0));
|
||||
right = wr.ScreenPxPosition(self.World.Map.CenterOfCell(new CPos(xMax, yMin)) + new WVec(768, 0, 0));
|
||||
top = wr.ScreenPxPosition(self.World.Map.CenterOfCell(new CPos(xMin, yMin)) - new WVec(0, 768, 0));
|
||||
bottom = wr.ScreenPxPosition(self.World.Map.CenterOfCell(new CPos(xMax, yMax)) + new WVec(0, 768, 0));
|
||||
}
|
||||
|
||||
if (height == 0)
|
||||
return new Polygon(new[] { top, left, bottom, right });
|
||||
|
||||
var h = new int2(0, height);
|
||||
return new Polygon(new[] { top - h, left - h, left, bottom, right, right - h });
|
||||
}
|
||||
|
||||
public Polygon Bounds(Actor self, WorldRenderer wr)
|
||||
{
|
||||
return Bounds(self, wr, info.Bounds, info.Height);
|
||||
}
|
||||
|
||||
public Polygon DecorationBounds(Actor self, WorldRenderer wr)
|
||||
{
|
||||
return Bounds(self, wr, info.DecorationBounds ?? info.Bounds, info.DecorationHeight >= 0 ? info.DecorationHeight : info.Height);
|
||||
}
|
||||
|
||||
Polygon IMouseBounds.MouseoverBounds(Actor self, WorldRenderer wr)
|
||||
{
|
||||
return Bounds(self, wr);
|
||||
}
|
||||
|
||||
string ISelectable.Class { get { return selectionClass; } }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
#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 System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using OpenRA.Graphics;
|
||||
using OpenRA.Mods.Common.Graphics;
|
||||
using OpenRA.Primitives;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.Common.Traits.Render
|
||||
{
|
||||
public class IsometricSelectionDecorationsInfo : SelectionDecorationsBaseInfo, Requires<IsometricSelectableInfo>
|
||||
{
|
||||
public override object Create(ActorInitializer init) { return new IsometricSelectionDecorations(init.Self, this); }
|
||||
}
|
||||
|
||||
public class IsometricSelectionDecorations : SelectionDecorationsBase
|
||||
{
|
||||
readonly IsometricSelectable selectable;
|
||||
|
||||
public IsometricSelectionDecorations(Actor self, IsometricSelectionDecorationsInfo info)
|
||||
: base(info)
|
||||
{
|
||||
selectable = self.Trait<IsometricSelectable>();
|
||||
}
|
||||
|
||||
protected override int2 GetDecorationPosition(Actor self, WorldRenderer wr, DecorationPosition pos)
|
||||
{
|
||||
var bounds = selectable.DecorationBounds(self, wr);
|
||||
switch (pos)
|
||||
{
|
||||
case DecorationPosition.TopLeft: return bounds.Vertices[1];
|
||||
case DecorationPosition.TopRight: return bounds.Vertices[5];
|
||||
case DecorationPosition.BottomLeft: return bounds.Vertices[2];
|
||||
case DecorationPosition.BottomRight: return bounds.Vertices[4];
|
||||
case DecorationPosition.Top: return new int2((bounds.Vertices[1].X + bounds.Vertices[5].X) / 2, bounds.Vertices[1].Y);
|
||||
default: return bounds.BoundingRect.TopLeft + new int2(bounds.BoundingRect.Size.Width / 2, bounds.BoundingRect.Size.Height / 2);
|
||||
}
|
||||
}
|
||||
|
||||
protected override IEnumerable<IRenderable> RenderSelectionBox(Actor self, WorldRenderer wr, Color color)
|
||||
{
|
||||
var bounds = selectable.DecorationBounds(self, wr);
|
||||
yield return new IsometricSelectionBoxAnnotationRenderable(self, bounds, color);
|
||||
}
|
||||
|
||||
protected override IEnumerable<IRenderable> RenderSelectionBars(Actor self, WorldRenderer wr, bool displayHealth, bool displayExtra)
|
||||
{
|
||||
if (!displayHealth && !displayExtra)
|
||||
yield break;
|
||||
|
||||
var bounds = selectable.DecorationBounds(self, wr);
|
||||
yield return new IsometricSelectionBarsAnnotationRenderable(self, bounds, displayHealth, displayExtra);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
#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 System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using OpenRA.Mods.Common.FileFormats;
|
||||
using OpenRA.Mods.Common.Traits;
|
||||
|
||||
namespace OpenRA.Mods.Common.UpdateRules.Rules
|
||||
{
|
||||
public class CopyIsometricSelectableHeight : UpdateRule
|
||||
{
|
||||
public override string Name { get { return "Copy IsometricSelectable.Height from art*.ini definitions."; } }
|
||||
public override string Description
|
||||
{
|
||||
get
|
||||
{
|
||||
return "Reads building Height entries art.ini/artfs.ini/artmd.ini from the current working directory\n" +
|
||||
"and adds IsometricSelectable definitions to matching actors.";
|
||||
}
|
||||
}
|
||||
|
||||
static readonly string[] SourceFiles = { "art.ini", "artfs.ini", "artmd.ini" };
|
||||
|
||||
readonly Dictionary<string, int> selectionHeight = new Dictionary<string, int>();
|
||||
|
||||
bool complete;
|
||||
|
||||
public override IEnumerable<string> BeforeUpdate(ModData modData)
|
||||
{
|
||||
if (complete)
|
||||
yield break;
|
||||
|
||||
var grid = Game.ModData.Manifest.Get<MapGrid>();
|
||||
foreach (var filename in SourceFiles)
|
||||
{
|
||||
if (!File.Exists(filename))
|
||||
continue;
|
||||
|
||||
var file = new IniFile(File.Open(filename, FileMode.Open));
|
||||
foreach (var section in file.Sections)
|
||||
{
|
||||
if (!section.Contains("Height"))
|
||||
continue;
|
||||
|
||||
selectionHeight[section.Name] = (int)(float.Parse(section.GetValue("Height", "1")) * grid.TileSize.Height);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override IEnumerable<string> AfterUpdate(ModData modData)
|
||||
{
|
||||
// Rule only applies to the default ruleset - skip maps
|
||||
complete = true;
|
||||
yield break;
|
||||
}
|
||||
|
||||
public override IEnumerable<string> UpdateActorNode(ModData modData, MiniYamlNode actorNode)
|
||||
{
|
||||
if (complete || actorNode.LastChildMatching("IsometricSelectable") != null)
|
||||
yield break;
|
||||
|
||||
var height = 0;
|
||||
if (!selectionHeight.TryGetValue(actorNode.Key.ToLowerInvariant(), out height))
|
||||
yield break;
|
||||
|
||||
// Don't redefine the default value
|
||||
if (height == 24)
|
||||
yield break;
|
||||
|
||||
var selection = new MiniYamlNode("IsometricSelectable", "");
|
||||
selection.AddNode("Height", FieldSaver.FormatValue(height));
|
||||
|
||||
actorNode.AddNode(selection);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -11,8 +11,10 @@ CABHUT:
|
||||
Palette: player
|
||||
Targetable:
|
||||
TargetTypes: C4
|
||||
-Selectable:
|
||||
-IsometricSelectable:
|
||||
-IsometricSelectionDecorations:
|
||||
Interactable:
|
||||
SelectionDecorations:
|
||||
-Demolishable:
|
||||
-Explodes:
|
||||
-FrozenUnderFog:
|
||||
|
||||
@@ -16,6 +16,8 @@ ABAN01:
|
||||
Pieces: 5, 9
|
||||
ThrowsShrapnel@LARGE:
|
||||
Pieces: 2, 4
|
||||
IsometricSelectable:
|
||||
Height: 72
|
||||
|
||||
ABAN02:
|
||||
Inherits: ^CivBuilding
|
||||
@@ -35,6 +37,8 @@ ABAN02:
|
||||
Pieces: 5, 9
|
||||
ThrowsShrapnel@LARGE:
|
||||
Pieces: 2, 4
|
||||
IsometricSelectable:
|
||||
Height: 48
|
||||
|
||||
ABAN03:
|
||||
Inherits: ^CivBuilding
|
||||
@@ -54,6 +58,8 @@ ABAN03:
|
||||
Pieces: 5, 9
|
||||
ThrowsShrapnel@LARGE:
|
||||
Pieces: 2, 4
|
||||
IsometricSelectable:
|
||||
Height: 48
|
||||
|
||||
ABAN04:
|
||||
Inherits: ^CivBuilding
|
||||
@@ -582,6 +588,8 @@ CA0012:
|
||||
Type: light
|
||||
Health:
|
||||
HP: 10000
|
||||
IsometricSelectable:
|
||||
Height: 36
|
||||
|
||||
CA0013:
|
||||
Inherits: ^CivBuilding
|
||||
@@ -595,6 +603,8 @@ CA0013:
|
||||
Type: heavy
|
||||
Health:
|
||||
HP: 30000
|
||||
IsometricSelectable:
|
||||
Height: 48
|
||||
|
||||
CA0014:
|
||||
Inherits: ^CivBuilding
|
||||
@@ -607,6 +617,8 @@ CA0014:
|
||||
Type: heavy
|
||||
Health:
|
||||
HP: 30000
|
||||
IsometricSelectable:
|
||||
Height: 48
|
||||
|
||||
CA0015:
|
||||
Inherits: ^CivBuilding
|
||||
@@ -631,6 +643,8 @@ CA0016:
|
||||
Type: light
|
||||
Health:
|
||||
HP: 30000
|
||||
IsometricSelectable:
|
||||
Height: 48
|
||||
|
||||
CA0017:
|
||||
Inherits: ^CivBuilding
|
||||
@@ -643,6 +657,8 @@ CA0017:
|
||||
Type: heavy
|
||||
Health:
|
||||
HP: 30000
|
||||
IsometricSelectable:
|
||||
Height: 48
|
||||
|
||||
CA0018:
|
||||
Inherits: ^CivBuilding
|
||||
@@ -659,6 +675,8 @@ CA0018:
|
||||
Type: light
|
||||
Health:
|
||||
HP: 20000
|
||||
IsometricSelectable:
|
||||
Height: 48
|
||||
|
||||
CA0019:
|
||||
Inherits: ^CivBuilding
|
||||
@@ -675,6 +693,8 @@ CA0019:
|
||||
Type: light
|
||||
Health:
|
||||
HP: 20000
|
||||
IsometricSelectable:
|
||||
Height: 48
|
||||
|
||||
CA0020:
|
||||
Inherits: ^CivBuilding
|
||||
@@ -691,6 +711,8 @@ CA0020:
|
||||
Type: light
|
||||
Health:
|
||||
HP: 20000
|
||||
IsometricSelectable:
|
||||
Height: 48
|
||||
|
||||
CA0021:
|
||||
Inherits: ^CivBuilding
|
||||
@@ -707,6 +729,8 @@ CA0021:
|
||||
Type: light
|
||||
Health:
|
||||
HP: 20000
|
||||
IsometricSelectable:
|
||||
Height: 48
|
||||
|
||||
CAARAY:
|
||||
Inherits: ^CivBuilding
|
||||
@@ -734,6 +758,8 @@ CAARAY:
|
||||
Pieces: 5, 7
|
||||
ThrowsShrapnel@LARGE:
|
||||
Pieces: 2, 4
|
||||
IsometricSelectable:
|
||||
Height: 72
|
||||
|
||||
CAARMR:
|
||||
Inherits: ^CivBuilding
|
||||
@@ -807,6 +833,8 @@ CAHOSP:
|
||||
Pieces: 2, 4
|
||||
MapEditorData:
|
||||
Categories: Civilian building
|
||||
IsometricSelectable:
|
||||
Height: 48
|
||||
|
||||
CAPYR01:
|
||||
Inherits: ^CivBuilding
|
||||
@@ -822,6 +850,8 @@ CAPYR01:
|
||||
HP: 40000
|
||||
MapEditorData:
|
||||
ExcludeTilesets: SNOW
|
||||
IsometricSelectable:
|
||||
Height: 48
|
||||
|
||||
CAPYR02:
|
||||
Inherits: ^CivBuilding
|
||||
@@ -841,6 +871,8 @@ CAPYR02:
|
||||
Pieces: 6, 9
|
||||
ThrowsShrapnel@LARGE:
|
||||
Pieces: 3, 4
|
||||
IsometricSelectable:
|
||||
Height: 96
|
||||
|
||||
CAPYR03:
|
||||
Inherits: ^CivBuilding
|
||||
@@ -860,6 +892,8 @@ CAPYR03:
|
||||
Pieces: 6, 9
|
||||
ThrowsShrapnel@LARGE:
|
||||
Pieces: 3, 4
|
||||
IsometricSelectable:
|
||||
Height: 96
|
||||
|
||||
CITY01:
|
||||
Inherits: ^CivBuilding
|
||||
@@ -879,6 +913,8 @@ CITY01:
|
||||
Pieces: 5, 9
|
||||
ThrowsShrapnel@LARGE:
|
||||
Pieces: 2, 4
|
||||
IsometricSelectable:
|
||||
Height: 72
|
||||
|
||||
CITY02:
|
||||
Inherits: ^CivBuilding
|
||||
@@ -898,6 +934,8 @@ CITY02:
|
||||
Pieces: 5, 9
|
||||
ThrowsShrapnel@LARGE:
|
||||
Pieces: 2, 4
|
||||
IsometricSelectable:
|
||||
Height: 72
|
||||
|
||||
CITY03:
|
||||
Inherits: ^CivBuilding
|
||||
@@ -917,6 +955,8 @@ CITY03:
|
||||
Pieces: 5, 9
|
||||
ThrowsShrapnel@LARGE:
|
||||
Pieces: 2, 4
|
||||
IsometricSelectable:
|
||||
Height: 48
|
||||
|
||||
CITY04:
|
||||
Inherits: ^CivBuilding
|
||||
@@ -936,6 +976,8 @@ CITY04:
|
||||
Pieces: 5, 9
|
||||
ThrowsShrapnel@LARGE:
|
||||
Pieces: 2, 4
|
||||
IsometricSelectable:
|
||||
Height: 72
|
||||
|
||||
CITY05:
|
||||
Inherits: ^CivBuilding
|
||||
@@ -955,6 +997,8 @@ CITY05:
|
||||
Pieces: 5, 9
|
||||
ThrowsShrapnel@LARGE:
|
||||
Pieces: 2, 4
|
||||
IsometricSelectable:
|
||||
Height: 96
|
||||
|
||||
CITY06:
|
||||
Inherits: ^CivBuilding
|
||||
@@ -974,6 +1018,8 @@ CITY06:
|
||||
Pieces: 7, 9
|
||||
ThrowsShrapnel@LARGE:
|
||||
Pieces: 3, 4
|
||||
IsometricSelectable:
|
||||
Height: 72
|
||||
|
||||
CITY07:
|
||||
Inherits: ^CivBuilding
|
||||
@@ -993,6 +1039,8 @@ CITY07:
|
||||
Pieces: 7, 9
|
||||
ThrowsShrapnel@LARGE:
|
||||
Pieces: 3, 4
|
||||
IsometricSelectable:
|
||||
Height: 60
|
||||
|
||||
CITY08:
|
||||
Inherits: ^CivBuilding
|
||||
@@ -1023,6 +1071,8 @@ CITY09:
|
||||
HP: 40000
|
||||
MapEditorData:
|
||||
RequireTilesets: TEMPERATE
|
||||
IsometricSelectable:
|
||||
Height: 48
|
||||
|
||||
CITY10:
|
||||
Inherits: ^CivBuilding
|
||||
@@ -1038,6 +1088,8 @@ CITY10:
|
||||
HP: 30000
|
||||
MapEditorData:
|
||||
RequireTilesets: TEMPERATE
|
||||
IsometricSelectable:
|
||||
Height: 48
|
||||
|
||||
CITY11:
|
||||
Inherits: ^CivBuilding
|
||||
@@ -1053,6 +1105,8 @@ CITY11:
|
||||
HP: 50000
|
||||
MapEditorData:
|
||||
RequireTilesets: TEMPERATE
|
||||
IsometricSelectable:
|
||||
Height: 96
|
||||
|
||||
CITY12:
|
||||
Inherits: ^CivBuilding
|
||||
@@ -1068,6 +1122,8 @@ CITY12:
|
||||
HP: 60000
|
||||
MapEditorData:
|
||||
RequireTilesets: TEMPERATE
|
||||
IsometricSelectable:
|
||||
Height: 96
|
||||
|
||||
CITY13:
|
||||
Inherits: ^CivBuilding
|
||||
@@ -1083,6 +1139,8 @@ CITY13:
|
||||
HP: 50000
|
||||
MapEditorData:
|
||||
RequireTilesets: TEMPERATE
|
||||
IsometricSelectable:
|
||||
Height: 96
|
||||
|
||||
CITY14:
|
||||
Inherits: ^CivBuilding
|
||||
@@ -1097,6 +1155,8 @@ CITY14:
|
||||
HP: 60000
|
||||
MapEditorData:
|
||||
RequireTilesets: TEMPERATE
|
||||
IsometricSelectable:
|
||||
Height: 96
|
||||
|
||||
CITY15:
|
||||
Inherits: ^CivBuilding
|
||||
@@ -1135,6 +1195,8 @@ CITY16:
|
||||
Pieces: 7, 9
|
||||
ThrowsShrapnel@LARGE:
|
||||
Pieces: 3, 4
|
||||
IsometricSelectable:
|
||||
Height: 72
|
||||
|
||||
CITY17:
|
||||
Inherits: ^CivBuilding
|
||||
@@ -1154,6 +1216,8 @@ CITY17:
|
||||
Pieces: 7, 9
|
||||
ThrowsShrapnel@LARGE:
|
||||
Pieces: 3, 4
|
||||
IsometricSelectable:
|
||||
Height: 108
|
||||
|
||||
CITY18:
|
||||
Inherits: ^CivBuilding
|
||||
@@ -1173,6 +1237,8 @@ CITY18:
|
||||
Pieces: 8, 12
|
||||
ThrowsShrapnel@LARGE:
|
||||
Pieces: 5, 7
|
||||
IsometricSelectable:
|
||||
Height: 72
|
||||
|
||||
CITY19:
|
||||
Inherits: ^CivBuilding
|
||||
@@ -1231,6 +1297,8 @@ CITY22:
|
||||
HP: 10000
|
||||
MapEditorData:
|
||||
RequireTilesets: TEMPERATE
|
||||
IsometricSelectable:
|
||||
Height: 72
|
||||
|
||||
CTDAM:
|
||||
Inherits: ^CivBuilding
|
||||
@@ -1278,6 +1346,8 @@ CTVEGA:
|
||||
Pieces: 7, 9
|
||||
ThrowsShrapnel@LARGE:
|
||||
Pieces: 3, 4
|
||||
IsometricSelectable:
|
||||
Height: 72
|
||||
|
||||
GAKODK:
|
||||
Inherits: ^CivBuilding
|
||||
@@ -1313,16 +1383,22 @@ GAOLDCC2:
|
||||
Name: Old Temple
|
||||
Building:
|
||||
Footprint: xx xX
|
||||
IsometricSelectable:
|
||||
Height: 36
|
||||
|
||||
GAOLDCC3:
|
||||
Inherits: ^OldBase
|
||||
Tooltip:
|
||||
Name: Old Weapons Factory
|
||||
IsometricSelectable:
|
||||
Height: 36
|
||||
|
||||
GAOLDCC4:
|
||||
Inherits: ^OldBase
|
||||
Tooltip:
|
||||
Name: Old Refinery
|
||||
IsometricSelectable:
|
||||
Height: 36
|
||||
|
||||
GAOLDCC5:
|
||||
Inherits: ^OldBase
|
||||
@@ -1371,9 +1447,6 @@ GASPOT:
|
||||
Building:
|
||||
Footprint: x
|
||||
Dimensions: 1, 1
|
||||
Selectable:
|
||||
Bounds: 48, 30, 0, -4
|
||||
DecorationBounds: 48, 82, 0, -25
|
||||
Power:
|
||||
Amount: -10
|
||||
Armor:
|
||||
@@ -1387,6 +1460,8 @@ GASPOT:
|
||||
Sequence: idle-lights
|
||||
MapEditorData:
|
||||
Categories: Civilian building
|
||||
IsometricSelectable:
|
||||
Height: 72
|
||||
|
||||
GALITE:
|
||||
Inherits: ^Building
|
||||
@@ -1413,9 +1488,6 @@ GALITE:
|
||||
WithIdleOverlay@LIGHTING:
|
||||
Sequence: lighting
|
||||
Palette: alpha
|
||||
Selectable:
|
||||
Bounds: 24, 24, 0, -4
|
||||
DecorationBounds: 25, 35, 0, -12
|
||||
-Cloak@EXTERNALCLOAK:
|
||||
-ExternalCondition@CLOAKGENERATOR:
|
||||
-ExternalCondition@CRATE-CLOAK:
|
||||
@@ -1453,6 +1525,8 @@ GAICBM:
|
||||
-WithDeathAnimation:
|
||||
MapEditorData:
|
||||
Categories: Vehicle
|
||||
IsometricSelectable:
|
||||
Height: 48
|
||||
|
||||
NAMNTK:
|
||||
Inherits: ^CivBuilding
|
||||
@@ -1470,6 +1544,8 @@ NAMNTK:
|
||||
Palette: player
|
||||
WithIdleOverlay@LIGHTS:
|
||||
Sequence: idle-lights
|
||||
IsometricSelectable:
|
||||
Height: 36
|
||||
|
||||
NTPYRA:
|
||||
Inherits: ^CivBuilding
|
||||
@@ -1493,6 +1569,8 @@ NTPYRA:
|
||||
Pieces: 7, 9
|
||||
ThrowsShrapnel@LARGE:
|
||||
Pieces: 3, 5
|
||||
IsometricSelectable:
|
||||
Height: 72
|
||||
|
||||
UFO:
|
||||
Inherits: ^CivBuilding
|
||||
@@ -1502,9 +1580,6 @@ UFO:
|
||||
Footprint: xxxxxx xxxxxx xxxxxx xxxxxx
|
||||
RenderSprites:
|
||||
Palette: terraindecoration
|
||||
Selectable:
|
||||
Bounds: 144, 72, 0, 0
|
||||
DecorationBounds: 144, 72, 0, 0
|
||||
Tooltip:
|
||||
Name: Scrin Ship
|
||||
Health:
|
||||
@@ -1517,3 +1592,5 @@ UFO:
|
||||
Pieces: 9, 12
|
||||
ThrowsShrapnel@LARGE:
|
||||
Pieces: 6, 8
|
||||
IsometricSelectable:
|
||||
Height: 144
|
||||
|
||||
@@ -1348,15 +1348,20 @@
|
||||
green: pip-green
|
||||
yellow: pip-yellow
|
||||
|
||||
^SelectableCombatBuilding:
|
||||
Inherits@selectiondecorations: ^Selectable
|
||||
Selectable:
|
||||
Priority: 4
|
||||
|
||||
^SelectableBuilding:
|
||||
Inherits@selectiondecorations: ^Selectable
|
||||
Selectable:
|
||||
IsometricSelectable:
|
||||
Priority: 2
|
||||
IsometricSelectionDecorations:
|
||||
WithTextControlGroupDecoration:
|
||||
Margin: 1, 1
|
||||
DrawLineToTarget:
|
||||
QueuedLineWidth: 2
|
||||
QueuedMarkerWidth: 3
|
||||
|
||||
^SelectableCombatBuilding:
|
||||
Inherits@selectiondecorations: ^SelectableBuilding
|
||||
IsometricSelectable:
|
||||
Priority: 4
|
||||
|
||||
^PrimaryBuilding:
|
||||
PrimaryBuilding:
|
||||
@@ -1366,6 +1371,5 @@
|
||||
RequiresCondition: primary
|
||||
Position: Top
|
||||
RequiresSelection: true
|
||||
Margin: 0, 5
|
||||
Text: PRIMARY
|
||||
Color: E0D048
|
||||
|
||||
@@ -29,9 +29,6 @@ GAPOWR:
|
||||
RequiresCondition: !build-incomplete
|
||||
PauseOnCondition: empdisable
|
||||
Sequence: idle-plug
|
||||
Selectable:
|
||||
Bounds: 90, 48, 0, -6
|
||||
DecorationBounds: 90, 84, 0, -12
|
||||
Power:
|
||||
Amount: 100
|
||||
RequiresCondition: !empdisable
|
||||
@@ -66,6 +63,8 @@ GAPOWR:
|
||||
RequiresCondition: !empdisable && powrup.b
|
||||
Amount: 50
|
||||
ProvidesPrerequisite@buildingname:
|
||||
IsometricSelectable:
|
||||
Height: 48
|
||||
|
||||
GAPILE:
|
||||
Inherits: ^Building
|
||||
@@ -85,9 +84,6 @@ GAPILE:
|
||||
Building:
|
||||
Footprint: xx xx
|
||||
Dimensions: 2,2
|
||||
Selectable:
|
||||
Bounds: 88, 48, 0, -8
|
||||
DecorationBounds: 88, 56, 0, -8
|
||||
Health:
|
||||
HP: 80000
|
||||
Armor:
|
||||
@@ -174,9 +170,6 @@ GAWEAP:
|
||||
Building:
|
||||
Footprint: xxX+ xxX+ xxX+
|
||||
Dimensions: 4,3
|
||||
Selectable:
|
||||
Bounds: 154, 96, -2, -12
|
||||
DecorationBounds: 154, 100, -2, -12
|
||||
Health:
|
||||
HP: 100000
|
||||
RevealsShroud:
|
||||
@@ -218,6 +211,8 @@ GAWEAP:
|
||||
Power:
|
||||
Amount: -30
|
||||
ProvidesPrerequisite@buildingname:
|
||||
IsometricSelectable:
|
||||
Height: 48
|
||||
|
||||
GAHPAD:
|
||||
Inherits: ^Building
|
||||
@@ -269,9 +264,6 @@ GAHPAD:
|
||||
UseDeathTypeSuffix: false
|
||||
Power:
|
||||
Amount: -10
|
||||
Selectable:
|
||||
Bounds: 88, 66, 0, -5
|
||||
DecorationBounds: 88, 66, 0, -5
|
||||
ProvidesPrerequisite@buildingname:
|
||||
|
||||
GADEPT:
|
||||
@@ -289,9 +281,6 @@ GADEPT:
|
||||
Building:
|
||||
Footprint: =+= x++ x+=
|
||||
Dimensions: 3,3
|
||||
Selectable:
|
||||
Bounds: 96, 64, -6, -6
|
||||
DecorationBounds: 98, 68, -6, -6
|
||||
Health:
|
||||
HP: 110000
|
||||
RevealsShroud:
|
||||
@@ -355,9 +344,6 @@ GARADR:
|
||||
Building:
|
||||
Footprint: xx xx
|
||||
Dimensions: 2,2
|
||||
Selectable:
|
||||
Bounds: 96, 48, 0, -6
|
||||
DecorationBounds: 96, 118, 0, -38
|
||||
Health:
|
||||
HP: 100000
|
||||
Armor:
|
||||
@@ -380,6 +366,8 @@ GARADR:
|
||||
Power:
|
||||
Amount: -50
|
||||
ProvidesPrerequisite@buildingname:
|
||||
IsometricSelectable:
|
||||
Height: 72
|
||||
|
||||
GATECH:
|
||||
Inherits: ^Building
|
||||
@@ -399,9 +387,6 @@ GATECH:
|
||||
Building:
|
||||
Footprint: xxx xxx
|
||||
Dimensions: 3,2
|
||||
Selectable:
|
||||
Bounds: 110, 60, 3, -4
|
||||
DecorationBounds: 110, 60, 3, -4
|
||||
Health:
|
||||
HP: 50000
|
||||
Armor:
|
||||
@@ -415,6 +400,8 @@ GATECH:
|
||||
Power:
|
||||
Amount: -150
|
||||
ProvidesPrerequisite@buildingname:
|
||||
IsometricSelectable:
|
||||
Height: 48
|
||||
|
||||
GAPLUG:
|
||||
Inherits: ^Building
|
||||
@@ -424,9 +411,6 @@ GAPLUG:
|
||||
Cost: 1000
|
||||
Tooltip:
|
||||
Name: GDI Upgrade Center
|
||||
Selectable:
|
||||
Bounds: 115,72,0,-12
|
||||
DecorationBounds: 115,104,0,-24
|
||||
Buildable:
|
||||
BuildPaletteOrder: 170
|
||||
Prerequisites: proc, gatech, ~structures.gdi, ~techlevel.superweapons
|
||||
@@ -524,3 +508,5 @@ GAPLUG:
|
||||
PauseOnCondition: disabled
|
||||
Sequence: idle-hunterseekerb
|
||||
ProvidesPrerequisite@buildingname:
|
||||
IsometricSelectable:
|
||||
Height: 48
|
||||
|
||||
@@ -57,9 +57,6 @@ GACTWR:
|
||||
BuildPaletteOrder: 70
|
||||
Prerequisites: gapile, ~structures.gdi, ~techlevel.low
|
||||
Description: Modular tower for base defenses.
|
||||
Selectable:
|
||||
Bounds: 48, 36, 0, -6
|
||||
DecorationBounds: 48, 48, 0, -12
|
||||
Health:
|
||||
HP: 50000
|
||||
Armor:
|
||||
@@ -139,6 +136,8 @@ GACTWR:
|
||||
ProvidesPrerequisite@buildingname:
|
||||
Replacement:
|
||||
ReplaceableTypes: GDITower
|
||||
IsometricSelectable:
|
||||
Height: 48
|
||||
|
||||
GAVULC:
|
||||
Inherits: ^BuildingPlug
|
||||
|
||||
@@ -15,9 +15,6 @@ NAPOWR:
|
||||
Building:
|
||||
Footprint: xx xx
|
||||
Dimensions: 2,2
|
||||
Selectable:
|
||||
Bounds: 88, 48, 2, -6
|
||||
DecorationBounds: 88, 80, 2, -12
|
||||
Health:
|
||||
HP: 75000
|
||||
Armor:
|
||||
@@ -35,6 +32,8 @@ NAPOWR:
|
||||
TargetTypes: Ground, Building, C4, SpyInfiltrate
|
||||
ScalePowerWithHealth:
|
||||
PowerTooltip:
|
||||
IsometricSelectable:
|
||||
Height: 48
|
||||
|
||||
NAAPWR:
|
||||
Inherits: ^Building
|
||||
@@ -53,9 +52,6 @@ NAAPWR:
|
||||
Building:
|
||||
Footprint: xxx xxx
|
||||
Dimensions: 2,3
|
||||
Selectable:
|
||||
Bounds: 100, 54, 0, -4
|
||||
DecorationBounds: 100, 74, 0, -12
|
||||
Health:
|
||||
HP: 75000
|
||||
Armor:
|
||||
@@ -74,6 +70,8 @@ NAAPWR:
|
||||
ScalePowerWithHealth:
|
||||
PowerTooltip:
|
||||
ProvidesPrerequisite@buildingname:
|
||||
IsometricSelectable:
|
||||
Height: 48
|
||||
|
||||
NAHAND:
|
||||
Inherits: ^Building
|
||||
@@ -93,9 +91,6 @@ NAHAND:
|
||||
Building:
|
||||
Footprint: xxx xxx
|
||||
Dimensions: 3,2
|
||||
Selectable:
|
||||
Bounds: 116, 60, 3, -6
|
||||
DecorationBounds: 116, 78, 3, -8
|
||||
Health:
|
||||
HP: 80000
|
||||
Armor:
|
||||
@@ -185,9 +180,6 @@ NAWEAP:
|
||||
Building:
|
||||
Footprint: xxX+ xxX+ xxX+
|
||||
Dimensions: 4,3
|
||||
Selectable:
|
||||
Bounds: 149, 80, -3, -10
|
||||
DecorationBounds: 149, 116, -3, -20
|
||||
Health:
|
||||
HP: 100000
|
||||
Armor:
|
||||
@@ -223,6 +215,8 @@ NAWEAP:
|
||||
Power:
|
||||
Amount: -30
|
||||
ProvidesPrerequisite@buildingname:
|
||||
IsometricSelectable:
|
||||
Height: 48
|
||||
|
||||
NAHPAD:
|
||||
Inherits: ^Building
|
||||
@@ -274,10 +268,9 @@ NAHPAD:
|
||||
UseDeathTypeSuffix: false
|
||||
Power:
|
||||
Amount: -10
|
||||
Selectable:
|
||||
Bounds: 78, 48, 0, -6
|
||||
DecorationBounds: 78, 54, 0, -8
|
||||
ProvidesPrerequisite@buildingname:
|
||||
IsometricSelectable:
|
||||
Height: 36
|
||||
|
||||
NARADR:
|
||||
Inherits: ^Building
|
||||
@@ -297,9 +290,6 @@ NARADR:
|
||||
Building:
|
||||
Footprint: xx xx
|
||||
Dimensions: 2,2
|
||||
Selectable:
|
||||
Bounds: 96, 48, 0, -6
|
||||
DecorationBounds: 96, 72, 0, -12
|
||||
Health:
|
||||
HP: 100000
|
||||
Armor:
|
||||
@@ -322,6 +312,8 @@ NARADR:
|
||||
Power:
|
||||
Amount: -40
|
||||
ProvidesPrerequisite@buildingname:
|
||||
IsometricSelectable:
|
||||
Height: 72
|
||||
|
||||
NATECH:
|
||||
Inherits: ^Building
|
||||
@@ -341,9 +333,6 @@ NATECH:
|
||||
Building:
|
||||
Footprint: xx xx
|
||||
Dimensions: 2,2
|
||||
Selectable:
|
||||
Bounds: 86, 48, 0, -4
|
||||
DecorationBounds: 86, 58, 0, -4
|
||||
Health:
|
||||
HP: 50000
|
||||
Armor:
|
||||
@@ -379,8 +368,6 @@ NATMPL:
|
||||
Dimensions: 4,3
|
||||
RequiresBuildableArea:
|
||||
Adjacent: 3
|
||||
Selectable:
|
||||
Bounds: 134, 120, 12, -12
|
||||
Health:
|
||||
HP: 100000
|
||||
Armor:
|
||||
@@ -407,3 +394,5 @@ NATMPL:
|
||||
PauseOnCondition: empdisable
|
||||
Exit@1:
|
||||
ExitsDebugOverlay:
|
||||
IsometricSelectable:
|
||||
Height: 60
|
||||
|
||||
@@ -63,8 +63,6 @@ NAPOST:
|
||||
NodeTypes: laserfencenode
|
||||
SegmentType: nafnce
|
||||
SegmentsRequireNode: true
|
||||
Selectable:
|
||||
Bounds: 42, 44, 0, -12
|
||||
LineBuildNode:
|
||||
Types: laserfencenode
|
||||
Power:
|
||||
@@ -156,9 +154,6 @@ NALASR:
|
||||
Prerequisites: nahand, ~structures.nod, ~techlevel.low
|
||||
BuildPaletteOrder: 90
|
||||
Description: Basic base defense.\nRequires power to operate.\n Strong vs Ground units\n Weak vs Aircraft
|
||||
Selectable:
|
||||
Bounds: 40, 30, -8, -6
|
||||
DecorationBounds: 40, 36, -8, -8
|
||||
Health:
|
||||
HP: 50000
|
||||
Armor:
|
||||
@@ -202,9 +197,6 @@ NAOBEL:
|
||||
Building:
|
||||
Footprint: xx xx
|
||||
Dimensions: 2,2
|
||||
Selectable:
|
||||
Bounds: 88, 42, 0, -6
|
||||
DecorationBounds: 88, 72, 0, -12
|
||||
Health:
|
||||
HP: 72500
|
||||
Armor:
|
||||
@@ -246,9 +238,6 @@ NASAM:
|
||||
Prerequisites: naradr, ~structures.nod, ~techlevel.medium
|
||||
BuildPaletteOrder: 100
|
||||
Description: Nod Anti-Air base defense.\nRequires power to operate.\n Strong vs Aircraft\n Weak vs Ground units
|
||||
Selectable:
|
||||
Bounds: 40, 30, -3, -8
|
||||
DecorationBounds: 40, 36, -3, -8
|
||||
Health:
|
||||
HP: 60000
|
||||
Armor:
|
||||
@@ -312,9 +301,6 @@ NASTLH:
|
||||
EnableSound: cloak5.aud
|
||||
DisableSound: cloak5.aud
|
||||
AffectsParent: true
|
||||
Selectable:
|
||||
Bounds: 106, 48, 8, -6
|
||||
DecorationBounds: 106, 60, 8, -15
|
||||
|
||||
NAMISL:
|
||||
Inherits: ^Building
|
||||
@@ -335,9 +321,6 @@ NAMISL:
|
||||
Building:
|
||||
Footprint: xx xx
|
||||
Dimensions: 2,2
|
||||
Selectable:
|
||||
Bounds: 75,48
|
||||
DecorationBounds: 75,48
|
||||
Health:
|
||||
HP: 100000
|
||||
Armor:
|
||||
@@ -397,9 +380,6 @@ NAWAST:
|
||||
Building:
|
||||
Footprint: Xx= xx= Xx=
|
||||
Dimensions: 3,3
|
||||
Selectable:
|
||||
Bounds: 100, 60, 5, -5
|
||||
DecorationBounds: 100, 60, 5, -5
|
||||
Health:
|
||||
HP: 40000
|
||||
RevealsShroud:
|
||||
@@ -429,7 +409,9 @@ NAWAST:
|
||||
WithResourceStoragePipsDecoration:
|
||||
Position: BottomLeft
|
||||
RequiresSelection: true
|
||||
Margin: 5, 2
|
||||
Margin: 8, 2
|
||||
FullSequence: pip-red-building
|
||||
EmptySequence: pip-empty-building
|
||||
PipStride: 4, 2
|
||||
PipCount: 15
|
||||
FullSequence: pip-red
|
||||
Palette: pips
|
||||
|
||||
@@ -75,15 +75,14 @@ GACNST:
|
||||
RequiresCondition: !build-incomplete
|
||||
Power:
|
||||
Amount: 0
|
||||
Selectable:
|
||||
Bounds: 144, 60, 0, -6
|
||||
DecorationBounds: 144, 80, 0, -12
|
||||
ProvidesPrerequisite@gdi:
|
||||
Factions: gdi
|
||||
Prerequisite: structures.gdi
|
||||
ProvidesPrerequisite@nod:
|
||||
Factions: nod
|
||||
Prerequisite: structures.nod
|
||||
IsometricSelectable:
|
||||
Height: 36
|
||||
|
||||
PROC:
|
||||
Inherits: ^Building
|
||||
@@ -100,9 +99,6 @@ PROC:
|
||||
Building:
|
||||
Footprint: xxX+ xx++ xxX+
|
||||
Dimensions: 4,3
|
||||
Selectable:
|
||||
Bounds: 134, 96, 0, -12
|
||||
DecorationBounds: 134, 122, 0, -18
|
||||
Health:
|
||||
HP: 90000
|
||||
RevealsShroud:
|
||||
@@ -148,8 +144,11 @@ PROC:
|
||||
WithResourceStoragePipsDecoration:
|
||||
Position: BottomLeft
|
||||
RequiresSelection: true
|
||||
Margin: 5, 2
|
||||
PipCount: 10
|
||||
Margin: 8, 2
|
||||
FullSequence: pip-green-building
|
||||
EmptySequence: pip-empty-building
|
||||
PipStride: 4, 2
|
||||
PipCount: 25
|
||||
Palette: pips
|
||||
|
||||
GASILO:
|
||||
@@ -167,9 +166,6 @@ GASILO:
|
||||
Building:
|
||||
Footprint: xx xx
|
||||
Dimensions: 2, 2
|
||||
Selectable:
|
||||
Bounds: 80, 48, -5, 0
|
||||
DecorationBounds: 80, 48, -5, 0
|
||||
-GivesBuildableArea:
|
||||
Health:
|
||||
HP: 30000
|
||||
@@ -203,8 +199,11 @@ GASILO:
|
||||
WithResourceStoragePipsDecoration:
|
||||
Position: BottomLeft
|
||||
RequiresSelection: true
|
||||
Margin: 5, 2
|
||||
PipCount: 5
|
||||
Margin: 8, 2
|
||||
FullSequence: pip-green-building
|
||||
EmptySequence: pip-empty-building
|
||||
PipStride: 4, 2
|
||||
PipCount: 12
|
||||
Palette: pips
|
||||
|
||||
ANYPOWER:
|
||||
|
||||
@@ -14,9 +14,6 @@ NAPULS:
|
||||
Building:
|
||||
Footprint: xx xx
|
||||
Dimensions: 2,2
|
||||
Selectable:
|
||||
Bounds: 78, 54, 0, -12
|
||||
DecorationBounds: 78, 54, 0, -12
|
||||
Health:
|
||||
HP: 50000
|
||||
Armor:
|
||||
|
||||
Reference in New Issue
Block a user