Mercurial > repos > IBBoard.WarFoundry.API
view api/Factories/Xml/WarFoundryXmlRaceFactory.cs @ 69:91cf8efbea0b
Re #50 - Complete core loading of WarFoundry XML files
* Make "Notes" a String value, as per schema
* Load contained units
author | IBBoard <dev@ibboard.co.uk> |
---|---|
date | Sat, 25 Apr 2009 19:26:12 +0000 |
parents | 10d14a7051d5 |
children | 780f3926abad |
line wrap: on
line source
// This file (WarFoundryXmlRaceFactory.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.Xml; using IBBoard.IO; using IBBoard.Logging; using ICSharpCode.SharpZipLib.Zip; using IBBoard.WarFoundry.API.Objects; namespace IBBoard.WarFoundry.API.Factories.Xml { /// <summary> /// A sub-factory for loading WarFoundry Race XML files /// </summary> public class WarFoundryXmlRaceFactory : AbstractStagedLoadedSubFactory { private Dictionary<Race, XmlDocument> extraData = new Dictionary<Race, XmlDocument>(); public WarFoundryXmlRaceFactory(WarFoundryXmlFactory factory) : base (factory) { } private void StoreExtraData(Race wfObject, XmlElement elem) { extraData[wfObject] = elem.OwnerDocument; } private XmlDocument GetExtraData(Race obj) { XmlDocument extra = null; extraData.TryGetValue(obj, out extra); return extra; } public Race CreateRaceFromElement(ZipFile file, XmlElement elem) { string id = elem.GetAttribute("id"); string subid = elem.GetAttribute("subid"); string systemID = elem.GetAttribute("system"); string name = elem.GetAttribute("name"); Race race = new Race(id, subid, name, WarFoundryLoader.GetDefault().GetGameSystem(systemID), mainFactory); StoreExtraData(race, elem); return race; } public void CompleteLoading(Race race) { if (!WarFoundryXmlFactoryUtils.CanCompleteLoading(race)) { return; } race.SetAsLoading(); XmlDocument extraData = GetExtraData(race); foreach (XmlElement node in WarFoundryXmlFactoryUtils.SelectNodes(extraData, "/race:race/race:categories/cat:cat")) { CreateCategoryFromElement(node, race); } foreach (XmlElement node in WarFoundryXmlFactoryUtils.SelectNodes(extraData, "/race:race/race:equipment/cat:equipmentItem")) { CreateEquipmentItemFromElement(node, race); } foreach (XmlElement node in WarFoundryXmlFactoryUtils.SelectNodes(extraData, "/race:race/race:abilities/cat:ability")) { CreateAbilityFromElement(node, race); } foreach (XmlElement node in WarFoundryXmlFactoryUtils.SelectNodes(extraData, "/race:race/race:units/race:unit")) { CreateUnitTypeFromElement(node, race); } race.SetAsFullyLoaded(); LogNotifier.DebugFormat(GetType(), "Completed loading of Race with ID {0}", race.ID); } private Category CreateCategoryFromElement(XmlElement elem, Race parentRace) { Category cat = CreateCategoryFromElement(elem); parentRace.AddCategory(cat); return cat; } private UnitType GetUnitTypeFromDocument(XmlDocument doc, string id, Race parentRace) { return CreateUnitTypeFromElement(WarFoundryXmlFactoryUtils.SelectSingleElement(doc, "/race:race/race:units/race:unit[id="+id+"]"), parentRace); } private UnitType CreateUnitTypeFromElement(XmlElement elem, Race parentRace) { string id = elem.GetAttribute("id"); UnitType type = parentRace.GetUnitType(id); if (type==null) { type = CreateUnitTypeFromElement(elem, id, parentRace); parentRace.AddUnitType(type); } return type; } private UnitType CreateUnitTypeFromElement(XmlElement elem, string id, Race parentRace) { string name = elem.GetAttribute("typeName"); UnitType type = new UnitType(id, name, parentRace); LoadCoreValuesForUnitType(elem, type); LoadEquipmentForUnitType(elem, type); LoadAbilitiesForUnitType(elem, type); LoadContainedUnitsForUnitType(elem, type); LoadRequirementsForUnitType(elem, type); LoadExtraDataForUnitType(elem, type); LoadNotesForUnitType(elem, type); parentRace.AddUnitType(type); return type; } private void LoadCoreValuesForUnitType(XmlElement elem, UnitType type) { type.MaxNumber = XmlTools.GetIntValueFromAttribute(elem, "maxNum"); type.MinNumber = XmlTools.GetIntValueFromAttribute(elem, "minNum"); type.MaxSize = XmlTools.GetIntValueFromAttribute(elem, "maxSize"); type.MinSize = XmlTools.GetIntValueFromAttribute(elem, "minSize"); type.BaseSize = XmlTools.GetIntValueFromAttribute(elem, "baseSize"); type.CostPerTrooper = XmlTools.GetIntValueFromAttribute(elem, "points"); type.BaseUnitCost = XmlTools.GetIntValueFromAttribute(elem, "unitPoints"); string mainCatID = elem.GetAttribute("cat"); Category cat = type.Race.GetCategory(mainCatID); if (cat == null) { throw new InvalidDataException(String.Format("Attribute 'cat' of UnitType {0} (value: {1}) did not reference a valid category", type.ID, mainCatID)); } type.MainCategory = cat; XmlElement statsElement = WarFoundryXmlFactoryUtils.SelectSingleElement(elem, "/race:race/race:units/race:unit/race:stats"); type.UnitStats = ParseUnitStats(statsElement, type.GameSystem); } private void LoadEquipmentForUnitType(XmlElement elem, UnitType type) { } private void LoadAbilitiesForUnitType(XmlElement elem, UnitType type) { foreach (XmlElement ability in WarFoundryXmlFactoryUtils.SelectNodes(elem, "race:unitAbilities/race:unitAbility")) { string id = ability.GetAttribute("abilityID"); bool required = XmlTools.GetBoolValueFromAttribute(ability, "required"); type.AddAbility(type.Race.GetAbility(id), required); } } private void LoadContainedUnitsForUnitType(XmlElement elem, UnitType type) { foreach (XmlElement containedUnitType in WarFoundryXmlFactoryUtils.SelectNodes(elem, "race:contains/race:containedUnit")) { string id = containedUnitType.GetAttribute("containedID"); UnitType containedType = GetUnitTypeFromDocument(elem.OwnerDocument, id, type.Race); if (containedType!=null) { type.AddContainedUnitType(containedType); } else { // TODO: Warn on invalid data, but don't exception } } } private void LoadRequirementsForUnitType(XmlElement elem, UnitType type) { //TODO: Load requirements } private void LoadExtraDataForUnitType(XmlElement elem, UnitType type) { } private void LoadNotesForUnitType(XmlElement elem, UnitType type) { XmlNode node = WarFoundryXmlFactoryUtils.SelectSingleNode(elem, "race:notes"); if (node!=null) { type.Notes = node.InnerText; } } private Stats ParseUnitStats(XmlElement elem, GameSystem system) { String statsID = elem.GetAttribute("statSet"); SystemStats statsSet; if (statsID == "") { statsSet = system.StandardSystemStats; } else { statsSet = system.GetSystemStatsForID(statsID); } Stats stats = new Stats(statsSet); foreach (XmlElement stat in WarFoundryXmlFactoryUtils.SelectNodes(elem, "race:stat")) { String statName = stat.GetAttribute("name"); stats.SetStatValue(statName, stat.InnerText); } return stats; } private EquipmentItem CreateEquipmentItemFromElement(XmlElement elem, Race race) { string id = elem.GetAttribute("id"); EquipmentItem item = race.GetEquipmentItem(id); if (item==null) { item = CreateEquipmentItemFromElement(elem, id, race); } return item; } private EquipmentItem CreateEquipmentItemFromElement(XmlElement elem, string id, Race race) { string name = elem.GetAttribute("name"); EquipmentItem item = new EquipmentItem(id, name, race); double cost = 0; ArmourType armourType; try { cost = XmlTools.GetDoubleValueFromAttribute(elem, "cost"); } catch(FormatException ex) { throw new InvalidFileException("Attribute 'cost' of equipment item "+id+" was not a valid number", ex); } try { armourType = (ArmourType)Enum.Parse(typeof(ArmourType), elem.GetAttribute("armourType")); } catch(ArgumentException ex) { throw new InvalidFileException("Attribute 'armourType' of equipment "+id+" was not a valid value from the enumeration", ex); } //TODO: Parse equipment stats if there are any item.Cost = cost; item.ItemArmourType = armourType; return item; } private Ability CreateAbilityFromElement(XmlElement elem, Race race) { string id = elem.GetAttribute("id"); string name = elem.GetAttribute("name"); Ability ability = new Ability(id, name); XmlNode node = elem.SelectSingleNode("description", WarFoundryXmlFactoryUtils.GetNamespaceManager()); ability.Description = (node == null) ? "" : node.InnerText; return ability; } } }