Chest.cs 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. //-----------------------------------------------------------------------------
  2. // Chest.cs
  3. //
  4. // Microsoft XNA Community Game Platform
  5. // Copyright (C) Microsoft Corporation. All rights reserved.
  6. //-----------------------------------------------------------------------------
  7. using Microsoft.Xna.Framework.Content;
  8. using Microsoft.Xna.Framework.Graphics;
  9. using System;
  10. using System.Collections.Generic;
  11. using System.IO;
  12. using System.Linq;
  13. using System.Xml.Linq;
  14. namespace RolePlaying.Data
  15. {
  16. /// <summary>
  17. /// A treasure chest in the game world.
  18. /// </summary>
  19. public class Chest : WorldObject
  20. #if WINDOWS
  21. , ICloneable
  22. #endif
  23. {
  24. /// <summary>
  25. /// The amount of gold in the chest.
  26. /// </summary>
  27. private int gold = 0;
  28. /// <summary>
  29. /// The amount of gold in the chest.
  30. /// </summary>
  31. [ContentSerializer(Optional = true)]
  32. public int Gold
  33. {
  34. get { return gold; }
  35. set { gold = value; }
  36. }
  37. /// <summary>
  38. /// The gear in the chest, along with quantities.
  39. /// </summary>
  40. private List<ContentEntry<Gear>> entries = new List<ContentEntry<Gear>>();
  41. /// <summary>
  42. /// The gear in the chest, along with quantities.
  43. /// </summary>
  44. public List<ContentEntry<Gear>> Entries
  45. {
  46. get { return entries; }
  47. set { entries = value; }
  48. }
  49. /// <summary>
  50. /// Array accessor for the chest's contents.
  51. /// </summary>
  52. public ContentEntry<Gear> this[int index]
  53. {
  54. get { return entries[index]; }
  55. }
  56. /// <summary>
  57. /// Returns true if the chest is empty.
  58. /// </summary>
  59. public bool IsEmpty
  60. {
  61. get { return ((gold <= 0) && (entries.Count <= 0)); }
  62. }
  63. /// <summary>
  64. /// The content name of the texture for this chest.
  65. /// </summary>
  66. private string textureName;
  67. /// <summary>
  68. /// The content name of the texture for this chest.
  69. /// </summary>
  70. public string TextureName
  71. {
  72. get { return textureName; }
  73. set { textureName = value; }
  74. }
  75. /// <summary>
  76. /// The texture for this chest.
  77. /// </summary>
  78. private Texture2D texture;
  79. /// <summary>
  80. /// The texture for this chest.
  81. /// </summary>
  82. [ContentSerializerIgnore]
  83. public Texture2D Texture
  84. {
  85. get { return texture; }
  86. set { texture = value; }
  87. }
  88. /// <summary>
  89. /// Reads a Chest object from the content pipeline.
  90. /// </summary>
  91. public class ChestReader : ContentTypeReader<Chest>
  92. {
  93. protected override Chest Read(ContentReader input,
  94. Chest existingInstance)
  95. {
  96. Chest chest = existingInstance;
  97. if (chest == null)
  98. {
  99. chest = new Chest();
  100. }
  101. input.ReadRawObject<WorldObject>(chest as WorldObject);
  102. chest.Gold = input.ReadInt32();
  103. chest.Entries.AddRange(
  104. input.ReadObject<List<ContentEntry<Gear>>>());
  105. foreach (ContentEntry<Gear> contentEntry in chest.Entries)
  106. {
  107. contentEntry.Content = input.ContentManager.Load<Gear>(Path.Combine("Gear", contentEntry.ContentName));
  108. }
  109. chest.TextureName = input.ReadString();
  110. chest.Texture = input.ContentManager.Load<Texture2D>(Path.Combine("Textures", "Chests", chest.TextureName));
  111. return chest;
  112. }
  113. }
  114. /// <summary>
  115. /// Clone implementation for chest copies.
  116. /// </summary>
  117. /// <remarks>
  118. /// The game has to handle chests that have had some contents removed
  119. /// without modifying the original chest (and all chests that come after).
  120. /// </remarks>
  121. public object Clone()
  122. {
  123. // create the new chest
  124. Chest chest = new Chest();
  125. // copy the data
  126. chest.Gold = Gold;
  127. chest.Name = Name;
  128. chest.Texture = Texture;
  129. chest.TextureName = TextureName;
  130. // recreate the list and entries, as counts may have changed
  131. chest.entries = new List<ContentEntry<Gear>>();
  132. foreach (ContentEntry<Gear> originalEntry in Entries)
  133. {
  134. ContentEntry<Gear> newEntry = new ContentEntry<Gear>();
  135. newEntry.Count = originalEntry.Count;
  136. newEntry.ContentName = originalEntry.ContentName;
  137. newEntry.Content = originalEntry.Content;
  138. chest.Entries.Add(newEntry);
  139. }
  140. return chest;
  141. }
  142. internal static Chest Load(XElement chestAsset, ContentManager contentManager)
  143. {
  144. var chest = new Chest
  145. {
  146. Name = (string)chestAsset.Element("Name"),
  147. Gold = (int)chestAsset.Element("Gold"),
  148. Entries = chestAsset.Element("Entries")?.Elements("Item").Select(chestItem =>
  149. {
  150. var contentName = (string)chestItem.Element("ContentName");
  151. var gearAsset = XmlHelper.GetAssetElementFromXML(Path.Combine("Gear", contentName));
  152. var gear = new Equipment
  153. {
  154. AssetName = contentName,
  155. Name = (string)gearAsset.Element("Name"),
  156. Description = (string)gearAsset.Element("Description"),
  157. GoldValue = (int?)gearAsset.Element("GoldValue") ?? 0,
  158. IconTextureName = (string)gearAsset.Element("IconTextureName"),
  159. IconTexture = contentManager.Load<Texture2D>(Path.Combine("Textures", "Gear", (string)gearAsset.Element("IconTextureName"))),
  160. IsDroppable = (bool?)gearAsset.Element("IsDroppable") ?? true,
  161. // Add other properties as needed
  162. };
  163. return new ContentEntry<Gear>
  164. {
  165. ContentName = contentName,
  166. Content = gear,
  167. Count = (int?)chestItem.Element("Count") ?? 1,
  168. };
  169. }).ToList(),
  170. TextureName = (string)chestAsset.Element("TextureName"),
  171. Texture = contentManager.Load<Texture2D>(Path.Combine("Textures", "Chests", (string)chestAsset.Element("TextureName"))),
  172. };
  173. return chest;
  174. }
  175. }
  176. }