Killed that fail TechTree, and added a new one to Rules.

This commit is contained in:
Bob
2009-10-30 09:04:33 +13:00
parent 7b28ab7979
commit 6306690730
16 changed files with 133 additions and 272 deletions

View File

@@ -1,15 +1,14 @@
using System;
using System.Collections.Generic; using System.Collections.Generic;
using OpenRa.FileFormats;
using OpenRa.Game.Graphics;
using OpenRa.TechTree;
using System.Drawing; using System.Drawing;
using System.Linq; using System.Linq;
using IrrKlang;
using IjwFramework.Collections; using IjwFramework.Collections;
using System;
using IjwFramework.Types; using IjwFramework.Types;
using OpenRa.Game.Traits; using IrrKlang;
using OpenRa.FileFormats;
using OpenRa.Game.GameRules; using OpenRa.Game.GameRules;
using OpenRa.Game.Graphics;
using OpenRa.Game.Traits;
namespace OpenRa.Game namespace OpenRa.Game
{ {
@@ -44,7 +43,7 @@ namespace OpenRa.Game
Rules.LoadRules(mapName); Rules.LoadRules(mapName);
for (int i = 0; i < 8; i++) for (int i = 0; i < 8; i++)
players.Add(i, new Player(i, string.Format("Multi{0}", i), Race.Soviet)); players.Add(i, new Player(i, string.Format("Multi{0}", i), Race.Allies));
localPlayerIndex = localPlayer; localPlayerIndex = localPlayer;
@@ -223,7 +222,7 @@ namespace OpenRa.Game
public static void BuildUnit(Player player, string name) public static void BuildUnit(Player player, string name)
{ {
var producerTypes = Rules.UnitInfo[name].BuiltAt; var producerTypes = Rules.TechTree.UnitBuiltAt( Rules.UnitInfo[ name ] );
var producer = world.Actors var producer = world.Actors
.FirstOrDefault(a => a.unitInfo != null .FirstOrDefault(a => a.unitInfo != null
&& producerTypes.Contains(a.unitInfo.Name) && a.Owner == player); && producerTypes.Contains(a.unitInfo.Name) && a.Owner == player);

View File

@@ -29,7 +29,7 @@ namespace OpenRa.Game.GameRules
return x; return x;
else if (fieldType.IsEnum) else if (fieldType.IsEnum)
return Enum.Parse(fieldType, x); return Enum.Parse(fieldType, x, true);
else if (fieldType == typeof(bool)) else if (fieldType == typeof(bool))
return ParseYesNo(x); return ParseYesNo(x);

View File

@@ -16,6 +16,7 @@ namespace OpenRa.Game
public static InfoLoader<WeaponInfo> WeaponInfo; public static InfoLoader<WeaponInfo> WeaponInfo;
public static InfoLoader<WarheadInfo> WarheadInfo; public static InfoLoader<WarheadInfo> WarheadInfo;
public static InfoLoader<ProjectileInfo> ProjectileInfo; public static InfoLoader<ProjectileInfo> ProjectileInfo;
public static TechTree TechTree;
public static void LoadRules( string mapFileName ) public static void LoadRules( string mapFileName )
{ {
@@ -52,6 +53,8 @@ namespace OpenRa.Game
ProjectileInfo = new InfoLoader<ProjectileInfo>( ProjectileInfo = new InfoLoader<ProjectileInfo>(
Pair.New<string, Func<string, ProjectileInfo>>("Projectile", _ => new ProjectileInfo())); Pair.New<string, Func<string, ProjectileInfo>>("Projectile", _ => new ProjectileInfo()));
TechTree = new TechTree();
} }
static void LoadCategories( params string[] types ) static void LoadCategories( params string[] types )

View File

@@ -0,0 +1,65 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using IjwFramework.Collections;
namespace OpenRa.Game.GameRules
{
class TechTree
{
readonly Cache<string, List<UnitInfo.BuildingInfo>> producesIndex = new Cache<string, List<UnitInfo.BuildingInfo>>( x => new List<UnitInfo.BuildingInfo>() );
public TechTree()
{
foreach( var b in Rules.Categories[ "Building" ] )
{
var info = (UnitInfo.BuildingInfo)Rules.UnitInfo[ b ];
foreach( var p in info.Produces )
producesIndex[ p ].Add( info );
}
}
public Cache<string, List<Actor>> GatherBuildings( Player player )
{
var ret = new Cache<string, List<Actor>>( x => new List<Actor>() );
foreach( var b in Game.world.Actors.Where( x => x.Owner == player && Rules.UnitCategory[ x.unitInfo.Name ] == "Building" ) )
ret[ b.unitInfo.Name ].Add( b );
return ret;
}
public bool CanBuild( UnitInfo unit, Player player, Cache<string, List<Actor>> playerBuildings )
{
if( unit.TechLevel == -1 )
return false;
if( !unit.Owner.Any( x => x == player.Race ) )
return false;
foreach( var p in unit.Prerequisite )
if( playerBuildings[ p ].Count == 0 )
return false;
if( producesIndex[ Rules.UnitCategory[ unit.Name ] ].All( x => playerBuildings[ x.Name ].Count == 0 ) )
return false;
return true;
}
public IEnumerable<string> BuildableItems( Player player, params string[] categories )
{
var playerBuildings = GatherBuildings( player );
foreach( var unit in categories.SelectMany( x => Rules.Categories[ x ] ).Select( x => Rules.UnitInfo[ x ] ) )
if( CanBuild( unit, player, playerBuildings ) )
yield return unit.Name;
}
public IEnumerable<string> UnitBuiltAt( UnitInfo info )
{
if( info.BuiltAt.Length != 0 )
return info.BuiltAt;
else
return producesIndex[ Rules.UnitCategory[ info.Name ] ].Select( x => x.Name );
}
}
}

View File

@@ -33,7 +33,7 @@ namespace OpenRa.Game.GameRules
public readonly int GuardRange = -1; // -1 = use weapon's range public readonly int GuardRange = -1; // -1 = use weapon's range
public readonly string Image = null; // sprite-set to use when rendering public readonly string Image = null; // sprite-set to use when rendering
public readonly bool Invisible = false; public readonly bool Invisible = false;
public readonly string[] Owner = { "allies", "soviet" }; public readonly Race[] Owner = { Race.Allies, Race.Soviet };
public readonly int Points = 0; public readonly int Points = 0;
public readonly string[] Prerequisite = { }; public readonly string[] Prerequisite = { };
public readonly string Primary = null; public readonly string Primary = null;
@@ -81,6 +81,7 @@ namespace OpenRa.Game.GameRules
{ {
public readonly int2 Dimensions = new int2( 1, 1 ); public readonly int2 Dimensions = new int2( 1, 1 );
public readonly string Footprint = "x"; public readonly string Footprint = "x";
public readonly string[] Produces = { };
public readonly bool BaseNormal = true; public readonly bool BaseNormal = true;
public readonly int Adjacent = 1; public readonly int Adjacent = 1;

View File

@@ -2,7 +2,6 @@ using System.Drawing;
using System.Windows.Forms; using System.Windows.Forms;
using OpenRa.FileFormats; using OpenRa.FileFormats;
using OpenRa.Game.Graphics; using OpenRa.Game.Graphics;
using OpenRa.TechTree;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
namespace OpenRa.Game namespace OpenRa.Game

View File

@@ -74,6 +74,7 @@
<Reference Include="System.Xml" /> <Reference Include="System.Xml" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="GameRules\TechTree.cs" />
<Compile Include="OrderManager.cs" /> <Compile Include="OrderManager.cs" />
<Compile Include="Traits\Activities\DeployMcv.cs" /> <Compile Include="Traits\Activities\DeployMcv.cs" />
<Compile Include="Actor.cs" /> <Compile Include="Actor.cs" />
@@ -99,7 +100,6 @@
<Compile Include="BuildingInfluenceMap.cs" /> <Compile Include="BuildingInfluenceMap.cs" />
<Compile Include="IOrderGenerator.cs" /> <Compile Include="IOrderGenerator.cs" />
<Compile Include="PlaceBuilding.cs" /> <Compile Include="PlaceBuilding.cs" />
<Compile Include="TechTree\Item.cs" />
<Compile Include="Player.cs" /> <Compile Include="Player.cs" />
<Compile Include="Race.cs" /> <Compile Include="Race.cs" />
<Compile Include="Support\SharedResources.cs" /> <Compile Include="Support\SharedResources.cs" />
@@ -124,7 +124,6 @@
<Compile Include="Graphics\Sprite.cs" /> <Compile Include="Graphics\Sprite.cs" />
<Compile Include="Graphics\SpriteRenderer.cs" /> <Compile Include="Graphics\SpriteRenderer.cs" />
<Compile Include="Graphics\SpriteSheetBuilder.cs" /> <Compile Include="Graphics\SpriteSheetBuilder.cs" />
<Compile Include="TechTree\TechTree.cs" />
<Compile Include="TerrainCosts.cs" /> <Compile Include="TerrainCosts.cs" />
<Compile Include="Graphics\TerrainRenderer.cs" /> <Compile Include="Graphics\TerrainRenderer.cs" />
<Compile Include="Graphics\TreeCache.cs" /> <Compile Include="Graphics\TreeCache.cs" />

View File

@@ -8,13 +8,13 @@ namespace OpenRa.Game
public int Palette; public int Palette;
public int Kills; public int Kills;
public string PlayerName; public string PlayerName;
public TechTree.TechTree TechTree = new OpenRa.TechTree.TechTree(); public Race Race;
public Player( int palette, string playerName, OpenRa.TechTree.Race race ) public Player( int palette, string playerName, Race race )
{ {
this.Palette = palette; this.Palette = palette;
this.PlayerName = playerName; this.PlayerName = playerName;
TechTree.CurrentRace = race; this.Race = race;
} }
public float GetSiloFullness() public float GetSiloFullness()

View File

@@ -2,7 +2,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using System.Text;
namespace OpenRa.TechTree namespace OpenRa.Game
{ {
[Flags] [Flags]
public enum Race public enum Race

View File

@@ -4,7 +4,6 @@ using System.Drawing;
using System.Windows.Forms; using System.Windows.Forms;
using OpenRa.FileFormats; using OpenRa.FileFormats;
using OpenRa.Game.Graphics; using OpenRa.Game.Graphics;
using OpenRa.TechTree;
using System.Linq; using System.Linq;
namespace OpenRa.Game namespace OpenRa.Game
@@ -34,7 +33,6 @@ namespace OpenRa.Game
public Sidebar( Renderer renderer, Player player ) public Sidebar( Renderer renderer, Player player )
{ {
this.player = player; this.player = player;
this.player.TechTree.BuildableItemsChanged += PopulateItemList;
region = GRegion.Create(Game.viewport, DockStyle.Right, 128, Paint, MouseHandler); region = GRegion.Create(Game.viewport, DockStyle.Right, 128, Paint, MouseHandler);
Game.viewport.AddRegion( region ); Game.viewport.AddRegion( region );
spriteRenderer = new SpriteRenderer(renderer, false); spriteRenderer = new SpriteRenderer(renderer, false);
@@ -68,11 +66,11 @@ namespace OpenRa.Game
{ {
if (item == null) return; if (item == null) return;
if (item.techTreeItem.IsStructure) if (item.IsStructure)
Game.controller.orderGenerator = new PlaceBuilding(player, Game.controller.orderGenerator = new PlaceBuilding(player,
item.techTreeItem.tag.ToLowerInvariant()); item.Tag.ToLowerInvariant());
else else
Game.controller.AddOrder(Order.BuildUnit(player, item.techTreeItem.tag.ToLowerInvariant())); Game.controller.AddOrder(Order.BuildUnit(player, item.Tag.ToLowerInvariant()));
} }
void LoadSprites( string group ) void LoadSprites( string group )
@@ -107,17 +105,20 @@ namespace OpenRa.Game
items.Clear(); items.Clear();
foreach (Item i in player.TechTree.BuildableItems) foreach (var i in Rules.TechTree.BuildableItems(player, "Building"))
{ {
Sprite sprite; Sprite sprite;
if (!sprites.TryGetValue(i.tag, out sprite)) continue; if (!sprites.TryGetValue(i, out sprite)) continue;
items.Add(new SidebarItem(sprite, i, true, buildPos));
buildPos += spriteHeight;
}
items.Add(new SidebarItem(sprite, i, i.IsStructure ? buildPos : unitPos)); foreach( var i in Rules.TechTree.BuildableItems( player, "Vehicle", "Infantry", "Ship", "Plane" ) )
{
if (i.IsStructure) Sprite sprite;
buildPos += spriteHeight; if( !sprites.TryGetValue( i, out sprite ) ) continue;
else items.Add( new SidebarItem( sprite, i, false, unitPos ) );
unitPos += spriteHeight; unitPos += spriteHeight;
} }
foreach( string g in groups ) player.CancelProduction( g ); foreach( string g in groups ) player.CancelProduction( g );
@@ -125,11 +126,12 @@ namespace OpenRa.Game
void Paint() void Paint()
{ {
PopulateItemList();
foreach( SidebarItem i in items ) foreach( SidebarItem i in items )
{ {
var group = Rules.UnitCategory[ i.techTreeItem.tag ]; var group = Rules.UnitCategory[ i.Tag ];
var producing = player.Producing( group ); var producing = player.Producing( group );
if( producing != null && producing.Item == i.techTreeItem.tag ) if( producing != null && producing.Item == i.Tag )
{ {
clockAnimations[ group ].Tick(); clockAnimations[ group ].Tick();
clockRenderer.DrawSprite( clockAnimations[ group ].Image, region.Location.ToFloat2() + i.location, 0 ); clockRenderer.DrawSprite( clockAnimations[ group ].Image, region.Location.ToFloat2() + i.location, 0 );
@@ -155,30 +157,22 @@ namespace OpenRa.Game
void MouseHandler(MouseInput mi) void MouseHandler(MouseInput mi)
{ {
if (mi.Button == MouseButtons.Left && mi.Event == MouseInputEvent.Down) var point = mi.Location.ToFloat2();
var item = GetItem( point );
if( item == null )
return;
if( mi.Button == MouseButtons.Left && mi.Event == MouseInputEvent.Down )
{ {
var point = mi.Location.ToFloat2(); string group = Rules.UnitCategory[ item.Tag ];
var item = GetItem(point);
if (item != null)
{
string group = Rules.UnitCategory[ item.techTreeItem.tag ];
if (player.Producing(group) == null) if (player.Producing(group) == null)
{ {
player.BeginProduction( group, new ProductionItem( item.techTreeItem.tag, 25, 0 ) ); player.BeginProduction( group, new ProductionItem( item.Tag, 25, 0 ) );
Build(item); Build(item);
} }
}
} }
else if( mi.Button == MouseButtons.Right && mi.Event == MouseInputEvent.Down ) else if( mi.Button == MouseButtons.Right && mi.Event == MouseInputEvent.Down )
{ player.CancelProduction( Rules.UnitCategory[ item.Tag ] );
var point = mi.Location.ToFloat2();
var item = GetItem(point);
if( item != null )
{
string group = Rules.UnitCategory[ item.techTreeItem.tag ];
player.CancelProduction( group );
}
}
} }
} }
} }

View File

@@ -1,19 +1,20 @@
using OpenRa.Game.Graphics; using OpenRa.Game.Graphics;
using OpenRa.TechTree;
namespace OpenRa.Game namespace OpenRa.Game
{ {
class SidebarItem class SidebarItem
{ {
public readonly Item techTreeItem;
public readonly float2 location; public readonly float2 location;
public readonly string Tag;
public readonly bool IsStructure;
readonly Sprite sprite; readonly Sprite sprite;
public SidebarItem(Sprite s, Item item, int y) public SidebarItem(Sprite s, string tag, bool isStructure, int y)
{ {
this.techTreeItem = item;
this.sprite = s; this.sprite = s;
location = new float2(item.IsStructure ? 0 : 64, y); this.Tag = tag;
this.IsStructure = isStructure;
location = new float2(isStructure ? 0 : 64, y);
} }
public bool Clicked(float2 p) public bool Clicked(float2 p)

View File

@@ -1,122 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using OpenRa.FileFormats;
using OpenRa.Game.GameRules;
using IjwFramework.Types;
using OpenRa.Game;
namespace OpenRa.TechTree
{
public class Item
{
readonly bool isStructure;
public bool IsStructure { get { return isStructure; } }
public Item(string tag, UnitInfo unitInfo, bool isStructure)
{
this.tag = tag;
this.friendlyName = unitInfo.Description;
this.isStructure = isStructure;
owner = ParseOwner(unitInfo.Owner, unitInfo.DoubleOwned);
techLevel = unitInfo.TechLevel;
var pre = ParsePrerequisites(unitInfo.Prerequisite, tag);
alliedPrerequisites = pre.a;
sovietPrerequisites = pre.b;
}
static Race ParseOwner(string[] owners, bool doubleOwned)
{
if (doubleOwned)
return Race.Allies | Race.Soviet;
Race race = Race.None;
foreach (string s in owners)
race |= Enum<Race>.Parse(s);
return race;
}
static Tuple<string[],string[]> ParsePrerequisites(string[] prerequisites, string tag)
{
var allied = prerequisites.Select( x => x.ToLowerInvariant() ).ToList();
var soviet = new List<string>(allied);
if (allied.Remove("stek")) allied.Add("atek");
if (soviet.Remove("atek")) soviet.Add("stek");
if (soviet.Remove("tent")) soviet.Add("barr");
if (allied.Remove("barr")) allied.Add("tent");
if( Rules.UnitCategory[ tag ] == "Infantry" )
{
if( !allied.Contains( "tent" ) ) allied.Add( "tent" );
if( !soviet.Contains( "barr" ) ) soviet.Add( "barr" );
}
if (tag == "lst")
{
if (!soviet.Contains("spen")) soviet.Add("spen");
if (!allied.Contains("syrd")) allied.Add("syrd");
}
return new Tuple<string[], string[]>(
allied.ToArray(), soviet.ToArray());
}
public readonly string tag, friendlyName;
readonly int techLevel;
readonly Race owner;
readonly string[] alliedPrerequisites, sovietPrerequisites;
bool ShouldMakeBuildable(IEnumerable<string> buildings, string[] racePrerequisites)
{
if (techLevel < 0)
return false;
if (racePrerequisites.Length == 0)
return true;
return racePrerequisites.Except(buildings).Count() == 0;
}
bool ShouldMakeUnbuildable(IEnumerable<string> buildings, string[] racePrerequisites)
{
if (racePrerequisites.Length == 0)
return false;
return racePrerequisites.Except(buildings).Count() == racePrerequisites.Length;
}
void CheckForBoth(IEnumerable<string> buildings)
{
if (CanBuild && (ShouldMakeUnbuildable(buildings, alliedPrerequisites)
&& ShouldMakeUnbuildable(buildings, sovietPrerequisites)))
CanBuild = false;
else if (!CanBuild && (ShouldMakeBuildable(buildings, alliedPrerequisites)
|| ShouldMakeBuildable(buildings, sovietPrerequisites)))
CanBuild = true;
}
public void CheckPrerequisites(IEnumerable<string> buildings, Race currentRace)
{
if (currentRace == Race.None || currentRace == (Race.Allies | Race.Soviet))
CheckForBoth(buildings);
else
{
string[] racePrerequisites = (currentRace == Race.Allies) ? alliedPrerequisites : sovietPrerequisites;
if ((CanBuild && ShouldMakeUnbuildable(buildings, racePrerequisites)) || !((owner & currentRace) == currentRace))
CanBuild = false;
else if (!CanBuild && ShouldMakeBuildable(buildings, racePrerequisites))
CanBuild = true;
}
}
public bool CanBuild { get; private set; }
public string Tooltip { get { return string.Format("{0} ({1})\n{2}", friendlyName, tag, owner); } }
}
}

View File

@@ -1,75 +0,0 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using OpenRa.FileFormats;
using System.Linq;
using OpenRa.Game;
namespace OpenRa.TechTree
{
public class TechTree
{
Dictionary<string, Item> objects = new Dictionary<string, Item>();
public ICollection<string> built = new List<string>();
Race currentRace = Race.None;
public Race CurrentRace
{
get { return currentRace; }
set
{
currentRace = value;
CheckAll();
}
}
public TechTree()
{
LoadRules();
CheckAll();
}
void LoadRules()
{
foreach( var unit in Rules.UnitInfo )
objects.Add( unit.Key, new Item( unit.Key, unit.Value, Rules.UnitCategory[ unit.Key ] == "Building" ) );
}
public bool Build(string key, bool force)
{
if( string.IsNullOrEmpty( key ) ) return false;
key = key.ToLowerInvariant();
Item b = objects[ key ];
if (!force && !b.CanBuild) return false;
built.Add(key);
CheckAll();
return true;
}
public bool Build(string key) { return Build(key, false); }
public bool Unbuild(string key)
{
key = key.ToLowerInvariant();
Item b = objects[key];
if (!built.Contains(key)) return false;
built.Remove(key);
CheckAll();
return true;
}
void CheckAll()
{
foreach (Item unit in objects.Values)
unit.CheckPrerequisites(built, currentRace);
BuildableItemsChanged();
}
public IEnumerable<Item> BuildableItems { get { return objects.Values.Where(b => b.CanBuild); } }
public event Action BuildableItemsChanged = () => { };
}
}

View File

@@ -15,10 +15,8 @@ namespace OpenRa.Game.Traits
public void Tick(Actor self) public void Tick(Actor self)
{ {
if (first && self.Owner == Game.LocalPlayer) if (first && self.Owner == Game.LocalPlayer)
{
self.Owner.TechTree.Build(self.unitInfo.Name, true);
self.CenterLocation = Game.CellSize * (float2)self.Location + 0.5f * self.SelectedSize; self.CenterLocation = Game.CellSize * (float2)self.Location + 0.5f * self.SelectedSize;
}
first = false; first = false;
} }
} }

View File

@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!-- openra/sequences.xml <!-- openra/sequences.xml
this file describes animation sequences for structures and units. this file describes animation sequences for structures and units.
@@ -361,7 +361,7 @@
<sequence name="attack" start="21" length="8" x="12" y="12" /> <sequence name="attack" start="21" length="8" x="12" y="12" />
<sequence name="move-minimap" start="29" length="6" /> <sequence name="move-minimap" start="29" length="6" />
<sequence name="repair" start="35" length="24" /> <sequence name="repair" start="35" length="24" />
<sequence name="deploy" start="59" length="9" x="12" y="12"/> <sequence name="deploy" start="59" length="9" x="12" y="12" />
<sequence name="sell" start="68" length="12" /> <sequence name="sell" start="68" length="12" />
<sequence name="default-minimap" start="80" length="1" /> <sequence name="default-minimap" start="80" length="1" />
<sequence name="ability" start="82" length="8" /> <sequence name="ability" start="82" length="8" />
@@ -465,4 +465,7 @@
<sequence name="5" start="0" length="22" src="veh-hit2" /> <sequence name="5" start="0" length="22" src="veh-hit2" />
<sequence name="6" start="0" length="27" src="atomsfx" /> <sequence name="6" start="0" length="27" src="atomsfx" />
</unit> </unit>
</sequences> <unit name="lst">
<sequence name="idle" start="0" length="1" />
</unit>
</sequences>

View File

@@ -16,55 +16,42 @@ MNLY
[V2RL] [V2RL]
Description=V2 Rocket Description=V2 Rocket
Traits=Mobile, RenderUnit Traits=Mobile, RenderUnit
BuiltAt=weap
[1TNK] [1TNK]
Description=Light Tank Description=Light Tank
Traits=Mobile, Turreted, AttackTurreted, RenderUnitTurreted Traits=Mobile, Turreted, AttackTurreted, RenderUnitTurreted
BuiltAt=weap
[2TNK] [2TNK]
Description=Medium Tank Description=Medium Tank
Traits=Mobile, Turreted, AttackTurreted, RenderUnitTurreted Traits=Mobile, Turreted, AttackTurreted, RenderUnitTurreted
BuiltAt=weap
[3TNK] [3TNK]
Description=Heavy Tank Description=Heavy Tank
Traits=Mobile, Turreted, AttackTurreted, RenderUnitTurreted Traits=Mobile, Turreted, AttackTurreted, RenderUnitTurreted
BuiltAt=weap
[4TNK] [4TNK]
Description=Mammoth Tank Description=Mammoth Tank
Traits=Mobile, Turreted, AttackTurreted, RenderUnitTurreted Traits=Mobile, Turreted, AttackTurreted, RenderUnitTurreted
BuiltAt=weap
[MRJ] [MRJ]
Description=Radar Jammer Description=Radar Jammer
Traits=Mobile, Turreted, RenderUnitTurreted ; temporary. It's not a turret, it's a spinney-thing Traits=Mobile, Turreted, RenderUnitTurreted ; temporary. It's not a turret, it's a spinney-thing
BuiltAt=weap
[MGG] [MGG]
Description=Mobile Gap Generator Description=Mobile Gap Generator
Traits=Mobile, Turreted, RenderUnitTurreted ; temporary. It's not a turret, it's a spinney-thing Traits=Mobile, Turreted, RenderUnitTurreted ; temporary. It's not a turret, it's a spinney-thing
BuiltAt=weap
[ARTY] [ARTY]
Description=Artillery Description=Artillery
Traits=Mobile, RenderUnit Traits=Mobile, RenderUnit
BuiltAt=weap
[HARV] [HARV]
Description=Ore Truck Description=Ore Truck
Traits=Mobile, RenderUnit Traits=Mobile, RenderUnit
BuiltAt=weap
[MCV] [MCV]
Description=Mobile Construction Vehicle Description=Mobile Construction Vehicle
Traits=Mobile, McvDeploy, RenderUnit Traits=Mobile, McvDeploy, RenderUnit
BuiltAt=weap
[JEEP] [JEEP]
Description=Ranger Description=Ranger
Traits=Mobile, Turreted, AttackTurreted, RenderUnitTurreted Traits=Mobile, Turreted, AttackTurreted, RenderUnitTurreted
BuiltAt=weap
[APC] [APC]
Description=Armored Personnel Carrier Description=Armored Personnel Carrier
Traits=Mobile, RenderUnit Traits=Mobile, RenderUnit
BuiltAt=weap
[MNLY] [MNLY]
Description=Minelayer Description=Minelayer
Traits=Mobile, RenderUnit Traits=Mobile, RenderUnit
BuiltAt=weap
@@ -95,7 +82,6 @@ Traits=Mobile, RenderUnit
[LST] [LST]
Description=Transport Description=Transport
WaterBound=yes WaterBound=yes
BuiltAt=syrd,spen
Traits=Mobile, RenderUnit Traits=Mobile, RenderUnit
[PT] [PT]
Description=Gunboat Description=Gunboat
@@ -178,6 +164,7 @@ DOMF
; _ : Not occupied by the building (e.g: the holes in the refinery and the service depot) ; _ : Not occupied by the building (e.g: the holes in the refinery and the service depot)
; x : Solid. cannot be walked on or built on. ; x : Solid. cannot be walked on or built on.
; = : Occupied by a building, but can be walked on normally. (e.g: the drop-off point on the refinery) ; = : Occupied by a building, but can be walked on normally. (e.g: the drop-off point on the refinery)
; `Produces` is a category of objects that this building can produce.
[IRON] [IRON]
Description=Iron Curtain Description=Iron Curtain
Traits=Building, RenderBuilding Traits=Building, RenderBuilding
@@ -198,16 +185,19 @@ Description=War Factory
Traits=Building, RenderWarFactory Traits=Building, RenderWarFactory
Dimensions=3,2 Dimensions=3,2
Footprint=xxx xxx Footprint=xxx xxx
Produces=Vehicle
[SYRD] [SYRD]
Description=Shipyard Description=Shipyard
Traits=Building, RenderBuilding Traits=Building, RenderBuilding
Dimensions=3,3 Dimensions=3,3
Footprint=xxx xxx xxx Footprint=xxx xxx xxx
Produces=Ship
[SPEN] [SPEN]
Description=Sub Pen Description=Sub Pen
Traits=Building, RenderBuilding Traits=Building, RenderBuilding
Dimensions=3,3 Dimensions=3,3
Footprint=xxx xxx xxx Footprint=xxx xxx xxx
Produces=Ship
[PBOX] [PBOX]
Description=Pillbox Description=Pillbox
Traits=Building, RenderBuilding Traits=Building, RenderBuilding
@@ -243,6 +233,7 @@ Description=Construction Yard
Traits=Building, RenderBuilding Traits=Building, RenderBuilding
Dimensions=3,3 Dimensions=3,3
Footprint=xxx xxx xxx Footprint=xxx xxx xxx
Produces=Building
[PROC] [PROC]
Description=Ore Refinery Description=Ore Refinery
Traits=Building, RenderBuilding Traits=Building, RenderBuilding
@@ -258,6 +249,7 @@ Description=Helipad
Traits=Building, RenderBuilding Traits=Building, RenderBuilding
Dimensions=2,2 Dimensions=2,2
Footprint=xx xx Footprint=xx xx
Produces=Plane
[DOME] [DOME]
Description=Radar Dome Description=Radar Dome
Traits=Building, RenderBuilding Traits=Building, RenderBuilding
@@ -283,6 +275,7 @@ Description=Airstrip
Traits=Building, RenderBuilding Traits=Building, RenderBuilding
Dimensions=3,2 Dimensions=3,2
Footprint=xxx xxx Footprint=xxx xxx
Produces=Plane
[POWR] [POWR]
Description=Power Plant Description=Power Plant
Traits=Building, RenderBuilding Traits=Building, RenderBuilding
@@ -303,11 +296,13 @@ Description=Soviet Barracks
Traits=Building, RenderBuilding Traits=Building, RenderBuilding
Dimensions=2,2 Dimensions=2,2
Footprint=xx xx Footprint=xx xx
Produces=Infantry
[TENT] [TENT]
Description=Allied Barracks Description=Allied Barracks
Traits=Building, RenderBuilding Traits=Building, RenderBuilding
Dimensions=2,2 Dimensions=2,2
Footprint=xx xx Footprint=xx xx
Produces=Infantry
[KENN] [KENN]
Description=Kennel Description=Kennel
Traits=Building, RenderBuilding Traits=Building, RenderBuilding
@@ -368,6 +363,7 @@ MEDI
[DOG] [DOG]
Description=Attack Dog Description=Attack Dog
BuiltAt=KENN
[E1] [E1]
Description=Rifle Infantry Description=Rifle Infantry
[E2] [E2]
@@ -467,4 +463,4 @@ Organic
Nuke Nuke
[HE] [HE]
ImpactSound=kaboom25 ImpactSound=kaboom25