Map.cs 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849
  1. #region File Description
  2. //-----------------------------------------------------------------------------
  3. // Map.cs
  4. //
  5. // Microsoft XNA Community Game Platform
  6. // Copyright (C) Microsoft Corporation. All rights reserved.
  7. //-----------------------------------------------------------------------------
  8. #endregion
  9. #region Using Statements
  10. using System;
  11. using System.Collections.Generic;
  12. using Microsoft.Xna.Framework;
  13. using Microsoft.Xna.Framework.Graphics;
  14. using Microsoft.Xna.Framework.Content;
  15. #endregion
  16. namespace RolePlayingGameData
  17. {
  18. /// <summary>
  19. /// One section of the world, and all of the data in it.
  20. /// </summary>
  21. public class Map : ContentObject
  22. #if WINDOWS
  23. , ICloneable
  24. #endif
  25. {
  26. #region Description
  27. /// <summary>
  28. /// The name of this section of the world.
  29. /// </summary>
  30. private string name;
  31. /// <summary>
  32. /// The name of this section of the world.
  33. /// </summary>
  34. public string Name
  35. {
  36. get { return name; }
  37. set { name = value; }
  38. }
  39. #endregion
  40. #region Dimensions
  41. /// <summary>
  42. /// The dimensions of the map, in tiles.
  43. /// </summary>
  44. private Point mapDimensions;
  45. /// <summary>
  46. /// The dimensions of the map, in tiles.
  47. /// </summary>
  48. public Point MapDimensions
  49. {
  50. get { return mapDimensions; }
  51. set { mapDimensions = value; }
  52. }
  53. /// <summary>
  54. /// The size of the tiles in this map, in pixels.
  55. /// </summary>
  56. private Point tileSize;
  57. /// <summary>
  58. /// The size of the tiles in this map, in pixels.
  59. /// </summary>
  60. public Point TileSize
  61. {
  62. get { return tileSize; }
  63. set { tileSize = value; }
  64. }
  65. /// <summary>
  66. /// The number of tiles in a row of the map texture.
  67. /// </summary>
  68. /// <remarks>
  69. /// Used to determine the source rectangle from the map layer value.
  70. /// </remarks>
  71. private int tilesPerRow;
  72. /// <summary>
  73. /// The number of tiles in a row of the map texture.
  74. /// </summary>
  75. /// <remarks>
  76. /// Used to determine the source rectangle from the map layer value.
  77. /// </remarks>
  78. [ContentSerializerIgnore]
  79. public int TilesPerRow
  80. {
  81. get { return tilesPerRow; }
  82. }
  83. #endregion
  84. #region Spawning
  85. /// <summary>
  86. /// A valid spawn position for this map.
  87. /// </summary>
  88. private Point spawnMapPosition;
  89. /// <summary>
  90. /// A valid spawn position for this map.
  91. /// </summary>
  92. public Point SpawnMapPosition
  93. {
  94. get { return spawnMapPosition; }
  95. set { spawnMapPosition = value; }
  96. }
  97. #endregion
  98. #region Graphics Data
  99. /// <summary>
  100. /// The content name of the texture that contains the tiles for this map.
  101. /// </summary>
  102. private string textureName;
  103. /// <summary>
  104. /// The content name of the texture that contains the tiles for this map.
  105. /// </summary>
  106. public string TextureName
  107. {
  108. get { return textureName; }
  109. set { textureName = value; }
  110. }
  111. /// <summary>
  112. /// The texture that contains the tiles for this map.
  113. /// </summary>
  114. private Texture2D texture;
  115. /// <summary>
  116. /// The texture that contains the tiles for this map.
  117. /// </summary>
  118. [ContentSerializerIgnore]
  119. public Texture2D Texture
  120. {
  121. get { return texture; }
  122. }
  123. /// <summary>
  124. /// The content name of the texture that contains the background for combats
  125. /// that occur while traveling on this map.
  126. /// </summary>
  127. private string combatTextureName;
  128. /// <summary>
  129. /// The content name of the texture that contains the background for combats
  130. /// that occur while traveling on this map.
  131. /// </summary>
  132. public string CombatTextureName
  133. {
  134. get { return combatTextureName; }
  135. set { combatTextureName = value; }
  136. }
  137. /// <summary>
  138. /// The texture that contains the background for combats
  139. /// that occur while traveling on this map.
  140. /// </summary>
  141. private Texture2D combatTexture;
  142. /// <summary>
  143. /// The texture that contains the background for combats
  144. /// that occur while traveling on this map.
  145. /// </summary>
  146. [ContentSerializerIgnore]
  147. public Texture2D CombatTexture
  148. {
  149. get { return combatTexture; }
  150. }
  151. #endregion
  152. #region Music
  153. /// <summary>
  154. /// The name of the music cue for this map.
  155. /// </summary>
  156. private string musicCueName;
  157. /// <summary>
  158. /// The name of the music cue for this map.
  159. /// </summary>
  160. public string MusicCueName
  161. {
  162. get { return musicCueName; }
  163. set { musicCueName = value; }
  164. }
  165. /// <summary>
  166. /// The name of the music cue for combats that occur while traveling on this map.
  167. /// </summary>
  168. private string combatMusicCueName;
  169. /// <summary>
  170. /// The name of the music cue for combats that occur while traveling on this map.
  171. /// </summary>
  172. public string CombatMusicCueName
  173. {
  174. get { return combatMusicCueName; }
  175. set { combatMusicCueName = value; }
  176. }
  177. #endregion
  178. #region Map Layers
  179. #region Base Layer
  180. /// <summary>
  181. /// Spatial array for the ground tiles for this map.
  182. /// </summary>
  183. private int[] baseLayer;
  184. /// <summary>
  185. /// Spatial array for the ground tiles for this map.
  186. /// </summary>
  187. public int[] BaseLayer
  188. {
  189. get { return baseLayer; }
  190. set { baseLayer = value; }
  191. }
  192. /// <summary>
  193. /// Retrieves the base layer value for the given map position.
  194. /// </summary>
  195. public int GetBaseLayerValue(Point mapPosition)
  196. {
  197. // check the parameter
  198. if ((mapPosition.X < 0) || (mapPosition.X >= mapDimensions.X) ||
  199. (mapPosition.Y < 0) || (mapPosition.Y >= mapDimensions.Y))
  200. {
  201. throw new ArgumentOutOfRangeException("mapPosition");
  202. }
  203. return baseLayer[mapPosition.Y * mapDimensions.X + mapPosition.X];
  204. }
  205. /// <summary>
  206. /// Retrieves the source rectangle for the tile in the given position
  207. /// in the base layer.
  208. /// </summary>
  209. /// <remarks>This method allows out-of-bound (blocked) positions.</remarks>
  210. public Rectangle GetBaseLayerSourceRectangle(Point mapPosition)
  211. {
  212. // check the parameter, but out-of-bounds is nonfatal
  213. if ((mapPosition.X < 0) || (mapPosition.X >= mapDimensions.X) ||
  214. (mapPosition.Y < 0) || (mapPosition.Y >= mapDimensions.Y))
  215. {
  216. return Rectangle.Empty;
  217. }
  218. int baseLayerValue = GetBaseLayerValue(mapPosition);
  219. if (baseLayerValue < 0)
  220. {
  221. return Rectangle.Empty;
  222. }
  223. return new Rectangle(
  224. (baseLayerValue % tilesPerRow) * tileSize.X,
  225. (baseLayerValue / tilesPerRow) * tileSize.Y,
  226. tileSize.X, tileSize.Y);
  227. }
  228. #endregion
  229. #region Fringe Layer
  230. /// <summary>
  231. /// Spatial array for the fringe tiles for this map.
  232. /// </summary>
  233. private int[] fringeLayer;
  234. /// <summary>
  235. /// Spatial array for the fringe tiles for this map.
  236. /// </summary>
  237. public int[] FringeLayer
  238. {
  239. get { return fringeLayer; }
  240. set { fringeLayer = value; }
  241. }
  242. /// <summary>
  243. /// Retrieves the fringe layer value for the given map position.
  244. /// </summary>
  245. public int GetFringeLayerValue(Point mapPosition)
  246. {
  247. // check the parameter
  248. if ((mapPosition.X < 0) || (mapPosition.X >= mapDimensions.X) ||
  249. (mapPosition.Y < 0) || (mapPosition.Y >= mapDimensions.Y))
  250. {
  251. throw new ArgumentOutOfRangeException("mapPosition");
  252. }
  253. return fringeLayer[mapPosition.Y * mapDimensions.X + mapPosition.X];
  254. }
  255. /// <summary>
  256. /// Retrieves the source rectangle for the tile in the given position
  257. /// in the fringe layer.
  258. /// </summary>
  259. /// <remarks>This method allows out-of-bound (blocked) positions.</remarks>
  260. public Rectangle GetFringeLayerSourceRectangle(Point mapPosition)
  261. {
  262. // check the parameter, but out-of-bounds is nonfatal
  263. if ((mapPosition.X < 0) || (mapPosition.X >= mapDimensions.X) ||
  264. (mapPosition.Y < 0) || (mapPosition.Y >= mapDimensions.Y))
  265. {
  266. return Rectangle.Empty;
  267. }
  268. int fringeLayerValue = GetFringeLayerValue(mapPosition);
  269. if (fringeLayerValue < 0)
  270. {
  271. return Rectangle.Empty;
  272. }
  273. return new Rectangle(
  274. (fringeLayerValue % tilesPerRow) * tileSize.X,
  275. (fringeLayerValue / tilesPerRow) * tileSize.Y,
  276. tileSize.X, tileSize.Y);
  277. }
  278. #endregion
  279. #region Object Layer
  280. /// <summary>
  281. /// Spatial array for the object images on this map.
  282. /// </summary>
  283. private int[] objectLayer;
  284. /// <summary>
  285. /// Spatial array for the object images on this map.
  286. /// </summary>
  287. public int[] ObjectLayer
  288. {
  289. get { return objectLayer; }
  290. set { objectLayer = value; }
  291. }
  292. /// <summary>
  293. /// Retrieves the object layer value for the given map position.
  294. /// </summary>
  295. public int GetObjectLayerValue(Point mapPosition)
  296. {
  297. // check the parameter
  298. if ((mapPosition.X < 0) || (mapPosition.X >= mapDimensions.X) ||
  299. (mapPosition.Y < 0) || (mapPosition.Y >= mapDimensions.Y))
  300. {
  301. throw new ArgumentOutOfRangeException("mapPosition");
  302. }
  303. return objectLayer[mapPosition.Y * mapDimensions.X + mapPosition.X];
  304. }
  305. /// <summary>
  306. /// Retrieves the source rectangle for the tile in the given position
  307. /// in the object layer.
  308. /// </summary>
  309. /// <remarks>This method allows out-of-bound (blocked) positions.</remarks>
  310. public Rectangle GetObjectLayerSourceRectangle(Point mapPosition)
  311. {
  312. // check the parameter, but out-of-bounds is nonfatal
  313. if ((mapPosition.X < 0) || (mapPosition.X >= mapDimensions.X) ||
  314. (mapPosition.Y < 0) || (mapPosition.Y >= mapDimensions.Y))
  315. {
  316. return Rectangle.Empty;
  317. }
  318. int objectLayerValue = GetObjectLayerValue(mapPosition);
  319. if (objectLayerValue < 0)
  320. {
  321. return Rectangle.Empty;
  322. }
  323. return new Rectangle(
  324. (objectLayerValue % tilesPerRow) * tileSize.X,
  325. (objectLayerValue / tilesPerRow) * tileSize.Y,
  326. tileSize.X, tileSize.Y);
  327. }
  328. #endregion
  329. #region Collision Layer
  330. /// <summary>
  331. /// Spatial array for the collision properties of this map.
  332. /// </summary>
  333. private int[] collisionLayer;
  334. /// <summary>
  335. /// Spatial array for the collision properties of this map.
  336. /// </summary>
  337. public int[] CollisionLayer
  338. {
  339. get { return collisionLayer; }
  340. set { collisionLayer = value; }
  341. }
  342. /// <summary>
  343. /// Retrieves the collision layer value for the given map position.
  344. /// </summary>
  345. public int GetCollisionLayerValue(Point mapPosition)
  346. {
  347. // check the parameter
  348. if ((mapPosition.X < 0) || (mapPosition.X >= mapDimensions.X) ||
  349. (mapPosition.Y < 0) || (mapPosition.Y >= mapDimensions.Y))
  350. {
  351. throw new ArgumentOutOfRangeException("mapPosition");
  352. }
  353. return collisionLayer[mapPosition.Y * mapDimensions.X + mapPosition.X];
  354. }
  355. /// <summary>
  356. /// Returns true if the given map position is blocked.
  357. /// </summary>
  358. /// <remarks>This method allows out-of-bound (blocked) positions.</remarks>
  359. public bool IsBlocked(Point mapPosition)
  360. {
  361. // check the parameter, but out-of-bounds is nonfatal
  362. if ((mapPosition.X < 0) || (mapPosition.X >= mapDimensions.X) ||
  363. (mapPosition.Y < 0) || (mapPosition.Y >= mapDimensions.Y))
  364. {
  365. return true;
  366. }
  367. return (GetCollisionLayerValue(mapPosition) != 0);
  368. }
  369. #endregion
  370. #endregion
  371. #region Portals
  372. /// <summary>
  373. /// Portals to other maps.
  374. /// </summary>
  375. private List<Portal> portals = new List<Portal>();
  376. /// <summary>
  377. /// Portals to other maps.
  378. /// </summary>
  379. public List<Portal> Portals
  380. {
  381. get { return portals; }
  382. set { portals = value; }
  383. }
  384. #endregion
  385. #region Map Contents
  386. /// <summary>
  387. /// The content names and positions of the portals on this map.
  388. /// </summary>
  389. private List<MapEntry<Portal>> portalEntries =
  390. new List<MapEntry<Portal>>();
  391. /// <summary>
  392. /// The content names and positions of the portals on this map.
  393. /// </summary>
  394. public List<MapEntry<Portal>> PortalEntries
  395. {
  396. get { return portalEntries; }
  397. set { portalEntries = value; }
  398. }
  399. /// <summary>
  400. /// Find a portal on this map based on the given portal name.
  401. /// </summary>
  402. public MapEntry<Portal> FindPortal(string name)
  403. {
  404. // check the parameter
  405. if (String.IsNullOrEmpty(name))
  406. {
  407. throw new ArgumentNullException("name");
  408. }
  409. return portalEntries.Find(delegate(MapEntry<Portal> portalEntry)
  410. {
  411. return (portalEntry.ContentName == name);
  412. });
  413. }
  414. /// <summary>
  415. /// The content names and positions of the treasure chests on this map.
  416. /// </summary>
  417. private List<MapEntry<Chest>> chestEntries =
  418. new List<MapEntry<Chest>>();
  419. /// <summary>
  420. /// The content names and positions of the treasure chests on this map.
  421. /// </summary>
  422. public List<MapEntry<Chest>> ChestEntries
  423. {
  424. get { return chestEntries; }
  425. set { chestEntries = value; }
  426. }
  427. /// <summary>
  428. /// The content name, positions, and orientations of the
  429. /// fixed combat encounters on this map.
  430. /// </summary>
  431. private List<MapEntry<FixedCombat>> fixedCombatEntries =
  432. new List<MapEntry<FixedCombat>>();
  433. /// <summary>
  434. /// The content name, positions, and orientations of the
  435. /// fixed combat encounters on this map.
  436. /// </summary>
  437. public List<MapEntry<FixedCombat>> FixedCombatEntries
  438. {
  439. get { return fixedCombatEntries; }
  440. set { fixedCombatEntries = value; }
  441. }
  442. /// <summary>
  443. /// The random combat definition for this map.
  444. /// </summary>
  445. private RandomCombat randomCombat;
  446. /// <summary>
  447. /// The random combat definition for this map.
  448. /// </summary>
  449. public RandomCombat RandomCombat
  450. {
  451. get { return randomCombat; }
  452. set { randomCombat = value; }
  453. }
  454. /// <summary>
  455. /// The content names, positions, and orientations of quest Npcs on this map.
  456. /// </summary>
  457. private List<MapEntry<QuestNpc>> questNpcEntries =
  458. new List<MapEntry<QuestNpc>>();
  459. /// <summary>
  460. /// The content names, positions, and orientations of quest Npcs on this map.
  461. /// </summary>
  462. public List<MapEntry<QuestNpc>> QuestNpcEntries
  463. {
  464. get { return questNpcEntries; }
  465. set { questNpcEntries = value; }
  466. }
  467. /// <summary>
  468. /// The content names, positions, and orientations of player Npcs on this map.
  469. /// </summary>
  470. private List<MapEntry<Player>> playerNpcEntries =
  471. new List<MapEntry<Player>>();
  472. /// <summary>
  473. /// The content names, positions, and orientations of player Npcs on this map.
  474. /// </summary>
  475. public List<MapEntry<Player>> PlayerNpcEntries
  476. {
  477. get { return playerNpcEntries; }
  478. set { playerNpcEntries = value; }
  479. }
  480. /// <summary>
  481. /// The content names, positions, and orientations of the inns on this map.
  482. /// </summary>
  483. private List<MapEntry<Inn>> innEntries =
  484. new List<MapEntry<Inn>>();
  485. /// <summary>
  486. /// The content names, positions, and orientations of the inns on this map.
  487. /// </summary>
  488. public List<MapEntry<Inn>> InnEntries
  489. {
  490. get { return innEntries; }
  491. set { innEntries = value; }
  492. }
  493. /// <summary>
  494. /// The content names, positions, and orientations of the stores on this map.
  495. /// </summary>
  496. private List<MapEntry<Store>> storeEntries =
  497. new List<MapEntry<Store>>();
  498. /// <summary>
  499. /// The content names, positions, and orientations of the stores on this map.
  500. /// </summary>
  501. public List<MapEntry<Store>> StoreEntries
  502. {
  503. get { return storeEntries; }
  504. set { storeEntries = value; }
  505. }
  506. #endregion
  507. #region ICloneable Members
  508. public object Clone()
  509. {
  510. Map map = new Map();
  511. map.AssetName = AssetName;
  512. map.baseLayer = BaseLayer.Clone() as int[];
  513. foreach (MapEntry<Chest> chestEntry in chestEntries)
  514. {
  515. MapEntry<Chest> mapEntry = new MapEntry<Chest>();
  516. mapEntry.Content = chestEntry.Content.Clone() as Chest;
  517. mapEntry.ContentName = chestEntry.ContentName;
  518. mapEntry.Count = chestEntry.Count;
  519. mapEntry.Direction = chestEntry.Direction;
  520. mapEntry.MapPosition = chestEntry.MapPosition;
  521. map.chestEntries.Add(mapEntry);
  522. }
  523. map.chestEntries.AddRange(ChestEntries);
  524. map.collisionLayer = CollisionLayer.Clone() as int[];
  525. map.combatMusicCueName = CombatMusicCueName;
  526. map.combatTexture = CombatTexture;
  527. map.combatTextureName = CombatTextureName;
  528. map.fixedCombatEntries.AddRange(FixedCombatEntries);
  529. map.fringeLayer = FringeLayer.Clone() as int[];
  530. map.innEntries.AddRange(InnEntries);
  531. map.mapDimensions = MapDimensions;
  532. map.musicCueName = MusicCueName;
  533. map.name = Name;
  534. map.objectLayer = ObjectLayer.Clone() as int[];
  535. map.playerNpcEntries.AddRange(PlayerNpcEntries);
  536. map.portals.AddRange(Portals);
  537. map.portalEntries.AddRange(PortalEntries);
  538. map.questNpcEntries.AddRange(QuestNpcEntries);
  539. map.randomCombat = new RandomCombat();
  540. map.randomCombat.CombatProbability = RandomCombat.CombatProbability;
  541. map.randomCombat.Entries.AddRange(RandomCombat.Entries);
  542. map.randomCombat.FleeProbability = RandomCombat.FleeProbability;
  543. map.randomCombat.MonsterCountRange = RandomCombat.MonsterCountRange;
  544. map.spawnMapPosition = SpawnMapPosition;
  545. map.storeEntries.AddRange(StoreEntries);
  546. map.texture = Texture;
  547. map.textureName = TextureName;
  548. map.tileSize = TileSize;
  549. map.tilesPerRow = tilesPerRow;
  550. return map;
  551. }
  552. #endregion
  553. #region Content Type Reader
  554. /// <summary>
  555. /// Read a Map object from the content pipeline.
  556. /// </summary>
  557. public class MapReader : ContentTypeReader<Map>
  558. {
  559. protected override Map Read(ContentReader input, Map existingInstance)
  560. {
  561. Map map = existingInstance;
  562. if (map == null)
  563. {
  564. map = new Map();
  565. }
  566. map.AssetName = input.AssetName;
  567. map.Name = input.ReadString();
  568. map.MapDimensions = input.ReadObject<Point>();
  569. map.TileSize = input.ReadObject<Point>();
  570. map.SpawnMapPosition = input.ReadObject<Point>();
  571. map.TextureName = input.ReadString();
  572. map.texture = input.ContentManager.Load<Texture2D>(
  573. System.IO.Path.Combine(@"Textures\Maps\NonCombat",
  574. map.TextureName));
  575. map.tilesPerRow = map.texture.Width / map.TileSize.X;
  576. map.CombatTextureName = input.ReadString();
  577. map.combatTexture = input.ContentManager.Load<Texture2D>(
  578. System.IO.Path.Combine(@"Textures\Maps\Combat",
  579. map.CombatTextureName));
  580. map.MusicCueName = input.ReadString();
  581. map.CombatMusicCueName = input.ReadString();
  582. map.BaseLayer = input.ReadObject<int[]>();
  583. map.FringeLayer = input.ReadObject<int[]>();
  584. map.ObjectLayer = input.ReadObject<int[]>();
  585. map.CollisionLayer = input.ReadObject<int[]>();
  586. map.Portals.AddRange(input.ReadObject<List<Portal>>());
  587. map.PortalEntries.AddRange(
  588. input.ReadObject<List<MapEntry<Portal>>>());
  589. foreach (MapEntry<Portal> portalEntry in map.PortalEntries)
  590. {
  591. portalEntry.Content = map.Portals.Find(delegate(Portal portal)
  592. {
  593. return (portal.Name == portalEntry.ContentName);
  594. });
  595. }
  596. map.ChestEntries.AddRange(
  597. input.ReadObject<List<MapEntry<Chest>>>());
  598. foreach (MapEntry<Chest> chestEntry in map.chestEntries)
  599. {
  600. chestEntry.Content = input.ContentManager.Load<Chest>(
  601. System.IO.Path.Combine(@"Maps\Chests",
  602. chestEntry.ContentName)).Clone() as Chest;
  603. }
  604. // load the fixed combat entries
  605. Random random = new Random();
  606. map.FixedCombatEntries.AddRange(
  607. input.ReadObject<List<MapEntry<FixedCombat>>>());
  608. foreach (MapEntry<FixedCombat> fixedCombatEntry in
  609. map.fixedCombatEntries)
  610. {
  611. fixedCombatEntry.Content =
  612. input.ContentManager.Load<FixedCombat>(
  613. System.IO.Path.Combine(@"Maps\FixedCombats",
  614. fixedCombatEntry.ContentName));
  615. // clone the map sprite in the entry, as there may be many entries
  616. // per FixedCombat
  617. fixedCombatEntry.MapSprite =
  618. fixedCombatEntry.Content.Entries[0].Content.MapSprite.Clone()
  619. as AnimatingSprite;
  620. // play the idle animation
  621. fixedCombatEntry.MapSprite.PlayAnimation("Idle",
  622. fixedCombatEntry.Direction);
  623. // advance in a random amount so the animations aren't synchronized
  624. fixedCombatEntry.MapSprite.UpdateAnimation(
  625. 4f * (float)random.NextDouble());
  626. }
  627. map.RandomCombat = input.ReadObject<RandomCombat>();
  628. map.QuestNpcEntries.AddRange(
  629. input.ReadObject<List<MapEntry<QuestNpc>>>());
  630. foreach (MapEntry<QuestNpc> questNpcEntry in
  631. map.questNpcEntries)
  632. {
  633. questNpcEntry.Content = input.ContentManager.Load<QuestNpc>(
  634. System.IO.Path.Combine(@"Characters\QuestNpcs",
  635. questNpcEntry.ContentName));
  636. questNpcEntry.Content.MapPosition = questNpcEntry.MapPosition;
  637. questNpcEntry.Content.Direction = questNpcEntry.Direction;
  638. }
  639. map.PlayerNpcEntries.AddRange(
  640. input.ReadObject<List<MapEntry<Player>>>());
  641. foreach (MapEntry<Player> playerNpcEntry in
  642. map.playerNpcEntries)
  643. {
  644. playerNpcEntry.Content = input.ContentManager.Load<Player>(
  645. System.IO.Path.Combine(@"Characters\Players",
  646. playerNpcEntry.ContentName)).Clone() as Player;
  647. playerNpcEntry.Content.MapPosition = playerNpcEntry.MapPosition;
  648. playerNpcEntry.Content.Direction = playerNpcEntry.Direction;
  649. }
  650. map.InnEntries.AddRange(
  651. input.ReadObject<List<MapEntry<Inn>>>());
  652. foreach (MapEntry<Inn> innEntry in
  653. map.innEntries)
  654. {
  655. innEntry.Content = input.ContentManager.Load<Inn>(
  656. System.IO.Path.Combine(@"Maps\Inns",
  657. innEntry.ContentName));
  658. }
  659. map.StoreEntries.AddRange(
  660. input.ReadObject<List<MapEntry<Store>>>());
  661. foreach (MapEntry<Store> storeEntry in
  662. map.storeEntries)
  663. {
  664. storeEntry.Content = input.ContentManager.Load<Store>(
  665. System.IO.Path.Combine(@"Maps\Stores",
  666. storeEntry.ContentName));
  667. }
  668. return map;
  669. }
  670. }
  671. #endregion
  672. }
  673. }