Mercurial > repos > IBBoard.WarFoundry.API
annotate api/Factories/Xml/WarFoundryXmlFactory.cs @ 8:613bc5eaac59
Re #9 - Make WarFoundry loading granular
* Remove specific staged loading classes
* Rework category loading for GameSystem and Race to make it use AddCategory(Category) method
* Promote staged loading from Native Factory to all Factories level
* Refactor XML Factory to use smaller methods
Also removed some commented code that isn't used any more
author | IBBoard <dev@ibboard.co.uk> |
---|---|
date | Sun, 04 Jan 2009 19:24:13 +0000 |
parents | 150a5669cd7b |
children | 6ad505b6c36e |
rev | line source |
---|---|
0 | 1 // WarFoundryXmlFactory.cs |
2 // | |
3 // Copyright (C) 2007 IBBoard | |
4 // | |
5 // This library is free software; you can redistribute it and/or | |
6 // modify it under the terms of the GNU Lesser General Public | |
7 // License version 2.1 of the License as published by the Free | |
8 // Software Foundation. | |
9 // | |
10 // This library is distributed in the hope that it will be useful, | |
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
13 // Lesser General Public License for more details. | |
14 // | |
15 // You should have received a copy of the GNU Lesser General Public | |
16 // License along with this library; if not, write to the Free Software | |
17 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
18 // | |
19 // | |
20 | |
21 using System; | |
22 using System.IO; | |
23 using System.Xml; | |
24 using System.Xml.Schema; | |
25 using System.Collections.Generic; | |
26 using System.Text; | |
27 using IBBoard; | |
28 using IBBoard.IO; | |
29 using IBBoard.Lang; | |
30 using IBBoard.Logging; | |
31 using IBBoard.Xml; | |
32 using IBBoard.WarFoundry.API.Requirements; | |
33 using IBBoard.WarFoundry.API.Objects; | |
34 using ICSharpCode.SharpZipLib.Zip; | |
35 | |
36 namespace IBBoard.WarFoundry.API.Factories.Xml | |
37 { | |
38 /// <summary> | |
39 /// Summary description for WarFoundryXmlFactory. | |
40 /// </summary> | |
41 public class WarFoundryXmlFactory : AbstractNativeWarFoundryFactory | |
42 { | |
43 private Dictionary<IWarFoundryObject, XmlDocument> extraData = new Dictionary<IWarFoundryObject, XmlDocument>(); | |
44 private XmlResolver xmlResolver; | |
45 | |
46 public static AbstractNativeWarFoundryFactory CreateFactory() | |
47 { | |
48 return new WarFoundryXmlFactory(); | |
49 } | |
50 | |
51 protected WarFoundryXmlFactory() : base() | |
52 { | |
53 xmlResolver = new IBBXmlResolver(Constants.ExecutablePath); | |
54 } | |
55 | |
56 protected override bool CheckCanFindArmyFileContent(ZipFile file) | |
57 { | |
58 return file.FindEntry("data.armyx", true) > -1; | |
59 } | |
60 | |
61 protected override bool CheckCanFindSystemFileContent(ZipFile file) | |
62 { | |
63 return file.FindEntry("data.systemx", true) > -1; | |
64 } | |
65 | |
66 protected override bool CheckCanFindRaceFileContent(ZipFile file) | |
67 { | |
68 return file.FindEntry("data.racex", true) > -1; | |
69 } | |
70 | |
71 protected XmlElement GetRootElementFromStream(Stream stream, WarFoundryXmlElementName elementName) | |
72 { | |
73 XmlDocument doc = CreateXmlDocumentFromStream(stream); | |
74 XmlElement elem = (XmlElement)doc.LastChild; | |
75 | |
76 if (!elem.Name.Equals(elementName.Value)) | |
77 { | |
78 throw new InvalidFileException(String.Format("Root element of XML was not valid. Expected {0} but got {1}", elementName.Value, elem.Name)); | |
79 } | |
80 | |
81 return elem; | |
82 } | |
83 | |
84 protected override Stream GetArmyDataStream(ZipFile file) | |
85 { | |
86 return file.GetInputStream(file.FindEntry("data.armyx", true)); | |
87 } | |
88 | |
89 protected override Army CreateArmyFromStream (ZipFile file, Stream dataStream) | |
90 { | |
91 XmlElement elem = GetRootElementFromStream(dataStream, WarFoundryXmlElementName.ARMY_ELEMENT); | |
92 return CreateArmyFromElement(file, elem); | |
93 } | |
94 | |
95 private Army CreateArmyFromElement(ZipFile file, XmlElement elem) | |
96 { | |
97 string name = elem.GetAttribute("name"); | |
98 string systemID = elem.GetAttribute("gameSystem"); | |
99 GameSystem system = WarFoundryLoader.GetDefault().GetGameSystem(systemID); | |
100 string raceID = elem.GetAttribute("race"); | |
101 Race race = WarFoundryLoader.GetDefault().GetRace(system, raceID); | |
102 string pointsString = elem.GetAttribute("maxPoints"); | |
103 int points = 0; | |
104 | |
105 try | |
106 { | |
107 points = int.Parse(pointsString); | |
108 } | |
109 catch(FormatException) | |
110 { | |
111 throw new FormatException("Attribute 'maxPoints' of army '"+name+"' was not a valid number"); | |
112 } | |
113 | |
114 Army army = new Army(race, name, points, file);//, this); | |
115 extraData[army] = elem.OwnerDocument; | |
116 return army; | |
117 } | |
118 | |
119 protected override Stream GetGameSystemDataStream (ZipFile file) | |
120 { | |
121 return file.GetInputStream(file.FindEntry("data.systemx", true)); | |
122 } | |
123 | |
124 protected override GameSystem CreateGameSystemFromStream (ZipFile file, Stream dataStream) | |
125 { | |
126 XmlElement elem = GetRootElementFromStream(dataStream, WarFoundryXmlElementName.SYSTEM_ELEMENT); | |
127 LogNotifier.Debug(GetType(), "Create GameSystem"); | |
128 return CreateSystemFromElement(file, elem); | |
129 } | |
130 | |
131 private GameSystem CreateSystemFromElement(ZipFile file, XmlElement elem) | |
132 { | |
133 string id = elem.GetAttribute("id"); | |
134 string name = elem.GetAttribute("name"); | |
8
613bc5eaac59
Re #9 - Make WarFoundry loading granular
IBBoard <dev@ibboard.co.uk>
parents:
6
diff
changeset
|
135 GameSystem system = new GameSystem(id, name, this); |
0 | 136 //system.SourceZipFile = file.; |
137 extraData[system] = elem.OwnerDocument; | |
138 return system; | |
139 } | |
140 | |
141 protected override Stream GetRaceDataStream (ZipFile file) | |
142 { | |
143 return file.GetInputStream(file.FindEntry("data.racex", true)); | |
144 } | |
145 | |
146 protected override Race CreateRaceFromStream (ZipFile file, Stream dataStream) | |
147 { | |
148 XmlElement elem = GetRootElementFromStream(dataStream, WarFoundryXmlElementName.RACE_ELEMENT); | |
149 LogNotifier.Debug(GetType(), "Create Race"); | |
150 return CreateRaceFromElement(file, elem); | |
151 } | |
152 | |
153 private Race CreateRaceFromElement(ZipFile file, XmlElement elem) | |
154 { | |
155 string id = elem.GetAttribute("id"); | |
156 string subid = elem.GetAttribute("subid"); | |
157 string systemID = elem.GetAttribute("system"); | |
158 string name = elem.GetAttribute("name"); | |
8
613bc5eaac59
Re #9 - Make WarFoundry loading granular
IBBoard <dev@ibboard.co.uk>
parents:
6
diff
changeset
|
159 Race race = new Race(id, subid, name, systemID, this); |
0 | 160 //race.SourceZipFile = file; //TODO reference source file |
161 extraData[race] = elem.OwnerDocument; | |
162 return race; | |
8
613bc5eaac59
Re #9 - Make WarFoundry loading granular
IBBoard <dev@ibboard.co.uk>
parents:
6
diff
changeset
|
163 } |
0 | 164 |
8
613bc5eaac59
Re #9 - Make WarFoundry loading granular
IBBoard <dev@ibboard.co.uk>
parents:
6
diff
changeset
|
165 public override void CompleteLoading(IWarFoundryStagedLoadObject obj) |
613bc5eaac59
Re #9 - Make WarFoundry loading granular
IBBoard <dev@ibboard.co.uk>
parents:
6
diff
changeset
|
166 { |
613bc5eaac59
Re #9 - Make WarFoundry loading granular
IBBoard <dev@ibboard.co.uk>
parents:
6
diff
changeset
|
167 LogNotifier.DebugFormat(GetType(), "Complete loading of {0} with ID {1}", obj.GetType().Name, obj.ID); |
613bc5eaac59
Re #9 - Make WarFoundry loading granular
IBBoard <dev@ibboard.co.uk>
parents:
6
diff
changeset
|
168 |
613bc5eaac59
Re #9 - Make WarFoundry loading granular
IBBoard <dev@ibboard.co.uk>
parents:
6
diff
changeset
|
169 if (obj is GameSystem) |
613bc5eaac59
Re #9 - Make WarFoundry loading granular
IBBoard <dev@ibboard.co.uk>
parents:
6
diff
changeset
|
170 { |
613bc5eaac59
Re #9 - Make WarFoundry loading granular
IBBoard <dev@ibboard.co.uk>
parents:
6
diff
changeset
|
171 CompleteLoading((GameSystem)obj); |
613bc5eaac59
Re #9 - Make WarFoundry loading granular
IBBoard <dev@ibboard.co.uk>
parents:
6
diff
changeset
|
172 } |
613bc5eaac59
Re #9 - Make WarFoundry loading granular
IBBoard <dev@ibboard.co.uk>
parents:
6
diff
changeset
|
173 else if (obj is Race) |
0 | 174 { |
8
613bc5eaac59
Re #9 - Make WarFoundry loading granular
IBBoard <dev@ibboard.co.uk>
parents:
6
diff
changeset
|
175 CompleteLoading((Race)obj); |
613bc5eaac59
Re #9 - Make WarFoundry loading granular
IBBoard <dev@ibboard.co.uk>
parents:
6
diff
changeset
|
176 } |
613bc5eaac59
Re #9 - Make WarFoundry loading granular
IBBoard <dev@ibboard.co.uk>
parents:
6
diff
changeset
|
177 } |
613bc5eaac59
Re #9 - Make WarFoundry loading granular
IBBoard <dev@ibboard.co.uk>
parents:
6
diff
changeset
|
178 |
613bc5eaac59
Re #9 - Make WarFoundry loading granular
IBBoard <dev@ibboard.co.uk>
parents:
6
diff
changeset
|
179 public XmlDocument GetExtraData(IWarFoundryObject obj) |
613bc5eaac59
Re #9 - Make WarFoundry loading granular
IBBoard <dev@ibboard.co.uk>
parents:
6
diff
changeset
|
180 { |
613bc5eaac59
Re #9 - Make WarFoundry loading granular
IBBoard <dev@ibboard.co.uk>
parents:
6
diff
changeset
|
181 XmlDocument extra = null; |
613bc5eaac59
Re #9 - Make WarFoundry loading granular
IBBoard <dev@ibboard.co.uk>
parents:
6
diff
changeset
|
182 extraData.TryGetValue(obj, out extra); |
613bc5eaac59
Re #9 - Make WarFoundry loading granular
IBBoard <dev@ibboard.co.uk>
parents:
6
diff
changeset
|
183 return extra; |
613bc5eaac59
Re #9 - Make WarFoundry loading granular
IBBoard <dev@ibboard.co.uk>
parents:
6
diff
changeset
|
184 } |
613bc5eaac59
Re #9 - Make WarFoundry loading granular
IBBoard <dev@ibboard.co.uk>
parents:
6
diff
changeset
|
185 |
613bc5eaac59
Re #9 - Make WarFoundry loading granular
IBBoard <dev@ibboard.co.uk>
parents:
6
diff
changeset
|
186 public void CompleteLoading(GameSystem system) |
613bc5eaac59
Re #9 - Make WarFoundry loading granular
IBBoard <dev@ibboard.co.uk>
parents:
6
diff
changeset
|
187 { |
613bc5eaac59
Re #9 - Make WarFoundry loading granular
IBBoard <dev@ibboard.co.uk>
parents:
6
diff
changeset
|
188 if (system.IsFullyLoaded) |
613bc5eaac59
Re #9 - Make WarFoundry loading granular
IBBoard <dev@ibboard.co.uk>
parents:
6
diff
changeset
|
189 { |
613bc5eaac59
Re #9 - Make WarFoundry loading granular
IBBoard <dev@ibboard.co.uk>
parents:
6
diff
changeset
|
190 LogNotifier.DebugFormat(GetType(), "Object of type GameSystem with ID {0} is already fully loaded", system.ID); |
613bc5eaac59
Re #9 - Make WarFoundry loading granular
IBBoard <dev@ibboard.co.uk>
parents:
6
diff
changeset
|
191 return; |
613bc5eaac59
Re #9 - Make WarFoundry loading granular
IBBoard <dev@ibboard.co.uk>
parents:
6
diff
changeset
|
192 } |
613bc5eaac59
Re #9 - Make WarFoundry loading granular
IBBoard <dev@ibboard.co.uk>
parents:
6
diff
changeset
|
193 |
613bc5eaac59
Re #9 - Make WarFoundry loading granular
IBBoard <dev@ibboard.co.uk>
parents:
6
diff
changeset
|
194 XmlDocument extra = GetExtraData(system); |
613bc5eaac59
Re #9 - Make WarFoundry loading granular
IBBoard <dev@ibboard.co.uk>
parents:
6
diff
changeset
|
195 XmlNode elem = extra.LastChild; |
613bc5eaac59
Re #9 - Make WarFoundry loading granular
IBBoard <dev@ibboard.co.uk>
parents:
6
diff
changeset
|
196 |
613bc5eaac59
Re #9 - Make WarFoundry loading granular
IBBoard <dev@ibboard.co.uk>
parents:
6
diff
changeset
|
197 XmlNode catsElem = elem.FirstChild; |
613bc5eaac59
Re #9 - Make WarFoundry loading granular
IBBoard <dev@ibboard.co.uk>
parents:
6
diff
changeset
|
198 WarFoundryObject tempObj; |
613bc5eaac59
Re #9 - Make WarFoundry loading granular
IBBoard <dev@ibboard.co.uk>
parents:
6
diff
changeset
|
199 |
613bc5eaac59
Re #9 - Make WarFoundry loading granular
IBBoard <dev@ibboard.co.uk>
parents:
6
diff
changeset
|
200 foreach (XmlElement cat in catsElem.ChildNodes) |
613bc5eaac59
Re #9 - Make WarFoundry loading granular
IBBoard <dev@ibboard.co.uk>
parents:
6
diff
changeset
|
201 { |
613bc5eaac59
Re #9 - Make WarFoundry loading granular
IBBoard <dev@ibboard.co.uk>
parents:
6
diff
changeset
|
202 tempObj = CreateObjectFromElement(cat); |
0 | 203 |
8
613bc5eaac59
Re #9 - Make WarFoundry loading granular
IBBoard <dev@ibboard.co.uk>
parents:
6
diff
changeset
|
204 if (tempObj is Category) |
613bc5eaac59
Re #9 - Make WarFoundry loading granular
IBBoard <dev@ibboard.co.uk>
parents:
6
diff
changeset
|
205 { |
613bc5eaac59
Re #9 - Make WarFoundry loading granular
IBBoard <dev@ibboard.co.uk>
parents:
6
diff
changeset
|
206 system.AddCategory((Category)tempObj); |
0 | 207 } |
208 else | |
209 { | |
8
613bc5eaac59
Re #9 - Make WarFoundry loading granular
IBBoard <dev@ibboard.co.uk>
parents:
6
diff
changeset
|
210 LogNotifier.WarnFormat(GetType(), "Object for string {0} was not of type Category", cat.OuterXml); |
0 | 211 } |
212 } | |
8
613bc5eaac59
Re #9 - Make WarFoundry loading granular
IBBoard <dev@ibboard.co.uk>
parents:
6
diff
changeset
|
213 |
613bc5eaac59
Re #9 - Make WarFoundry loading granular
IBBoard <dev@ibboard.co.uk>
parents:
6
diff
changeset
|
214 XmlElement statsElem = (XmlElement)catsElem.NextSibling; |
613bc5eaac59
Re #9 - Make WarFoundry loading granular
IBBoard <dev@ibboard.co.uk>
parents:
6
diff
changeset
|
215 LoadSystemStatsFromElement(statsElem, system); |
613bc5eaac59
Re #9 - Make WarFoundry loading granular
IBBoard <dev@ibboard.co.uk>
parents:
6
diff
changeset
|
216 string defaultStatsID = statsElem.GetAttribute("defaultStats"); |
613bc5eaac59
Re #9 - Make WarFoundry loading granular
IBBoard <dev@ibboard.co.uk>
parents:
6
diff
changeset
|
217 |
613bc5eaac59
Re #9 - Make WarFoundry loading granular
IBBoard <dev@ibboard.co.uk>
parents:
6
diff
changeset
|
218 LogNotifier.DebugFormat(GetType(), "Completed loading of GameSystem with ID {0}", system.Name); |
613bc5eaac59
Re #9 - Make WarFoundry loading granular
IBBoard <dev@ibboard.co.uk>
parents:
6
diff
changeset
|
219 system.StandardSystemStatsID = defaultStatsID; |
613bc5eaac59
Re #9 - Make WarFoundry loading granular
IBBoard <dev@ibboard.co.uk>
parents:
6
diff
changeset
|
220 system.SetAsFullyLoaded(); |
0 | 221 } |
222 | |
8
613bc5eaac59
Re #9 - Make WarFoundry loading granular
IBBoard <dev@ibboard.co.uk>
parents:
6
diff
changeset
|
223 public void CompleteLoading(Race race) |
0 | 224 { |
8
613bc5eaac59
Re #9 - Make WarFoundry loading granular
IBBoard <dev@ibboard.co.uk>
parents:
6
diff
changeset
|
225 if (race.IsFullyLoaded) |
0 | 226 { |
8
613bc5eaac59
Re #9 - Make WarFoundry loading granular
IBBoard <dev@ibboard.co.uk>
parents:
6
diff
changeset
|
227 LogNotifier.DebugFormat(GetType(), "Object of type Race with ID {0} is already fully loaded", race.ID); |
613bc5eaac59
Re #9 - Make WarFoundry loading granular
IBBoard <dev@ibboard.co.uk>
parents:
6
diff
changeset
|
228 return; |
0 | 229 } |
230 | |
8
613bc5eaac59
Re #9 - Make WarFoundry loading granular
IBBoard <dev@ibboard.co.uk>
parents:
6
diff
changeset
|
231 XmlDocument extra = GetExtraData(race); |
613bc5eaac59
Re #9 - Make WarFoundry loading granular
IBBoard <dev@ibboard.co.uk>
parents:
6
diff
changeset
|
232 XmlNode elem = extra.LastChild; |
613bc5eaac59
Re #9 - Make WarFoundry loading granular
IBBoard <dev@ibboard.co.uk>
parents:
6
diff
changeset
|
233 XmlNode colNode = elem.FirstChild; |
613bc5eaac59
Re #9 - Make WarFoundry loading granular
IBBoard <dev@ibboard.co.uk>
parents:
6
diff
changeset
|
234 |
613bc5eaac59
Re #9 - Make WarFoundry loading granular
IBBoard <dev@ibboard.co.uk>
parents:
6
diff
changeset
|
235 Dictionary<string, UnitType> unitTypes = new Dictionary<string, UnitType>(); |
613bc5eaac59
Re #9 - Make WarFoundry loading granular
IBBoard <dev@ibboard.co.uk>
parents:
6
diff
changeset
|
236 |
613bc5eaac59
Re #9 - Make WarFoundry loading granular
IBBoard <dev@ibboard.co.uk>
parents:
6
diff
changeset
|
237 foreach (XmlElement node in colNode.ChildNodes) |
613bc5eaac59
Re #9 - Make WarFoundry loading granular
IBBoard <dev@ibboard.co.uk>
parents:
6
diff
changeset
|
238 { |
613bc5eaac59
Re #9 - Make WarFoundry loading granular
IBBoard <dev@ibboard.co.uk>
parents:
6
diff
changeset
|
239 UnitType type = CreateUnitTypeFromElement(node, race, race.GameSystem); |
613bc5eaac59
Re #9 - Make WarFoundry loading granular
IBBoard <dev@ibboard.co.uk>
parents:
6
diff
changeset
|
240 unitTypes.Add(type.ID, type); |
613bc5eaac59
Re #9 - Make WarFoundry loading granular
IBBoard <dev@ibboard.co.uk>
parents:
6
diff
changeset
|
241 } |
613bc5eaac59
Re #9 - Make WarFoundry loading granular
IBBoard <dev@ibboard.co.uk>
parents:
6
diff
changeset
|
242 |
613bc5eaac59
Re #9 - Make WarFoundry loading granular
IBBoard <dev@ibboard.co.uk>
parents:
6
diff
changeset
|
243 colNode = colNode.NextSibling; |
613bc5eaac59
Re #9 - Make WarFoundry loading granular
IBBoard <dev@ibboard.co.uk>
parents:
6
diff
changeset
|
244 |
613bc5eaac59
Re #9 - Make WarFoundry loading granular
IBBoard <dev@ibboard.co.uk>
parents:
6
diff
changeset
|
245 if (colNode!=null && colNode.Name == WarFoundryXmlElementName.CATEGORIES_ELEMENT.Value) |
613bc5eaac59
Re #9 - Make WarFoundry loading granular
IBBoard <dev@ibboard.co.uk>
parents:
6
diff
changeset
|
246 { |
613bc5eaac59
Re #9 - Make WarFoundry loading granular
IBBoard <dev@ibboard.co.uk>
parents:
6
diff
changeset
|
247 foreach (XmlElement node in colNode.ChildNodes) |
0 | 248 { |
8
613bc5eaac59
Re #9 - Make WarFoundry loading granular
IBBoard <dev@ibboard.co.uk>
parents:
6
diff
changeset
|
249 race.AddCategory(CreateCategoryFromElement(node)); |
0 | 250 } |
8
613bc5eaac59
Re #9 - Make WarFoundry loading granular
IBBoard <dev@ibboard.co.uk>
parents:
6
diff
changeset
|
251 |
613bc5eaac59
Re #9 - Make WarFoundry loading granular
IBBoard <dev@ibboard.co.uk>
parents:
6
diff
changeset
|
252 colNode = colNode.NextSibling; |
613bc5eaac59
Re #9 - Make WarFoundry loading granular
IBBoard <dev@ibboard.co.uk>
parents:
6
diff
changeset
|
253 } |
613bc5eaac59
Re #9 - Make WarFoundry loading granular
IBBoard <dev@ibboard.co.uk>
parents:
6
diff
changeset
|
254 |
613bc5eaac59
Re #9 - Make WarFoundry loading granular
IBBoard <dev@ibboard.co.uk>
parents:
6
diff
changeset
|
255 Dictionary<string, EquipmentItem> raceEquipment = new Dictionary<string, EquipmentItem>(); |
613bc5eaac59
Re #9 - Make WarFoundry loading granular
IBBoard <dev@ibboard.co.uk>
parents:
6
diff
changeset
|
256 |
613bc5eaac59
Re #9 - Make WarFoundry loading granular
IBBoard <dev@ibboard.co.uk>
parents:
6
diff
changeset
|
257 if (colNode!=null && colNode.Name == WarFoundryXmlElementName.RACE_EQUIPMENT_ITEMS_ELEMENT.Value) |
613bc5eaac59
Re #9 - Make WarFoundry loading granular
IBBoard <dev@ibboard.co.uk>
parents:
6
diff
changeset
|
258 { |
613bc5eaac59
Re #9 - Make WarFoundry loading granular
IBBoard <dev@ibboard.co.uk>
parents:
6
diff
changeset
|
259 foreach (XmlElement node in colNode.ChildNodes) |
0 | 260 { |
8
613bc5eaac59
Re #9 - Make WarFoundry loading granular
IBBoard <dev@ibboard.co.uk>
parents:
6
diff
changeset
|
261 EquipmentItem item = CreateEquipmentItemFromElement(node, race); |
613bc5eaac59
Re #9 - Make WarFoundry loading granular
IBBoard <dev@ibboard.co.uk>
parents:
6
diff
changeset
|
262 raceEquipment.Add(item.ID, item); |
0 | 263 } |
264 } | |
8
613bc5eaac59
Re #9 - Make WarFoundry loading granular
IBBoard <dev@ibboard.co.uk>
parents:
6
diff
changeset
|
265 |
613bc5eaac59
Re #9 - Make WarFoundry loading granular
IBBoard <dev@ibboard.co.uk>
parents:
6
diff
changeset
|
266 Dictionary<string, Ability> raceAbilities = new Dictionary<string, Ability>(); |
613bc5eaac59
Re #9 - Make WarFoundry loading granular
IBBoard <dev@ibboard.co.uk>
parents:
6
diff
changeset
|
267 //TODO: Load abilities |
613bc5eaac59
Re #9 - Make WarFoundry loading granular
IBBoard <dev@ibboard.co.uk>
parents:
6
diff
changeset
|
268 |
613bc5eaac59
Re #9 - Make WarFoundry loading granular
IBBoard <dev@ibboard.co.uk>
parents:
6
diff
changeset
|
269 race.SetUnitTypes(unitTypes); |
613bc5eaac59
Re #9 - Make WarFoundry loading granular
IBBoard <dev@ibboard.co.uk>
parents:
6
diff
changeset
|
270 race.SetEquipmentItems(raceEquipment); |
613bc5eaac59
Re #9 - Make WarFoundry loading granular
IBBoard <dev@ibboard.co.uk>
parents:
6
diff
changeset
|
271 race.SetAbilities(raceAbilities); |
613bc5eaac59
Re #9 - Make WarFoundry loading granular
IBBoard <dev@ibboard.co.uk>
parents:
6
diff
changeset
|
272 race.SetAsFullyLoaded(); |
613bc5eaac59
Re #9 - Make WarFoundry loading granular
IBBoard <dev@ibboard.co.uk>
parents:
6
diff
changeset
|
273 LogNotifier.DebugFormat(GetType(), "Completed loading of Race with ID {0}", race.Name); |
0 | 274 } |
275 | |
276 protected XmlDocument CreateXmlDocumentFromStream(Stream stream) | |
277 { | |
278 XmlDocument doc = new XmlDocument(); | |
279 XmlReaderSettings settings = new XmlReaderSettings(); | |
280 settings.XmlResolver = xmlResolver; | |
281 settings.ValidationType = ValidationType.DTD; | |
282 settings.ProhibitDtd = false; | |
283 settings.ValidationEventHandler+= new ValidationEventHandler(ValidationEventMethod); | |
284 XmlReader reader = XmlReader.Create(stream, settings); | |
285 | |
286 try | |
287 { | |
288 doc.Load(reader); | |
289 } | |
290 //Don't catch XMLSchemaExceptions - let them get thrown out | |
291 finally | |
292 { | |
293 reader.Close(); | |
294 } | |
295 | |
296 if (doc.ChildNodes.Count!=3) | |
297 { | |
298 throw new InvalidFileException(Translation.GetTranslation("ErrorInvalidXmlFile", "XML file was not a valid XML file. It should contain three child nodes - XML definition, DocType and root node.")); | |
299 } | |
300 | |
301 return doc; | |
302 } | |
303 | |
304 protected XmlDocument CreateXmlDocumentFromString(string xmlString) | |
305 { | |
306 XmlReaderSettings settings = new XmlReaderSettings(); | |
307 settings.XmlResolver = xmlResolver; | |
308 settings.ValidationType = ValidationType.DTD; | |
309 settings.ProhibitDtd = false; | |
310 settings.ValidationEventHandler+= new ValidationEventHandler(ValidationEventMethod); | |
311 XmlReader reader = XmlReader.Create(new MemoryStream(Encoding.UTF8.GetBytes(xmlString)), settings); | |
312 XmlDocument doc = new XmlDocument(); | |
313 | |
314 try | |
315 { | |
316 doc.Load(reader); | |
317 } | |
318 catch(XmlSchemaException ex) | |
319 { | |
320 throw new InvalidFileException(Translation.GetTranslation("ErrorInvalidXmlString", "Failed to parse invalid XML string"), ex); | |
321 } | |
322 finally | |
323 { | |
324 //We might not need to make sure the memory stream is closed, but do it just in case | |
325 reader.Close(); | |
326 } | |
327 | |
328 if (doc.ChildNodes.Count!=3) | |
329 { | |
330 throw new InvalidFileException(String.Format(Translation.GetTranslation("ErrorInvalidXmlFile", "XML string was not a valid XML file. It should contain three child nodes - XML definition, DocType and root node."))); | |
331 } | |
332 | |
333 return doc; | |
334 } | |
335 | |
336 private WarFoundryObject CreateObjectFromElement(XmlElement elem) | |
337 { | |
338 WarFoundryObject obj = null; | |
339 LogNotifier.DebugFormat(GetType(), "Create object for <{0}>", elem.Name); | |
340 | |
341 if (elem.Name.Equals(WarFoundryXmlElementName.CATEGORY_ELEMENT.Value)) | |
342 { | |
343 LogNotifier.Debug(GetType(), "Create Category"); | |
344 obj = CreateCategoryFromElement(elem); | |
345 } | |
346 else | |
347 { | |
348 LogNotifier.Debug(GetType(), "No match"); | |
349 } | |
350 | |
351 return obj; | |
352 } | |
353 | |
354 private Category CreateCategoryFromElement(XmlElement elem) | |
355 { | |
356 string id = elem.GetAttribute("id"); | |
357 string name = elem.GetAttribute("name"); | |
358 int minPc, maxPc, minPts, maxPts, minChoices, maxChoices, baseValue, incValue, incAmount; | |
359 | |
360 try | |
361 { | |
362 minPc = int.Parse(elem.GetAttribute("minPercentage")); | |
363 } | |
364 catch(FormatException) | |
365 { | |
366 throw new FormatException("Attribute 'minPercentage' of category "+id+" was not a valid number"); | |
367 } | |
368 | |
369 try | |
370 { | |
371 maxPc = int.Parse(elem.GetAttribute("maxPercentage")); | |
372 } | |
373 catch(FormatException) | |
374 { | |
375 throw new FormatException("Attribute 'maxPercentage' of category "+id+" was not a valid number"); | |
376 } | |
377 | |
378 try | |
379 { | |
380 minPts = int.Parse(elem.GetAttribute("minPoints")); | |
381 } | |
382 catch(FormatException) | |
383 { | |
384 throw new FormatException("Attribute 'minPoints' of category "+id+" was not a valid number"); | |
385 } | |
386 | |
387 try | |
388 { | |
389 maxPts = int.Parse(elem.GetAttribute("maxPoints")); | |
390 } | |
391 catch(FormatException) | |
392 { | |
393 throw new FormatException("Attribute 'maxPoints' of category "+id+" was not a valid number"); | |
394 } | |
395 | |
396 try | |
397 { | |
398 minChoices = int.Parse(elem.GetAttribute("minChoices")); | |
399 } | |
400 catch(FormatException) | |
401 { | |
402 throw new FormatException("Attribute 'minChoices' of category "+id+" was not a valid number"); | |
403 } | |
404 | |
405 try | |
406 { | |
407 maxChoices = int.Parse(elem.GetAttribute("maxChoices")); | |
408 } | |
409 catch(FormatException) | |
410 { | |
411 throw new FormatException("Attribute 'maxChoices' of category "+id+" was not a valid number"); | |
412 } | |
413 | |
414 try | |
415 { | |
416 baseValue = int.Parse(elem.GetAttribute("baseValue")); | |
417 | |
418 } | |
419 catch(FormatException) | |
420 { | |
421 throw new FormatException("Attribute 'baseValue' of category "+id+" was not a valid number"); | |
422 } | |
423 | |
424 try | |
425 { | |
426 incValue = int.Parse(elem.GetAttribute("incValue")); | |
427 } | |
428 catch(FormatException) | |
429 { | |
430 throw new FormatException("Attribute 'incValue' of category "+id+" was not a valid number"); | |
431 } | |
432 | |
433 try | |
434 { | |
435 incAmount = int.Parse(elem.GetAttribute("incAmount")); | |
436 } | |
437 catch(FormatException) | |
438 { | |
439 throw new FormatException("Attribute 'incAmount' of category "+id+" was not a valid number"); | |
440 } | |
441 | |
442 return new Category(id, name, minPts, maxPts, minPc, maxPc, minChoices, maxChoices, baseValue, incValue, incAmount); | |
443 } | |
444 | |
445 private UnitType CreateUnitTypeFromElement(XmlElement elem, Race parentRace, GameSystem system) | |
446 { | |
447 string id = elem.GetAttribute("id"); | |
448 string name = elem.GetAttribute("typeName"); | |
449 string mainCatID = elem.GetAttribute("cat"); | |
450 int minNum, maxNum, minSize, maxSize, baseSize;//TODO: Add base size | |
451 float points, unitPoints; | |
452 Stats stats; | |
453 List<UnitRequirement> unitRequirements = new List<UnitRequirement>(); | |
454 bool found = false; | |
455 List<string> catIDs = new List<string>(); | |
456 string catID; | |
457 | |
458 try | |
459 { | |
460 minNum = int.Parse(elem.GetAttribute("minNum")); | |
461 } | |
462 catch(FormatException) | |
463 { | |
464 throw new FormatException("Attribute 'minNum' of unit "+id+" was not a valid number"); | |
465 } | |
466 | |
467 try | |
468 { | |
469 maxNum = int.Parse(elem.GetAttribute("maxNum")); | |
470 } | |
471 catch(FormatException) | |
472 { | |
473 throw new FormatException("Attribute 'maxNum' of unit "+id+" was not a valid number"); | |
474 } | |
475 | |
476 try | |
477 { | |
478 minSize = int.Parse(elem.GetAttribute("minSize")); | |
479 } | |
480 catch(FormatException) | |
481 { | |
482 throw new FormatException("Attribute 'minSize' of unit "+id+" was not a valid number"); | |
483 } | |
484 | |
485 try | |
486 { | |
487 maxSize = int.Parse(elem.GetAttribute("maxSize")); | |
488 } | |
489 catch(FormatException) | |
490 { | |
491 throw new FormatException("Attribute 'maxSize' of unit "+id+" was not a valid number"); | |
492 } | |
493 | |
494 if (minSize > maxSize && maxSize!=-1) | |
495 { | |
496 minSize = maxSize; | |
497 } | |
498 | |
499 try | |
500 { | |
501 points = int.Parse(elem.GetAttribute("points")); | |
502 } | |
503 catch(FormatException) | |
504 { | |
505 throw new FormatException("Attribute 'points' of unit "+id+" was not a valid number"); | |
506 } | |
507 | |
508 try | |
509 { | |
510 unitPoints = int.Parse(elem.GetAttribute("unitPoints")); | |
511 } | |
512 catch(FormatException) | |
513 { | |
514 throw new FormatException("Attribute 'trooperPoints' of unit "+id+" was not a valid number"); | |
515 } | |
516 | |
517 XmlNode node = elem.FirstChild; | |
518 | |
519 foreach(XmlElement cat in node.ChildNodes) | |
520 { | |
521 catID = cat.GetAttribute("catID"); | |
522 catIDs.Add(catID); | |
523 | |
524 if (catID == mainCatID) | |
525 { | |
526 found = true; | |
527 } | |
528 } | |
529 | |
530 if (!found) | |
531 { | |
532 throw new InvalidFileException("The main cat "+mainCatID+" was not found in the list of categories for unit "+id); | |
533 } | |
534 | |
535 node = node.NextSibling; | |
536 stats = ParseUnitStats((XmlElement)node, system); | |
537 //TODO: Add unit requirements | |
538 UnitType type = new UnitType(id, name, mainCatID, catIDs.ToArray(), minNum, maxNum, minSize, maxSize, unitPoints, points, stats, unitRequirements.ToArray(), parentRace); | |
539 | |
540 return type; | |
541 } | |
542 | |
543 private Stats ParseUnitStats(XmlElement elem, GameSystem system) | |
544 { | |
545 List<Stat> statsList = new List<Stat>(); | |
546 String statsID = elem.GetAttribute("statSet"); | |
547 SystemStats statsSet; | |
548 | |
549 if (statsID == "") | |
550 { | |
551 statsSet = system.StandardSystemStats; | |
552 } | |
553 else | |
554 { | |
6 | 555 statsSet = system.GetSystemStatsForID(statsID); |
0 | 556 } |
557 | |
558 Stats stats = new Stats(statsSet); | |
559 | |
560 foreach (XmlElement stat in elem.ChildNodes) | |
561 { | |
562 String statID = stat.GetAttribute("name"); | |
563 StatSlot slot = statsSet[statID]; | |
564 | |
565 if (slot!=null) | |
566 { | |
567 statsList.Add(new Stat(slot, stat.InnerText)); | |
568 } | |
569 else | |
570 { | |
571 throw new InvalidFileException("The stat "+statID+" was not found in stats set "+statsID); | |
572 } | |
573 } | |
574 | |
575 stats.SetStats(statsList); | |
576 | |
577 return stats; | |
578 } | |
579 | |
6 | 580 private void LoadSystemStatsFromElement(XmlElement elem, GameSystem system) |
0 | 581 { |
582 foreach (XmlElement stats in elem.ChildNodes) | |
583 { | |
584 SystemStats sysStats = CreateSystemStatsFromElement(stats); | |
6 | 585 system.AddSystemStats(sysStats); |
0 | 586 } |
587 } | |
588 | |
589 private SystemStats CreateSystemStatsFromElement(XmlElement elem) | |
590 { | |
591 List<StatSlot> slots = new List<StatSlot>(); | |
592 string id = elem.GetAttribute("id"); | |
593 | |
594 foreach (XmlElement slot in elem.ChildNodes) | |
595 { | |
596 StatSlot statSlot = new StatSlot(slot.GetAttribute("name")); | |
597 slots.Add(statSlot); | |
598 } | |
599 | |
600 return new SystemStats(id, slots.ToArray()); | |
601 } | |
602 | |
603 private EquipmentItem CreateEquipmentItemFromElement(XmlElement elem, Race race) | |
604 { | |
605 string id = elem.GetAttribute("id"); | |
606 string name = elem.GetAttribute("name"); | |
607 float cost = 0, min = 0, max = 0; | |
608 ArmourType armourType; | |
609 | |
610 try | |
611 { | |
612 cost = float.Parse(elem.GetAttribute("cost")); | |
613 } | |
614 catch(FormatException) | |
615 { | |
616 throw new FormatException("Attribute 'cost' of equipment item "+id+" was not a valid number"); | |
617 } | |
618 | |
619 try | |
620 { | |
621 min = float.Parse(elem.GetAttribute("min")); | |
622 } | |
623 catch(FormatException) | |
624 { | |
625 throw new FormatException("Attribute 'min' of equipment item "+id+" was not a valid number"); | |
626 } | |
627 | |
628 try | |
629 { | |
630 max = float.Parse(elem.GetAttribute("max")); | |
631 } | |
632 catch(FormatException) | |
633 { | |
634 throw new FormatException("Attribute 'max' of equipment item "+id+" was not a valid number"); | |
635 } | |
636 | |
637 try | |
638 { | |
639 armourType = (ArmourType)Enum.Parse(typeof(ArmourType), elem.GetAttribute("armourType")); | |
640 } | |
641 catch(FormatException) | |
642 { | |
643 throw new InvalidFileException("Attribute 'armourType' of equipment "+id+" was not a valid value from the enumeration"); | |
644 } | |
645 | |
646 if (elem.ChildNodes.Count>0) | |
647 { | |
648 //It has stats! | |
649 //TODO: Parse equipment stats | |
650 } | |
651 | |
652 return new EquipmentItem(id, name, cost, min, max, armourType, race); | |
653 } | |
654 | |
655 private void ValidationEventMethod(object sender, ValidationEventArgs e) | |
656 { | |
657 //TODO: Fire a validation failure event | |
658 LogNotifier.WarnFormat(GetType(), "Validation Error: {0}", e.Message); | |
659 } | |
660 } | |
661 } |