CharacterClass.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313
  1. //-----------------------------------------------------------------------------
  2. // CharacterClass.cs
  3. //
  4. // Microsoft XNA Community Game Platform
  5. // Copyright (C) Microsoft Corporation. All rights reserved.
  6. //-----------------------------------------------------------------------------
  7. using System;
  8. using System.Collections.Generic;
  9. using System.Linq;
  10. using Microsoft.Xna.Framework.Content;
  11. namespace RolePlaying.Data
  12. {
  13. /// <summary>
  14. /// The definition of a type of character.
  15. /// </summary>
  16. public class CharacterClass : ContentObject
  17. {
  18. /// <summary>
  19. /// The name of the character class.
  20. /// </summary>
  21. private string name;
  22. /// <summary>
  23. /// The name of the character class.
  24. /// </summary>
  25. public string Name
  26. {
  27. get { return name; }
  28. set { name = value; }
  29. }
  30. /// <summary>
  31. /// The initial statistics of characters that use this class.
  32. /// </summary>
  33. private StatisticsValue initialStatistics = new StatisticsValue();
  34. /// <summary>
  35. /// The initial statistics of characters that use this class.
  36. /// </summary>
  37. public StatisticsValue InitialStatistics
  38. {
  39. get { return initialStatistics; }
  40. set { initialStatistics = value; }
  41. }
  42. /// <summary>
  43. /// Statistics changes for leveling up characters that use this class.
  44. /// </summary>
  45. private CharacterLevelingStatistics levelingStatistics;
  46. /// <summary>
  47. /// Statistics changes for leveling up characters that use this class.
  48. /// </summary>
  49. public CharacterLevelingStatistics LevelingStatistics
  50. {
  51. get { return levelingStatistics; }
  52. set { levelingStatistics = value; }
  53. }
  54. /// <summary>
  55. /// Entries of the requirements and rewards for each level of this class.
  56. /// </summary>
  57. private List<CharacterLevelDescription> levelEntries =
  58. new List<CharacterLevelDescription>();
  59. /// <summary>
  60. /// Entries of the requirements and rewards for each level of this class.
  61. /// </summary>
  62. public List<CharacterLevelDescription> LevelEntries
  63. {
  64. get { return levelEntries; }
  65. set { levelEntries = value; }
  66. }
  67. /// <summary>
  68. /// Calculate the statistics of a character of this class and the given level.
  69. /// </summary>
  70. public StatisticsValue GetStatisticsForLevel(int characterLevel)
  71. {
  72. // check the parameter
  73. if (characterLevel <= 0)
  74. {
  75. throw new ArgumentOutOfRangeException("characterLevel");
  76. }
  77. // start with the initial statistics
  78. StatisticsValue output = initialStatistics;
  79. // add each level of leveling statistics
  80. for (int i = 1; i < characterLevel; i++)
  81. {
  82. if ((levelingStatistics.LevelsPerHealthPointsIncrease > 0) &&
  83. ((i % levelingStatistics.LevelsPerHealthPointsIncrease) == 0))
  84. {
  85. output.HealthPoints += levelingStatistics.HealthPointsIncrease;
  86. }
  87. if ((levelingStatistics.LevelsPerMagicPointsIncrease > 0) &&
  88. ((i % levelingStatistics.LevelsPerMagicPointsIncrease) == 0))
  89. {
  90. output.MagicPoints += levelingStatistics.MagicPointsIncrease;
  91. }
  92. if ((levelingStatistics.LevelsPerPhysicalOffenseIncrease > 0) &&
  93. ((i % levelingStatistics.LevelsPerPhysicalOffenseIncrease) == 0))
  94. {
  95. output.PhysicalOffense += levelingStatistics.PhysicalOffenseIncrease;
  96. }
  97. if ((levelingStatistics.LevelsPerPhysicalDefenseIncrease > 0) &&
  98. ((i % levelingStatistics.LevelsPerPhysicalDefenseIncrease) == 0))
  99. {
  100. output.PhysicalDefense += levelingStatistics.PhysicalDefenseIncrease;
  101. }
  102. if ((levelingStatistics.LevelsPerMagicalOffenseIncrease > 0) &&
  103. ((i % levelingStatistics.LevelsPerMagicalOffenseIncrease) == 0))
  104. {
  105. output.MagicalOffense += levelingStatistics.MagicalOffenseIncrease;
  106. }
  107. if ((levelingStatistics.LevelsPerMagicalDefenseIncrease > 0) &&
  108. ((i % levelingStatistics.LevelsPerMagicalDefenseIncrease) == 0))
  109. {
  110. output.MagicalDefense += levelingStatistics.MagicalDefenseIncrease;
  111. }
  112. }
  113. return output;
  114. }
  115. /// <summary>
  116. /// Build a list of all spells available to a character
  117. /// of this class and the given level.
  118. /// </summary>
  119. public List<Spell> GetAllSpellsForLevel(int characterLevel)
  120. {
  121. // check the parameter
  122. if (characterLevel <= 0)
  123. {
  124. throw new ArgumentOutOfRangeException("characterLevel");
  125. }
  126. // go through each level and add the spells to the output list
  127. List<Spell> spells = new List<Spell>();
  128. for (int i = 0; i < characterLevel; i++)
  129. {
  130. if (i >= levelEntries.Count)
  131. {
  132. break;
  133. }
  134. // add new spells, and level up existing ones
  135. foreach (Spell spell in levelEntries[i].Spells)
  136. {
  137. Spell existingSpell = spells.Find(
  138. delegate (Spell testSpell)
  139. {
  140. return spell.AssetName == testSpell.AssetName;
  141. });
  142. if (existingSpell == null)
  143. {
  144. spells.Add(spell.Clone() as Spell);
  145. }
  146. else
  147. {
  148. existingSpell.Level++;
  149. }
  150. }
  151. }
  152. return spells;
  153. }
  154. internal static CharacterClass Load(string path)
  155. {
  156. var asset = XmlHelper.GetAssetElementFromXML(path);
  157. var characterClass = new CharacterClass
  158. {
  159. Name = (string)asset.Element("Name"),
  160. InitialStatistics = new StatisticsValue
  161. {
  162. HealthPoints = (int?)asset.Element("InitialStatistics").Element("HealthPoints") ?? 0,
  163. MagicPoints = (int?)asset.Element("InitialStatistics").Element("MagicPoints") ?? 0,
  164. PhysicalOffense = (int?)asset.Element("InitialStatistics").Element("PhysicalOffense") ?? 0,
  165. PhysicalDefense = (int?)asset.Element("InitialStatistics").Element("PhysicalDefense") ?? 0,
  166. MagicalOffense = (int?)asset.Element("InitialStatistics").Element("MagicalOffense") ?? 0,
  167. MagicalDefense = (int?)asset.Element("InitialStatistics").Element("MagicalDefense") ?? 0,
  168. },
  169. LevelingStatistics = new CharacterLevelingStatistics
  170. {
  171. HealthPointsIncrease = (int?)asset.Element("LevelingStatistics").Element("HealthPointsIncrease") ?? 0,
  172. LevelsPerHealthPointsIncrease = (int?)asset.Element("LevelingStatistics").Element("LevelsPerHealthPointsIncrease") ?? 0,
  173. MagicPointsIncrease = (int?)asset.Element("LevelingStatistics").Element("MagicPointsIncrease") ?? 0,
  174. LevelsPerMagicPointsIncrease = (int?)asset.Element("LevelingStatistics").Element("LevelsPerMagicPointsIncrease") ?? 0,
  175. PhysicalOffenseIncrease = (int?)asset.Element("LevelingStatistics").Element("PhysicalOffenseIncrease") ?? 0,
  176. LevelsPerPhysicalOffenseIncrease = (int?)asset.Element("LevelingStatistics").Element("LevelsPerPhysicalOffenseIncrease") ?? 0,
  177. PhysicalDefenseIncrease = (int?)asset.Element("LevelingStatistics").Element("PhysicalDefenseIncrease") ?? 0,
  178. LevelsPerPhysicalDefenseIncrease = (int?)asset.Element("LevelingStatistics").Element("LevelsPerPhysicalDefenseIncrease") ?? 0,
  179. MagicalOffenseIncrease = (int?)asset.Element("LevelingStatistics").Element("MagicalOffenseIncrease") ?? 0,
  180. LevelsPerMagicalOffenseIncrease = (int?)asset.Element("LevelingStatistics").Element("LevelsPerMagicalOffenseIncrease") ?? 0,
  181. MagicalDefenseIncrease = (int?)asset.Element("LevelingStatistics").Element("MagicalDefenseIncrease") ?? 0,
  182. LevelsPerMagicalDefenseIncrease = (int?)asset.Element("LevelingStatistics").Element("LevelsPerMagicalDefenseIncrease") ?? 0,
  183. },
  184. LevelEntries = asset.Element("LevelEntries")
  185. .Elements("Item")
  186. .Select(item => new CharacterLevelDescription
  187. {
  188. ExperiencePoints = (int?)item.Element("ExperiencePoints") ?? 0,
  189. SpellContentNames = item.Element("SpellContentNames")?
  190. .Elements("Item")
  191. .Select(x => (string)x)
  192. .ToList() ?? new List<string>()
  193. })
  194. .ToList(),
  195. BaseExperienceValue = (int?)asset.Element("BaseExperienceValue") ?? 0,
  196. BaseGoldValue = (int?)asset.Element("BaseGoldValue") ?? 0
  197. };
  198. return characterClass;
  199. }
  200. /// <summary>
  201. /// The base experience value of Npcs of this character class.
  202. /// </summary>
  203. /// <remarks>Used for calculating combat rewards.</remarks>
  204. private int baseExperienceValue;
  205. /// <summary>
  206. /// The base experience value of Npcs of this character class.
  207. /// </summary>
  208. /// <remarks>Used for calculating combat rewards.</remarks>
  209. public int BaseExperienceValue
  210. {
  211. get { return baseExperienceValue; }
  212. set { baseExperienceValue = value; }
  213. }
  214. /// <summary>
  215. /// The base gold value of Npcs of this character class.
  216. /// </summary>
  217. /// <remarks>Used for calculating combat rewards.</remarks>
  218. private int baseGoldValue;
  219. /// <summary>
  220. /// The base gold value of Npcs of this character class.
  221. /// </summary>
  222. /// <remarks>Used for calculating combat rewards.</remarks>
  223. public int BaseGoldValue
  224. {
  225. get { return baseGoldValue; }
  226. set { baseGoldValue = value; }
  227. }
  228. /// <summary>
  229. /// Reads a CharacterClass object from the content pipeline.
  230. /// </summary>
  231. public class CharacterClassReader : ContentTypeReader<CharacterClass>
  232. {
  233. /// <summary>
  234. /// Reads a CharacterClass object from the content pipeline.
  235. /// </summary>
  236. protected override CharacterClass Read(ContentReader input,
  237. CharacterClass existingInstance)
  238. {
  239. CharacterClass characterClass = existingInstance;
  240. if (characterClass == null)
  241. {
  242. characterClass = new CharacterClass();
  243. }
  244. characterClass.AssetName = input.AssetName;
  245. characterClass.Name = input.ReadString();
  246. characterClass.InitialStatistics =
  247. input.ReadObject<StatisticsValue>();
  248. characterClass.LevelingStatistics =
  249. input.ReadObject<CharacterLevelingStatistics>();
  250. characterClass.LevelEntries.AddRange(
  251. input.ReadObject<List<CharacterLevelDescription>>());
  252. characterClass.BaseExperienceValue = input.ReadInt32();
  253. characterClass.BaseGoldValue = input.ReadInt32();
  254. return characterClass;
  255. }
  256. }
  257. }
  258. }