PageRenderTime 60ms CodeModel.GetById 23ms RepoModel.GetById 1ms app.codeStats 0ms

/WorldView/Structures/TerraInfo/TerraInfo.cs

#
C# | 1416 lines | 1175 code | 237 blank | 4 comment | 213 complexity | 671e706de87f6581140c76bdcdb59908 MD5 | raw file
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. using System.Xml;
  5. using System.IO;
  6. using System.Drawing;
  7. using System.Globalization;
  8. namespace MoreTerra.Structures.TerraInfo
  9. {
  10. public class TerraInfo
  11. {
  12. private Dictionary<Int32, MarkerInfo> markers;
  13. private Dictionary<String, List<MarkerInfo>> markerSets;
  14. private Dictionary<Int32, TileInfo> tiles;
  15. private Dictionary<Int32, WallInfo> walls;
  16. private Dictionary<String, ItemInfo> items;
  17. private Dictionary<String, RenameInfo> renames;
  18. private Dictionary<String, ColorInfo> colors;
  19. private Dictionary<String, NpcInfo> npcs;
  20. private Dictionary<String, List<SpecialObjectInfo>> specialobjects;
  21. private Dictionary<Int32, String> itemNames;
  22. private StringBuilder errorLog;
  23. public TerraInfo()
  24. {
  25. markers = new Dictionary<Int32, MarkerInfo>();
  26. markerSets = new Dictionary<String, List<MarkerInfo>>();
  27. items = new Dictionary<String, ItemInfo>();
  28. itemNames = new Dictionary<Int32, String>();
  29. renames = new Dictionary<String, RenameInfo>();
  30. colors = new Dictionary<String, ColorInfo>();
  31. npcs = new Dictionary<String, NpcInfo>();
  32. tiles = new Dictionary<Int32, TileInfo>();
  33. walls = new Dictionary<Int32, WallInfo>();
  34. specialobjects = new Dictionary<String, List<SpecialObjectInfo>>();
  35. errorLog = new StringBuilder();
  36. }
  37. public String LoadInfo(String itemXmlFile)
  38. {
  39. XmlDocument xmlDoc = new XmlDocument();
  40. try
  41. {
  42. xmlDoc.LoadXml(itemXmlFile);
  43. }
  44. catch (FileNotFoundException e)
  45. {
  46. errorLog.AppendLine(e.Message);
  47. return errorLog.ToString();
  48. }
  49. XmlNode dataNode = xmlDoc.DocumentElement;
  50. LoadMarkers(dataNode.SelectSingleNode("markers"));
  51. LoadRenames(dataNode.SelectSingleNode("namechanges").SelectNodes("item"));
  52. LoadNpcs(dataNode.SelectSingleNode("npcs").SelectNodes("npc"));
  53. LoadItems(dataNode.SelectSingleNode("items").SelectNodes("item"));
  54. LoadColors(dataNode.SelectSingleNode("colors").SelectNodes("color"));
  55. LoadTiles(dataNode.SelectSingleNode("tiles").SelectNodes("tile"));
  56. LoadWalls(dataNode.SelectSingleNode("walls").SelectNodes("wall"));
  57. LoadSpecialObjects(dataNode.SelectSingleNode("specialobjects").SelectNodes("object"));
  58. SetupItemNames();
  59. return errorLog.ToString();
  60. }
  61. public String SaveInfo(String toFile)
  62. {
  63. FileStream stream = new FileStream(toFile, FileMode.Create);
  64. StreamWriter writer = new StreamWriter(stream);
  65. writer.WriteLine("<?xml version=\"1.0\" encoding=\"utf-8\" ?>");
  66. writer.WriteLine("<data>");
  67. SaveTiles(writer);
  68. SaveWalls(writer);
  69. SaveItems(writer);
  70. SaveRenames(writer);
  71. SaveNPCs(writer);
  72. SaveColors(writer);
  73. SaveMarkers(writer);
  74. SaveSpecialObjects(writer);
  75. writer.WriteLine("</data>");
  76. writer.Close();
  77. return errorLog.ToString();
  78. }
  79. #region Load Functions
  80. private void LoadMarkers(XmlNode markerNodes)
  81. {
  82. Int32 setCount = -1;
  83. Int32 markerCount = -1;
  84. if ((markerNodes == null) || (markerNodes.ChildNodes.Count == 0))
  85. {
  86. errorLog.AppendLine("There are no Marker items to load.");
  87. return;
  88. }
  89. XmlNodeList markerSetNodes = markerNodes.SelectNodes("markerset");
  90. foreach (XmlNode setNode in markerSetNodes)
  91. {
  92. String setName = String.Empty;
  93. List<MarkerInfo> curSet;
  94. foreach (XmlAttribute att in setNode.Attributes)
  95. {
  96. switch (att.Name)
  97. {
  98. case "name":
  99. setName = att.Value;
  100. break;
  101. default:
  102. errorLog.AppendLine(String.Format("Marker Set #{0} has unknown attribute \"{1}\" has value \"{2}\"",
  103. setCount, att.Name, att.Value));
  104. break;
  105. }
  106. if (setName == String.Empty)
  107. {
  108. errorLog.AppendLine(String.Format("Marker Set #{0} has an empty name attribute.", setCount));
  109. continue;
  110. }
  111. if (markerSets.ContainsKey(setName))
  112. {
  113. errorLog.AppendLine(String.Format("Marker Set #{0} has a duplicate name. Value=\"{1}\"",
  114. setCount, setName));
  115. continue;
  116. }
  117. else
  118. {
  119. curSet = new List<MarkerInfo>();
  120. markerSets.Add(setName, curSet);
  121. }
  122. XmlNodeList markerNodeList = setNode.SelectNodes("marker");
  123. foreach (XmlNode markerNode in markerNodeList)
  124. {
  125. String name = String.Empty;
  126. String markerImage = String.Empty;
  127. markerCount++;
  128. foreach (XmlAttribute markerAtt in markerNode.Attributes)
  129. {
  130. switch (markerAtt.Name)
  131. {
  132. case "name":
  133. name = markerAtt.Value;
  134. break;
  135. default:
  136. errorLog.AppendLine(String.Format("Marker #{0} has unknown attribute \"{1}\" has value \"{2}\"",
  137. markerCount, markerAtt.Name, markerAtt.Value));
  138. break;
  139. }
  140. }
  141. if (name == String.Empty)
  142. {
  143. errorLog.AppendLine(String.Format("Marker #{0} had no name attribute.", markerCount));
  144. continue;
  145. }
  146. if (name.IndexOf(" ") != -1)
  147. {
  148. String[] imageSegments = name.Split(' ');
  149. markerImage = "";
  150. foreach (String str in imageSegments)
  151. {
  152. markerImage += str;
  153. }
  154. }
  155. else
  156. {
  157. markerImage = name;
  158. }
  159. MarkerInfo marker = new MarkerInfo();
  160. marker.name = name;
  161. marker.markerSet = setName;
  162. marker.markerImage = markerImage;
  163. curSet.Add(marker);
  164. markers.Add(markerCount, marker);
  165. }
  166. }
  167. }
  168. }
  169. private void LoadNpcs(XmlNodeList npcNodes)
  170. {
  171. Int32 count = -1;
  172. if ((npcNodes == null) || (npcNodes.Count == 0))
  173. {
  174. errorLog.AppendLine("There are no Npc items to load.");
  175. return;
  176. }
  177. foreach (XmlNode npcNode in npcNodes)
  178. {
  179. String name = String.Empty;
  180. Int32 imageId = -1;
  181. count++;
  182. foreach (XmlAttribute att in npcNode.Attributes)
  183. {
  184. switch (att.Name)
  185. {
  186. case "name":
  187. name = att.Value;
  188. break;
  189. case "npcImage":
  190. if (Int32.TryParse(att.Value, out imageId) == false)
  191. {
  192. errorLog.AppendLine(String.Format("Npc #{0} has an invalid itemImage attribute. Value = \"{1}\"",
  193. count, att.Value));
  194. continue;
  195. }
  196. if (imageId < 0)
  197. {
  198. errorLog.AppendLine(String.Format("Npc #{0} had a out of range itemImage attribute. Value=\"{1}\"",
  199. count, imageId));
  200. continue;
  201. }
  202. break;
  203. default:
  204. errorLog.AppendLine(String.Format("Npc #{0} has unknown attribute \"{1}\" has value \"{2}\"",
  205. count, att.Name, att.Value));
  206. break;
  207. }
  208. }
  209. if (name == String.Empty)
  210. {
  211. errorLog.AppendLine(String.Format("Npc #{0} had no name attribute.", count));
  212. continue;
  213. }
  214. if (imageId == -1)
  215. {
  216. errorLog.AppendLine(String.Format("Npc #{0} had no npcImage attribute.", count));
  217. continue;
  218. }
  219. if (npcs.ContainsKey(name))
  220. {
  221. errorLog.AppendLine(String.Format("Npc #{0} had a duplicate name to {1}.", count, name));
  222. continue;
  223. }
  224. NpcInfo npc = new NpcInfo();
  225. npc.name = name;
  226. npc.imageId = imageId;
  227. npcs.Add(name, npc);
  228. }
  229. }
  230. private void LoadWalls(XmlNodeList wallNodes)
  231. {
  232. Int32 count = -1;
  233. if ((wallNodes == null) || (wallNodes.Count == 0))
  234. {
  235. errorLog.AppendLine("There are no Wall items to load.");
  236. return;
  237. }
  238. foreach (XmlNode wallNode in wallNodes)
  239. {
  240. String name = String.Empty;
  241. String color = String.Empty;
  242. String officialColor = String.Empty;
  243. Color useColor;
  244. Color useOfficialColor;
  245. Boolean safe = false;
  246. Boolean transparent = false;
  247. Int32 wallImage = -1;
  248. count++;
  249. foreach (XmlAttribute att in wallNode.Attributes)
  250. {
  251. switch (att.Name)
  252. {
  253. case "name":
  254. name = att.Value;
  255. break;
  256. case "color":
  257. color = att.Value;
  258. break;
  259. case "officialColor":
  260. officialColor = att.Value;
  261. break;
  262. case "wallImage":
  263. if (Int32.TryParse(att.Value, out wallImage) == false)
  264. {
  265. errorLog.AppendLine(String.Format("Wall #{0} has an invalid wallImage attribute. Value = \"{1}\"",
  266. count, att.Value));
  267. continue;
  268. }
  269. if (wallImage < 0)
  270. {
  271. errorLog.AppendLine(String.Format("Wall #{0} had an out of range wallImage attribute. Value=\"{1}\"",
  272. count, wallImage));
  273. continue;
  274. }
  275. break;
  276. case "unsafe":
  277. if (Boolean.TryParse(att.Value, out safe) == false)
  278. {
  279. errorLog.AppendLine(String.Format("Wall #{0} had an invalid unsafe attribute. Value=\"{1}\"",
  280. count, att.Value));
  281. continue;
  282. }
  283. safe = !safe;
  284. break;
  285. case "transparent":
  286. if (Boolean.TryParse(att.Value, out transparent) == false)
  287. {
  288. errorLog.AppendLine(String.Format("Wall #{0} had an invalid transparent attribute. Value=\"{1}\"",
  289. count, att.Value));
  290. continue;
  291. }
  292. break;
  293. default:
  294. errorLog.AppendLine(String.Format("Wall #{0} has unknown attribute \"{1}\" has value \"{2}\"",
  295. count, att.Name, att.Value));
  296. break;
  297. }
  298. }
  299. if (name == String.Empty)
  300. {
  301. errorLog.AppendLine(String.Format("Wall #{0} had no name attribute.", count));
  302. continue;
  303. }
  304. if (color == String.Empty)
  305. {
  306. errorLog.AppendLine(String.Format("Wall #{0} had no color attribute.", count));
  307. continue;
  308. }
  309. if (Global.TryParseColor(color, out useColor) == false)
  310. {
  311. if (!colors.ContainsKey(color))
  312. {
  313. errorLog.AppendLine(String.Format("Wall #{0} had a color attribute that was not a color or a color lookup name. Value=\"{1}\"",
  314. count, color));
  315. continue;
  316. }
  317. else
  318. {
  319. useColor = colors[color].color;
  320. }
  321. }
  322. else
  323. {
  324. color = String.Empty;
  325. }
  326. if (officialColor == String.Empty)
  327. {
  328. errorLog.AppendLine(String.Format("Wall #{0} had no officialColor attribute.", count));
  329. continue;
  330. }
  331. if (Global.TryParseColor(officialColor, out useOfficialColor) == false)
  332. {
  333. errorLog.AppendLine(String.Format("Wall #{0} had a officialColor attribute that was not a color. Value=\"{1}\"",
  334. count, officialColor));
  335. continue;
  336. }
  337. else
  338. {
  339. officialColor = String.Empty;
  340. }
  341. if (wallImage == -1)
  342. {
  343. errorLog.AppendLine(String.Format("Wall #{0} had no wallImage attribute.", count));
  344. continue;
  345. }
  346. if (walls.ContainsKey(wallImage))
  347. {
  348. errorLog.AppendLine(String.Format("Wall #{0} had a duplicate wallImage to {1}.", count, wallImage));
  349. continue;
  350. }
  351. WallInfo wall = new WallInfo();
  352. wall.name = name;
  353. wall.wallImage = wallImage;
  354. wall.colorName = color;
  355. wall.color = useColor;
  356. wall.officialColor = useOfficialColor;
  357. wall.transparent = transparent;
  358. wall.color = wall.transparent ? Color.FromArgb(0,useColor) : useColor;
  359. walls.Add(wallImage, wall);
  360. }
  361. }
  362. private void LoadTiles(XmlNodeList tileNodes)
  363. {
  364. Int32 count = -1;
  365. if ((tileNodes == null) || (tileNodes.Count == 0))
  366. {
  367. errorLog.AppendLine("There are no Tile items to load.");
  368. return;
  369. }
  370. foreach (XmlNode tileNode in tileNodes)
  371. {
  372. String name = String.Empty;
  373. String color = String.Empty;
  374. String officialColor = String.Empty;
  375. String marker = String.Empty;
  376. Color useColor;
  377. Color useOfficialColor;
  378. Boolean important = false;
  379. Int32 tileImage = -1;
  380. count++;
  381. foreach (XmlAttribute att in tileNode.Attributes)
  382. {
  383. switch (att.Name)
  384. {
  385. case "name":
  386. name = att.Value;
  387. break;
  388. case "tileImage":
  389. if (Int32.TryParse(att.Value, out tileImage) == false)
  390. {
  391. errorLog.AppendLine(String.Format("Tile #{0} has an invalid tileImage attribute. Value = \"{1}\"",
  392. count, att.Value));
  393. continue;
  394. }
  395. if ((tileImage < 0) || (tileImage >= TileProperties.TYPES))
  396. {
  397. errorLog.AppendLine(String.Format("Tile #{0} had a out of range numMade attribute. Value=\"{1}\"",
  398. count, tileImage));
  399. continue;
  400. }
  401. break;
  402. case "important":
  403. if (!Boolean.TryParse(att.Value, out important))
  404. {
  405. errorLog.AppendLine(String.Format("Tile #{0} had an invalid important attribute. Value=\"{1}\"",
  406. count, att.Value));
  407. continue;
  408. }
  409. break;
  410. case "color":
  411. color = att.Value;
  412. break;
  413. case "officialColor":
  414. officialColor = att.Value;
  415. break;
  416. case "marker":
  417. marker = att.Value;
  418. break;
  419. default:
  420. errorLog.AppendLine(String.Format("Tile #{0} has unknown attribute \"{1}\" has value \"{2}\"",
  421. count, att.Name, att.Value));
  422. break;
  423. }
  424. }
  425. if (name == String.Empty)
  426. {
  427. errorLog.AppendLine(String.Format("Tile #{0} had no name attribute.", count));
  428. continue;
  429. }
  430. if (tileImage == -1)
  431. {
  432. errorLog.AppendLine(String.Format("Tile #{0} had no tileImage attribute.", count));
  433. continue;
  434. }
  435. if (tiles.ContainsKey(tileImage))
  436. {
  437. errorLog.AppendLine(String.Format("Tile #{0} had a duplicate tileImage value to \"{1}\"",
  438. count, tileImage));
  439. continue;
  440. }
  441. if (color == String.Empty)
  442. {
  443. errorLog.AppendLine(String.Format("Tile #{0} had no color attribute.", count));
  444. continue;
  445. }
  446. if (Global.TryParseColor(color, out useColor) == false)
  447. {
  448. if (!colors.ContainsKey(color))
  449. {
  450. errorLog.AppendLine(String.Format("Tile #{0} had a color attribute that was not a color or a color lookup name. Value=\"{1}\"",
  451. count, color));
  452. continue;
  453. }
  454. else
  455. {
  456. useColor = colors[color].color;
  457. }
  458. }
  459. else
  460. {
  461. color = String.Empty;
  462. }
  463. if (officialColor == String.Empty)
  464. {
  465. //errorLog.AppendLine(String.Format("Tile #{0} had no officialColor attribute.", count));
  466. officialColor = "#FF00FF";
  467. // continue;
  468. }
  469. if (Global.TryParseColor(officialColor, out useOfficialColor) == false)
  470. {
  471. errorLog.AppendLine(String.Format("Tile #{0} had an officialColor attribute that was not a color. Value=\"{1}\"",
  472. count, officialColor));
  473. continue;
  474. }
  475. else
  476. {
  477. officialColor = String.Empty;
  478. }
  479. TileInfo tile = new TileInfo();
  480. tile.name = name;
  481. tile.colorName = color;
  482. tile.color = useColor;
  483. tile.important = important;
  484. tile.officialColor = useOfficialColor;
  485. tile.markerName = marker;
  486. tile.tileImage = tileImage;
  487. tiles.Add(tileImage, tile);
  488. }
  489. }
  490. private void LoadItems(XmlNodeList itemNodes)
  491. {
  492. Int32 count = -1;
  493. if ((itemNodes == null) || (itemNodes.Count == 0))
  494. {
  495. errorLog.AppendLine("There are no Item items to load.");
  496. return;
  497. }
  498. foreach (XmlNode itemNode in itemNodes)
  499. {
  500. String name = String.Empty;
  501. String found = String.Empty;
  502. Int32 netId = 0;
  503. Int32 imageId = -1;
  504. count++;
  505. foreach (XmlAttribute att in itemNode.Attributes)
  506. {
  507. switch (att.Name)
  508. {
  509. case "name":
  510. name = att.Value;
  511. break;
  512. case "netId":
  513. if (Int32.TryParse(att.Value, out netId) == false)
  514. {
  515. errorLog.AppendLine(String.Format("Item #{0} has an invalid netId attribute. Value = \"{1}\"",
  516. count, att.Value));
  517. continue;
  518. }
  519. break;
  520. case "itemImage":
  521. if (Int32.TryParse(att.Value, out imageId) == false)
  522. {
  523. errorLog.AppendLine(String.Format("Item #{0} has an invalid itemImage attribute. Value = \"{1}\"",
  524. count, att.Value));
  525. continue;
  526. }
  527. if (imageId < 0)
  528. {
  529. errorLog.AppendLine(String.Format("Item #{0} had a out of range itemImage attribute. Value=\"{1}\"",
  530. count, imageId));
  531. continue;
  532. }
  533. break;
  534. case "foundIn":
  535. found = att.Value;
  536. break;
  537. default:
  538. errorLog.AppendLine(String.Format("Item #{0} has unknown attribute \"{1}\" has value \"{2}\"",
  539. count, att.Name, att.Value));
  540. break;
  541. }
  542. }
  543. if (name == String.Empty)
  544. {
  545. errorLog.AppendLine(String.Format("Item #{0} had no name attribute.", count));
  546. continue;
  547. }
  548. if (imageId == -1)
  549. {
  550. errorLog.AppendLine(String.Format("Item #{0} had no itemImage attribute.", count));
  551. continue;
  552. }
  553. if (netId == 0)
  554. netId = imageId;
  555. if (items.ContainsKey(name))
  556. {
  557. errorLog.AppendLine(String.Format("Item #{0} had a duplicate name to {1}.", count, name));
  558. continue;
  559. }
  560. ItemInfo item = new ItemInfo();
  561. item.name = name;
  562. item.foundIn = found;
  563. item.netId = netId;
  564. item.imageId = imageId;
  565. items.Add(name, item);
  566. }
  567. }
  568. private void LoadRenames(XmlNodeList renameNodes)
  569. {
  570. Int32 count = -1;
  571. if ((renameNodes == null) || (renameNodes.Count == 0))
  572. {
  573. errorLog.AppendLine("There are no Rename items to load.");
  574. return;
  575. }
  576. foreach (XmlNode renameNode in renameNodes)
  577. {
  578. String name = String.Empty;
  579. String newName = String.Empty;
  580. count++;
  581. foreach (XmlAttribute att in renameNode.Attributes)
  582. {
  583. switch (att.Name)
  584. {
  585. case "name":
  586. name = att.Value;
  587. break;
  588. case "newName":
  589. newName = att.Value;
  590. break;
  591. default:
  592. errorLog.AppendLine(String.Format("Rename #{0} has unknown attribute \"{1}\" has value \"{2}\"",
  593. count, att.Name, att.Value));
  594. break;
  595. }
  596. }
  597. if (name == String.Empty)
  598. {
  599. errorLog.AppendLine(String.Format("Rename #{0} had no name attribute.", count));
  600. continue;
  601. }
  602. if (newName == String.Empty)
  603. {
  604. errorLog.AppendLine(String.Format("Rename #{0} had no newName attribute.", count));
  605. continue;
  606. }
  607. if (renames.ContainsKey(name))
  608. {
  609. errorLog.AppendLine(String.Format("Rename #{0} had a duplicate name to {1}.", count, name));
  610. continue;
  611. }
  612. RenameInfo rename = new RenameInfo();
  613. rename.name = name;
  614. rename.newName = newName;
  615. renames.Add(name, rename);
  616. }
  617. }
  618. private void LoadColors(XmlNodeList colorNodes)
  619. {
  620. Int32 count = -1;
  621. if ((colorNodes == null) || (colorNodes.Count == 0))
  622. {
  623. errorLog.AppendLine("There are no Color items to load.");
  624. return;
  625. }
  626. foreach (XmlNode colorNode in colorNodes)
  627. {
  628. String name = String.Empty;
  629. Int32 red = -1;
  630. Int32 green = -1;
  631. Int32 blue = -1;
  632. Color useColor = Color.Black;
  633. Boolean hasColor = false;
  634. count++;
  635. foreach (XmlAttribute att in colorNode.Attributes)
  636. {
  637. switch (att.Name)
  638. {
  639. case "name":
  640. name = att.Value;
  641. break;
  642. case "red":
  643. if (Int32.TryParse(att.Value, out red) == false)
  644. {
  645. errorLog.AppendLine(String.Format("Color #{0} has an invalid red attribute. Value=\"{1}\"",
  646. count, att.Value));
  647. continue;
  648. }
  649. if ((red < 0) || (red > 255))
  650. {
  651. errorLog.AppendLine(String.Format("Color #{0} had a out of range red attribute. Value=\"{1}\"",
  652. count, red));
  653. continue;
  654. }
  655. break;
  656. case "green":
  657. if (Int32.TryParse(att.Value, out green) == false)
  658. {
  659. errorLog.AppendLine(String.Format("Color #{0} has an invalid green attribute. Value=\"{1}\"",
  660. count, att.Value));
  661. continue;
  662. }
  663. if ((green < 0) || (green > 255))
  664. {
  665. errorLog.AppendLine(String.Format("Color #{0} had a out of range green attribute. Value=\"{1}\"",
  666. count, green));
  667. continue;
  668. }
  669. break;
  670. case "blue":
  671. if (Int32.TryParse(att.Value, out blue) == false)
  672. {
  673. errorLog.AppendLine(String.Format("Color #{0} has an invalid blue attribute. Value=\"{1}\"",
  674. count, att.Value));
  675. continue;
  676. }
  677. if ((blue < 0) || (blue > 255))
  678. {
  679. errorLog.AppendLine(String.Format("Color #{0} had a out of range blue attribute. Value=\"{1}\"",
  680. count, blue));
  681. continue;
  682. }
  683. break;
  684. case "colorString":
  685. hasColor = Global.TryParseColor(att.Value, out useColor);
  686. if (hasColor == false)
  687. {
  688. errorLog.AppendLine(String.Format("Color #{0} has a bad colorString value. Value={1}",
  689. count, att.Value));
  690. continue;
  691. }
  692. break;
  693. default:
  694. errorLog.AppendLine(String.Format("Color #{0} has unknown attribute \"{1}\" has value \"{2}\"",
  695. count, att.Name, att.Value));
  696. break;
  697. }
  698. }
  699. if (name == String.Empty)
  700. {
  701. errorLog.AppendLine(String.Format("Color #{0} had no name attribute.", count));
  702. continue;
  703. }
  704. if (hasColor == false)
  705. {
  706. if (red == -1)
  707. {
  708. errorLog.AppendLine(String.Format("Color #{0} had no colorString and no red attribute.", count));
  709. continue;
  710. }
  711. if (green == -1)
  712. {
  713. errorLog.AppendLine(String.Format("Color #{0} had no colorString and no green attribute.", count));
  714. continue;
  715. }
  716. if (blue == -1)
  717. {
  718. errorLog.AppendLine(String.Format("Color #{0} had no colorString and no blue attribute.", count));
  719. continue;
  720. }
  721. useColor = Color.FromArgb(red, green, blue);
  722. }
  723. else
  724. {
  725. if ((red != -1) && (useColor.R != red))
  726. {
  727. errorLog.AppendLine(String.Format("Color #{0} has both a colorString and a red attribute but they do not match.",
  728. count));
  729. continue;
  730. }
  731. if ((green != -1) && (useColor.G != green))
  732. {
  733. errorLog.AppendLine(String.Format("Color #{0} has both a colorString and a green attribute but they do not match.",
  734. count));
  735. continue;
  736. }
  737. if ((blue != -1) && (useColor.B != blue))
  738. {
  739. errorLog.AppendLine(String.Format("Color #{0} has both a colorString and a blue attribute but they do not match.",
  740. count));
  741. continue;
  742. }
  743. }
  744. if (colors.ContainsKey(name))
  745. {
  746. errorLog.AppendLine(String.Format("Color #{0} had a duplicate name to {1}.", count, name));
  747. continue;
  748. }
  749. ColorInfo color = new ColorInfo();
  750. color.name = name;
  751. color.color = useColor;
  752. colors.Add(name, color);
  753. }
  754. }
  755. private void LoadSpecialObjects(XmlNodeList soNodes)
  756. {
  757. Int32 count = -1;
  758. if ((soNodes == null) || (soNodes.Count == 0))
  759. {
  760. errorLog.AppendLine("There are no Special Object items to load.");
  761. return;
  762. }
  763. foreach (XmlNode objectNode in soNodes)
  764. {
  765. String name = String.Empty;
  766. String type = String.Empty;
  767. String color = String.Empty;
  768. String officialColor = String.Empty;
  769. Color useColor;
  770. Color useOfficialColor;
  771. count++;
  772. foreach (XmlAttribute att in objectNode.Attributes)
  773. {
  774. switch (att.Name)
  775. {
  776. case "name":
  777. name = att.Value;
  778. break;
  779. case "type":
  780. type = att.Value;
  781. break;
  782. case "color":
  783. color = att.Value;
  784. break;
  785. case "officialColor":
  786. officialColor = att.Value;
  787. break;
  788. default:
  789. errorLog.AppendLine(String.Format("Special Object #{0} has unknown attribute \"{1}\" has value \"{2}\"",
  790. count, att.Name, att.Value));
  791. break;
  792. }
  793. }
  794. if (name == String.Empty)
  795. {
  796. errorLog.AppendLine(String.Format("Special Object #{0} had no name attribute.", count));
  797. continue;
  798. }
  799. if (type == String.Empty)
  800. {
  801. errorLog.AppendLine(String.Format("Special Object #{0} had no type attribute.", count));
  802. continue;
  803. }
  804. if (color == String.Empty)
  805. {
  806. errorLog.AppendLine(String.Format("Special Object #{0} had no color attribute.", count));
  807. continue;
  808. }
  809. if (Global.TryParseColor(color, out useColor) == false)
  810. {
  811. if (!colors.ContainsKey(color))
  812. {
  813. errorLog.AppendLine(String.Format("Special Object #{0} had a color attribute that was not a color or a color lookup name. Value=\"{1}\"",
  814. count, color));
  815. continue;
  816. }
  817. else
  818. {
  819. useColor = colors[color].color;
  820. }
  821. }
  822. else
  823. {
  824. color = String.Empty;
  825. }
  826. if (officialColor == String.Empty)
  827. {
  828. errorLog.AppendLine(String.Format("Special Object #{0} had no officialColor attribute.", count));
  829. continue;
  830. }
  831. if (Global.TryParseColor(officialColor, out useOfficialColor) == false)
  832. {
  833. errorLog.AppendLine(String.Format("Special Object #{0} had a officialColor attribute that was not a color. Value=\"{1}\"",
  834. count, officialColor));
  835. continue;
  836. }
  837. SpecialObjectInfo so = new SpecialObjectInfo();
  838. so.name = name;
  839. so.type = type;
  840. so.colorName = color;
  841. so.color = useColor;
  842. so.officialColor = useOfficialColor;
  843. if (!specialobjects.ContainsKey(type))
  844. specialobjects.Add(type, new List<SpecialObjectInfo>());
  845. specialobjects[type].Add(so);
  846. }
  847. }
  848. private void SetupItemNames()
  849. {
  850. itemNames.Add(0, "Unknown Item");
  851. foreach (KeyValuePair<String, ItemInfo> kvp in items)
  852. {
  853. if (itemNames.ContainsKey(kvp.Value.netId))
  854. {
  855. errorLog.AppendLine(String.Format("Item {0} had a duplicate netId: \"{1}\"",
  856. kvp.Value.name, kvp.Value.netId));
  857. }
  858. else
  859. {
  860. itemNames.Add(kvp.Value.netId, kvp.Value.name);
  861. }
  862. }
  863. }
  864. #endregion
  865. #region Save Functions
  866. private void SaveTiles(StreamWriter writer)
  867. {
  868. Dictionary<int, TileInfo> tiles = Global.Instance.Info.Tiles;
  869. TileInfo ti;
  870. String tileXML;
  871. writer.WriteLine(" <tiles>");
  872. for (int i = 0; i < tiles.Count; i++)
  873. {
  874. ti = tiles[i];
  875. // Bit of a hack but this needs to stay in until it's coded properly.
  876. if (ti.name == "Gold Cache")
  877. {
  878. writer.WriteLine();
  879. writer.WriteLine(" <!-- Tiles after this are a hack and not meant to be kept past testing -->");
  880. }
  881. tileXML = " <tile ";
  882. if (ti.name != null)
  883. tileXML = tileXML + "name=\"" + ti.name + "\" ";
  884. tileXML = tileXML + "tileImage=\"" + i + "\" ";
  885. if (ti.important)
  886. tileXML = tileXML + "important=\"true\" ";
  887. if (!String.IsNullOrEmpty(ti.colorName))
  888. tileXML = tileXML + "color=\"" + ti.colorName + "\" ";
  889. else
  890. tileXML = tileXML + String.Format("color=\"#{0:X2}{1:X2}{2:X2}\" ", ti.color.R, ti.color.G, ti.color.B);
  891. tileXML = tileXML + String.Format("officialColor=\"#{0:X2}{1:X2}{2:X2}\" ",
  892. ti.officialColor.R, ti.officialColor.G, ti.officialColor.B);
  893. if (!String.IsNullOrEmpty(ti.markerName))
  894. tileXML = tileXML + "marker=\"" + ti.markerName + "\" ";
  895. tileXML = tileXML + "/>";
  896. writer.WriteLine(tileXML);
  897. if (i % 10 == 9)
  898. writer.WriteLine();
  899. }
  900. writer.WriteLine(" </tiles>");
  901. }
  902. private void SaveWalls(StreamWriter writer)
  903. {
  904. Dictionary<int, WallInfo> walls = Global.Instance.Info.Walls;
  905. WallInfo wi;
  906. String wallXML;
  907. writer.WriteLine(" <walls>");
  908. for (int i = 1; i <= walls.Count; i++)
  909. {
  910. wi = walls[i];
  911. wallXML = " <wall ";
  912. if (wi.name != null)
  913. wallXML = wallXML + "name=\"" + wi.name + "\" ";
  914. wallXML = wallXML + "wallImage=\"" + i + "\" ";
  915. if (!String.IsNullOrEmpty(wi.colorName))
  916. wallXML = wallXML + "color=\"" + wi.colorName + "\" ";
  917. else
  918. wallXML = wallXML + String.Format("color=\"#{0:X2}{1:X2}{2:X2}\" ", wi.color.R, wi.color.G, wi.color.B);
  919. wallXML = wallXML + String.Format("officialColor=\"#{0:X2}{1:X2}{2:X2}\" ",
  920. wi.officialColor.R, wi.officialColor.G, wi.officialColor.B);
  921. if (wi.transparent)
  922. wallXML = wallXML + "transparent=\"true\" ";
  923. wallXML = wallXML + "/>";
  924. writer.WriteLine(wallXML);
  925. if (i % 10 == 9)
  926. writer.WriteLine();
  927. }
  928. writer.WriteLine(" </walls>");
  929. }
  930. private void SaveItems(StreamWriter writer)
  931. {
  932. SortedDictionary<String, ItemInfo> sorted = new SortedDictionary<string,ItemInfo>();
  933. String itemXML;
  934. String prevLetter = "";
  935. String curLetter;
  936. String numbers = "1234567890";
  937. foreach (KeyValuePair<String, ItemInfo> kvp in items)
  938. {
  939. sorted.Add(kvp.Key, kvp.Value);
  940. }
  941. writer.WriteLine(" <items>");
  942. foreach (KeyValuePair<String, ItemInfo> kvp in sorted)
  943. {
  944. curLetter = kvp.Value.name.Substring(0, 1);
  945. if (numbers.IndexOf(curLetter) == -1)
  946. {
  947. if (curLetter != prevLetter)
  948. {
  949. writer.WriteLine();
  950. prevLetter = curLetter;
  951. }
  952. }
  953. itemXML = String.Format(" <item name=\"{0}\" ", kvp.Value.name);
  954. if (!String.IsNullOrEmpty(kvp.Value.foundIn))
  955. itemXML = itemXML + String.Format("foundIn=\"{0}\" ", kvp.Value.foundIn);
  956. itemXML = itemXML + String.Format("itemImage=\"{0}\" ", kvp.Value.imageId);
  957. if (kvp.Value.netId != kvp.Value.imageId)
  958. itemXML = itemXML + String.Format("netId=\"{0}\" ", kvp.Value.netId);
  959. itemXML = itemXML + "/>";
  960. writer.WriteLine(itemXML);
  961. }
  962. writer.WriteLine(" </items>");
  963. }
  964. private void SaveRenames(StreamWriter writer)
  965. {
  966. writer.WriteLine(" <namechanges>");
  967. foreach (KeyValuePair<String, RenameInfo> kvp in renames)
  968. {
  969. writer.WriteLine(String.Format(" <item name=\"{0}\" newName=\"{1}\" />", kvp.Value.name, kvp.Value.newName));
  970. }
  971. writer.WriteLine(" </namechanges>");
  972. }
  973. private void SaveNPCs(StreamWriter writer)
  974. {
  975. writer.WriteLine(" <npcs>");
  976. foreach (KeyValuePair<String, NpcInfo> kvp in npcs)
  977. {
  978. writer.WriteLine(String.Format(" <npc name=\"{0}\" npcImage=\"{1}\" />", kvp.Value.name, kvp.Value.imageId));
  979. }
  980. writer.WriteLine(" </npcs>");
  981. }
  982. private void SaveColors(StreamWriter writer)
  983. {
  984. String colorXML;
  985. writer.WriteLine(" <colors>");
  986. foreach (KeyValuePair<String, ColorInfo> kvp in colors)
  987. {
  988. colorXML = String.Format(" <color name=\"{0}\" ", kvp.Value.name);
  989. colorXML = colorXML + String.Format("red=\"{0}\" green=\"{1}\" blue=\"{2}\" ",
  990. kvp.Value.color.R, kvp.Value.color.G, kvp.Value.color.B);
  991. colorXML = colorXML + "/>";
  992. writer.WriteLine(colorXML);
  993. }
  994. writer.WriteLine(" </colors>");
  995. }
  996. private void SaveMarkers(StreamWriter writer)
  997. {
  998. writer.WriteLine(" <markers>");
  999. foreach (KeyValuePair<String, List<MarkerInfo>> kvp in markerSets)
  1000. {
  1001. writer.WriteLine(" <markerset name=\"{0}\">", kvp.Key);
  1002. foreach (MarkerInfo mi in kvp.Value)
  1003. {
  1004. writer.WriteLine(String.Format(" <marker name=\"{0}\" />", mi.name));
  1005. }
  1006. writer.WriteLine(" </markerset>");
  1007. }
  1008. writer.WriteLine(" </markers>");
  1009. }
  1010. private void SaveSpecialObjects(StreamWriter writer)
  1011. {
  1012. String soXML;
  1013. Boolean skipNewline = true;
  1014. writer.WriteLine(" <specialobjects>");
  1015. foreach (KeyValuePair<String, List<SpecialObjectInfo>> kvp in specialobjects)
  1016. {
  1017. if (skipNewline == true)
  1018. skipNewline = false;
  1019. else
  1020. writer.WriteLine();
  1021. // I don't like hacking in the comments but neither do I like leaving them out.
  1022. if (kvp.Key == "Wire")
  1023. writer.WriteLine(" <!-- Wire does not have an official color so it's copied over -->");
  1024. else if (kvp.Key == "Background")
  1025. writer.WriteLine(" <!-- Backgrounds have to be last so they do not turn off the Lava & Water when Draw Walls is off.-->");
  1026. foreach (SpecialObjectInfo soi in kvp.Value)
  1027. {
  1028. soXML = String.Format(" <object name=\"{0}\" type=\"{1}\" ", soi.name, soi.type);
  1029. if (!String.IsNullOrEmpty(soi.colorName))
  1030. soXML = soXML + string.Format("color=\"{0}\" ", soi.colorName);
  1031. else
  1032. soXML = soXML + String.Format("color=\"#{0:X2}{1:X2}{2:X2}\" ",
  1033. soi.color.R, soi.color.G, soi.color.B);
  1034. soXML = soXML + String.Format("officialColor=\"#{0:X2}{1:X2}{2:X2}\" ",
  1035. soi.officialColor.R, soi.officialColor.G, soi.officialColor.B);
  1036. soXML = soXML + "/>";
  1037. writer.WriteLine(soXML);
  1038. }
  1039. }
  1040. writer.WriteLine(" </specialobjects>");
  1041. }
  1042. #endregion
  1043. public ItemInfo GetItem(String itemName)
  1044. {
  1045. if (!items.ContainsKey(itemName))
  1046. {
  1047. if (renames.ContainsKey(itemName))
  1048. {
  1049. String newName = renames[itemName].newName;
  1050. if (!items.ContainsKey(newName))
  1051. return null;
  1052. return items[newName];
  1053. }
  1054. else
  1055. {
  1056. return null;
  1057. }
  1058. }
  1059. return items[itemName];
  1060. }
  1061. public Dictionary<String, ItemInfo> Items
  1062. {
  1063. get
  1064. {
  1065. return items;
  1066. }
  1067. }
  1068. public Dictionary<Int32, TileInfo> Tiles
  1069. {
  1070. get
  1071. {
  1072. return tiles;
  1073. }
  1074. }
  1075. public Dictionary<Int32, WallInfo> Walls
  1076. {
  1077. get
  1078. {
  1079. return walls;
  1080. }
  1081. }
  1082. public Dictionary<String, List<MarkerInfo>> MarkerSets
  1083. {
  1084. get
  1085. {
  1086. return markerSets;
  1087. }
  1088. }
  1089. public Dictionary<Int32, MarkerInfo> Markers
  1090. {
  1091. get
  1092. {
  1093. return markers;
  1094. }
  1095. }
  1096. public Dictionary<String, List<SpecialObjectInfo>> SpecialObjects
  1097. {
  1098. get
  1099. {
  1100. return specialobjects;
  1101. }
  1102. }
  1103. public Dictionary<String, ColorInfo> Colors
  1104. {
  1105. get
  1106. {
  1107. return colors;
  1108. }
  1109. }
  1110. public String MarkerImageToName(String findName)
  1111. {
  1112. foreach (KeyValuePair<Int32, MarkerInfo> kvp in markers)
  1113. {
  1114. if (kvp.Value.markerImage == findName)
  1115. return kvp.Value.name;
  1116. }
  1117. return String.Empty;
  1118. }
  1119. public MarkerInfo GetMarkerByName(String markerName)
  1120. {
  1121. foreach (KeyValuePair<Int32, MarkerInfo> kvp in markers)
  1122. if (kvp.Value.name == markerName)
  1123. return kvp.Value;
  1124. return null;
  1125. }
  1126. public String GetItemName(Int32 netId)
  1127. {
  1128. if (itemNames.ContainsKey(netId))
  1129. return itemNames[netId];
  1130. return "Unknown Item";
  1131. }
  1132. public ItemEnum GetItemEnum(String itemName)
  1133. {
  1134. ItemInfo ii;
  1135. if (items.ContainsKey(itemName))
  1136. {
  1137. ii = items[itemName];
  1138. if (ii.foundIn == "Chest")
  1139. return ItemEnum.InChest;
  1140. return ItemEnum.Normal;
  1141. }
  1142. else
  1143. {
  1144. return ItemEnum.NotFound;
  1145. }
  1146. }
  1147. public void AddCustomColor(String colorName, Color newColor)
  1148. {
  1149. if (colors.ContainsKey(colorName))
  1150. return;
  1151. ColorInfo ci = new ColorInfo();
  1152. ci.name = colorName;
  1153. ci.color = newColor;
  1154. ci.isCustom = true;
  1155. colors.Add(colorName, ci);
  1156. }
  1157. public void RemoveCustomColor(String colorName)
  1158. {
  1159. if (!colors.ContainsKey(colorName))
  1160. return;
  1161. if (colors[colorName].isCustom == true)
  1162. colors.Remove(colorName);
  1163. }
  1164. public ColorInfo GetColor(String colorName)
  1165. {
  1166. if (colors.ContainsKey(colorName))
  1167. return colors[colorName];
  1168. return null;
  1169. }
  1170. }
  1171. #region Helper enumerations
  1172. public enum ItemEnum
  1173. {
  1174. NotFound = 0,
  1175. InChest,
  1176. Normal
  1177. }
  1178. #endregion
  1179. }