using System; using System.Collections.Generic; using OpenRa.FileFormats; using OpenRa.Game.GameRules; namespace OpenRa.TechTree { public class Item { readonly bool isStructure; public bool IsStructure { get { return isStructure; } } public Item(string tag, string friendlyName, UnitInfo.BaseInfo unitInfo, bool isStructure) { this.tag = tag; this.friendlyName = friendlyName; this.isStructure = isStructure; owner = ParseOwner(unitInfo.Owner, unitInfo.DoubleOwned); techLevel = unitInfo.TechLevel; Tuple 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; string[] frags = owners.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries); foreach (string s in frags) race |= (Race)Enum.Parse(typeof(Race), s, true); return race; } static Tuple ParsePrerequisites(string prerequisites, string tag) { List allied = new List(prerequisites.ToUpper().Split( new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries)); List soviet = new List(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 ((tag.Length == 2 && tag[0] == 'E') || tag == "MEDI" || tag == "THF" || tag == "SPY") { 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( allied.ToArray(), soviet.ToArray()); } public readonly string tag, friendlyName; readonly int techLevel; readonly Race owner; readonly string[] alliedPrerequisites, sovietPrerequisites; bool ShouldMakeBuildable(IEnumerable buildings, string[] racePrerequisites) { if (techLevel < 0) return false; if (racePrerequisites.Length == 0) return true; List p = new List(racePrerequisites); foreach (string b in buildings) p.Remove(b); return p.Count == 0; } bool ShouldMakeUnbuildable(IEnumerable buildings, string[] racePrerequisites) { if (racePrerequisites.Length == 0) return false; List p = new List(racePrerequisites); foreach (string b in buildings) p.Remove(b); return p.Count == racePrerequisites.Length; } void CheckForBoth(IEnumerable 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 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; } } bool canBuild; public bool CanBuild { get { return canBuild; } } public string Tooltip { get { return string.Format("{0} ({1})\n{2}", friendlyName, tag, owner); } } } }