Mercurial > repos > IBBoard.WarFoundry.API
comparison api/Factories/Xml/WarFoundryXmlFactory.cs @ 0:520818033bb6
Initial commit of WarFoundry code
author | IBBoard <dev@ibboard.co.uk> |
---|---|
date | Fri, 19 Dec 2008 15:57:51 +0000 |
parents | |
children | 150a5669cd7b |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:520818033bb6 |
---|---|
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"); | |
135 GameSystem system = new StagedLoadingGameSystem(id, name, this); | |
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"); | |
159 Race race = new StagedLoadingRace(id, subid, name, systemID, this); | |
160 //race.SourceZipFile = file; //TODO reference source file | |
161 extraData[race] = elem.OwnerDocument; | |
162 return race; | |
163 } | |
164 | |
165 /*public WarFoundryObject CreateObjectFromStream(ZipFile file, Stream stream) | |
166 { | |
167 try | |
168 { | |
169 WarFoundryObject obj = LoadFileObjectFromElement(file, elem); | |
170 | |
171 if (obj != null) | |
172 { | |
173 extraData[obj] = doc; | |
174 return obj; | |
175 } | |
176 else | |
177 { | |
178 throw new InvalidFileException(String.Format(Translation.GetTranslation("ErrorInvalidXmlFile", "XML file '{0}' was not a loadable XML file. Please ensure it is a valid and supported WarFoundry XML file."), file.Name)); | |
179 } | |
180 } | |
181 catch (XmlSchemaException ex) | |
182 { | |
183 throw new InvalidFileException(String.Format(Translation.GetTranslation("ErrorInvalidXmlFile", "Failed to parse invalid XML data file in {0}. Error at line {1} position {2}: {3}"), file.Name, ex.LineNumber, ex.LinePosition, ex.Message.Substring(0, ex.Message.IndexOf(".")+1)), ex); | |
184 } | |
185 catch (InvalidFileException ex) | |
186 { | |
187 throw new InvalidFileException(String.Format(Translation.GetTranslation("ErrorInvalidNamedXmlFile", "XML data file in '{0}' was not a valid XML file. It should contain three child nodes - XML definition, DocType and root node."), file.Name), ex); | |
188 } | |
189 } | |
190 | |
191 private WarFoundryObject LoadFileObjectFromElement(ZipFile file, XmlElement elem) | |
192 { | |
193 WarFoundryObject obj = null; | |
194 | |
195 if (elem.Name.Equals(WarFoundryXmlElementName.SYSTEM_ELEMENT.Value)) | |
196 { | |
197 logger.Debug("Create GameSystem"); | |
198 obj = CreateSystemFromElement(file, elem); | |
199 } | |
200 else if (elem.Name.Equals(WarFoundryXmlElementName.RACE_ELEMENT.Value)) | |
201 { | |
202 logger.Debug("Create Race"); | |
203 obj = CreateRaceFromElement(file, elem); | |
204 } | |
205 | |
206 return obj; | |
207 }*/ | |
208 | |
209 public override void CompleteLoading(IWarFoundryStagedLoadObject obj) | |
210 { | |
211 LogNotifier.DebugFormat(GetType(), "Complete loading of {0} with ID {1}", obj.GetType().Name, obj.ID); | |
212 | |
213 if (!obj.IsFullyLoaded) | |
214 { | |
215 XmlDocument extra = extraData[obj]; | |
216 | |
217 if (obj is GameSystem) | |
218 { | |
219 GameSystem system = (GameSystem)obj; | |
220 XmlNode elem = extra.LastChild; | |
221 | |
222 XmlNode catsElem = elem.FirstChild; | |
223 Category[] cats; | |
224 List<Category> catList = new List<Category>(); | |
225 WarFoundryObject tempObj; | |
226 | |
227 foreach (XmlElement cat in catsElem.ChildNodes) | |
228 { | |
229 tempObj = CreateObjectFromElement(cat); | |
230 | |
231 if (tempObj is Category) | |
232 { | |
233 catList.Add((Category)tempObj); | |
234 } | |
235 else | |
236 { | |
237 LogNotifier.WarnFormat(GetType(), "Object for string {0} was not of type Category", cat.OuterXml); | |
238 } | |
239 } | |
240 | |
241 cats = catList.ToArray(); | |
242 LogNotifier.DebugFormat(GetType(), "Found {0} categories", cats.Length); | |
243 | |
244 XmlElement statsElem = (XmlElement)catsElem.NextSibling; | |
245 Dictionary<string, SystemStats> sysStats = CreateSystemStatsSetFromElement(statsElem); | |
246 string defaultStatsID = statsElem.GetAttribute("defaultStats"); | |
247 | |
248 LogNotifier.DebugFormat(GetType(), "Complete loading of {0}", system.Name); | |
249 system.Categories = cats; | |
250 system.SystemStats = new SystemStatsSet(sysStats); | |
251 system.StandardSystemStatsID = defaultStatsID; | |
252 } | |
253 else if (obj is Race) | |
254 { | |
255 Race race = (Race)obj; | |
256 XmlNode elem = extra.LastChild; | |
257 XmlNode colNode = elem.FirstChild; | |
258 | |
259 Dictionary<string, UnitType> unitTypes = new Dictionary<string, UnitType>(); | |
260 | |
261 foreach (XmlElement node in colNode.ChildNodes) | |
262 { | |
263 UnitType type = CreateUnitTypeFromElement(node, race, race.GameSystem); | |
264 unitTypes.Add(type.ID, type); | |
265 } | |
266 | |
267 colNode = colNode.NextSibling; | |
268 List<Category> catOverrides = new List<Category>(); | |
269 | |
270 if (colNode!=null && colNode.Name == WarFoundryXmlElementName.CATEGORIES_ELEMENT.Value) | |
271 { | |
272 foreach (XmlElement node in colNode.ChildNodes) | |
273 { | |
274 catOverrides.Add(CreateCategoryFromElement(node)); | |
275 } | |
276 | |
277 colNode = colNode.NextSibling; | |
278 } | |
279 | |
280 Dictionary<string, EquipmentItem> raceEquipment = new Dictionary<string, EquipmentItem>(); | |
281 | |
282 if (colNode!=null && colNode.Name == WarFoundryXmlElementName.RACE_EQUIPMENT_ITEMS_ELEMENT.Value) | |
283 { | |
284 foreach (XmlElement node in colNode.ChildNodes) | |
285 { | |
286 EquipmentItem item = CreateEquipmentItemFromElement(node, race); | |
287 raceEquipment.Add(item.ID, item); | |
288 } | |
289 } | |
290 | |
291 Dictionary<string, Ability> raceAbilities = new Dictionary<string, Ability>(); | |
292 //TODO: Load abilities | |
293 | |
294 LogNotifier.DebugFormat(GetType(), "Complete loading of {0}", race.Name); | |
295 race.Categories = catOverrides.ToArray(); | |
296 race.SetUnitTypes(unitTypes); | |
297 race.SetEquipmentItems(raceEquipment); | |
298 race.SetAbilities(raceAbilities); | |
299 } | |
300 } | |
301 else | |
302 { | |
303 LogNotifier.Debug(GetType(), "Object is already fully loaded"); | |
304 } | |
305 } | |
306 | |
307 protected XmlDocument CreateXmlDocumentFromStream(Stream stream) | |
308 { | |
309 XmlDocument doc = new XmlDocument(); | |
310 XmlReaderSettings settings = new XmlReaderSettings(); | |
311 settings.XmlResolver = xmlResolver; | |
312 settings.ValidationType = ValidationType.DTD; | |
313 settings.ProhibitDtd = false; | |
314 settings.ValidationEventHandler+= new ValidationEventHandler(ValidationEventMethod); | |
315 XmlReader reader = XmlReader.Create(stream, settings); | |
316 | |
317 try | |
318 { | |
319 doc.Load(reader); | |
320 } | |
321 //Don't catch XMLSchemaExceptions - let them get thrown out | |
322 finally | |
323 { | |
324 reader.Close(); | |
325 } | |
326 | |
327 if (doc.ChildNodes.Count!=3) | |
328 { | |
329 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.")); | |
330 } | |
331 | |
332 return doc; | |
333 } | |
334 | |
335 protected XmlDocument CreateXmlDocumentFromString(string xmlString) | |
336 { | |
337 XmlReaderSettings settings = new XmlReaderSettings(); | |
338 settings.XmlResolver = xmlResolver; | |
339 settings.ValidationType = ValidationType.DTD; | |
340 settings.ProhibitDtd = false; | |
341 settings.ValidationEventHandler+= new ValidationEventHandler(ValidationEventMethod); | |
342 XmlReader reader = XmlReader.Create(new MemoryStream(Encoding.UTF8.GetBytes(xmlString)), settings); | |
343 XmlDocument doc = new XmlDocument(); | |
344 | |
345 try | |
346 { | |
347 doc.Load(reader); | |
348 } | |
349 catch(XmlSchemaException ex) | |
350 { | |
351 throw new InvalidFileException(Translation.GetTranslation("ErrorInvalidXmlString", "Failed to parse invalid XML string"), ex); | |
352 } | |
353 finally | |
354 { | |
355 //We might not need to make sure the memory stream is closed, but do it just in case | |
356 reader.Close(); | |
357 } | |
358 | |
359 if (doc.ChildNodes.Count!=3) | |
360 { | |
361 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."))); | |
362 } | |
363 | |
364 return doc; | |
365 } | |
366 | |
367 private WarFoundryObject CreateObjectFromElement(XmlElement elem) | |
368 { | |
369 WarFoundryObject obj = null; | |
370 LogNotifier.DebugFormat(GetType(), "Create object for <{0}>", elem.Name); | |
371 | |
372 if (elem.Name.Equals(WarFoundryXmlElementName.CATEGORY_ELEMENT.Value)) | |
373 { | |
374 LogNotifier.Debug(GetType(), "Create Category"); | |
375 obj = CreateCategoryFromElement(elem); | |
376 } | |
377 else | |
378 { | |
379 LogNotifier.Debug(GetType(), "No match"); | |
380 } | |
381 | |
382 return obj; | |
383 } | |
384 | |
385 private Category CreateCategoryFromElement(XmlElement elem) | |
386 { | |
387 string id = elem.GetAttribute("id"); | |
388 string name = elem.GetAttribute("name"); | |
389 int minPc, maxPc, minPts, maxPts, minChoices, maxChoices, baseValue, incValue, incAmount; | |
390 | |
391 try | |
392 { | |
393 minPc = int.Parse(elem.GetAttribute("minPercentage")); | |
394 } | |
395 catch(FormatException) | |
396 { | |
397 throw new FormatException("Attribute 'minPercentage' of category "+id+" was not a valid number"); | |
398 } | |
399 | |
400 try | |
401 { | |
402 maxPc = int.Parse(elem.GetAttribute("maxPercentage")); | |
403 } | |
404 catch(FormatException) | |
405 { | |
406 throw new FormatException("Attribute 'maxPercentage' of category "+id+" was not a valid number"); | |
407 } | |
408 | |
409 try | |
410 { | |
411 minPts = int.Parse(elem.GetAttribute("minPoints")); | |
412 } | |
413 catch(FormatException) | |
414 { | |
415 throw new FormatException("Attribute 'minPoints' of category "+id+" was not a valid number"); | |
416 } | |
417 | |
418 try | |
419 { | |
420 maxPts = int.Parse(elem.GetAttribute("maxPoints")); | |
421 } | |
422 catch(FormatException) | |
423 { | |
424 throw new FormatException("Attribute 'maxPoints' of category "+id+" was not a valid number"); | |
425 } | |
426 | |
427 try | |
428 { | |
429 minChoices = int.Parse(elem.GetAttribute("minChoices")); | |
430 } | |
431 catch(FormatException) | |
432 { | |
433 throw new FormatException("Attribute 'minChoices' of category "+id+" was not a valid number"); | |
434 } | |
435 | |
436 try | |
437 { | |
438 maxChoices = int.Parse(elem.GetAttribute("maxChoices")); | |
439 } | |
440 catch(FormatException) | |
441 { | |
442 throw new FormatException("Attribute 'maxChoices' of category "+id+" was not a valid number"); | |
443 } | |
444 | |
445 try | |
446 { | |
447 baseValue = int.Parse(elem.GetAttribute("baseValue")); | |
448 | |
449 } | |
450 catch(FormatException) | |
451 { | |
452 throw new FormatException("Attribute 'baseValue' of category "+id+" was not a valid number"); | |
453 } | |
454 | |
455 try | |
456 { | |
457 incValue = int.Parse(elem.GetAttribute("incValue")); | |
458 } | |
459 catch(FormatException) | |
460 { | |
461 throw new FormatException("Attribute 'incValue' of category "+id+" was not a valid number"); | |
462 } | |
463 | |
464 try | |
465 { | |
466 incAmount = int.Parse(elem.GetAttribute("incAmount")); | |
467 } | |
468 catch(FormatException) | |
469 { | |
470 throw new FormatException("Attribute 'incAmount' of category "+id+" was not a valid number"); | |
471 } | |
472 | |
473 return new Category(id, name, minPts, maxPts, minPc, maxPc, minChoices, maxChoices, baseValue, incValue, incAmount); | |
474 } | |
475 | |
476 private UnitType CreateUnitTypeFromElement(XmlElement elem, Race parentRace, GameSystem system) | |
477 { | |
478 string id = elem.GetAttribute("id"); | |
479 string name = elem.GetAttribute("typeName"); | |
480 string mainCatID = elem.GetAttribute("cat"); | |
481 int minNum, maxNum, minSize, maxSize, baseSize;//TODO: Add base size | |
482 float points, unitPoints; | |
483 Stats stats; | |
484 List<UnitRequirement> unitRequirements = new List<UnitRequirement>(); | |
485 bool found = false; | |
486 List<string> catIDs = new List<string>(); | |
487 string catID; | |
488 | |
489 try | |
490 { | |
491 minNum = int.Parse(elem.GetAttribute("minNum")); | |
492 } | |
493 catch(FormatException) | |
494 { | |
495 throw new FormatException("Attribute 'minNum' of unit "+id+" was not a valid number"); | |
496 } | |
497 | |
498 try | |
499 { | |
500 maxNum = int.Parse(elem.GetAttribute("maxNum")); | |
501 } | |
502 catch(FormatException) | |
503 { | |
504 throw new FormatException("Attribute 'maxNum' of unit "+id+" was not a valid number"); | |
505 } | |
506 | |
507 try | |
508 { | |
509 minSize = int.Parse(elem.GetAttribute("minSize")); | |
510 } | |
511 catch(FormatException) | |
512 { | |
513 throw new FormatException("Attribute 'minSize' of unit "+id+" was not a valid number"); | |
514 } | |
515 | |
516 try | |
517 { | |
518 maxSize = int.Parse(elem.GetAttribute("maxSize")); | |
519 } | |
520 catch(FormatException) | |
521 { | |
522 throw new FormatException("Attribute 'maxSize' of unit "+id+" was not a valid number"); | |
523 } | |
524 | |
525 if (minSize > maxSize && maxSize!=-1) | |
526 { | |
527 minSize = maxSize; | |
528 } | |
529 | |
530 try | |
531 { | |
532 points = int.Parse(elem.GetAttribute("points")); | |
533 } | |
534 catch(FormatException) | |
535 { | |
536 throw new FormatException("Attribute 'points' of unit "+id+" was not a valid number"); | |
537 } | |
538 | |
539 try | |
540 { | |
541 unitPoints = int.Parse(elem.GetAttribute("unitPoints")); | |
542 } | |
543 catch(FormatException) | |
544 { | |
545 throw new FormatException("Attribute 'trooperPoints' of unit "+id+" was not a valid number"); | |
546 } | |
547 | |
548 XmlNode node = elem.FirstChild; | |
549 | |
550 foreach(XmlElement cat in node.ChildNodes) | |
551 { | |
552 catID = cat.GetAttribute("catID"); | |
553 catIDs.Add(catID); | |
554 | |
555 if (catID == mainCatID) | |
556 { | |
557 found = true; | |
558 } | |
559 } | |
560 | |
561 if (!found) | |
562 { | |
563 throw new InvalidFileException("The main cat "+mainCatID+" was not found in the list of categories for unit "+id); | |
564 } | |
565 | |
566 node = node.NextSibling; | |
567 stats = ParseUnitStats((XmlElement)node, system); | |
568 //TODO: Add unit requirements | |
569 UnitType type = new UnitType(id, name, mainCatID, catIDs.ToArray(), minNum, maxNum, minSize, maxSize, unitPoints, points, stats, unitRequirements.ToArray(), parentRace); | |
570 | |
571 return type; | |
572 } | |
573 | |
574 private Stats ParseUnitStats(XmlElement elem, GameSystem system) | |
575 { | |
576 List<Stat> statsList = new List<Stat>(); | |
577 String statsID = elem.GetAttribute("statSet"); | |
578 SystemStats statsSet; | |
579 | |
580 if (statsID == "") | |
581 { | |
582 statsSet = system.StandardSystemStats; | |
583 } | |
584 else | |
585 { | |
586 statsSet = system.SystemStats[statsID]; | |
587 } | |
588 | |
589 Stats stats = new Stats(statsSet); | |
590 | |
591 foreach (XmlElement stat in elem.ChildNodes) | |
592 { | |
593 String statID = stat.GetAttribute("name"); | |
594 StatSlot slot = statsSet[statID]; | |
595 | |
596 if (slot!=null) | |
597 { | |
598 statsList.Add(new Stat(slot, stat.InnerText)); | |
599 } | |
600 else | |
601 { | |
602 throw new InvalidFileException("The stat "+statID+" was not found in stats set "+statsID); | |
603 } | |
604 } | |
605 | |
606 stats.SetStats(statsList); | |
607 | |
608 return stats; | |
609 } | |
610 | |
611 private Dictionary<string, SystemStats> CreateSystemStatsSetFromElement(XmlElement elem) | |
612 { | |
613 Dictionary<string, SystemStats> dict = new Dictionary<string,SystemStats>(); | |
614 | |
615 foreach (XmlElement stats in elem.ChildNodes) | |
616 { | |
617 SystemStats sysStats = CreateSystemStatsFromElement(stats); | |
618 dict.Add(sysStats.ID, sysStats); | |
619 } | |
620 | |
621 return dict; | |
622 } | |
623 | |
624 private SystemStats CreateSystemStatsFromElement(XmlElement elem) | |
625 { | |
626 List<StatSlot> slots = new List<StatSlot>(); | |
627 string id = elem.GetAttribute("id"); | |
628 | |
629 foreach (XmlElement slot in elem.ChildNodes) | |
630 { | |
631 StatSlot statSlot = new StatSlot(slot.GetAttribute("name")); | |
632 slots.Add(statSlot); | |
633 } | |
634 | |
635 return new SystemStats(id, slots.ToArray()); | |
636 } | |
637 | |
638 private EquipmentItem CreateEquipmentItemFromElement(XmlElement elem, Race race) | |
639 { | |
640 string id = elem.GetAttribute("id"); | |
641 string name = elem.GetAttribute("name"); | |
642 float cost = 0, min = 0, max = 0; | |
643 ArmourType armourType; | |
644 | |
645 try | |
646 { | |
647 cost = float.Parse(elem.GetAttribute("cost")); | |
648 } | |
649 catch(FormatException) | |
650 { | |
651 throw new FormatException("Attribute 'cost' of equipment item "+id+" was not a valid number"); | |
652 } | |
653 | |
654 try | |
655 { | |
656 min = float.Parse(elem.GetAttribute("min")); | |
657 } | |
658 catch(FormatException) | |
659 { | |
660 throw new FormatException("Attribute 'min' of equipment item "+id+" was not a valid number"); | |
661 } | |
662 | |
663 try | |
664 { | |
665 max = float.Parse(elem.GetAttribute("max")); | |
666 } | |
667 catch(FormatException) | |
668 { | |
669 throw new FormatException("Attribute 'max' of equipment item "+id+" was not a valid number"); | |
670 } | |
671 | |
672 try | |
673 { | |
674 armourType = (ArmourType)Enum.Parse(typeof(ArmourType), elem.GetAttribute("armourType")); | |
675 } | |
676 catch(FormatException) | |
677 { | |
678 throw new InvalidFileException("Attribute 'armourType' of equipment "+id+" was not a valid value from the enumeration"); | |
679 } | |
680 | |
681 if (elem.ChildNodes.Count>0) | |
682 { | |
683 //It has stats! | |
684 //TODO: Parse equipment stats | |
685 } | |
686 | |
687 return new EquipmentItem(id, name, cost, min, max, armourType, race); | |
688 } | |
689 | |
690 private void ValidationEventMethod(object sender, ValidationEventArgs e) | |
691 { | |
692 //TODO: Fire a validation failure event | |
693 LogNotifier.WarnFormat(GetType(), "Validation Error: {0}", e.Message); | |
694 } | |
695 } | |
696 } |