Added UnitInfo.
- units.txt turned into infantry.txt and vehicles.txt
- slight sidebar fixes
This commit is contained in:
@@ -30,7 +30,9 @@ namespace OpenRa.Game
|
||||
|
||||
public Game(string mapName, Renderer renderer, int2 clientSize)
|
||||
{
|
||||
for (int i = 0; i < 8; i++)
|
||||
Rules.LoadRules();
|
||||
|
||||
for( int i = 0 ; i < 8 ; i++ )
|
||||
players.Add(i, new Player(i, string.Format("Multi{0}", i), OpenRa.TechTree.Race.Soviet));
|
||||
|
||||
map = new Map(new IniFile(FileSystem.Open(mapName)));
|
||||
|
||||
19
OpenRa.Game/GameRules/Rules.cs
Executable file
19
OpenRa.Game/GameRules/Rules.cs
Executable file
@@ -0,0 +1,19 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using OpenRa.FileFormats;
|
||||
using OpenRa.Game.GameRules;
|
||||
|
||||
namespace OpenRa.Game
|
||||
{
|
||||
static class Rules
|
||||
{
|
||||
public static UnitInfo UnitInfo;
|
||||
|
||||
// TODO: load rules from the map, where appropriate.
|
||||
public static void LoadRules()
|
||||
{
|
||||
UnitInfo = new UnitInfo( new IniFile( FileSystem.Open( "rules.ini" ) ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
200
OpenRa.Game/GameRules/UnitInfo.cs
Executable file
200
OpenRa.Game/GameRules/UnitInfo.cs
Executable file
@@ -0,0 +1,200 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.IO;
|
||||
using OpenRa.FileFormats;
|
||||
using OpenRa.Game.Graphics;
|
||||
|
||||
namespace OpenRa.Game.GameRules
|
||||
{
|
||||
public class UnitInfo
|
||||
{
|
||||
static bool ParseYesNo( string p )
|
||||
{
|
||||
p = p.ToLowerInvariant();
|
||||
if( p == "yes" ) return true;
|
||||
if( p == "true" ) return true;
|
||||
if( p == "no" ) return false;
|
||||
if( p == "false" ) return false;
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
|
||||
readonly Dictionary<string, BaseInfo> unitInfos = new Dictionary<string, BaseInfo>();
|
||||
|
||||
public UnitInfo( IniFile rules )
|
||||
{
|
||||
foreach( var s in Util.ReadAllLines( FileSystem.Open( "buildings.txt" ) ) )
|
||||
{
|
||||
var unitName = s.Split( ',' )[ 0 ];
|
||||
unitInfos.Add( unitName.ToLowerInvariant(), new BuildingInfo( unitName, rules.GetSection( unitName ) ) );
|
||||
}
|
||||
foreach( var s in Util.ReadAllLines( FileSystem.Open( "infantry.txt" ) ) )
|
||||
{
|
||||
var unitName = s.Split( ',' )[ 0 ];
|
||||
unitInfos.Add( unitName.ToLowerInvariant(), new InfantryInfo( unitName, rules.GetSection( unitName ) ) );
|
||||
}
|
||||
foreach( var s in Util.ReadAllLines( FileSystem.Open( "vehicles.txt" ) ) )
|
||||
{
|
||||
var unitName = s.Split( ',' )[ 0 ];
|
||||
unitInfos.Add( unitName.ToLowerInvariant(), new VehicleInfo( unitName, rules.GetSection( unitName ) ) );
|
||||
}
|
||||
}
|
||||
|
||||
public BaseInfo Get( string unitName )
|
||||
{
|
||||
return unitInfos[ unitName.ToLowerInvariant() ];
|
||||
}
|
||||
|
||||
public enum ArmorType
|
||||
{
|
||||
none = 0,
|
||||
wood = 1,
|
||||
light = 2,
|
||||
heavy = 3,
|
||||
concrete = 4,
|
||||
}
|
||||
|
||||
public class BaseInfo
|
||||
{
|
||||
public readonly string Name;
|
||||
|
||||
public readonly int Ammo = -1;
|
||||
public readonly ArmorType Armor = ArmorType.none;
|
||||
public readonly bool DoubleOwned = false;
|
||||
public readonly bool Cloakable = false;
|
||||
public readonly int Cost = 0;
|
||||
public readonly bool Crewed = false;
|
||||
public readonly bool Explodes = false;
|
||||
public readonly int GuardRange = -1; // -1 = use weapon's range
|
||||
public readonly string Image = null; // sprite-set to use when rendering
|
||||
public readonly bool Invisible = false;
|
||||
public readonly string Owner = "allies,soviet"; // TODO: make this an enum
|
||||
public readonly int Points = 0;
|
||||
public readonly string Prerequisite = "";
|
||||
public readonly string Primary = null;
|
||||
public readonly string Secondary = null;
|
||||
public readonly int ROT = 0;
|
||||
public readonly int Reload = 0;
|
||||
public readonly bool SelfHealing = false;
|
||||
public readonly bool Sensors = false; // no idea what this does
|
||||
public readonly int Sight = 1;
|
||||
public readonly int Strength = 1;
|
||||
public readonly int TechLevel = -1;
|
||||
|
||||
public BaseInfo( string name, IniSection ini )
|
||||
{
|
||||
Name = name;
|
||||
|
||||
foreach( var x in ini )
|
||||
{
|
||||
var field = this.GetType().GetField( x.Key );
|
||||
if( field.FieldType == typeof( int ) )
|
||||
field.SetValue( this, int.Parse( x.Value ) );
|
||||
|
||||
else if( field.FieldType == typeof( float ) )
|
||||
field.SetValue( this, float.Parse( x.Value ) );
|
||||
|
||||
else if( field.FieldType == typeof( string ) )
|
||||
field.SetValue( this, x.Value );
|
||||
|
||||
else if( field.FieldType == typeof( ArmorType ) )
|
||||
field.SetValue( this, Enum.Parse( typeof( ArmorType ), x.Value ) );
|
||||
|
||||
else if( field.FieldType == typeof( bool ) )
|
||||
field.SetValue( this, ParseYesNo( x.Value ) );
|
||||
|
||||
else
|
||||
do { } while( false );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class MobileInfo : BaseInfo
|
||||
{
|
||||
public readonly int Passengers = 0;
|
||||
public readonly int Speed = 0;
|
||||
|
||||
public MobileInfo( string name, IniSection ini )
|
||||
: base( name, ini )
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public class InfantryInfo : MobileInfo
|
||||
{
|
||||
|
||||
public readonly bool C4 = false;
|
||||
public readonly bool FraidyCat = false;
|
||||
public readonly bool Infiltrate = false;
|
||||
public readonly bool IsCanine = false;
|
||||
|
||||
public InfantryInfo( string name, IniSection ini )
|
||||
: base( name, ini )
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public class VehicleInfo : MobileInfo
|
||||
{
|
||||
public readonly bool Crushable = false;
|
||||
public readonly bool Tracked = false;
|
||||
public readonly bool NoMovingFire = false;
|
||||
|
||||
public VehicleInfo( string name, IniSection ini )
|
||||
: base( name, ini )
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public class BuildingInfo : BaseInfo
|
||||
{
|
||||
public readonly bool BaseNormal = true;
|
||||
public readonly int Adjacent = 1;
|
||||
public readonly bool Bib = false;
|
||||
public readonly bool Capturable = false;
|
||||
public readonly int Power = 0;
|
||||
public readonly bool Powered = false;
|
||||
public readonly bool Repairable = true;
|
||||
public readonly int Storage = 0;
|
||||
public readonly bool Unsellable = false;
|
||||
public readonly bool WaterBound = false;
|
||||
|
||||
public BuildingInfo( string name, IniSection ini )
|
||||
: base( name, ini )
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Example: HARV
|
||||
* Unit (can move, etc)
|
||||
* PlayerOwned
|
||||
* Selectable
|
||||
* CanHarvest
|
||||
*
|
||||
* Example: PROC (refinery)
|
||||
* Building (can't move)
|
||||
* AcceptsOre (harvester returns here)
|
||||
*
|
||||
* Example: 3TNK (soviet heavy tank)
|
||||
* Unit
|
||||
* Turret (can aim in different direction to movement)
|
||||
*
|
||||
* Example: GUN (allied base defense turret)
|
||||
* Building
|
||||
* Turret
|
||||
*
|
||||
* some traits can be determined by fields in rules.ini
|
||||
* and some can't :
|
||||
* Gap-generator's ability
|
||||
* Nuke, chrone, curtain, (super-weapons)
|
||||
* Aircraft-landable
|
||||
* Selectable (bomber/spyplane can't be selected, for example)
|
||||
* AppearsFriendly (spy)
|
||||
* IsInfantry (can be build in TENT/BARR, 5-in-a-square)
|
||||
* IsVehicle
|
||||
* Squashable (sandbags, infantry)
|
||||
* Special rendering for war factory
|
||||
*/
|
||||
}
|
||||
}
|
||||
@@ -23,8 +23,12 @@ namespace OpenRa.Game.Graphics
|
||||
{
|
||||
List<string> result = new List<string>();
|
||||
using (StreamReader reader = new StreamReader(s))
|
||||
while (!reader.EndOfStream)
|
||||
result.Add(reader.ReadLine());
|
||||
while(!reader.EndOfStream)
|
||||
{
|
||||
var line = reader.ReadLine();
|
||||
if( !string.IsNullOrEmpty( line ) && line[0] != '#' )
|
||||
result.Add( line );
|
||||
}
|
||||
|
||||
return result.ToArray();
|
||||
}
|
||||
|
||||
@@ -72,6 +72,8 @@
|
||||
<ItemGroup>
|
||||
<Compile Include="Actor.cs" />
|
||||
<Compile Include="Controller.cs" />
|
||||
<Compile Include="GameRules\Rules.cs" />
|
||||
<Compile Include="GameRules\UnitInfo.cs" />
|
||||
<Compile Include="Graphics\Animation.cs" />
|
||||
<Compile Include="Building.cs" />
|
||||
<Compile Include="Game.cs" />
|
||||
@@ -83,7 +85,6 @@
|
||||
<Compile Include="Player.cs" />
|
||||
<Compile Include="PlayerOwned.cs" />
|
||||
<Compile Include="Race.cs" />
|
||||
<Compile Include="Rules.cs" />
|
||||
<Compile Include="Support\SharedResources.cs" />
|
||||
<Compile Include="Graphics\Sheet.cs" />
|
||||
<Compile Include="Support\Log.cs" />
|
||||
@@ -115,7 +116,6 @@
|
||||
<Compile Include="Graphics\TreeCache.cs" />
|
||||
<Compile Include="UiOverlay.cs" />
|
||||
<Compile Include="Unit.cs" />
|
||||
<Compile Include="UnitInfo.cs" />
|
||||
<Compile Include="UnitMissions.cs" />
|
||||
<Compile Include="Graphics\UnitSheetBuilder.cs" />
|
||||
<Compile Include="Graphics\Util.cs" />
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using OpenRa.FileFormats;
|
||||
using OpenRa.Game.Graphics;
|
||||
|
||||
namespace OpenRa.Game
|
||||
{
|
||||
static class Rules
|
||||
{
|
||||
static readonly Dictionary<string, UnitInfo> unitInfos = new Dictionary<string, UnitInfo>();
|
||||
|
||||
static Rules()
|
||||
{
|
||||
var rulesIni = SharedResources.Rules;
|
||||
|
||||
foreach (string line in Util.ReadAllLines(FileSystem.Open("units.txt")))
|
||||
{
|
||||
string unit = line.Substring( 0, line.IndexOf( ',' ) ).ToUpperInvariant();
|
||||
IniSection section = rulesIni.GetSection( unit );
|
||||
if (section == null)
|
||||
{
|
||||
Log.Write("rules.ini doesnt contain entry for unit \"{0}\"", unit);
|
||||
continue;
|
||||
}
|
||||
unitInfos.Add( unit, new UnitInfo( unit, section ) );
|
||||
}
|
||||
}
|
||||
|
||||
public static UnitInfo UnitInfo( string name )
|
||||
{
|
||||
return unitInfos[ name.ToUpperInvariant() ];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -45,7 +45,8 @@ namespace OpenRa.Game
|
||||
clockRenderer = new SpriteRenderer(renderer, true);
|
||||
|
||||
LoadSprites("buildings.txt");
|
||||
LoadSprites("units.txt");
|
||||
LoadSprites("vehicles.txt");
|
||||
LoadSprites("infantry.txt");
|
||||
|
||||
foreach (string s in groups)
|
||||
{
|
||||
@@ -158,6 +159,16 @@ namespace OpenRa.Game
|
||||
Build(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( mi.Button == MouseButtons.Right && mi.Event == MouseInputEvent.Down )
|
||||
{
|
||||
var point = new float2(mi.Location.X, mi.Location.Y);
|
||||
var item = GetItem(point);
|
||||
if( item != null )
|
||||
{
|
||||
string group = itemGroups[ item.techTreeItem.tag ];
|
||||
selectedItems[ group ] = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using OpenRa.FileFormats;
|
||||
using OpenRa.Game.GameRules;
|
||||
|
||||
namespace OpenRa.TechTree
|
||||
{
|
||||
@@ -10,31 +11,26 @@ namespace OpenRa.TechTree
|
||||
|
||||
public bool IsStructure { get { return isStructure; } }
|
||||
|
||||
public Item(string tag, string friendlyName, IniSection section, bool isStructure)
|
||||
public Item(string tag, string friendlyName, UnitInfo.BaseInfo unitInfo, bool isStructure)
|
||||
{
|
||||
this.tag = tag;
|
||||
this.friendlyName = friendlyName;
|
||||
this.isStructure = isStructure;
|
||||
|
||||
owner = ParseOwner(section);
|
||||
techLevel = ParseTechLevel(section);
|
||||
Tuple<string[], string[]> pre = ParsePrerequisites(section, tag);
|
||||
owner = ParseOwner(unitInfo.Owner, unitInfo.DoubleOwned);
|
||||
techLevel = unitInfo.TechLevel;
|
||||
Tuple<string[], string[]> pre = ParsePrerequisites(unitInfo.Prerequisite, tag);
|
||||
alliedPrerequisites = pre.a;
|
||||
sovietPrerequisites = pre.b;
|
||||
}
|
||||
|
||||
static int ParseTechLevel(IniSection section)
|
||||
static Race ParseOwner(string owners, bool doubleOwned)
|
||||
{
|
||||
return int.Parse(section.GetValue("TechLevel", "-1"));
|
||||
}
|
||||
|
||||
static Race ParseOwner(IniSection section)
|
||||
{
|
||||
if (section.GetValue("DoubleOwned", "No") == "Yes")
|
||||
if (doubleOwned)
|
||||
return Race.Allies | Race.Soviet;
|
||||
|
||||
Race race = Race.None;
|
||||
string[] frags = section.GetValue("Owner", "").Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
string[] frags = owners.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
|
||||
foreach (string s in frags)
|
||||
race |= (Race)Enum.Parse(typeof(Race), s, true);
|
||||
@@ -42,9 +38,9 @@ namespace OpenRa.TechTree
|
||||
return race;
|
||||
}
|
||||
|
||||
static Tuple<string[],string[]> ParsePrerequisites(IniSection section, string tag)
|
||||
static Tuple<string[],string[]> ParsePrerequisites(string prerequisites, string tag)
|
||||
{
|
||||
List<string> allied = new List<string>(section.GetValue("Prerequisite", "").ToUpper().Split(
|
||||
List<string> allied = new List<string>(prerequisites.ToUpper().Split(
|
||||
new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries));
|
||||
|
||||
List<string> soviet = new List<string>(allied);
|
||||
|
||||
@@ -55,14 +55,15 @@ namespace OpenRa.TechTree
|
||||
|
||||
void LoadRules()
|
||||
{
|
||||
IEnumerable<Tuple<string, string, bool>> definitions = Concat(
|
||||
IEnumerable<Tuple<string, string, bool>> definitions = Concat( Concat(
|
||||
Lines("buildings.txt", true),
|
||||
Lines("units.txt", false));
|
||||
Lines("vehicles.txt", false) ),
|
||||
Lines("infantry.txt", false) );
|
||||
|
||||
var rules = SharedResources.Rules;
|
||||
|
||||
foreach (Tuple<string, string, bool> p in definitions)
|
||||
objects.Add(p.a, new Item(p.a, p.b, rules.GetSection(p.a), p.c));
|
||||
objects.Add(p.a, new Item(p.a, p.b, Rules.UnitInfo.Get(p.a), p.c));
|
||||
}
|
||||
|
||||
public bool Build(string key, bool force)
|
||||
@@ -102,7 +103,8 @@ namespace OpenRa.TechTree
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if (changed) BuildableItemsChanged();
|
||||
//if (changed)
|
||||
BuildableItemsChanged();
|
||||
}
|
||||
|
||||
public IEnumerable<Item> BuildableItems
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
using OpenRa.Game.Graphics;
|
||||
using IjwFramework.Types;
|
||||
using OpenRa.Game.GameRules;
|
||||
using OpenRa.Game.Graphics;
|
||||
|
||||
namespace OpenRa.Game
|
||||
{
|
||||
@@ -20,7 +20,7 @@ namespace OpenRa.Game
|
||||
public int moveFraction, moveFractionTotal;
|
||||
|
||||
readonly float2 renderOffset;
|
||||
public readonly UnitInfo unitInfo;
|
||||
public readonly UnitInfo.MobileInfo unitInfo;
|
||||
|
||||
public Unit( string name, int2 cell, Player owner, Game game )
|
||||
: base( game, name, cell )
|
||||
@@ -28,7 +28,7 @@ namespace OpenRa.Game
|
||||
fromCell = toCell = cell;
|
||||
|
||||
this.owner = owner;
|
||||
this.unitInfo = Rules.UnitInfo( name );
|
||||
this.unitInfo = (UnitInfo.MobileInfo)Rules.UnitInfo.Get( name );
|
||||
|
||||
animation.PlayFetchIndex( "idle", () => facing );
|
||||
renderOffset = animation.Center;
|
||||
@@ -90,7 +90,11 @@ namespace OpenRa.Game
|
||||
|
||||
bool SupportsMission( SupportedMissions mission )
|
||||
{
|
||||
return mission == ( unitInfo.supportedMissions & mission );
|
||||
if( mission == SupportedMissions.Deploy )
|
||||
return this.unitInfo.Name == "MCV";
|
||||
if( mission == SupportedMissions.Harvest )
|
||||
return this.unitInfo.Name == "HARV";
|
||||
return false;
|
||||
}
|
||||
|
||||
public Order Order( Game game, int2 xy )
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using OpenRa.FileFormats;
|
||||
|
||||
namespace OpenRa.Game
|
||||
{
|
||||
class UnitInfo
|
||||
{
|
||||
public readonly int Speed;
|
||||
public readonly SupportedMissions supportedMissions;
|
||||
|
||||
public UnitInfo(string unitName, IniSection ini)
|
||||
{
|
||||
Speed = int.Parse(ini.GetValue("Speed", "0"));
|
||||
|
||||
supportedMissions = SupportedMissions.Stop;
|
||||
if (unitName == "MCV")
|
||||
supportedMissions |= SupportedMissions.Deploy;
|
||||
if (unitName == "HARV")
|
||||
supportedMissions |= SupportedMissions.Harvest;
|
||||
}
|
||||
}
|
||||
}
|
||||
17
infantry.txt
Executable file
17
infantry.txt
Executable file
@@ -0,0 +1,17 @@
|
||||
#
|
||||
# The infantry that we (currently) support.
|
||||
#
|
||||
|
||||
DOG,Attack Dog,infantry
|
||||
E1,Rifle Infantry,infantry
|
||||
E2,Grenadier,infantry
|
||||
E3,Rocket Soldier,infantry
|
||||
E4,Flamethrower,infantry
|
||||
E6,Engineer,infantry
|
||||
SPY,Spy,infantry
|
||||
THF,Thief,infantry
|
||||
E7,Tanya,infantry
|
||||
MEDI,Medic,infantry
|
||||
|
||||
# TODO: civilians, special (campaign) units
|
||||
|
||||
20
units.txt → vehicles.txt
Normal file → Executable file
20
units.txt → vehicles.txt
Normal file → Executable file
@@ -1,3 +1,7 @@
|
||||
#
|
||||
# The vehicles that we (currently) support.
|
||||
#
|
||||
|
||||
V2RL,V2 Rocket,vehicle
|
||||
1TNK,Light Tank,vehicle
|
||||
3TNK,Heavy Tank,vehicle
|
||||
@@ -11,23 +15,19 @@ MCV,Mobile Construction Vehicle,vehicle
|
||||
JEEP,Ranger,vehicle
|
||||
APC,Armored Personnel Carrier,vehicle
|
||||
MNLY,Minelayer,vehicle
|
||||
|
||||
# TODO: move ships and planes into their own files
|
||||
|
||||
SS,Submarine,boat
|
||||
DD,Destroyer,boat
|
||||
CA,Cruiser,boat
|
||||
LST,Transport,boat
|
||||
PT,Gunboat,boat
|
||||
DOG,Attack Dog,infantry
|
||||
E1,Rifle Infantry,infantry
|
||||
E2,Grenadier,infantry
|
||||
E3,Rocket Soldier,infantry
|
||||
E4,Flamethrower,infantry
|
||||
E6,Engineer,infantry
|
||||
SPY,Spy,infantry
|
||||
THF,Thief,infantry
|
||||
E7,Tanya,infantry
|
||||
MEDI,Medic,infantry
|
||||
|
||||
MIG,Mig Attack Plane,plane
|
||||
YAK,Yak Attack Plane,plane
|
||||
TRAN,Transport Helicopter,plane
|
||||
HELI,Longbow,plane
|
||||
HIND,Hind,plane
|
||||
# TODO: U2 (spyplane), BADR (paratrooper/paradrop plane)
|
||||
|
||||
Reference in New Issue
Block a user