diff --git a/OpenRa.TechTreeTest/Building.cs b/OpenRa.TechTreeTest/Building.cs deleted file mode 100644 index 1c2d13b9f8..0000000000 --- a/OpenRa.TechTreeTest/Building.cs +++ /dev/null @@ -1,126 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; -using OpenRa.FileFormats; -using System.Drawing; -using System.IO; - -namespace OpenRa.TechTreeTest -{ - [Flags] - public enum Race - { - None = 0, - Allies = 1, - Soviet = 2 - } - - class Building : IRAUnit - { - readonly string friendlyName; - readonly string tag; - - public string FriendlyName - { - get { return friendlyName; } - } - - public string Tag - { - get { return tag; } - } - - string[] prerequisites; - - public string[] Prerequisites - { - get { return prerequisites; } - set { prerequisites = value; } - } - - int techLevel; - - public int TechLevel - { - get { return techLevel; } - set { techLevel = value; } - } - - Race owner; - - public Race Owner - { - get { return owner; } - set { owner = value; } - } - - public Building(string tag, string friendlyName) - { - this.friendlyName = friendlyName; - this.tag = tag; - } - - public bool ShouldMakeBuildable(IEnumerable buildings) - { - if (techLevel > 10 || techLevel < 0) - return false; - - if (prerequisites.Length == 0) - return true; - - List p = new List(prerequisites); - foreach (string b in buildings) - p.Remove(b); - - return p.Count == 0; - } - - public bool ShouldMakeUnbuildable(IEnumerable buildings) - { - if (prerequisites.Length == 0) - return false; - - List p = new List(prerequisites); - foreach (string b in buildings) - p.Remove(b); - - return p.Count == prerequisites.Length; - } - - bool buildable = false; - public bool Buildable { get { return buildable; } } - - public void CheckPrerequisites(IEnumerable buildings, Race currentRace) - { - if ((buildable && ShouldMakeUnbuildable(buildings)) || !((owner & currentRace) == currentRace)) - buildable = false; - else if (!buildable && ShouldMakeBuildable(buildings)) - buildable = true; - } - - Bitmap icon; - public Bitmap Icon - { - get { return icon ?? (icon = LoadIcon(tag)); } - } - - static Package package = new Package("../../../hires.mix"); - static Palette palette = new Palette( File.OpenRead("../../../temperat.pal")); - - static Bitmap LoadIcon(string tag) - { - string filename = tag + "icon.shp"; - - try - { - Stream s = package.GetContent(filename); - ShpReader reader = new ShpReader(s); - foreach (ImageHeader h in reader) - return BitmapBuilder.FromBytes(h.Image, reader.Width, reader.Height, palette); - - return null; - } - catch (FileNotFoundException) { return LoadIcon("dog"); } - } - } -} diff --git a/OpenRa.TechTreeTest/Form1.cs b/OpenRa.TechTreeTest/Form1.cs index b6bb4b7686..8ae429846d 100644 --- a/OpenRa.TechTreeTest/Form1.cs +++ b/OpenRa.TechTreeTest/Form1.cs @@ -22,25 +22,25 @@ namespace OpenRa.TechTreeTest { buildableItems.Controls.Clear(); - foreach (IRAUnit b in techTree.BuildableItems) + foreach (Item b in techTree.BuildableItems) { PictureBox box = new PictureBox(); box.SizeMode = PictureBoxSizeMode.AutoSize; box.Image = b.Icon; - toolTip1.SetToolTip(box, b.Tag + "\n" + b.Owner.ToString()); + toolTip1.SetToolTip(box, b.Tooltip); buildableItems.Controls.Add(box); - IRAUnit k = b; + Item k = b; box.Click += delegate { Build(k); }; } } - void Build(IRAUnit b) + void Build(Item b) { - techTree.Build(b.Tag); + techTree.Build(b.tag); RefreshList(); } } diff --git a/OpenRa.TechTreeTest/IRAUnit.cs b/OpenRa.TechTreeTest/IRAUnit.cs deleted file mode 100644 index f0f35db98d..0000000000 --- a/OpenRa.TechTreeTest/IRAUnit.cs +++ /dev/null @@ -1,19 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Drawing; -namespace OpenRa.TechTreeTest -{ - interface IRAUnit - { - bool Buildable { get; } - void CheckPrerequisites(IEnumerable units, Race currentRace); - string FriendlyName { get; } - Bitmap Icon { get; } - Race Owner { get; set; } - string[] Prerequisites { get; set; } - bool ShouldMakeBuildable(IEnumerable units); - bool ShouldMakeUnbuildable(IEnumerable units); - string Tag { get; } - int TechLevel { get; set; } - } -} diff --git a/OpenRa.TechTreeTest/Item.cs b/OpenRa.TechTreeTest/Item.cs new file mode 100644 index 0000000000..f50b6e1099 --- /dev/null +++ b/OpenRa.TechTreeTest/Item.cs @@ -0,0 +1,123 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Drawing; +using OpenRa.FileFormats; +using System.IO; + +namespace OpenRa.TechTreeTest +{ + class Item + { + public Item(string tag, string friendlyName, IniSection section, bool isStructure) + { + this.tag = tag; + this.friendlyName = friendlyName; + + owner = ParseOwner(section); + techLevel = ParseTechLevel(section); + prerequisites = ParsePrerequisites(section); + } + + static int ParseTechLevel(IniSection section) + { + return int.Parse(section.GetValue("TechLevel", "-1")); + } + + static string[] ParsePrerequisites(IniSection section) + { + return section.GetValue("Prerequisite", "").ToUpper().Split( + new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries); + } + + static Race ParseOwner(IniSection section) + { + if (section.GetValue("DoubleOwned", "No") == "Yes") + return Race.Allies | Race.Soviet; + + Race race = Race.None; + string[] frags = section.GetValue("Owner", "").Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries); + + foreach (string s in frags) + race |= (Race)Enum.Parse(typeof(Race), s, true); + + return race; + } + + public readonly string tag, friendlyName; + readonly int techLevel; + readonly Race owner; + readonly string[] prerequisites; + + bool ShouldMakeBuildable(IEnumerable buildings) + { + if (techLevel < 0) + return false; + + if (prerequisites.Length == 0) + return true; + + List p = new List(prerequisites); + foreach (string b in buildings) + p.Remove(b); + + return p.Count == 0; + } + + bool ShouldMakeUnbuildable(IEnumerable buildings) + { + if (prerequisites.Length == 0) + return false; + + List p = new List(prerequisites); + foreach (string b in buildings) + p.Remove(b); + + return p.Count == prerequisites.Length; + } + + public void CheckPrerequisites(IEnumerable buildings, Race currentRace) + { + if ((canBuild && ShouldMakeUnbuildable(buildings)) || !((owner & currentRace) == currentRace)) + canBuild = false; + else if (!canBuild && ShouldMakeBuildable(buildings)) + canBuild = true; + } + + bool canBuild; + public bool CanBuild { get { return canBuild; } } + + Bitmap icon; + public Bitmap Icon + { + get { return icon ?? (icon = LoadIcon(tag)); } + } + + static Package package = new Package("../../../hires.mix"); + static Palette palette = new Palette(File.OpenRead("../../../temperat.pal")); + + static Bitmap LoadIcon(string tag) + { + string filename = tag + "icon.shp"; + + try + { + Stream s = package.GetContent(filename); + ShpReader reader = new ShpReader(s); + foreach (ImageHeader h in reader) + return BitmapBuilder.FromBytes(h.Image, reader.Width, reader.Height, palette); + + return null; + } + catch (FileNotFoundException) { return LoadIcon("dog"); } + } + + public string Tooltip + { + get + { + return string.Format("{0} ({1})\n{2}", friendlyName, tag, owner); + } + } + } +} diff --git a/OpenRa.TechTreeTest/OpenRa.TechTreeTest.csproj b/OpenRa.TechTreeTest/OpenRa.TechTreeTest.csproj index 904c370ee4..dbc18e665f 100644 --- a/OpenRa.TechTreeTest/OpenRa.TechTreeTest.csproj +++ b/OpenRa.TechTreeTest/OpenRa.TechTreeTest.csproj @@ -36,14 +36,13 @@ - + Form Form1.cs - @@ -68,8 +67,8 @@ Settings.settings True + - diff --git a/OpenRa.TechTreeTest/Race.cs b/OpenRa.TechTreeTest/Race.cs new file mode 100644 index 0000000000..f5a7756e74 --- /dev/null +++ b/OpenRa.TechTreeTest/Race.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace OpenRa.TechTreeTest +{ + [Flags] + public enum Race + { + None = 0, + Allies = 1, + Soviet = 2 + } +} diff --git a/OpenRa.TechTreeTest/TechTree.cs b/OpenRa.TechTreeTest/TechTree.cs index 013666c62e..dc62b38ef7 100644 --- a/OpenRa.TechTreeTest/TechTree.cs +++ b/OpenRa.TechTreeTest/TechTree.cs @@ -9,84 +9,57 @@ namespace OpenRa.TechTreeTest { class TechTree { - Dictionary units = new Dictionary(); + Dictionary objects = new Dictionary(); public ICollection built = new List(); + readonly Race currentRace; public TechTree(Race race) { this.currentRace = race; - LoadBuildings(); - LoadUnits(); LoadRules(); built.Add("FACT"); CheckAll(); } + static IEnumerable Concat(IEnumerable one, IEnumerable two) + { + foreach (T t in one) + yield return t; + foreach (T t in two) + yield return t; + } + + IEnumerable> Lines(string filename, bool param) + { + Regex pattern = new Regex(@"^(\w+),([\w ]+)$"); + foreach (string s in File.ReadAllLines(filename)) + { + Match m = pattern.Match(s); + if (m == null || !m.Success) + continue; + + yield return new Tuple( + m.Groups[1].Value, m.Groups[2].Value, param); + } + } + void LoadRules() { - IniFile rulesFile; - rulesFile = new IniFile(File.OpenRead("../../../rules.ini")); - foreach (string key in units.Keys) - { - IniSection section = rulesFile.GetSection(key); - IRAUnit b = units[key]; - string s = section.GetValue("Prerequisite", "").ToUpper(); - b.Prerequisites = s.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries); - b.TechLevel = int.Parse(section.GetValue("TechLevel", "-1")); - s = section.GetValue("Owner", ""); - - if (string.IsNullOrEmpty(s)) - { - s = section.GetValue("DoubleOwned", "No"); - if (s.Equals("Yes", StringComparison.InvariantCultureIgnoreCase)) - b.Owner = Race.Allies | Race.Soviet; - else - b.Owner = Race.None; - continue; - } - - if (s.Equals("Both", StringComparison.InvariantCultureIgnoreCase)) - { - b.Owner = Race.Allies | Race.Soviet; - continue; - } - - string[] frags = s.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries); - if (frags.Length > 1) - b.Owner = Race.Allies | Race.Soviet; - else - b.Owner = (Race)Enum.Parse(typeof(Race), frags[0], true); - } - } + IniFile rulesFile = new IniFile(File.OpenRead("../../../rules.ini")); + IEnumerable> definitions = Concat( + Lines("../../../buildings.txt", true), + Lines("../../../units.txt", false)); - void LoadBuildings() - { - foreach (string line in File.ReadAllLines("../../../buildings.txt")) - { - Regex pattern = new Regex(@"^(\w+),([\w ]+)$"); - Match m = pattern.Match(line); - if (!m.Success) continue; - units.Add(m.Groups[1].Value, new Building(m.Groups[1].Value, m.Groups[2].Value)); - } - } - - void LoadUnits() - { - foreach (string line in File.ReadAllLines("../../../units.txt")) - { - Regex pattern = new Regex(@"^(\w+),([\w ]+)$"); - Match m = pattern.Match(line); - if (!m.Success) continue; - units.Add(m.Groups[1].Value, new Unit(m.Groups[1].Value, m.Groups[2].Value)); - } + foreach (Tuple p in definitions) + objects.Add(p.a, new Item(p.a, p.b, rulesFile.GetSection(p.a), p.c)); } public bool Build(string key) { - IRAUnit b = units[key]; - if (!b.Buildable) return false; + Item b = objects[key]; + if (!b.CanBuild) return false; built.Add(key); CheckAll(); return true; @@ -94,7 +67,7 @@ namespace OpenRa.TechTreeTest public bool Unbuild(string key) { - IRAUnit b = units[key]; + Item b = objects[key]; if (!built.Contains(key)) return false; built.Remove(key); CheckAll(); @@ -103,16 +76,16 @@ namespace OpenRa.TechTreeTest void CheckAll() { - foreach (IRAUnit unit in units.Values) + foreach (Item unit in objects.Values) unit.CheckPrerequisites(built, currentRace); } - public IEnumerable BuildableItems + public IEnumerable BuildableItems { get { - foreach (IRAUnit b in units.Values) - if (b.Buildable) + foreach (Item b in objects.Values) + if (b.CanBuild) yield return b; } } diff --git a/OpenRa.TechTreeTest/Unit.cs b/OpenRa.TechTreeTest/Unit.cs deleted file mode 100644 index 2fe00b74fa..0000000000 --- a/OpenRa.TechTreeTest/Unit.cs +++ /dev/null @@ -1,111 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; -using System.Drawing; -using OpenRa.FileFormats; -using System.IO; - -namespace OpenRa.TechTreeTest -{ - class Unit : IRAUnit - { - bool buildable; - public bool Buildable { get { return buildable; } } - - public void CheckPrerequisites(IEnumerable units, Race currentRace) - { - if ((buildable && ShouldMakeUnbuildable(units)) || !((owner & currentRace) == currentRace)) - buildable = false; - else if (!buildable && ShouldMakeBuildable(units)) - buildable = true; ; - } - - readonly string friendlyName; - public string FriendlyName { get { return friendlyName; } } - - Bitmap icon; - public Bitmap Icon - { - get { return icon ?? (icon = LoadIcon(tag)); } - } - - static Package package = new Package("../../../hires.mix"); - static Palette palette = new Palette(File.OpenRead("../../../temperat.pal")); - - static Bitmap LoadIcon(string tag) - { - string filename = tag + "icon.shp"; - - try - { - Stream s = package.GetContent(filename); - ShpReader reader = new ShpReader(s); - foreach (ImageHeader h in reader) - return BitmapBuilder.FromBytes(h.Image, reader.Width, reader.Height, palette); - - return null; - } - catch (FileNotFoundException) { return LoadIcon("dog"); } - } - - Race owner; - public Race Owner - { - get { return owner; } - set { owner = value; } - } - - string[] prerequisites; - public string[] Prerequisites - { - get { return prerequisites; } - set { prerequisites = value; } - } - - public bool ShouldMakeBuildable(IEnumerable units) - { - if (techLevel > 10 || techLevel < 0) - return false; - - if (prerequisites.Length == 0) - return true; - - List p = new List(prerequisites); - foreach (string b in units) - p.Remove(b); - - return p.Count == 0; - } - - public bool ShouldMakeUnbuildable(IEnumerable units) - { - if (prerequisites.Length == 0) - return false; - - List p = new List(prerequisites); - foreach (string b in units) - p.Remove(b); - - return p.Count == prerequisites.Length; - } - - readonly string tag; - public string Tag - { - get { return tag; } - } - - int techLevel; - public int TechLevel - { - get { return techLevel; } - set { techLevel = value; } - } - - public Unit(string tag, string friendlyName) - { - this.friendlyName = friendlyName; - this.tag = tag; - } - } -}