// This file (Race.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2009 IBBoard. // // The file and the library/program it is in are licensed under the GNU LGPL license, either version 3 of the License or (at your option) any later version. Please see COPYING.LGPL for more information and the full license. using System; using System.Collections.Generic; using System.IO; using System.Xml; using IBBoard.IO; using IBBoard.WarFoundry.API.Factories; namespace IBBoard.WarFoundry.API.Objects { public class Race : WarFoundryStagedLoadingObject { public static string SYSTEM_DEFAULT_RACE_ID = "GameDefault"; private string subID; private GameSystem system; private Dictionary> unitTypesByCat; private Dictionary unitTypes = new Dictionary(); private Dictionary equipment = new Dictionary(); private Dictionary abilities = new Dictionary(); private Dictionary categories = new Dictionary(); public Race(string raceID, string raceName, GameSystem gameSystem, IWarFoundryFactory creatingFactory) : this(raceID, "", raceName, gameSystem, creatingFactory) { } public Race(string raceID, string raceSubID, string raceName, GameSystem gameSystem, IWarFoundryFactory creatingFactory) : base(raceID + (raceSubID!="" ? "_"+raceSubID : ""), raceName, creatingFactory) { subID = (raceSubID == null ? "" : raceSubID); system = gameSystem; } [Obsolete("Use constructor with GameSystem argument instead")] public Race(string raceID, string raceName, string gameSystemID, IWarFoundryFactory creatingFactory) : this(raceID, "", raceName, WarFoundryLoader.GetDefault().GetGameSystem(gameSystemID), creatingFactory) { } [Obsolete("Use constructor with GameSystem argument instead")] public Race(string raceID, string raceSubID, string raceName, string gameSystemID, IWarFoundryFactory creatingFactory) : this(raceID, raceSubID, raceName, WarFoundryLoader.GetDefault().GetGameSystem(gameSystemID), creatingFactory) { } public string SubID { get { return subID; } set { subID = (value == null ? "" : value.Trim()); } } public GameSystem GameSystem { get { return system; } set { if (value == null) { throw new ArgumentException("Game system for a race cannot be null"); } system = value; } } public void AddCategory(Category cat) { categories[cat.ID] = cat; } /// /// Gets a category from its ID. Attempts to get the category from the race's overrides, or else it falls back to getting the Game System's category with that ID. /// /// /// The ID of the category to get /// /// /// The Category with the specified ID, or null if one doesn't exist. /// public Category GetCategory(string id) { EnsureFullyLoaded(); Category cat = null; categories.TryGetValue(id, out cat); if (cat == null) { cat = GameSystem.GetCategory(id); } return cat; } public Category[] Categories { get { EnsureFullyLoaded(); Category[] cats; if (!HasCategoryOverrides()) { cats = GameSystem.Categories; } else { cats = DictionaryUtils.ToArray(categories); } return cats; } } public bool HasCategoryOverrides() { return categories.Count > 0; } public void AddEquipmentItem(EquipmentItem item) { //TODO: Throw DuplicateItemException equipment.Add(item.ID, item); } [Obsolete("Use AddEquipmentItem method instead")] public void SetEquipmentItems(Dictionary items) { foreach (EquipmentItem item in items.Values) { AddEquipmentItem(item); } } public EquipmentItem GetEquipmentItem(string id) { EnsureFullyLoaded(); return (EquipmentItem)equipment[id]; } public List GetEquipmentList() { List items = new List(); foreach (EquipmentItem item in equipment.Values) { items.Add(item); } return items; } public void AddUnitType(UnitType type) { CacheUnitType(type); unitTypes.Add(type.ID, type); } [Obsolete("Use AddUnitType method instead")] public void SetUnitTypes(Dictionary types) { foreach (UnitType type in types.Values) { AddUnitType(type); } } public UnitType[] GetUnitTypes(Category cat) { BuildUnitTypesByCategoryCache(); Dictionary unitTypesDictionary; unitTypesByCat.TryGetValue(cat, out unitTypesDictionary); UnitType[] unitTypesArray; if (unitTypesDictionary == null) { unitTypesArray = new UnitType[0]; } else { unitTypesArray = DictionaryUtils.ToArray(unitTypesDictionary); } return unitTypesArray; } private void CacheUnitType(UnitType unit) { BuildUnitTypesByCategoryCache(); Dictionary catUnitTypes; unitTypesByCat.TryGetValue(unit.MainCategory, out catUnitTypes); if (catUnitTypes == null) { throw new InvalidFileException(String.Format("Unit type {0} with name {1} is a unit of an undefined category", unit.ID, unit.Name)); } catUnitTypes.Add(unit.ID, unit); } private void BuildUnitTypesByCategoryCache() { if (unitTypesByCat == null) { DoBuildUnitTypesByCategoryCache(); } } private void DoBuildUnitTypesByCategoryCache() { unitTypesByCat = new Dictionary>(); foreach (Category category in Categories) { unitTypesByCat.Add(category, new Dictionary()); } foreach (UnitType unit in unitTypes.Values) { CacheUnitType(unit); } } public UnitType GetUnitType(string id) { UnitType type = null; unitTypes.TryGetValue(id, out type); return type; } public List GetAbilityList() { List items = new List(); items.AddRange(abilities.Values); return items; } public void AddAbility(Ability newAbility) { //TODO: Throw DuplicateItemException abilities.Add(newAbility.ID, newAbility); } [Obsolete("Use AddAbility method instead")] public void SetAbilities(Dictionary newAbilities) { foreach (Ability ability in newAbilities.Values) { AddAbility(ability); } } public Ability GetAbility(string id) { Ability ability = null; abilities.TryGetValue(id, out ability); return ability; } protected virtual Dictionary RaceUnitTypes { get { return RaceRawUnitTypes; } set { RaceRawUnitTypes = value; } } protected virtual Dictionary RaceEquipment { get { return RaceRawEquipment; } set { RaceRawEquipment = value; } } protected virtual Dictionary RaceAbilities { get { return RaceRawAbilities; } set { RaceRawAbilities = value; } } protected Dictionary RaceRawUnitTypes { get { return unitTypes; } set { unitTypes = value; } } protected Dictionary RaceRawEquipment { get { return equipment; } set { equipment = value; } } protected Dictionary RaceRawAbilities { get { return abilities; } set { abilities = value; } } } }