Mercurial > repos > IBDev-IBBoard.WarFoundry.API
view API/Objects/Race.cs @ 480:e0641e0eb86c
Re #410: "N units per M models in parent" requirement
* Move context to a sub-folder/namespace to reduce clutter
* Add simple "parent unit" context
author | IBBoard <dev@ibboard.co.uk> |
---|---|
date | Wed, 23 May 2012 21:00:33 +0100 |
parents | 95c1b68a600b |
children |
line wrap: on
line source
// This file (Race.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2007, 2008, 2009 IBBoard. // // The file and the library/program it is in are licensed and distributed, without warranty, under the GNU Affero GPL license, either version 3 of the License or (at your option) any later version. Please see COPYING 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; using IBBoard.WarFoundry.API.Objects.Requirement; namespace IBBoard.WarFoundry.API.Objects { public class Race : WarFoundryStagedLoadingObject { public static string SYSTEM_DEFAULT_RACE_ID = "GameDefault"; private string subID; private GameSystem system; private string defaultArmyName = ""; private Dictionary<Category, Dictionary<string, UnitType>> unitTypesByCat; private Dictionary<string, UnitType> unitTypes = new Dictionary<string,UnitType>(); private Dictionary<string, EquipmentItem> equipment = new Dictionary<string,EquipmentItem>(); private Dictionary<string, Ability> abilities = new Dictionary<string,Ability>(); private Dictionary<string, Category> categories = new Dictionary<string,Category>(); private Dictionary<string, UnitMemberType> memberTypes = new Dictionary<string, UnitMemberType>(); 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 ?? ""; system = gameSystem; } public override bool Equals (object obj) { if (obj == null) { return false; } else if (!(obj is Race)) { return false; } else { Race other = (Race)obj; if (!ID.Equals(other.ID) || !SubID.Equals(other.SubID) || !GameSystem.Equals(other.GameSystem)) { return false; } else { return true; } } } public override int GetHashCode() { return ID.GetHashCode() + SubID.GetHashCode() + GameSystem.GetHashCode() + ArmyDefaultName.GetHashCode(); } 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 string ArmyDefaultName { get { return defaultArmyName; } set { if (value == null) { throw new ArgumentException("No default army name"); } defaultArmyName = value; } } public void AddCategory(Category cat) { categories[cat.ID] = cat; } /// <summary> /// 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. /// </summary> /// <param name="id"> /// The ID of the category to get /// </param> /// <returns> /// The <code>Category</code> with the specified ID, or null if one doesn't exist. /// </returns> 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<string, Category>(categories); } return cats; } } public bool HasCategoryOverrides() { EnsureFullyLoaded(); return categories.Count > 0; } public void AddEquipmentItem(EquipmentItem item) { //TODO: Throw DuplicateItemException equipment.Add(item.ID, item); } public EquipmentItem GetEquipmentItem(string id) { EnsureFullyLoaded(); return DictionaryUtils.GetValue(equipment, id); } public List<EquipmentItem> GetEquipmentList() { EnsureFullyLoaded(); List<EquipmentItem> items = new List<EquipmentItem>(); foreach (EquipmentItem item in equipment.Values) { items.Add(item); } return items; } public void AddUnitType(UnitType type) { CacheUnitType(type); unitTypes.Add(type.ID, type); } public UnitType[] GetUnitTypes(Category cat) { EnsureFullyLoaded(); BuildUnitTypesByCategoryCache(); Dictionary<string, UnitType> unitTypesDictionary; unitTypesByCat.TryGetValue(cat, out unitTypesDictionary); UnitType[] unitTypesArray; if (unitTypesDictionary == null) { unitTypesArray = new UnitType[0]; } else { unitTypesArray = DictionaryUtils.ToArray<string, UnitType>(unitTypesDictionary); } return unitTypesArray; } private void CacheUnitType(UnitType unit) { if (unit.IsContainedOnly) { return; } BuildUnitTypesByCategoryCache(); foreach (Category cat in unit.Categories) { Dictionary<string, UnitType> catUnitTypes = DictionaryUtils.GetValue(unitTypesByCat, cat); if (catUnitTypes == null) { throw new InvalidFileException(String.Format("Unit type {0} with name {1} is a unit of an undefined category ({2})", unit.ID, unit.Name, cat.ID)); } catUnitTypes.Add(unit.ID, unit); } } private void BuildUnitTypesByCategoryCache() { if (unitTypesByCat == null) { DoBuildUnitTypesByCategoryCache(); } } private void DoBuildUnitTypesByCategoryCache() { unitTypesByCat = new Dictionary<Category,Dictionary<string,UnitType>>(); foreach (Category category in Categories) { unitTypesByCat.Add(category, new Dictionary<string, UnitType>()); } foreach (UnitType unit in unitTypes.Values) { CacheUnitType(unit); } } public UnitType GetUnitType(string id) { EnsureFullyLoaded(); return DictionaryUtils.GetValue(unitTypes, id); } public List<Ability> GetAbilityList() { EnsureFullyLoaded(); List<Ability> items = new List<Ability>(); items.AddRange(abilities.Values); return items; } public void AddAbility(Ability newAbility) { //TODO: Throw DuplicateItemException abilities.Add(newAbility.ID, newAbility); } public Ability GetAbility(string id) { EnsureFullyLoaded(); return DictionaryUtils.GetValue(abilities, id); } protected virtual Dictionary<string, UnitType> RaceUnitTypes { get { return RaceRawUnitTypes; } set { RaceRawUnitTypes = value; } } protected virtual Dictionary<string, EquipmentItem> RaceEquipment { get { return RaceRawEquipment; } set { RaceRawEquipment = value; } } protected virtual Dictionary<string, Ability> RaceAbilities { get { return RaceRawAbilities; } set { RaceRawAbilities = value; } } protected Dictionary<string, UnitType> RaceRawUnitTypes { get { return unitTypes; } set { unitTypes = value; } } protected Dictionary<string, EquipmentItem> RaceRawEquipment { get { return equipment; } set { equipment = value; } } protected Dictionary<string, Ability> RaceRawAbilities { get { return abilities; } set { abilities = value; } } public void AddUnitMemberType(UnitMemberType memberType) { memberTypes[memberType.ID] = memberType; } /// <summary> /// Gets a unit member type by its ID. /// </summary> /// <param name="id"> /// The ID of the unit member type to get /// </param> /// <returns> /// The <code>UnitMemberType</code> with the specified ID, or null if one doesn't exist. /// </returns> public UnitMemberType GetUnitMemberType(string id) { EnsureFullyLoaded(); return DictionaryUtils.GetValue(memberTypes, id); } public UnitMemberType[] UnitMemberTypes { get { EnsureFullyLoaded(); return DictionaryUtils.ToArray(memberTypes); } } public ICollection<IRequirement> GetRequirements() { ICollection<IRequirement> reqs = new List<IRequirement>(); foreach (UnitType unitType in unitTypes.Values) { foreach (IRequirement requirement in unitType.GetRequirements()) { reqs.Add(requirement); } } return reqs; } } }