52
|
1 // This file (WarFoundryXmlRaceFactory.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2009 IBBoard
|
|
2 //
|
|
3 // 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.
|
|
4 //
|
|
5
|
|
6 using System;
|
|
7 using System.Collections.Generic;
|
|
8 using System.IO;
|
|
9 using System.Xml;
|
|
10 using IBBoard.Xml;
|
|
11 using IBBoard.IO;
|
|
12 using IBBoard.Logging;
|
|
13 using ICSharpCode.SharpZipLib.Zip;
|
|
14 using IBBoard.WarFoundry.API.Objects;
|
|
15
|
|
16 namespace IBBoard.WarFoundry.API.Factories.Xml
|
|
17 {
|
|
18 /// <summary>
|
|
19 /// A sub-factory for loading WarFoundry Race XML files
|
|
20 /// </summary>
|
|
21 public class WarFoundryXmlRaceFactory : AbstractStagedLoadedSubFactory
|
|
22 {
|
|
23 private Dictionary<Race, XmlDocument> extraData = new Dictionary<Race, XmlDocument>();
|
|
24
|
|
25 public WarFoundryXmlRaceFactory(WarFoundryXmlFactory factory) : base (factory)
|
|
26 {
|
|
27 }
|
|
28
|
|
29 private void StoreExtraData(Race wfObject, XmlElement elem)
|
|
30 {
|
|
31 extraData[wfObject] = elem.OwnerDocument;
|
|
32 }
|
|
33
|
|
34 private XmlDocument GetExtraData(Race obj)
|
|
35 {
|
|
36 XmlDocument extra = null;
|
|
37 extraData.TryGetValue(obj, out extra);
|
|
38 return extra;
|
|
39 }
|
|
40
|
|
41 public Race CreateRaceFromElement(ZipFile file, XmlElement elem)
|
|
42 {
|
|
43 string id = elem.GetAttribute("id");
|
|
44 string subid = elem.GetAttribute("subid");
|
|
45 string systemID = elem.GetAttribute("system");
|
|
46 string name = elem.GetAttribute("name");
|
|
47 Race race = new Race(id, subid, name, systemID, mainFactory);
|
|
48 StoreExtraData(race, elem);
|
|
49 return race;
|
|
50 }
|
|
51
|
|
52 public void CompleteLoading(Race race)
|
|
53 {
|
|
54 if (!WarFoundryXmlFactoryUtils.CanCompleteLoading(race))
|
|
55 {
|
|
56 return;
|
|
57 }
|
|
58
|
|
59 race.SetAsLoading();
|
|
60 XmlDocument extraData = GetExtraData(race);
|
|
61
|
|
62 foreach (XmlElement node in WarFoundryXmlFactoryUtils.SelectNodes(extraData, "/race:race/race:units/race:unit"))
|
|
63 {
|
|
64 UnitType type = CreateUnitTypeFromElement(node, race, race.GameSystem);
|
|
65 race.AddUnitType(type);
|
|
66 }
|
|
67
|
|
68 foreach (XmlElement node in WarFoundryXmlFactoryUtils.SelectNodes(extraData, "/race:race/race:categories/cat:cat"))
|
|
69 {
|
|
70 race.AddCategory(CreateCategoryFromElement(node));
|
|
71 }
|
|
72
|
|
73 foreach (XmlElement node in WarFoundryXmlFactoryUtils.SelectNodes(extraData, "/race:race/race:equipment/cat:equipmentItem"))
|
|
74 {
|
|
75 EquipmentItem item = CreateEquipmentItemFromElement(node, race);
|
|
76 race.AddEquipmentItem(item);
|
|
77 }
|
|
78
|
|
79 foreach (XmlElement node in WarFoundryXmlFactoryUtils.SelectNodes(extraData, "/race:race/race:abilities/cat:ability"))
|
|
80 {
|
|
81 Ability ability = CreateAbilityFromElement(node, race);
|
|
82 race.AddAbility(ability);
|
|
83 }
|
|
84
|
|
85 race.SetAsFullyLoaded();
|
|
86 LogNotifier.DebugFormat(GetType(), "Completed loading of Race with ID {0}", race.ID);
|
|
87 }
|
|
88
|
|
89 private UnitType CreateUnitTypeFromElement(XmlElement elem, Race parentRace, GameSystem system)
|
|
90 {
|
|
91 string id = elem.GetAttribute("id");
|
|
92 string name = elem.GetAttribute("typeName");
|
|
93 UnitType type = new UnitType(id, name, parentRace);
|
|
94 type.MaxNumber = XmlTools.GetIntValueFromAttribute(elem, "maxNum");
|
|
95 type.MinNumber = XmlTools.GetIntValueFromAttribute(elem, "minNum");
|
|
96 type.MaxSize = XmlTools.GetIntValueFromAttribute(elem, "maxSize");
|
|
97 type.MinSize = XmlTools.GetIntValueFromAttribute(elem, "minSize");
|
|
98 type.BaseSize = XmlTools.GetIntValueFromAttribute(elem, "baseSize");
|
|
99 type.CostPerTrooper = XmlTools.GetIntValueFromAttribute(elem, "points");
|
|
100 type.BaseUnitCost = XmlTools.GetIntValueFromAttribute(elem, "unitPoints");
|
|
101 string mainCatID = elem.GetAttribute("cat");
|
|
102 Category cat = parentRace.GetCategory(mainCatID);
|
|
103
|
|
104 if (cat == null)
|
|
105 {
|
|
106 throw new InvalidDataException(String.Format("Attribute 'cat' of UnitType {0} (value: {1}) did not reference a valid category", id, mainCatID));
|
|
107 }
|
|
108
|
|
109 type.MainCategory = cat;
|
|
110 XmlElement statsElement = WarFoundryXmlFactoryUtils.SelectSingleElement(elem, "/race:race/race:units/race:unit/race:stats");
|
|
111 type.UnitStats = ParseUnitStats(statsElement, system);
|
|
112 //TODO: Add unit requirements
|
|
113 LogNotifier.Debug(GetType(), "Loaded "+type.Name);
|
|
114 return type;
|
|
115 }
|
|
116
|
|
117 private Stats ParseUnitStats(XmlElement elem, GameSystem system)
|
|
118 {
|
|
119 List<Stat> statsList = new List<Stat>();
|
|
120 String statsID = elem.GetAttribute("statSet");
|
|
121 SystemStats statsSet;
|
|
122
|
|
123 if (statsID == "")
|
|
124 {
|
|
125 statsSet = system.StandardSystemStats;
|
|
126 }
|
|
127 else
|
|
128 {
|
|
129 statsSet = system.GetSystemStatsForID(statsID);
|
|
130 }
|
|
131
|
|
132 Stats stats = new Stats(statsSet);
|
|
133
|
|
134 foreach (XmlElement stat in elem.ChildNodes)
|
|
135 {
|
|
136 String statID = stat.GetAttribute("name");
|
|
137 StatSlot slot = statsSet[statID];
|
|
138
|
|
139 if (slot!=null)
|
|
140 {
|
|
141 statsList.Add(new Stat(slot, stat.InnerText));
|
|
142 }
|
|
143 else
|
|
144 {
|
|
145 throw new InvalidFileException("The stat "+statID+" was not found in stats set "+statsID);
|
|
146 }
|
|
147 }
|
|
148
|
|
149 stats.SetStats(statsList);
|
|
150
|
|
151 return stats;
|
|
152 }
|
|
153
|
|
154 private EquipmentItem CreateEquipmentItemFromElement(XmlElement elem, Race race)
|
|
155 {
|
|
156 string id = elem.GetAttribute("id");
|
|
157 string name = elem.GetAttribute("name");
|
|
158 double cost = 0, min = 0, max = 0;
|
|
159 ArmourType armourType;
|
|
160
|
|
161 try
|
|
162 {
|
|
163 cost = XmlTools.GetDoubleValueFromAttribute(elem, "cost");
|
|
164 }
|
|
165 catch(FormatException ex)
|
|
166 {
|
|
167 throw new InvalidFileException("Attribute 'cost' of equipment item "+id+" was not a valid number", ex);
|
|
168 }
|
|
169
|
|
170 try
|
|
171 {
|
|
172 armourType = (ArmourType)Enum.Parse(typeof(ArmourType), elem.GetAttribute("armourType"));
|
|
173 }
|
|
174 catch(ArgumentException ex)
|
|
175 {
|
|
176 throw new InvalidFileException("Attribute 'armourType' of equipment "+id+" was not a valid value from the enumeration", ex);
|
|
177 }
|
|
178
|
|
179 //TODO: Parse equipment stats if there are any
|
|
180
|
|
181 return new EquipmentItem(id, name, cost, min, max, armourType, race);
|
|
182 }
|
|
183
|
|
184 private Ability CreateAbilityFromElement(XmlElement elem, Race race)
|
|
185 {
|
|
186 string id = elem.GetAttribute("id");
|
|
187 string name = elem.GetAttribute("name");
|
|
188 Ability ability = new Ability(id, name);
|
|
189 XmlNode node = elem.SelectSingleNode("description", WarFoundryXmlFactoryUtils.GetNamespaceManager());
|
|
190 ability.Description = (node == null) ? "" : node.InnerText;
|
|
191 return ability;
|
|
192 }
|
|
193 }
|
|
194 }
|