2
0
Эх сурвалжийг харах

RPG - Fix Audio, Standardise to Path.Combine(...), Load questlines fully.

CartBlanche 1 сар өмнө
parent
commit
894ebff9ba

+ 8 - 46
RolePlayingGame/Core/AudioManager.cs

@@ -21,18 +21,11 @@ namespace RolePlaying
     /// </remarks>
     public class AudioManager : GameComponent
     {
-
-
         /// <summary>
         /// The singleton for this type.
         /// </summary>
         private static AudioManager audioManager = null;
 
-
-
-
-
-
         /// <summary>
         /// The audio engine used to play all cues.
         /// </summary>
@@ -48,11 +41,6 @@ namespace RolePlaying
         /// </summary>
         private WaveBank waveBank;
 
-
-
-
-
-
         /// <summary>
         /// Constructs the manager for audio playback of all cues.
         /// </summary>
@@ -64,13 +52,13 @@ namespace RolePlaying
             string soundBankFile)
             : base(game)
         {
-            /*TODO: try
+            try
             {
                 audioEngine = new AudioEngine(settingsFile);
                 waveBank = new WaveBank(audioEngine, waveBankFile);
                 soundBank = new SoundBank(audioEngine, soundBankFile);
             }
-            catch (NoAudioHardwareException)*/
+            catch (NoAudioHardwareException)
             {
                 // silently fall back to silence
                 audioEngine = null;
@@ -79,7 +67,6 @@ namespace RolePlaying
             }
         }
 
-
         /// <summary>
         /// Initialize the static AudioManager functionality.
         /// </summary>
@@ -87,22 +74,20 @@ namespace RolePlaying
         /// <param name="settingsFile">The filename of the XACT settings file.</param>
         /// <param name="waveBankFile">The filename of the XACT wavebank file.</param>
         /// <param name="soundBankFile">The filename of the XACT soundbank file.</param>
-        public static void Initialize(Game game, string settingsFile, 
+        public static void Initialize(Game game, string settingsFile,
             string waveBankFile, string soundBankFile)
         {
-            audioManager = new AudioManager(game, settingsFile, waveBankFile,
+            audioManager = new AudioManager(game,
+                settingsFile,
+                waveBankFile,
                 soundBankFile);
+
             if (game != null)
             {
                 game.Components.Add(audioManager);
             }
         }
 
-
-
-
-
-
         /// <summary>
         /// Retrieve a cue by name.
         /// </summary>
@@ -119,7 +104,6 @@ namespace RolePlaying
             return audioManager.soundBank.GetCue(cueName);
         }
 
-
         /// <summary>
         /// Plays a cue by name.
         /// </summary>
@@ -133,23 +117,16 @@ namespace RolePlaying
             }
         }
 
-
-
-
-
-
         /// <summary>
         /// The cue for the music currently playing, if any.
         /// </summary>
         private Cue musicCue;
 
-
         /// <summary>
         /// Stack of music cue names, for layered music playback.
         /// </summary>
         private Stack<string> musicCueNameStack = new Stack<string>();
 
-
         /// <summary>
         /// Plays the desired music, clearing the stack of music cues.
         /// </summary>
@@ -164,7 +141,6 @@ namespace RolePlaying
             }
         }
 
-
         /// <summary>
         /// Plays the music for this game, adding it to the music stack.
         /// </summary>
@@ -194,7 +170,6 @@ namespace RolePlaying
             }
         }
 
-
         /// <summary>
         /// Stops the current music and plays the previous music on the stack.
         /// </summary>
@@ -234,7 +209,6 @@ namespace RolePlaying
             }
         }
 
-
         /// <summary>
         /// Stop music playback, clearing the cue.
         /// </summary>
@@ -252,11 +226,6 @@ namespace RolePlaying
             }
         }
 
-
-
-
-
-
         /// <summary>
         /// Update the audio manager, particularly the engine.
         /// </summary>
@@ -277,11 +246,6 @@ namespace RolePlaying
             base.Update(gameTime);
         }
 
-
-
-
-
-
         /// <summary>
         /// Clean up the component when it is disposing.
         /// </summary>
@@ -314,7 +278,5 @@ namespace RolePlaying
                 base.Dispose(disposing);
             }
         }
-
-
     }
-}
+}

+ 1 - 1
RolePlayingGame/Core/Combat/CombatEngine.cs

@@ -1594,7 +1594,7 @@ namespace RolePlaying
                     foreach (string gearRewardName in gearRewardNames)
                     {
                         gearRewards.Add(Session.ScreenManager.Game.Content.Load<Gear>(
-                            Path.Combine(@"Gear", gearRewardName)));
+                            Path.Combine("Gear", gearRewardName)));
                     }
                     // add the reward screen
                     Session.ScreenManager.AddScreen(new RewardsScreen(

+ 3 - 36
RolePlayingGame/Core/GameScreens/QuestDetailsScreen.cs

@@ -21,9 +21,6 @@ namespace RolePlaying
     {
         private Quest quest;
 
-
-
-
         private Texture2D backgroundTexture;
         private Texture2D backIconTexture;
         private Texture2D scrollTexture;
@@ -44,11 +41,6 @@ namespace RolePlaying
         private Color headerColor = new Color(128, 6, 6);
         private Color textColor = new Color(102, 40, 16);
 
-
-
-
-
-
         private string titleString = "Quest Details";
         private List<Line> currentDialogue;
 
@@ -56,11 +48,6 @@ namespace RolePlaying
         private int endIndex;
         private int maxLines;
 
-
-
-
-
-
         /// <summary>
         /// Creates a new QuestDetailsScreen object.
         /// </summary>
@@ -85,7 +72,6 @@ namespace RolePlaying
                 Fonts.DescriptionFont, 715), GetRequirements(this.quest));
         }
 
-
         /// <summary>
         /// Loads the graphics content from the content manager.
         /// </summary>
@@ -128,11 +114,6 @@ namespace RolePlaying
             bottomLinePosition = new Vector2(topLinePosition.X, 550f);
         }
 
-
-
-
-
-
         /// <summary>
         /// A line of text with its own color and font.
         /// </summary>
@@ -143,7 +124,6 @@ namespace RolePlaying
             public SpriteFont font;
         }
 
-
         /// <summary>
         /// Add strings to list of lines
         /// </summary>
@@ -196,7 +176,6 @@ namespace RolePlaying
             }
         }
 
-
         /// <summary>
         /// Get the quest requirements
         /// </summary>
@@ -228,7 +207,7 @@ namespace RolePlaying
                     currentCount = quest.MonsterRequirements[i].CompletedCount;
                     totalCount = quest.MonsterRequirements[i].Count;
                     Monster monster = quest.MonsterRequirements[i].Content;
-                    reqd.text = monster.Name + " = " + currentCount + " / " + 
+                    reqd.text = monster.Name + " = " + currentCount + " / " +
                         totalCount;
 
                     if (currentCount == totalCount)
@@ -304,11 +283,6 @@ namespace RolePlaying
             return reqdList;
         }
 
-
-
-
-
-
         /// <summary>
         /// Handles user input.
         /// </summary>
@@ -341,11 +315,6 @@ namespace RolePlaying
             }
         }
 
-
-
-
-
-
         /// <summary>
         /// Draw the screen
         /// </summary>
@@ -388,14 +357,12 @@ namespace RolePlaying
                     currentDialogue[i].text).X) / 2) - 20;
 
                 spriteBatch.DrawString(currentDialogue[i].font,
-                    currentDialogue[i].text, dialoguePosition, 
+                    currentDialogue[i].text, dialoguePosition,
                     currentDialogue[i].color);
                 dialoguePosition.Y += currentDialogue[i].font.LineSpacing;
             }
 
             spriteBatch.End();
         }
-
-
     }
-}
+}

+ 5 - 2
RolePlayingGame/Core/RolePlayingGame.cs

@@ -5,6 +5,7 @@
 // Copyright (C) Microsoft Corporation. All rights reserved.
 //-----------------------------------------------------------------------------
 
+using System.IO;
 using Microsoft.Xna.Framework;
 using Microsoft.Xna.Framework.Audio;
 using Microsoft.Xna.Framework.Content;
@@ -44,8 +45,10 @@ namespace RolePlaying
             // Components.Add(new GamerServicesComponent(this));
 
             // add the audio manager
-            AudioManager.Initialize(this, @"Content\Audio\RpgAudio.xgs",
-                @"Content\Audio\Wave Bank.xwb", @"Content\Audio\Sound Bank.xsb");
+            AudioManager.Initialize(this,
+                Path.Combine("Content", "Audio", "RpgAudio.xgs"),
+                Path.Combine("Content", "Audio", "Wave Bank.xwb"),
+                Path.Combine("Content", "Audio", "Sound Bank.xsb"));
 
             // add the screen manager
             screenManager = new ScreenManager(this);

+ 4 - 4
RolePlayingGame/Core/Session/Party.cs

@@ -164,7 +164,7 @@ namespace RolePlaying
             newEntry.Content = gear;
             newEntry.Count = count;
             newEntry.ContentName = gear.AssetName;
-            if (newEntry.ContentName.StartsWith(@"Gear\"))
+            if (newEntry.ContentName.StartsWith("Gear" + Path.DirectorySeparatorChar.ToString()))
             {
                 newEntry.ContentName = newEntry.ContentName.Substring(5);
             }
@@ -295,10 +295,10 @@ namespace RolePlaying
             {
                 // load the player and add it to the party
                 /* TODO var player = contentManager.Load<Player>(
-                    Path.Combine(@"Characters\Players", contentName)).Clone()
+                    Path.Combine("Characters", "Players", contentName)).Clone()
                     as Player;*/
 
-                var player = Player.Load(Path.Combine(@"Characters\Players", contentName), contentManager);
+                var player = Player.Load(Path.Combine("Characters", "Players", contentName), contentManager);
 
                 JoinParty(player);
             }
@@ -350,7 +350,7 @@ namespace RolePlaying
             foreach (ContentEntry<Gear> entry in inventory)
             {
                 entry.Content = contentManager.Load<Gear>(
-                    Path.Combine(@"Gear", entry.ContentName));
+                    Path.Combine("Gear", entry.ContentName));
             }
 
             // set the party gold

+ 8 - 10
RolePlayingGame/Core/Session/Session.cs

@@ -47,9 +47,9 @@ namespace RolePlaying
         {
             // make sure the content name is valid
             string mapContentName = contentName;
-            if (!mapContentName.StartsWith(@"Maps\"))
+            if (!mapContentName.StartsWith("Maps" + Path.DirectorySeparatorChar.ToString()))
             {
-                mapContentName = Path.Combine(@"Maps", mapContentName);
+                mapContentName = Path.Combine("Maps", mapContentName);
             }
 
             // check for trivial movement - typically intra-map portals
@@ -418,7 +418,7 @@ namespace RolePlaying
                 return;
             }
 
-            // if we don't have a quest, then take the next one from teh list
+            // if we don't have a quest, then take the next one from the list
             if ((quest == null) && (questLine.Quests.Count > 0) &&
                 !Session.IsQuestLineComplete)
             {
@@ -1495,18 +1495,16 @@ namespace RolePlaying
             ChangeMap(gameStartDescription.MapContentName, null);
 
             // set up the initial party
-            ContentManager content = singleton.screenManager.Game.Content;
-            singleton.party = new Party(gameStartDescription, content);
+            ContentManager contentManager = singleton.screenManager.Game.Content;
+            singleton.party = new Party(gameStartDescription, contentManager);
 
             /* var loadedQuestLine = content.Load<QuestLine>(
-                Path.Combine(@"Quests\QuestLines",
-                gameStartDescription.QuestLineContentName)).Clone() as QuestLine;*/
+                Path.Combine("Quests", "QuestLines", gameStartDescription.QuestLineContentName)).Clone() as QuestLine;*/
 
-            var loadedQuestLine = QuestLine.Load(Path.Combine(@"Quests\QuestLines",
-                gameStartDescription.QuestLineContentName));
+            var questLine = QuestLine.Load(Path.Combine("Quests", "QuestLines", gameStartDescription.QuestLineContentName), contentManager);
 
             // load the quest line
-            singleton.questLine = loadedQuestLine;
+            singleton.questLine = questLine;
         }
 
         /// <summary>

+ 2 - 1
RolePlayingGame/RolePlayingGameData/Characters/CharacterLevelDescription.cs

@@ -8,6 +8,7 @@
 using System;
 using System.Collections.Generic;
 using System.ComponentModel.DataAnnotations;
+using System.IO;
 using System.Linq;
 using System.Xml.Linq;
 using Microsoft.Xna.Framework.Content;
@@ -124,7 +125,7 @@ namespace RolePlaying.Data
                 characterLevelDescription.Spells = new List<Spell>();
                 foreach (var spellContentName in characterLevelDescription.SpellContentNames)
                 {
-                    var spell = Spell.Load(System.IO.Path.Combine("Spells", spellContentName), contentManager);
+                    var spell = Spell.Load(Path.Combine("Spells", spellContentName), contentManager);
                     characterLevelDescription.Spells.Add(spell);
                 }
             }

+ 5 - 2
RolePlayingGame/RolePlayingGameData/Characters/Player.cs

@@ -315,6 +315,9 @@ namespace RolePlaying.Data
                 Name = (string)asset.Element("Name"),
                 Direction = Enum.TryParse<Direction>((string)asset.Element("Direction"), out var dir) ? dir : default,
                 MapSprite = AnimatingSprite.Load(asset.Element("MapSprite"), contentManager),
+                MapPosition = asset.Element("MapPosition") != null ? new Point(
+                    (int)asset.Element("MapPosition").Element("X"),
+                    (int)asset.Element("MapPosition").Element("Y")) : Point.Zero,
                 WalkingSprite = AnimatingSprite.Load(asset.Element("WalkingSprite"), contentManager),
                 MapIdleAnimationInterval = (int)asset.Element("MapIdleAnimationInterval"),
                 CharacterClassContentName = (string)asset.Element("CharacterClassContentName"),
@@ -338,7 +341,7 @@ namespace RolePlaying.Data
                 Inventory = asset.Element("Inventory")?.Elements("Item")
                     .Select(x => new ContentEntry<Gear>
                     {
-                        Content = Item.Load(Path.Combine(@"Gear", (string)x.Element("ContentName")), contentManager),
+                        Content = Item.Load(Path.Combine("Gear", (string)x.Element("ContentName")), contentManager),
                         ContentName = (string)x.Element("ContentName"),
                         Count = (int?)x.Element("Count") ?? 1 // Default to 1 if not specified
                     })
@@ -349,7 +352,7 @@ namespace RolePlaying.Data
             player.CharacterClass = CharacterClass.Load(Path.Combine("CharacterClasses", player.CharacterClassContentName), contentManager);
             foreach (var item in player.InitialEquipmentContentNames)
             {
-                player.EquippedEquipment.Add(Equipment.Load(Path.Combine(@"Gear", item), contentManager));
+                player.EquippedEquipment.Add(Equipment.Load(Path.Combine("Gear", item), contentManager));
             }
 
             player.AddStandardCharacterCombatAnimations();

+ 4 - 5
RolePlayingGame/RolePlayingGameData/Map/Chest.cs

@@ -120,13 +120,12 @@ namespace RolePlaying.Data
                 foreach (ContentEntry<Gear> contentEntry in chest.Entries)
                 {
                     contentEntry.Content = input.ContentManager.Load<Gear>(
-                        System.IO.Path.Combine(@"Gear",
-                        contentEntry.ContentName));
+                        Path.Combine("Gear",  contentEntry.ContentName));
                 }
 
                 chest.TextureName = input.ReadString();
                 chest.Texture = input.ContentManager.Load<Texture2D>(
-                    System.IO.Path.Combine(@"Textures\Chests", chest.TextureName));
+                    Path.Combine("Textures", "Chests", chest.TextureName));
 
                 return chest;
             }
@@ -173,7 +172,7 @@ namespace RolePlaying.Data
                 Entries = chestAsset.Element("Entries")?.Elements("Item").Select(chestItem =>
                 {
                     var contentName = (string)chestItem.Element("ContentName");
-                    var gearAsset = XmlHelper.GetAssetElementFromXML(Path.Combine(@"Gear", contentName));
+                    var gearAsset = XmlHelper.GetAssetElementFromXML(Path.Combine("Gear", contentName));
                     var gear = new Equipment
                     {
                         AssetName = contentName,
@@ -182,7 +181,7 @@ namespace RolePlaying.Data
                         GoldValue = (int?)gearAsset.Element("GoldValue") ?? 0,
                         IconTextureName = (string)gearAsset.Element("IconTextureName"),
                         IconTexture = contentManager.Load<Texture2D>(
-                            Path.Combine(@"Textures\Gear", (string)gearAsset.Element("IconTextureName"))),
+                            Path.Combine("Textures", "Gear", (string)gearAsset.Element("IconTextureName"))),
                         IsDroppable = (bool?)gearAsset.Element("IsDroppable") ?? true,
 
                         // Add other properties as needed

+ 1 - 1
RolePlayingGame/RolePlayingGameData/Map/FixedCombat.cs

@@ -47,7 +47,7 @@ namespace RolePlaying.Data
                         var monsterContentName = (string)entry.Element("ContentName");
                         var monsterCount = (int?)entry.Element("Count") ?? 1;
 
-                        var monster = Monster.Load(Path.Combine(@"Characters\Monsters", monsterContentName), contentManager);
+                        var monster = Monster.Load(Path.Combine("Characters", "Monsters", monsterContentName), contentManager);
 
                         return new ContentEntry<Monster>
                         {

+ 8 - 8
RolePlayingGame/RolePlayingGameData/Map/Map.cs

@@ -617,10 +617,10 @@ namespace RolePlaying.Data
                     int.Parse(asset.Element("SpawnMapPosition").Value.Split(' ')[1])), // e.g. [9, 7]
                 TextureName = (string)asset.Element("TextureName"),
                 Texture = contentManager.Load<Texture2D>(
-                    Path.Combine(@"Textures\Maps\NonCombat", (string)asset.Element("TextureName"))),
+                    Path.Combine("Textures", "Maps", "NonCombat", (string)asset.Element("TextureName"))),
                 CombatTextureName = (string)asset.Element("CombatTextureName"),
                 CombatTexture = contentManager.Load<Texture2D>(
-                    Path.Combine(@"Textures\Maps\Combat", (string)asset.Element("CombatTextureName"))),
+                    Path.Combine("Textures", "Maps", "Combat", (string)asset.Element("CombatTextureName"))),
                 MusicCueName = (string)asset.Element("MusicCueName"),
                 CombatMusicCueName = (string)asset.Element("CombatMusicCueName"),
                 BaseLayer = asset.Element("BaseLayer").Value
@@ -689,7 +689,7 @@ namespace RolePlaying.Data
                             int.Parse(item.Element("MapPosition").Value.Split(' ')[1]));
 
                         // Load the QuestNpc asset XML using contentName
-                        var chestAsset = XmlHelper.GetAssetElementFromXML(Path.Combine(@"Maps/Chests", contentName));
+                        var chestAsset = XmlHelper.GetAssetElementFromXML(Path.Combine("Maps", "Chests", contentName));
                         var chest = Chest.Load(chestAsset, contentManager);
 
                         return new MapEntry<Chest>
@@ -710,7 +710,7 @@ namespace RolePlaying.Data
                             int.Parse(item.Element("MapPosition").Value.Split(' ')[1]));
 
                         // Load the fixed combat asset XML using contentName
-                        var fixedCombat = FixedCombat.Load(Path.Combine(@"Maps/FixedCombats", contentName), contentManager);
+                        var fixedCombat = FixedCombat.Load(Path.Combine("Maps", "FixedCombats", contentName), contentManager);
 
                         AnimatingSprite animatingSprite = null;
 
@@ -738,7 +738,7 @@ namespace RolePlaying.Data
                             int.Parse(item.Element("MapPosition").Value.Split(' ')[1]));
 
                         // Load the PlayerNpc asset XML using contentName
-                        var playerNpc = Player.Load(Path.Combine(@"Characters/Players", contentName), contentManager);
+                        var playerNpc = Player.Load(Path.Combine("Characters", "Players", contentName), contentManager);
 
                         return new MapEntry<Player>
                         {
@@ -758,7 +758,7 @@ namespace RolePlaying.Data
                             int.Parse(item.Element("MapPosition").Value.Split(' ')[1]));
 
                         // Load the QuestNpc asset XML using contentName
-                        var questNpc = QuestNpc.Load(Path.Combine(@"Characters/QuestNPCs", contentName), contentManager);
+                        var questNpc = QuestNpc.Load(Path.Combine("Characters", "QuestNPCs", contentName), contentManager);
 
                         return new MapEntry<QuestNpc>
                         {
@@ -778,7 +778,7 @@ namespace RolePlaying.Data
                             int.Parse(item.Element("MapPosition").Value.Split(' ')[1]));
 
                         // Load the Inn asset XML using contentName
-                        var inn = Inn.Load(Path.Combine(@"Maps/Inns", contentName), contentManager);
+                        var inn = Inn.Load(Path.Combine("Maps", "Inns", contentName), contentManager);
 
                         return new MapEntry<Inn>
                         {
@@ -798,7 +798,7 @@ namespace RolePlaying.Data
                             int.Parse(item.Element("MapPosition").Value.Split(' ')[1]));
 
                         // Load the Store asset XML using contentName
-                        var store = Store.Load(Path.Combine(@"Maps/Stores", contentName), contentManager);
+                        var store = Store.Load(Path.Combine("Maps", "Stores", contentName), contentManager);
 
                         return new MapEntry<Store>
                         {

+ 1 - 2
RolePlayingGame/RolePlayingGameData/Map/RandomCombat.cs

@@ -104,8 +104,7 @@ namespace RolePlaying.Data
                 foreach (ContentEntry<Monster> randomCombatEntry in randomCombat.Entries)
                 {
                     randomCombatEntry.Content = input.ContentManager.Load<Monster>(
-                        Path.Combine(@"Characters\Monsters",
-                            randomCombatEntry.ContentName));
+                        Path.Combine("Characters", "Monsters", randomCombatEntry.ContentName));
                 }
 
                 return randomCombat;

+ 3 - 2
RolePlayingGame/RolePlayingGameData/Map/Store.cs

@@ -7,6 +7,7 @@
 
 using System;
 using System.Collections.Generic;
+using System.IO;
 using System.Linq;
 using Microsoft.Xna.Framework.Content;
 using Microsoft.Xna.Framework.Graphics;
@@ -130,7 +131,7 @@ namespace RolePlaying.Data
                 WelcomeMessage = asset.Element("WelcomeMessage").Value,
                 ShopkeeperTextureName = asset.Element("ShopkeeperTextureName").Value,
                 ShopkeeperTexture = contentManager.Load<Texture2D>(
-                    System.IO.Path.Combine(@"Textures\Characters\Portraits",
+                    Path.Combine("Textures", "Characters", "Portraits",
                     asset.Element("ShopkeeperTextureName").Value)),
                 StoreCategories = asset.Element("StoreCategories")
                     .Elements("Item")
@@ -161,7 +162,7 @@ namespace RolePlaying.Data
                 store.WelcomeMessage = input.ReadString();
                 store.ShopkeeperTextureName = input.ReadString();
                 store.shopkeeperTexture = input.ContentManager.Load<Texture2D>(
-                    System.IO.Path.Combine(@"Textures\Characters\Portraits",
+                    Path.Combine("Textures", "Characters", "Portraits",
                     store.ShopkeeperTextureName));
 
                 return store;

+ 113 - 52
RolePlayingGame/RolePlayingGameData/Quests/Quest.cs

@@ -8,6 +8,9 @@
 using System;
 using System.Collections.Generic;
 using System.IO;
+using System.Linq;
+using System.Xml.Linq;
+using Microsoft.Xna.Framework;
 using Microsoft.Xna.Framework.Content;
 
 namespace RolePlaying.Data
@@ -47,11 +50,6 @@ namespace RolePlaying.Data
             get { return stage; }
             set { stage = value; }
         }
-        
-
-
-
-
 
         /// <summary>
         /// The name of the quest.
@@ -67,7 +65,6 @@ namespace RolePlaying.Data
             set { name = value; }
         }
 
-
         /// <summary>
         /// A description of the quest.
         /// </summary>
@@ -82,7 +79,6 @@ namespace RolePlaying.Data
             set { description = value; }
         }
 
-
         /// <summary>
         /// A message describing the objective of the quest, 
         /// presented when the player receives the quest.
@@ -99,7 +95,6 @@ namespace RolePlaying.Data
             set { objectiveMessage = value; }
         }
 
-
         /// <summary>
         /// A message announcing the completion of the quest, 
         /// presented when the player reaches the goals of the quest.
@@ -112,11 +107,6 @@ namespace RolePlaying.Data
             set { completionMessage = value; }
         }
 
-
-
-
-
-
         /// <summary>
         /// The gear that the player must have to finish the quest.
         /// </summary>
@@ -132,7 +122,6 @@ namespace RolePlaying.Data
             set { gearRequirements = value; }
         }
 
-
         /// <summary>
         /// The monsters that must be killed to finish the quest.
         /// </summary>
@@ -148,7 +137,6 @@ namespace RolePlaying.Data
             set { monsterRequirements = value; }
         }
 
-
         /// <summary>
         /// Returns true if all requirements for this quest have been met.
         /// </summary>
@@ -163,7 +151,7 @@ namespace RolePlaying.Data
                         return false;
                     }
                 }
-                foreach (QuestRequirement<Monster> monsterRequirement 
+                foreach (QuestRequirement<Monster> monsterRequirement
                     in monsterRequirements)
                 {
                     if (monsterRequirement.CompletedCount < monsterRequirement.Count)
@@ -175,15 +163,10 @@ namespace RolePlaying.Data
             }
         }
 
-
-
-
-
-
         /// <summary>
         /// The fixed combat encounters added to the world when this quest is active.
         /// </summary>
-        private List<WorldEntry<FixedCombat>> fixedCombatEntries = 
+        private List<WorldEntry<FixedCombat>> fixedCombatEntries =
             new List<WorldEntry<FixedCombat>>();
 
         /// <summary>
@@ -195,7 +178,6 @@ namespace RolePlaying.Data
             set { fixedCombatEntries = value; }
         }
 
-
         /// <summary>
         /// The chests added to thew orld when this quest is active.
         /// </summary>
@@ -210,11 +192,6 @@ namespace RolePlaying.Data
             set { chestEntries = value; }
         }
 
-
-
-
-
-
         /// <summary>
         /// The map with the destination Npc, if any.
         /// </summary>
@@ -230,7 +207,6 @@ namespace RolePlaying.Data
             set { destinationMapContentName = value; }
         }
 
-
         /// <summary>
         /// The Npc that the party must visit to finish the quest, if any.
         /// </summary>
@@ -246,7 +222,6 @@ namespace RolePlaying.Data
             set { destinationNpcContentName = value; }
         }
 
-
         /// <summary>
         /// The message shown when the party is eligible to complete the quest, if any.
         /// </summary>
@@ -262,11 +237,6 @@ namespace RolePlaying.Data
             set { destinationObjectiveMessage = value; }
         }
 
-
-
-
-
-
         /// <summary>
         /// The number of experience points given to each party member as a reward.
         /// </summary>
@@ -282,7 +252,6 @@ namespace RolePlaying.Data
             set { experienceReward = value; }
         }
 
-
         /// <summary>
         /// The amount of gold given to the party as a reward.
         /// </summary>
@@ -298,7 +267,6 @@ namespace RolePlaying.Data
             set { goldReward = value; }
         }
 
-
         /// <summary>
         /// The content names of the gear given to the party as a reward.
         /// </summary>
@@ -314,7 +282,6 @@ namespace RolePlaying.Data
             set { gearRewardContentNames = value; }
         }
 
-
         /// <summary>
         /// The gear given to the party as a reward.
         /// </summary>
@@ -330,11 +297,6 @@ namespace RolePlaying.Data
             set { gearRewards = value; }
         }
 
-
-
-
-
-
         /// <summary>
         /// Reads a Quest object from the content pipeline.
         /// </summary>
@@ -372,7 +334,7 @@ namespace RolePlaying.Data
                 {
                     fixedCombatEntry.Content =
                         input.ContentManager.Load<FixedCombat>(
-                        System.IO.Path.Combine(@"Maps\FixedCombats",
+                        Path.Combine("Maps", "FixedCombats",
                         fixedCombatEntry.ContentName));
                     // clone the map sprite in the entry, as there may be many entries
                     // per FixedCombat
@@ -392,8 +354,7 @@ namespace RolePlaying.Data
                 foreach (WorldEntry<Chest> chestEntry in quest.ChestEntries)
                 {
                     chestEntry.Content = input.ContentManager.Load<Chest>(
-                        System.IO.Path.Combine(@"Maps\Chests",
-                        chestEntry.ContentName)).Clone() as Chest;
+                        Path.Combine("Maps", "Chests", chestEntry.ContentName)).Clone() as Chest;
                 }
 
                 quest.DestinationMapContentName = input.ReadString();
@@ -415,11 +376,6 @@ namespace RolePlaying.Data
             }
         }
 
-
-
-
-
-
         public object Clone()
         {
             Quest quest = new Quest();
@@ -455,6 +411,111 @@ namespace RolePlaying.Data
             return quest;
         }
 
+        internal static Quest Load(string questContentName, ContentManager contentManager)
+        {
+            var questElement = XmlHelper.GetAssetElementFromXML(Path.Combine("Quests", questContentName));
+            var quest = new Quest
+            {
+                AssetName = questContentName,
+                Name = (string)questElement.Element("Name"),
+                Description = (string)questElement.Element("Description"),
+                ObjectiveMessage = (string)questElement.Element("ObjectiveMessage"),
+                CompletionMessage = (string)questElement.Element("CompletionMessage"),
+                DestinationMapContentName = (string)questElement.Element("DestinationMapContentName"),
+                DestinationNpcContentName = (string)questElement.Element("DestinationNpcContentName"),
+                DestinationObjectiveMessage = (string)questElement.Element("DestinationObjectiveMessage"),
+                ExperienceReward = (int?)questElement.Element("ExperienceReward") ?? 0,
+                GoldReward = (int?)questElement.Element("GoldReward") ?? 0,
+                Stage = Enum.TryParse<QuestStage>((string)questElement.Element("Stage"), out var stage) ? stage : QuestStage.NotStarted,
+                GearRewardContentNames = questElement.Element("GearRewardContentNames")?
+                    .Elements("Item")
+                    .Select(x => (string)x)
+                    .ToList() ?? new List<string>(),
+                GearRequirements = questElement.Element("GearRequirements")?
+                    .Elements("Item")
+                    .Select(gearElement =>
+                    {
+                        var gearContentName = (string)gearElement.Element("ContentName");
+                        var gearCount = (int?)gearElement.Element("Count") ?? 1;
+
+                        var gear = Equipment.Load(Path.Combine("Gear", gearContentName), contentManager);
+
+                        return new QuestRequirement<Gear>
+                        {
+                            ContentName = gearContentName,
+                            Count = gearCount,
+                            Content = gear
+                        };
+                    }).ToList() ?? new List<QuestRequirement<Gear>>(),
+                MonsterRequirements = questElement.Element("MonsterRequirements")?
+                    .Elements("Item")
+                    .Select(entry =>
+                    {
+                        var monsterContentName = (string)entry.Element("ContentName");
+                        var monsterCount = (int?)entry.Element("Count") ?? 1;
+
+                        var monster = Monster.Load(Path.Combine("Characters", "Monsters", monsterContentName), contentManager);
+
+                        return new QuestRequirement<Monster>
+                        {
+                            ContentName = monsterContentName,
+                            Count = monsterCount,
+                            Content = monster
+                        };
+                    }).ToList() ?? new List<QuestRequirement<Monster>>(),
+                FixedCombatEntries = questElement.Element("FixedCombatEntries")?.Elements("Item")
+                    .Select(item =>
+                    {
+                        var contentName = (string)item.Element("ContentName");
+                        var direction = Enum.TryParse<Direction>((string)item.Element("Direction"), out var dir) ? dir : default;
+                        var mapPosition = new Point(
+                            int.Parse(item.Element("MapPosition").Value.Split(' ')[0]),
+                            int.Parse(item.Element("MapPosition").Value.Split(' ')[1]));
+
+                        // Load the fixed combat asset XML using contentName
+                        var fixedCombat = FixedCombat.Load(Path.Combine("Maps", "FixedCombats", contentName), contentManager);
+
+                        AnimatingSprite animatingSprite = null;
+
+                        if (fixedCombat.Entries.Count > 0)
+                        {
+                            animatingSprite = fixedCombat.Entries[0].Content.MapSprite.Clone() as AnimatingSprite;
+                        }
+
+                        return new WorldEntry<FixedCombat>
+                        {
+                            ContentName = contentName,
+                            Content = fixedCombat,
+                            Direction = direction,
+                            MapPosition = mapPosition,
+                            MapSprite = animatingSprite,
+                        };
+                    }).ToList() ?? new List<WorldEntry<FixedCombat>>(),
+                ChestEntries = questElement.Element("ChestEntries")?
+                    .Elements("Item")
+                    .Select(chestRequirement =>
+                    {
+                        var contentName = (string)chestRequirement.Element("ContentName");
+                        var direction = Enum.TryParse<Direction>((string)chestRequirement.Element("Direction"), out var dir) ? dir : default;
+                        var mapPosition = new Point(
+                            int.Parse(chestRequirement.Element("MapPosition").Value.Split(' ')[0]),
+                            int.Parse(chestRequirement.Element("MapPosition").Value.Split(' ')[1]));
+
+                        // Load the QuestNpc asset XML using contentName
+                        var chestAsset = XmlHelper.GetAssetElementFromXML(Path.Combine("Maps", "Chests", contentName));
+                        var chest = Chest.Load(chestAsset, contentManager);
+
+                        return new WorldEntry<Chest>
+                        {
+                            ContentName = contentName,
+                            Content = chest,
+                            Direction = direction,
+                            MapPosition = mapPosition
+                        };
+                    }).ToList() ?? new List<WorldEntry<Chest>>(),
+            };
 
+            return quest;
+        }
     }
-}
+}

+ 11 - 9
RolePlayingGame/RolePlayingGameData/Quests/QuestLine.cs

@@ -69,6 +69,7 @@ namespace RolePlaying.Data
         public List<Quest> Quests
         {
             get { return quests; }
+            set { quests = value; }
         }
 
 
@@ -128,22 +129,23 @@ namespace RolePlaying.Data
             return questLine;
         }
 
-        public static QuestLine Load(string questPath)
+        public static QuestLine Load(string questPath, ContentManager contentManager)
         {
             var asset = XmlHelper.GetAssetElementFromXML(questPath);
 
-            var name = asset.Element("Name").Value;
-            var questContentNames = asset.Element("QuestContentNames")
-                .Elements("Item")
-                .Select(x => (string)x)
-                .ToList();
-
             var loadedQuestLine = new QuestLine
             {
-                Name = name,
-                QuestContentNames = questContentNames,
+                Name = asset.Element("Name").Value,
+                QuestContentNames = asset.Element("QuestContentNames")?
+                    .Elements("Item")
+                    .Select(x => (string)x)
+                    .ToList(),
             };
 
+            loadedQuestLine.Quests = loadedQuestLine.QuestContentNames
+                .Select(x => Quest.Load(x, contentManager))
+                .ToList() ?? new List<Quest>();
+
             return loadedQuestLine;
         }
     }

+ 3 - 3
RolePlayingGame/RolePlayingGameData/Quests/QuestRequirement.cs

@@ -6,6 +6,7 @@
 //-----------------------------------------------------------------------------
 
 using System;
+using System.IO;
 using Microsoft.Xna.Framework.Content;
 
 namespace RolePlaying.Data
@@ -55,13 +56,12 @@ namespace RolePlaying.Data
                 if (typeof(T) == typeof(Gear))
                 {
                     requirement.Content = input.ContentManager.Load<T>(
-                        System.IO.Path.Combine("Gear", requirement.ContentName));
+                        Path.Combine("Gear", requirement.ContentName));
                 }
                 else if (typeof(T) == typeof(Monster))
                 {
                     requirement.Content = input.ContentManager.Load<T>(
-                        System.IO.Path.Combine(@"Characters\Monsters", 
-                        requirement.ContentName));
+                        Path.Combine("Characters", "Monsters", requirement.ContentName));
                 }
 
                 return requirement;

+ 2 - 1
RolePlayingGame/RolePlayingGameData/XmlHelper.cs

@@ -1,6 +1,7 @@
 using Microsoft.Xna.Framework;
 using System;
 using System.Collections.Generic;
+using System.IO;
 using System.Linq;
 using System.Text;
 using System.Threading.Tasks;
@@ -13,7 +14,7 @@ namespace RolePlaying.Data
 		public static XElement GetAssetElementFromXML(string filePath)
 		{
 			XDocument doc;
-			using (var stream = TitleContainer.OpenStream($"Content/{filePath}.xml"))
+			using (var stream = TitleContainer.OpenStream(Path.Combine("Content", $"{filePath}.xml")))
 			{
 				doc = XDocument.Load(stream);
 			}

+ 5 - 5
RolePlayingGame/Tutorial_2_Engine.md

@@ -194,7 +194,7 @@ Map existingInstance)
 
                 map.TextureName \= input.ReadString();  
                 map.texture \= input.ContentManager.Load\<Texture2D\>(  
-                    System.IO.Path.Combine(@"Textures\\Maps\\NonCombat",  
+                    System.IO.Path.Combine("Textures", "Maps", "NonCombat",  
                     map.TextureName));  
                 map.tilesPerRow \= map.texture.Width / map.TileSize.X;
 
@@ -425,9 +425,9 @@ Next, we need to make sure that the map name in the **portalEntry** object is a
         // make sure the content name is valid  
         string mapContentName \=   
             portalEntry.Content.DestinationMapContentName;  
-        if (\!mapContentName.StartsWith(@"Maps\\"))  
+        if (\!mapContentName.StartsWith("Maps" + Path.IO.DirectorySeparator.ToString()))  
         {  
-            mapContentName \= System.IO.Path.Combine(@"Maps", mapContentName);  
+            mapContentName \= System.IO.Path.Combine("Maps", mapContentName);  
         }  
         return false;  
     }
@@ -447,9 +447,9 @@ Finally, add calls to load the new map and to **TileEngine.SetMap**, passing in
         // make sure the content name is valid  
         string mapContentName \=   
             portalEntry.Content.DestinationMapContentName;  
-        if (\!mapContentName.StartsWith(@"Maps\\"))  
+        if (\!mapContentName.StartsWith("Maps" + + Path.IO.DirectorySeparator.ToString()))  
         {  
-            mapContentName \= System.IO.Path.Combine(@"Maps", mapContentName);  
+            mapContentName \= System.IO.Path.Combine("Maps", mapContentName);  
         }  
         // load the new map  
         Map newMap \= ContentManager.Load\<Map\>(mapContentName);