Ver Fonte

RPG - Tweaks to get the starting, at least. More work required.

CartBlanche há 1 mês atrás
pai
commit
4e49c82afb

Diff do ficheiro suprimidas por serem muito extensas
+ 405 - 405
RolePlayingGame/Core/Content/Content.mgcb


+ 1 - 1
RolePlayingGame/Core/Content/MainGameDescription.xml

@@ -7,4 +7,4 @@
 	  </PlayerContentNames>
       <QuestLineContentName>MainQuestLine</QuestLineContentName>
   </Asset>
-</XnaContent>
+</XnaContent>

+ 5 - 5
RolePlayingGame/Core/GameScreens/InventoryScreen.cs

@@ -72,7 +72,7 @@ namespace RolePlaying
 
             // sort the list by name
             dataList.Sort(
-                delegate(ContentEntry<Gear> gearEntry1, ContentEntry<Gear> gearEntry2)
+                delegate (ContentEntry<Gear> gearEntry1, ContentEntry<Gear> gearEntry2)
                 {
                     // handle null values
                     if ((gearEntry1 == null) || (gearEntry1.Content == null))
@@ -181,7 +181,7 @@ namespace RolePlaying
                 new MessageBoxScreen("Are you sure you want to drop the " +
                 entry.Content.Name + "?");
             dropEquipmentConfirmationScreen.Accepted +=
-                new EventHandler<EventArgs>(delegate(object sender, EventArgs args)
+                new EventHandler<EventArgs>(delegate (object sender, EventArgs args)
                 {
                     Session.Party.RemoveFromInventory(entry.Content, 1);
                 });
@@ -234,7 +234,7 @@ namespace RolePlaying
             }
         }
 
-        
+
         /// <summary>
         /// Reset the trigger button text to the names of the 
         /// previous and next UI screens.
@@ -254,7 +254,7 @@ namespace RolePlaying
                 }
                 else
                 {
-                    leftTriggerText = "Items";
+                    leftTriggerText = "Inventory";
                     rightTriggerText = "Quests";
                 }
             }
@@ -406,4 +406,4 @@ namespace RolePlaying
 
 
     }
-}
+}

+ 24 - 25
RolePlayingGame/Core/GameScreens/ListScreen.cs

@@ -30,7 +30,7 @@ namespace RolePlaying
 
         private Texture2D listTexture;
         private readonly Vector2 listTexturePosition = new Vector2(187f, 180f);
-        protected readonly Vector2 listEntryStartPosition = new Vector2(200f, 202f);
+        protected readonly Vector2 listEntryStartPosition = new Vector2(200f, 195f);
         protected const int listLineSpacing = 76;
 
         private Texture2D plankTexture;
@@ -166,8 +166,8 @@ namespace RolePlaying
         /// Increase the selected quantity by one.
         /// </summary>
         protected virtual void MoveCursorRight() { }
-        
-        
+
+
         /// <summary>
         /// The first index displayed on the screen from the list.
         /// </summary>
@@ -212,11 +212,11 @@ namespace RolePlaying
         /// Constructs a new ListScreen object.
         /// </summary>
         public ListScreen()
-            : base() 
+            : base()
         {
             this.IsPopup = true;
         }
- 
+
 
         /// <summary>
         /// Load the graphics content from the content manager.
@@ -227,9 +227,9 @@ namespace RolePlaying
 
             // load the background textures
             fadeTexture = content.Load<Texture2D>(@"Textures\GameScreens\FadeScreen");
-            backgroundTexture = 
+            backgroundTexture =
                 content.Load<Texture2D>(@"Textures\GameScreens\GameScreenBkgd");
-            listTexture = 
+            listTexture =
                 content.Load<Texture2D>(@"Textures\GameScreens\InfoDisplay");
             plankTexture =
                 content.Load<Texture2D>(@"Textures\MainMenu\MainMenuPlank03");
@@ -243,21 +243,21 @@ namespace RolePlaying
                 content.Load<Texture2D>(@"Textures\GameScreens\SelectionArrow");
 
             // load the trigger images
-            leftTriggerTexture = 
+            leftTriggerTexture =
                 content.Load<Texture2D>(@"Textures\Buttons\LeftTriggerButton");
-            rightTriggerTexture = 
+            rightTriggerTexture =
                 content.Load<Texture2D>(@"Textures\Buttons\RightTriggerButton");
-            leftQuantityArrowTexture = 
+            leftQuantityArrowTexture =
                 content.Load<Texture2D>(@"Textures\Buttons\QuantityArrowLeft");
-            rightQuantityArrowTexture = 
+            rightQuantityArrowTexture =
                 content.Load<Texture2D>(@"Textures\Buttons\QuantityArrowRight");
-            backButtonTexture = 
+            backButtonTexture =
                 content.Load<Texture2D>(@"Textures\Buttons\BButton");
-            selectButtonTexture = 
+            selectButtonTexture =
                 content.Load<Texture2D>(@"Textures\Buttons\AButton");
             xButtonTexture =
                 content.Load<Texture2D>(@"Textures\Buttons\XButton");
-            yButtonTexture = 
+            yButtonTexture =
                 content.Load<Texture2D>(@"Textures\Buttons\YButton");
 
             // calculate the centered positions
@@ -274,7 +274,7 @@ namespace RolePlaying
             {
                 xButtonTextPosition.X += xButtonTexture.Width;
             }
-            
+
             base.LoadContent();
         }
 
@@ -407,7 +407,7 @@ namespace RolePlaying
 
             // fix the indices for the current list size
             SelectedIndex = (int)MathHelper.Clamp(SelectedIndex, 0, dataList.Count - 1);
-            startIndex = (int)MathHelper.Clamp(startIndex, 0, 
+            startIndex = (int)MathHelper.Clamp(startIndex, 0,
                 dataList.Count - MaximumListEntries);
             endIndex = Math.Min(startIndex + MaximumListEntries, dataList.Count);
 
@@ -424,7 +424,7 @@ namespace RolePlaying
             DrawTitle();
 
             // draw each item currently shown
-            Vector2 position = listEntryStartPosition + 
+            Vector2 position = listEntryStartPosition +
                 new Vector2(0f, listLineSpacing / 2);
             if (startIndex >= 0)
             {
@@ -466,7 +466,7 @@ namespace RolePlaying
         {
             SpriteBatch spriteBatch = ScreenManager.SpriteBatch;
 
-            spriteBatch.Draw(highlightTexture, 
+            spriteBatch.Draw(highlightTexture,
                 new Vector2(highlightStartPosition.X, position.Y), Color.White);
             spriteBatch.Draw(selectionArrowTexture,
                 new Vector2(selectionArrowPosition.X, position.Y + 10f), Color.White);
@@ -512,7 +512,7 @@ namespace RolePlaying
                 drawPosition, Fonts.CountColor);
         }
 
-        
+
         /// <summary>
         /// Draw the party gold text.
         /// </summary>
@@ -563,7 +563,7 @@ namespace RolePlaying
                     leftTriggerTexture.Width / 2f - (float)Math.Ceiling(
                     Fonts.PlayerStatisticsFont.MeasureString(leftTriggerText).X / 2f),
                     90f);
-                spriteBatch.Draw(leftTriggerTexture, leftTriggerTexturePosition, 
+                spriteBatch.Draw(leftTriggerTexture, leftTriggerTexturePosition,
                     Color.White);
                 spriteBatch.DrawString(Fonts.PlayerStatisticsFont, leftTriggerText,
                     position, Color.Black);
@@ -639,14 +639,13 @@ namespace RolePlaying
                 Vector2 titleTextSize = Fonts.HeaderFont.MeasureString(titleText);
                 Viewport viewport = ScreenManager.GraphicsDevice.Viewport;
                 Vector2 position = new Vector2(
-                    (float)Math.Floor(viewport.X + viewport.Width / 2 - 
-                    titleTextSize.X / 2f), 90f);
+                    (float)Math.Floor(viewport.X + viewport.Width / 2 -
+                    titleTextSize.X / 2f), 95f);
                 spriteBatch.Draw(plankTexture, plankTexturePosition, Color.White);
-                spriteBatch.DrawString(Fonts.HeaderFont, titleText, position,
-                    Fonts.TitleColor);
+                spriteBatch.DrawString(Fonts.HeaderFont, titleText, position, Fonts.TitleColor, MathHelper.ToRadians(-3.0f), Vector2.Zero, 1.0f, SpriteEffects.None, 0f);
             }
         }
 
 
     }
-}
+}

+ 22 - 23
RolePlayingGame/Core/GameScreens/PlayerSelectionScreen.cs

@@ -102,7 +102,7 @@ namespace RolePlaying
         /// <summary>
         /// Load the graphics content from the content manager.
         /// </summary>
-        public override void  LoadContent()
+        public override void LoadContent()
         {
             Viewport viewport = ScreenManager.GraphicsDevice.Viewport;
             ContentManager content = ScreenManager.Game.Content;
@@ -110,22 +110,22 @@ namespace RolePlaying
             fadeTexture = content.Load<Texture2D>(@"Textures\GameScreens\FadeScreen");
 
             // Display screens
-            playerInfoScreen = 
+            playerInfoScreen =
                 content.Load<Texture2D>(@"Textures\GameScreens\PopupScreen");
             popupPosition = new Vector2(viewport.Width / 2f, viewport.Height / 2f);
             popupPosition.X -= playerInfoScreen.Width / 2;
             popupPosition.Y -= playerInfoScreen.Height / 2;
 
-            scoreBoard = 
+            scoreBoard =
                 content.Load<Texture2D>(@"Textures\GameScreens\CountShieldWithArrow");
-            lineTexture = 
+            lineTexture =
                 content.Load<Texture2D>(@"Textures\GameScreens\SeparationLine");
             selectButton = content.Load<Texture2D>(@"Textures\Buttons\AButton");
             backButton = content.Load<Texture2D>(@"Textures\Buttons\BButton");
             tickMarkTexture = content.Load<Texture2D>(@"Textures\GameScreens\TickMark");
-            playerSelTexture = 
+            playerSelTexture =
                 content.Load<Texture2D>(@"Textures\GameScreens\PlayerSelected");
-            playerUnSelTexture = 
+            playerUnSelTexture =
                 content.Load<Texture2D>(@"Textures\GameScreens\PlayerUnSelected");
 
             titlePosition = new Vector2(
@@ -189,7 +189,7 @@ namespace RolePlaying
                 return;
             }
             // use the item or close the screen
-            else if (isUseAllowed && 
+            else if (isUseAllowed &&
                 InputManager.IsActionTriggered(InputManager.Action.Ok))
             {
                 if (isGearUsed)
@@ -239,7 +239,7 @@ namespace RolePlaying
                 return;
             }
             // cursor up
-            else if (!isGearUsed && 
+            else if (!isGearUsed &&
                 InputManager.IsActionTriggered(InputManager.Action.CursorUp))
             {
                 if (selectionMark > 0)
@@ -264,7 +264,7 @@ namespace RolePlaying
                 }
             }
             // cursor down
-            else if (!isGearUsed && 
+            else if (!isGearUsed &&
                 InputManager.IsActionTriggered(InputManager.Action.CursorDown))
             {
                 isGearUsed = false;
@@ -319,8 +319,7 @@ namespace RolePlaying
             DrawViewablePlayers();
 
             // Display Title of the Screen
-            spriteBatch.DrawString(Fonts.HeaderFont, "Choose Player", titlePosition,
-                Fonts.TitleColor);
+            spriteBatch.DrawString(Fonts.HeaderFont, "Choose Player", titlePosition, Fonts.TitleColor, MathHelper.ToRadians(-3.0f), Vector2.Zero, 1.0f, SpriteEffects.None, 0f);
 
             spriteBatch.End();
         }
@@ -372,7 +371,7 @@ namespace RolePlaying
             // Draw portrait
             portraitPosition.X = position.X + 3f;
             portraitPosition.Y = position.Y + 16f;
-            spriteBatch.Draw(player.ActivePortraitTexture, portraitPosition, 
+            spriteBatch.Draw(player.ActivePortraitTexture, portraitPosition,
                 Color.White);
             if (isGearUsed && isSelected)
             {
@@ -429,9 +428,9 @@ namespace RolePlaying
                             previewDamageRange -= equippedWeapon.TargetDamageRange;
                             previewDamageRange -=
                                 equippedWeapon.OwnerBuffStatistics.PhysicalOffense;
-                            previewHealthDefenseRange -= 
+                            previewHealthDefenseRange -=
                                 equippedWeapon.OwnerBuffStatistics.PhysicalDefense;
-                            previewMagicDefenseRange -= 
+                            previewMagicDefenseRange -=
                                 equippedWeapon.OwnerBuffStatistics.MagicalDefense;
                         }
                     }
@@ -501,7 +500,7 @@ namespace RolePlaying
                 Fonts.CountColor);
             equipEffectPosition.X += length;
 
-            Int32Range drawHealthDefenseRange = player.HealthDefenseRange + 
+            Int32Range drawHealthDefenseRange = player.HealthDefenseRange +
                 previewHealthDefenseRange + player.CharacterStatistics.PhysicalDefense;
             text = drawHealthDefenseRange.Minimum.ToString();
             length = (int)Fonts.DescriptionFont.MeasureString(text).X;
@@ -539,7 +538,7 @@ namespace RolePlaying
                 Fonts.CountColor);
             equipEffectPosition.X += length;
 
-            Int32Range drawMagicDefenseRange = player.MagicDefenseRange + 
+            Int32Range drawMagicDefenseRange = player.MagicDefenseRange +
                 previewMagicDefenseRange + player.CharacterStatistics.MagicalDefense;
             text = drawMagicDefenseRange.Minimum.ToString();
             length = (int)Fonts.DescriptionFont.MeasureString(text).X;
@@ -616,10 +615,10 @@ namespace RolePlaying
             }
 
             // Calculate HP and MP string Length
-            detail1 = "HP: " + player.CurrentStatistics.HealthPoints + "/" + 
+            detail1 = "HP: " + player.CurrentStatistics.HealthPoints + "/" +
                 player.CharacterStatistics.HealthPoints;
             length1 = Fonts.DescriptionFont.MeasureString(detail1).X;
-            detail2 = "MP: " + player.CurrentStatistics.MagicPoints + "/" + 
+            detail2 = "MP: " + player.CurrentStatistics.MagicPoints + "/" +
                 player.CharacterStatistics.MagicPoints;
             length2 = Fonts.DescriptionFont.MeasureString(detail2).X;
 
@@ -670,7 +669,7 @@ namespace RolePlaying
             color = GetStatColor(playersStatisticsModifier.MagicalDefense, isSelected);
             spriteBatch.DrawString(Fonts.DescriptionFont, "MD: " +
                 drawCurrentStatistics.MagicalDefense, position, color);
-            
+
 
             position.Y += Fonts.DescriptionFont.LineSpacing;
         }
@@ -743,7 +742,7 @@ namespace RolePlaying
                 position, Fonts.CountColor);
             position.Y += 30;
             // Display Total Players count
-            spriteBatch.DrawString(Fonts.GearInfoFont, 
+            spriteBatch.DrawString(Fonts.GearInfoFont,
                 Session.Party.Players.Count.ToString(), position, Fonts.CountColor);
         }
 
@@ -876,12 +875,12 @@ namespace RolePlaying
             selectedPlayers.Add(selMark);
             for (int i = 1; i <= range; i++)
             {
-                if ((selMark >= i) && 
+                if ((selMark >= i) &&
                     !Session.Party.Players[selMark - i].IsDeadOrDying)
                 {
                     selectedPlayers.Add(selMark - i);
                 }
-                if ((selMark < (Session.Party.Players.Count - i)) && 
+                if ((selMark < (Session.Party.Players.Count - i)) &&
                     !Session.Party.Players[selMark + i].IsDeadOrDying)
                 {
                     selectedPlayers.Add(selMark + i);
@@ -934,4 +933,4 @@ namespace RolePlaying
         }
 
     }
-}
+}

+ 8 - 13
RolePlayingGame/Core/GameScreens/StatisticsScreen.cs

@@ -5,11 +5,9 @@
 // Copyright (C) Microsoft Corporation. All rights reserved.
 //-----------------------------------------------------------------------------
 
-using System;
-using System.Collections.Generic;
 using Microsoft.Xna.Framework;
-using Microsoft.Xna.Framework.Graphics;
 using Microsoft.Xna.Framework.Content;
+using Microsoft.Xna.Framework.Graphics;
 using RolePlaying.Data;
 
 namespace RolePlaying
@@ -142,7 +140,7 @@ namespace RolePlaying
 
             statisticsNamePosition.X = (viewport.Width -
                 Fonts.HeaderFont.MeasureString("Statistics").X) / 2;
-            statisticsNamePosition.Y = 90f;
+            statisticsNamePosition.Y = 95f;
 
             plankPosition.X = (viewport.Width - plankTexture.Width) / 2;
             plankPosition.Y = 67f;
@@ -167,8 +165,7 @@ namespace RolePlaying
             // shows the spells for this player
             else if (InputManager.IsActionTriggered(InputManager.Action.Ok))
             {
-                ScreenManager.AddScreen(new SpellbookScreen(player,
-                    player.CharacterStatistics));
+                ScreenManager.AddScreen(new SpellbookScreen(player, player.CharacterStatistics));
                 return;
             }
             // show the equipment for this player, allowing the user to unequip
@@ -283,8 +280,8 @@ namespace RolePlaying
                  new Vector2(screenAnimation.SourceOffset.X,
                  screenAnimation.SourceOffset.Y), 1f, SpriteEffects.None, 0f);
 
-            spriteBatch.DrawString(Fonts.HeaderFont, "Statistics",
-                statisticsNamePosition, Fonts.TitleColor);
+            spriteBatch.DrawString(Fonts.HeaderFont, "Statistics", statisticsNamePosition, Fonts.TitleColor, MathHelper.ToRadians(-3.0f), Vector2.Zero, 1.0f, SpriteEffects.None, 0f);
+
             DrawPlayerDetails();
             DrawButtons();
         }
@@ -322,9 +319,9 @@ namespace RolePlaying
 
                 // Draw Right Trigger Information
                 position.Y += rightTriggerButton.Height;
-                placeTextMid = Fonts.PlayerStatisticsFont.MeasureString("Items");
+                placeTextMid = Fonts.PlayerStatisticsFont.MeasureString("Inventory");
                 position.X += (leftTriggerButton.Width / 2) - placeTextMid.X / 2;
-                spriteBatch.DrawString(Fonts.PlayerStatisticsFont, "Items", position,
+                spriteBatch.DrawString(Fonts.PlayerStatisticsFont, "Inventory", position,
                     Color.Black);
             }
 
@@ -567,7 +564,5 @@ namespace RolePlaying
                 magicDefenseRange.Maximum + ")",
                 position, Color.Black);
         }
-
-
     }
-}
+}

+ 10 - 10
RolePlayingGame/Core/GameScreens/StoreSellScreen.cs

@@ -70,7 +70,7 @@ namespace RolePlaying
             selectedQuantity = 1;
         }
 
-        
+
 
 
 
@@ -165,7 +165,7 @@ namespace RolePlaying
             ResetQuantities();
         }
 
-        
+
         /// <summary>
         /// Load the graphics content from the content manager.
         /// </summary>
@@ -189,7 +189,7 @@ namespace RolePlaying
         /// <summary>
         /// Respond to the triggering of the Select action.
         /// </summary>
-        protected override void SelectTriggered(ContentEntry<Gear> entry) 
+        protected override void SelectTriggered(ContentEntry<Gear> entry)
         {
             // check the parameter
             if ((entry == null) || (entry.Content == null))
@@ -215,7 +215,7 @@ namespace RolePlaying
         /// <summary>
         /// Switch to the previous store category.
         /// </summary>
-        protected override void PageScreenLeft() 
+        protected override void PageScreenLeft()
         {
             isItems = !isItems;
             ResetTriggerText();
@@ -226,7 +226,7 @@ namespace RolePlaying
         /// <summary>
         /// Switch to the next store category.
         /// </summary>
-        protected override void PageScreenRight() 
+        protected override void PageScreenRight()
         {
             isItems = !isItems;
             ResetTriggerText();
@@ -240,7 +240,7 @@ namespace RolePlaying
         /// </summary>
         protected override void ResetTriggerText()
         {
-            leftTriggerText = rightTriggerText = isItems ? "Equipment" : "Items";
+            leftTriggerText = rightTriggerText = isItems ? "Equipment" : "Inventory";
         }
 
 
@@ -267,14 +267,14 @@ namespace RolePlaying
             Vector2 drawPosition = position;
 
             // draw the icon
-            spriteBatch.Draw(entry.Content.IconTexture, drawPosition + iconOffset, 
+            spriteBatch.Draw(entry.Content.IconTexture, drawPosition + iconOffset,
                 Color.White);
 
             // draw the name
             Color color = isSelected ? Fonts.HighlightColor : Fonts.DisplayColor;
             drawPosition.Y += listLineSpacing / 4;
             drawPosition.X += nameColumnInterval;
-            spriteBatch.DrawString(Fonts.GearInfoFont, entry.Content.Name, 
+            spriteBatch.DrawString(Fonts.GearInfoFont, entry.Content.Name,
                 drawPosition, color);
 
             // draw the power
@@ -329,7 +329,7 @@ namespace RolePlaying
             }
             else
             {
-                priceText = ((int)Math.Ceiling(entry.Content.GoldValue * 
+                priceText = ((int)Math.Ceiling(entry.Content.GoldValue *
                     store.SellMultiplier)).ToString();
             }
             spriteBatch.DrawString(Fonts.GearInfoFont, priceText,
@@ -424,4 +424,4 @@ namespace RolePlaying
 
 
     }
-}
+}

+ 15 - 21
RolePlayingGame/Core/MenuScreens/ControlsScreen.cs

@@ -300,7 +300,7 @@ namespace RolePlaying
             // draw the control pad screen
             if (isShowControlPad)
             {
-                spriteBatch.Draw(controlPadTexture, controlPosition, 
+                spriteBatch.Draw(controlPadTexture, controlPosition,
                     Color.White);
 
                 for (int i = 0; i < leftStrings.Length; i++)
@@ -315,7 +315,6 @@ namespace RolePlaying
                         rightStrings[i].textPosition, Color.Black);
                 }
 
-#if !XBOX
                 // Near left trigger
                 spriteBatch.DrawString(Fonts.PlayerStatisticsFont, "Keyboard",
                     new Vector2(leftTriggerPosition.X + (leftTriggerButton.Width -
@@ -329,15 +328,13 @@ namespace RolePlaying
                     Fonts.PlayerStatisticsFont.MeasureString("Keyboard").X) / 2,
                     rightTriggerPosition.Y + 85),
                     Color.Black);
-#endif
 
                 // Draw the title text
                 titlePosition.X = plankPosition.X + (plankTexture.Width -
                     Fonts.HeaderFont.MeasureString("Gamepad").X) / 2;
                 titlePosition.Y = plankPosition.Y + (plankTexture.Height -
                     Fonts.HeaderFont.MeasureString("Gamepad").Y) / 2;
-                spriteBatch.DrawString(Fonts.HeaderFont, "Gamepad", titlePosition,
-                    Fonts.TitleColor);
+                spriteBatch.DrawString(Fonts.HeaderFont, "Gamepad", titlePosition, Fonts.TitleColor, MathHelper.ToRadians(-3.0f), Vector2.Zero, 1.0f, SpriteEffects.None, 0f);
             }
             else // draws the keyboard screen
             {
@@ -349,22 +346,22 @@ namespace RolePlaying
                     i++, j++)
                 {
                     keyboardString = InputManager.GetActionName((InputManager.Action)i);
-                    textPosition.X = chartLine1Position + 
+                    textPosition.X = chartLine1Position +
                         ((chartLine2Position - chartLine1Position) -
                         Fonts.DescriptionFont.MeasureString(keyboardString).X) / 2;
                     textPosition.Y = 253 + (spacing * j);
 
                     // Draw the action
-                    spriteBatch.DrawString(Fonts.DescriptionFont, keyboardString, 
+                    spriteBatch.DrawString(Fonts.DescriptionFont, keyboardString,
                         textPosition, Color.Black);
 
                     // Draw the key one
-                    keyboardString = 
+                    keyboardString =
                         keyboardInfo.totalActionList[i].keyboardKeys[0].ToString();
-                    textPosition.X = chartLine2Position + 
+                    textPosition.X = chartLine2Position +
                         ((chartLine3Position - chartLine2Position) -
                         Fonts.DescriptionFont.MeasureString(keyboardString).X) / 2;
-                    spriteBatch.DrawString(Fonts.DescriptionFont, keyboardString, 
+                    spriteBatch.DrawString(Fonts.DescriptionFont, keyboardString,
                         textPosition, Color.Black);
 
                     // Draw the key two
@@ -372,15 +369,15 @@ namespace RolePlaying
                     {
                         keyboardString = keyboardInfo.totalActionList[i].
                             keyboardKeys[1].ToString();
-                        textPosition.X = chartLine3Position + 
+                        textPosition.X = chartLine3Position +
                             ((chartLine4Position - chartLine3Position) -
                         Fonts.DescriptionFont.MeasureString(keyboardString).X) / 2;
-                        spriteBatch.DrawString(Fonts.DescriptionFont, keyboardString, 
+                        spriteBatch.DrawString(Fonts.DescriptionFont, keyboardString,
                             textPosition, Color.Black);
                     }
                     else
                     {
-                        textPosition.X = chartLine3Position + 
+                        textPosition.X = chartLine3Position +
                             ((chartLine4Position - chartLine3Position) -
                             Fonts.DescriptionFont.MeasureString("---").X) / 2;
                         spriteBatch.DrawString(Fonts.DescriptionFont, "---",
@@ -389,7 +386,7 @@ namespace RolePlaying
                 }
 
                 // Draw the Action
-                actionPosition.X = chartLine1Position + 
+                actionPosition.X = chartLine1Position +
                     ((chartLine2Position - chartLine1Position) -
                         Fonts.CaptionFont.MeasureString("Action").X) / 2;
                 actionPosition.Y = 200;
@@ -397,7 +394,7 @@ namespace RolePlaying
                     Fonts.CaptionColor);
 
                 // Draw the Key 1
-                key1Position.X = chartLine2Position + 
+                key1Position.X = chartLine2Position +
                     ((chartLine3Position - chartLine2Position) -
                     Fonts.CaptionFont.MeasureString("Key 1").X) / 2;
                 key1Position.Y = 200;
@@ -405,7 +402,7 @@ namespace RolePlaying
                     Fonts.CaptionColor);
 
                 // Draw the Key 2
-                key2Position.X = chartLine3Position + 
+                key2Position.X = chartLine3Position +
                     ((chartLine4Position - chartLine3Position) -
                     Fonts.CaptionFont.MeasureString("Key 2").X) / 2;
                 key2Position.Y = 200;
@@ -429,8 +426,7 @@ namespace RolePlaying
                     Fonts.HeaderFont.MeasureString("Keyboard").X) / 2;
                 titlePosition.Y = plankPosition.Y + (plankTexture.Height -
                     Fonts.HeaderFont.MeasureString("Keyboard").Y) / 2;
-                spriteBatch.DrawString(Fonts.HeaderFont, "Keyboard", titlePosition,
-                    Fonts.TitleColor);
+                spriteBatch.DrawString(Fonts.HeaderFont, "Keyboard", titlePosition, Fonts.TitleColor, MathHelper.ToRadians(-3.0f), Vector2.Zero, 1.0f, SpriteEffects.None, 0f);
 
                 // Draw the scroll textures
                 spriteBatch.Draw(scrollUpTexture, scrollUpPosition, Color.White);
@@ -439,7 +435,5 @@ namespace RolePlaying
 
             spriteBatch.End();
         }
-
-
     }
-}
+}

+ 28 - 21
RolePlayingGame/Core/MenuScreens/MainMenuScreen.cs

@@ -6,6 +6,9 @@
 //-----------------------------------------------------------------------------
 
 using System;
+using System.Linq;
+using System.Xml.Linq;
+using System.Xml.Serialization;
 using Microsoft.Xna.Framework;
 using Microsoft.Xna.Framework.Content;
 using Microsoft.Xna.Framework.Graphics;
@@ -43,7 +46,7 @@ namespace RolePlaying
 
 
 
-        MenuEntry newGameMenuEntry, exitGameMenuEntry; 
+        MenuEntry newGameMenuEntry, exitGameMenuEntry;
         MenuEntry saveGameMenuEntry, loadGameMenuEntry;
         MenuEntry controlsMenuEntry, helpMenuEntry;
 
@@ -64,6 +67,7 @@ namespace RolePlaying
             newGameMenuEntry.Font = Fonts.HeaderFont;
             newGameMenuEntry.Position = new Vector2(RolePlayingGame.BUFFER_HEIGHT - 5, 0f);
             newGameMenuEntry.Angle = -3.0f;
+            newGameMenuEntry.TextOffset = new Vector2(0f, 5.0f);
             newGameMenuEntry.Selected += NewGameMenuEntrySelected;
             MenuEntries.Add(newGameMenuEntry);
 
@@ -97,6 +101,7 @@ namespace RolePlaying
             controlsMenuEntry.Font = Fonts.HeaderFont;
             controlsMenuEntry.Position = new Vector2(RolePlayingGame.BUFFER_HEIGHT, 0f);
             controlsMenuEntry.Angle = 5.0f;
+            controlsMenuEntry.TextOffset = new Vector2(0f, -15.0f);
             controlsMenuEntry.Selected += ControlsMenuEntrySelected;
             MenuEntries.Add(controlsMenuEntry);
 
@@ -130,14 +135,14 @@ namespace RolePlaying
             // load the textures
             ContentManager content = ScreenManager.Game.Content;
             backgroundTexture = content.Load<Texture2D>(@"Textures\MainMenu\MainMenu");
-            descriptionAreaTexture = 
+            descriptionAreaTexture =
                 content.Load<Texture2D>(@"Textures\MainMenu\MainMenuInfoSpace");
             iconTexture = content.Load<Texture2D>(@"Textures\MainMenu\GameLogo");
-            plankTexture1 = 
+            plankTexture1 =
                 content.Load<Texture2D>(@"Textures\MainMenu\MainMenuPlank");
-            plankTexture2 = 
+            plankTexture2 =
                 content.Load<Texture2D>(@"Textures\MainMenu\MainMenuPlank02");
-            plankTexture3 = 
+            plankTexture3 =
                 content.Load<Texture2D>(@"Textures\MainMenu\MainMenuPlank03");
             backTexture = content.Load<Texture2D>(@"Textures\Buttons\BButton");
             selectTexture = content.Load<Texture2D>(@"Textures\Buttons\AButton");
@@ -169,7 +174,7 @@ namespace RolePlaying
             {
                 MenuEntries[i].Position = new Vector2(
                     MenuEntries[i].Position.X,
-                    500f - ((MenuEntries[i].Texture.Height - 10) * 
+                    500f - ((MenuEntries[i].Texture.Height - 10) *
                         (MenuEntries.Count - 1 - i)));
             }
 
@@ -208,10 +213,13 @@ namespace RolePlaying
             }
 
             ContentManager content = ScreenManager.Game.Content;
-            
-            var gameDescription = content.Load<GameStartDescription>("MainGameDescription");
-            var gameplayScreen = new GameplayScreen(gameDescription);
-			LoadingScreen.Load(ScreenManager, true, gameplayScreen);
+
+            //var gameStartDescription = content.Load<GameStartDescription>("MainGameDescription");
+
+            var gameStartDescription = GameStartDescription.Load("MainGameDescription");
+
+            var gameplayScreen = new GameplayScreen(gameStartDescription);
+            LoadingScreen.Load(ScreenManager, true, gameplayScreen);
         }
 
 
@@ -230,7 +238,7 @@ namespace RolePlaying
         /// </summary>
         void LoadGameMenuEntrySelected(object sender, EventArgs e)
         {
-            SaveLoadScreen loadGameScreen = 
+            SaveLoadScreen loadGameScreen =
                 new SaveLoadScreen(SaveLoadScreen.SaveLoadScreenMode.Load);
             loadGameScreen.LoadingSaveGame += new SaveLoadScreen.LoadingSaveGameHandler(
                 loadGameScreen_LoadingSaveGame);
@@ -247,7 +255,7 @@ namespace RolePlaying
             {
                 ExitScreen();
             }
-            LoadingScreen.Load(ScreenManager, true, 
+            LoadingScreen.Load(ScreenManager, true,
                 new GameplayScreen(saveGameDescription));
         }
 
@@ -269,7 +277,7 @@ namespace RolePlaying
             ScreenManager.AddScreen(new HelpScreen());
         }
 
-        
+
         /// <summary>
         /// When the user cancels the main menu,
         /// or when the Exit Game menu entry is selected.
@@ -280,7 +288,7 @@ namespace RolePlaying
             string message = String.Empty;
             if (Session.IsActive)
             {
-                message = 
+                message =
                     "Are you sure you want to exit?  All unsaved progress will be lost.";
             }
             else
@@ -301,7 +309,7 @@ namespace RolePlaying
         {
             ScreenManager.Game.Exit();
         }
-        
+
 
 
 
@@ -318,7 +326,7 @@ namespace RolePlaying
 
             // draw the background images
             spriteBatch.Draw(backgroundTexture, backgroundPosition, Color.White);
-            spriteBatch.Draw(descriptionAreaTexture, descriptionAreaPosition, 
+            spriteBatch.Draw(descriptionAreaTexture, descriptionAreaPosition,
                 Color.White);
             spriteBatch.Draw(iconTexture, iconPosition, Color.White);
 
@@ -335,12 +343,12 @@ namespace RolePlaying
             if ((selectedMenuEntry != null) &&
                 !String.IsNullOrEmpty(selectedMenuEntry.Description))
             {
-                Vector2 textSize = 
+                Vector2 textSize =
                     Fonts.DescriptionFont.MeasureString(selectedMenuEntry.Description);
                 Vector2 textPosition = descriptionAreaTextPosition + new Vector2(
                     (float)Math.Floor((descriptionAreaTexture.Width - textSize.X) / 2),
                     0f);
-                spriteBatch.DrawString(Fonts.DescriptionFont, 
+                spriteBatch.DrawString(Fonts.DescriptionFont,
                     selectedMenuEntry.Description, textPosition, Color.White);
             }
 
@@ -348,7 +356,7 @@ namespace RolePlaying
             spriteBatch.Draw(selectTexture, selectPosition, Color.White);
             spriteBatch.DrawString(Fonts.ButtonNamesFont, "Select",
                 new Vector2(
-                selectPosition.X - Fonts.ButtonNamesFont.MeasureString("Select").X - 5, 
+                selectPosition.X - Fonts.ButtonNamesFont.MeasureString("Select").X - 5,
                 selectPosition.Y + 5), Color.White);
 
             // if we are in-game, draw the back instruction
@@ -361,6 +369,5 @@ namespace RolePlaying
 
             spriteBatch.End();
         }
-
     }
-}
+}

+ 0 - 0
RolePlayingGame/Core/ModernRolePlayingGame.cs


+ 19 - 5
RolePlayingGame/Core/ScreenManager/MenuEntry.cs

@@ -41,6 +41,11 @@ namespace RolePlaying
         /// </summary>
         Vector2 position;
 
+        /// <summary>
+        /// The offset from the positionof this menu item.
+        /// </summary>
+        Vector2 textOffset = new Vector2(0, 0);
+
         /// <summary>
         /// The angle of this menu item on the screen.
         /// </summary>
@@ -83,7 +88,7 @@ namespace RolePlaying
             set { spriteFont = value; }
         }
 
-        
+
         /// <summary>
         /// Gets or sets the position of this menu entry.
         /// </summary>
@@ -102,6 +107,15 @@ namespace RolePlaying
             set { angle = value; }
         }
 
+        /// <summary>
+        /// Gets or sets the position of this menu entry.
+        /// </summary>
+        public Vector2 TextOffset
+        {
+            get { return textOffset; }
+            set { textOffset = value; }
+        }
+
 
         /// <summary>
         /// A description of the function of the button.
@@ -175,7 +189,7 @@ namespace RolePlaying
         {
             // Draw the selected entry in yellow, otherwise white.
             Color color = isSelected ? Fonts.MenuSelectedColor : Fonts.TitleColor;
-            
+
             // Draw text, centered on the middle of each line.
             ScreenManager screenManager = screen.ScreenManager;
             SpriteBatch spriteBatch = screenManager.SpriteBatch;
@@ -187,8 +201,8 @@ namespace RolePlaying
                 {
                     Vector2 textSize = spriteFont.MeasureString(text);
                     Vector2 textPosition = position + new Vector2(
-                        (float)Math.Floor((texture.Width - textSize.X) / 2),
-                        (float)Math.Floor((texture.Height - textSize.Y) / 2));
+                        (float)Math.Floor((texture.Width - textSize.X + textOffset.X) / 2),
+                        (float)Math.Floor((texture.Height - textSize.Y + textOffset.Y) / 2));
                     spriteBatch.DrawString(spriteFont, text, textPosition, color, MathHelper.ToRadians(angle), Vector2.Zero, 1.0f, SpriteEffects.None, 0f);
                 }
             }
@@ -209,4 +223,4 @@ namespace RolePlaying
 
 
     }
-}
+}

+ 29 - 14
RolePlayingGame/Core/Session/Party.cs

@@ -9,7 +9,11 @@ using System;
 using System.Collections.Generic;
 using System.Collections.ObjectModel;
 using System.IO;
+using System.Linq;
+using System.Xml.Linq;
+using Microsoft.Xna.Framework;
 using Microsoft.Xna.Framework.Content;
+using Microsoft.Xna.Framework.Graphics;
 using RolePlaying.Data;
 
 namespace RolePlaying
@@ -38,7 +42,7 @@ namespace RolePlaying
             set { players = value; }
         }
 
-        
+
 
         /// <summary>
         /// Add a new player to the party.
@@ -144,7 +148,7 @@ namespace RolePlaying
 
             // search for an existing entry
             ContentEntry<Gear> existingEntry = inventory.Find(
-                delegate(ContentEntry<Gear> entry)
+                delegate (ContentEntry<Gear> entry)
                 {
                     return (entry.Content == gear);
                 });
@@ -186,7 +190,7 @@ namespace RolePlaying
 
             // search for an existing entry
             ContentEntry<Gear> existingEntry = inventory.Find(
-                delegate(ContentEntry<Gear> entry)
+                delegate (ContentEntry<Gear> entry)
                 {
                     return (entry.Content == gear);
                 });
@@ -229,7 +233,7 @@ namespace RolePlaying
 
 
 
-        
+
         /// <summary>
         /// The name and kill-count of monsters killed in the active quest.
         /// </summary>
@@ -273,7 +277,7 @@ namespace RolePlaying
         /// <summary>
         /// Creates a new Party object from the game-start description.
         /// </summary>
-        public Party(GameStartDescription gameStartDescription, 
+        public Party(GameStartDescription gameStartDescription,
             ContentManager contentManager)
         {
             // check the parameters
@@ -289,9 +293,14 @@ namespace RolePlaying
             // load the players
             foreach (string contentName in gameStartDescription.PlayerContentNames)
             {
-                JoinParty(contentManager.Load<Player>(
+                // load the player and add it to the party
+                /* TODO var player = contentManager.Load<Player>(
                     Path.Combine(@"Characters\Players", contentName)).Clone()
-                    as Player);
+                    as Player;*/
+
+                var player = Player.Load(Path.Combine(@"Characters\Players", contentName), contentManager);
+
+                JoinParty(player);
             }
         }
 
@@ -314,16 +323,24 @@ namespace RolePlaying
             // load the players
             foreach (PlayerSaveData playerData in partyData.players)
             {
-                Player player = 
-                    contentManager.Load<Player>(playerData.assetName).Clone() as Player;
+                /*Player player = 
+                    contentManager.Load<Player>(playerData.assetName).Clone() as Player;*/
+
+                var player = Player.Load(playerData.assetName, contentManager);
+
                 player.CharacterLevel = playerData.characterLevel;
                 player.Experience = playerData.experience;
                 player.EquippedEquipment.Clear();
                 foreach (string equipmentAssetName in playerData.equipmentAssetNames)
                 {
-                    player.Equip(contentManager.Load<Equipment>(equipmentAssetName));
+                    // TODO var equipment = contentManager.Load<Equipment>(equipmentAssetName);
+
+                    var equipment = Equipment.Load(equipmentAssetName);
+
+                    player.Equip(equipment);
                 }
                 player.StatisticsModifiers = playerData.statisticsModifiers;
+
                 JoinParty(player);
             }
 
@@ -344,9 +361,7 @@ namespace RolePlaying
             {
                 monsterKills.Add(partyData.monsterKillNames[i],
                     partyData.monsterKillCounts[i]);
-            }            
+            }
         }
-
-
     }
-}
+}

+ 105 - 98
RolePlayingGame/Core/Session/Session.cs

@@ -8,6 +8,8 @@
 using System;
 using System.Collections.Generic;
 using System.IO;
+using System.Linq;
+using System.Xml.Linq;
 using System.Xml.Serialization;
 using Microsoft.Xna.Framework;
 using Microsoft.Xna.Framework.Content;
@@ -71,7 +73,9 @@ namespace RolePlaying
 
             // load the map
             ContentManager content = singleton.screenManager.Game.Content;
-            Map map = content.Load<Map>(mapContentName).Clone() as Map;
+
+            //Map map = content.Load<Map>(mapContentName).Clone() as Map;
+            var map = Map.Load(mapContentName, content);
 
             // modify the map based on the world changes (removed chests, etc.).
             singleton.ModifyMap(map);
@@ -99,11 +103,11 @@ namespace RolePlaying
             {
                 MapEntry<FixedCombat> fixedCombatEntry =
                     singleton.quest.FixedCombatEntries.Find(
-                        delegate(WorldEntry<FixedCombat> worldEntry)
+                        delegate (WorldEntry<FixedCombat> worldEntry)
                         {
-                            return 
+                            return
                                 TileEngine.Map.AssetName.EndsWith(
-                                    worldEntry.MapContentName) && 
+                                    worldEntry.MapContentName) &&
                                 worldEntry.MapPosition == mapPosition;
                         });
                 if (fixedCombatEntry != null)
@@ -114,9 +118,9 @@ namespace RolePlaying
             }
 
             // look for fixed-combats from the map
-            MapEntry<FixedCombat> fixedCombatMapEntry = 
+            MapEntry<FixedCombat> fixedCombatMapEntry =
                 TileEngine.Map.FixedCombatEntries.Find(
-                    delegate(MapEntry<FixedCombat> mapEntry)
+                    delegate (MapEntry<FixedCombat> mapEntry)
                     {
                         return mapEntry.MapPosition == mapPosition;
                     });
@@ -130,7 +134,7 @@ namespace RolePlaying
             if (singleton.quest != null)
             {
                 MapEntry<Chest> chestEntry = singleton.quest.ChestEntries.Find(
-                    delegate(WorldEntry<Chest> worldEntry)
+                    delegate (WorldEntry<Chest> worldEntry)
                     {
                         return
                             TileEngine.Map.AssetName.EndsWith(
@@ -146,7 +150,7 @@ namespace RolePlaying
 
             // look for chests from the map
             MapEntry<Chest> chestMapEntry =
-                TileEngine.Map.ChestEntries.Find(delegate(MapEntry<Chest> mapEntry)
+                TileEngine.Map.ChestEntries.Find(delegate (MapEntry<Chest> mapEntry)
                 {
                     return mapEntry.MapPosition == mapPosition;
                 });
@@ -158,7 +162,7 @@ namespace RolePlaying
 
             // look for player NPCs from the map
             MapEntry<Player> playerNpcEntry =
-                TileEngine.Map.PlayerNpcEntries.Find(delegate(MapEntry<Player> mapEntry)
+                TileEngine.Map.PlayerNpcEntries.Find(delegate (MapEntry<Player> mapEntry)
                 {
                     return mapEntry.MapPosition == mapPosition;
                 });
@@ -170,7 +174,7 @@ namespace RolePlaying
 
             // look for quest NPCs from the map
             MapEntry<QuestNpc> questNpcEntry =
-                TileEngine.Map.QuestNpcEntries.Find(delegate(MapEntry<QuestNpc> mapEntry)
+                TileEngine.Map.QuestNpcEntries.Find(delegate (MapEntry<QuestNpc> mapEntry)
                 {
                     return mapEntry.MapPosition == mapPosition;
                 });
@@ -182,7 +186,7 @@ namespace RolePlaying
 
             // look for portals from the map
             MapEntry<Portal> portalEntry =
-                TileEngine.Map.PortalEntries.Find(delegate(MapEntry<Portal> mapEntry)
+                TileEngine.Map.PortalEntries.Find(delegate (MapEntry<Portal> mapEntry)
                 {
                     return mapEntry.MapPosition == mapPosition;
                 });
@@ -194,7 +198,7 @@ namespace RolePlaying
 
             // look for inns from the map
             MapEntry<Inn> innEntry =
-                TileEngine.Map.InnEntries.Find(delegate(MapEntry<Inn> mapEntry)
+                TileEngine.Map.InnEntries.Find(delegate (MapEntry<Inn> mapEntry)
                 {
                     return mapEntry.MapPosition == mapPosition;
                 });
@@ -206,7 +210,7 @@ namespace RolePlaying
 
             // look for stores from the map
             MapEntry<Store> storeEntry =
-                TileEngine.Map.StoreEntries.Find(delegate(MapEntry<Store> mapEntry)
+                TileEngine.Map.StoreEntries.Find(delegate (MapEntry<Store> mapEntry)
                 {
                     return mapEntry.MapPosition == mapPosition;
                 });
@@ -318,7 +322,7 @@ namespace RolePlaying
             // add the store screen
             singleton.screenManager.AddScreen(new StoreScreen(storeEntry.Content));
         }
-        
+
 
         /// <summary>
         /// Performs the actions associated with encountering a Portal entry.
@@ -332,7 +336,7 @@ namespace RolePlaying
             }
 
             // change to the new map
-            ChangeMap(portalEntry.Content.DestinationMapContentName, 
+            ChangeMap(portalEntry.Content.DestinationMapContentName,
                 portalEntry.Content);
         }
 
@@ -369,7 +373,7 @@ namespace RolePlaying
         }
 
 
-        
+
 
 
 
@@ -399,7 +403,7 @@ namespace RolePlaying
                 {
                     return false;
                 }
-                return singleton.currentQuestIndex >= 
+                return singleton.currentQuestIndex >=
                     singleton.questLine.QuestContentNames.Count;
             }
         }
@@ -445,7 +449,7 @@ namespace RolePlaying
             }
 
             // if we don't have a quest, then take the next one from teh list
-            if ((quest == null) && (questLine.Quests.Count > 0) && 
+            if ((quest == null) && (questLine.Quests.Count > 0) &&
                 !Session.IsQuestLineComplete)
             {
                 quest = questLine.Quests[currentQuestIndex];
@@ -561,13 +565,13 @@ namespace RolePlaying
         /// <summary>
         /// The chests removed from the map asset by player actions.
         /// </summary>
-        private List<WorldEntry<Chest>> removedMapChests = 
+        private List<WorldEntry<Chest>> removedMapChests =
             new List<WorldEntry<Chest>>();
 
         /// <summary>
         /// The chests removed from the current quest asset by player actions.
         /// </summary>
-        private List<WorldEntry<Chest>> removedQuestChests = 
+        private List<WorldEntry<Chest>> removedQuestChests =
             new List<WorldEntry<Chest>>();
 
         /// <summary>
@@ -585,7 +589,7 @@ namespace RolePlaying
             if (TileEngine.Map != null)
             {
                 int removedEntries = TileEngine.Map.ChestEntries.RemoveAll(
-                    delegate(MapEntry<Chest> entry)
+                    delegate (MapEntry<Chest> entry)
                     {
                         return ((entry.ContentName == mapEntry.ContentName) &&
                             (entry.MapPosition == mapEntry.MapPosition));
@@ -608,7 +612,7 @@ namespace RolePlaying
             if (singleton.quest != null)
             {
                 int removedEntries = singleton.quest.ChestEntries.RemoveAll(
-                    delegate(WorldEntry<Chest> entry)
+                    delegate (WorldEntry<Chest> entry)
                     {
                         return ((entry.ContentName == mapEntry.ContentName) &&
                             (entry.MapPosition == mapEntry.MapPosition) &&
@@ -657,7 +661,7 @@ namespace RolePlaying
             if (TileEngine.Map != null)
             {
                 int removedEntries = TileEngine.Map.FixedCombatEntries.RemoveAll(
-                    delegate(MapEntry<FixedCombat> entry)
+                    delegate (MapEntry<FixedCombat> entry)
                     {
                         return ((entry.ContentName == mapEntry.ContentName) &&
                             (entry.MapPosition == mapEntry.MapPosition));
@@ -680,7 +684,7 @@ namespace RolePlaying
             if (singleton.quest != null)
             {
                 int removedEntries = singleton.quest.FixedCombatEntries.RemoveAll(
-                    delegate(WorldEntry<FixedCombat> entry)
+                    delegate (WorldEntry<FixedCombat> entry)
                     {
                         return ((entry.ContentName == mapEntry.ContentName) &&
                             (entry.MapPosition == mapEntry.MapPosition) &&
@@ -723,7 +727,7 @@ namespace RolePlaying
             if (TileEngine.Map != null)
             {
                 int removedEntries = TileEngine.Map.PlayerNpcEntries.RemoveAll(
-                    delegate(MapEntry<Player> entry)
+                    delegate (MapEntry<Player> entry)
                     {
                         return ((entry.ContentName == mapEntry.ContentName) &&
                             (entry.MapPosition == mapEntry.MapPosition));
@@ -749,7 +753,7 @@ namespace RolePlaying
         /// <summary>
         /// The chests that have been modified, but not emptied, by player action.
         /// </summary>
-        private List<ModifiedChestEntry> modifiedMapChests = 
+        private List<ModifiedChestEntry> modifiedMapChests =
             new List<ModifiedChestEntry>();
 
 
@@ -757,7 +761,7 @@ namespace RolePlaying
         /// The chests belonging to the current quest that have been modified,
         /// but not emptied, by player action.
         /// </summary>
-        private List<ModifiedChestEntry> modifiedQuestChests = 
+        private List<ModifiedChestEntry> modifiedQuestChests =
             new List<ModifiedChestEntry>();
 
 
@@ -773,8 +777,8 @@ namespace RolePlaying
                 throw new ArgumentNullException("mapEntry");
             }
 
-            Predicate<ModifiedChestEntry> checkModifiedChests = 
-                delegate(ModifiedChestEntry entry)
+            Predicate<ModifiedChestEntry> checkModifiedChests =
+                delegate (ModifiedChestEntry entry)
                 {
                     return
                         (TileEngine.Map.AssetName.EndsWith(
@@ -785,7 +789,7 @@ namespace RolePlaying
 
             // check the map for the item first
             if ((TileEngine.Map != null) && TileEngine.Map.ChestEntries.Exists(
-                delegate(MapEntry<Chest> entry)
+                delegate (MapEntry<Chest> entry)
                 {
                     return ((entry.ContentName == mapEntry.ContentName) &&
                         (entry.MapPosition == mapEntry.MapPosition));
@@ -797,7 +801,7 @@ namespace RolePlaying
                 modifiedChestEntry.WorldEntry.ContentName = mapEntry.ContentName;
                 modifiedChestEntry.WorldEntry.Count = mapEntry.Count;
                 modifiedChestEntry.WorldEntry.Direction = mapEntry.Direction;
-                modifiedChestEntry.WorldEntry.MapContentName = 
+                modifiedChestEntry.WorldEntry.MapContentName =
                     TileEngine.Map.AssetName;
                 modifiedChestEntry.WorldEntry.MapPosition = mapEntry.MapPosition;
                 Chest chest = mapEntry.Content;
@@ -806,11 +810,11 @@ namespace RolePlaying
                 singleton.modifiedMapChests.Add(modifiedChestEntry);
                 return;
             }
-            
+
 
             // look for the map entry within the quest
             if ((singleton.quest != null) && singleton.quest.ChestEntries.Exists(
-                delegate(WorldEntry<Chest> entry)
+                delegate (WorldEntry<Chest> entry)
                 {
                     return ((entry.ContentName == mapEntry.ContentName) &&
                         (entry.MapPosition == mapEntry.MapPosition) &&
@@ -849,12 +853,12 @@ namespace RolePlaying
             if ((removedMapChests != null) && (removedMapChests.Count > 0))
             {
                 // check each removed-content entry
-                map.ChestEntries.RemoveAll(delegate(MapEntry<Chest> mapEntry)
+                map.ChestEntries.RemoveAll(delegate (MapEntry<Chest> mapEntry)
                 {
                     return (removedMapChests.Exists(
-                        delegate(WorldEntry<Chest> removedEntry)
+                        delegate (WorldEntry<Chest> removedEntry)
                         {
-                            return 
+                            return
                                 (map.AssetName.EndsWith(removedEntry.MapContentName) &&
                                 (removedEntry.ContentName == mapEntry.ContentName) &&
                                 (removedEntry.MapPosition == mapEntry.MapPosition));
@@ -866,10 +870,10 @@ namespace RolePlaying
             if ((removedMapFixedCombats != null) && (removedMapFixedCombats.Count > 0))
             {
                 // check each removed-content entry
-                map.FixedCombatEntries.RemoveAll(delegate(MapEntry<FixedCombat> mapEntry)
+                map.FixedCombatEntries.RemoveAll(delegate (MapEntry<FixedCombat> mapEntry)
                 {
                     return (removedMapFixedCombats.Exists(
-                        delegate(WorldEntry<FixedCombat> removedEntry)
+                        delegate (WorldEntry<FixedCombat> removedEntry)
                         {
                             return
                                 (map.AssetName.EndsWith(removedEntry.MapContentName) &&
@@ -883,10 +887,10 @@ namespace RolePlaying
             if ((removedMapPlayerNpcs != null) && (removedMapPlayerNpcs.Count > 0))
             {
                 // check each removed-content entry
-                map.PlayerNpcEntries.RemoveAll(delegate(MapEntry<Player> mapEntry)
+                map.PlayerNpcEntries.RemoveAll(delegate (MapEntry<Player> mapEntry)
                 {
                     return (removedMapPlayerNpcs.Exists(
-                        delegate(WorldEntry<Player> removedEntry)
+                        delegate (WorldEntry<Player> removedEntry)
                         {
                             return
                                 (map.AssetName.EndsWith(removedEntry.MapContentName) &&
@@ -902,14 +906,14 @@ namespace RolePlaying
                 foreach (MapEntry<Chest> entry in map.ChestEntries)
                 {
                     ModifiedChestEntry modifiedEntry = modifiedMapChests.Find(
-                        delegate(ModifiedChestEntry modifiedTestEntry)
+                        delegate (ModifiedChestEntry modifiedTestEntry)
                         {
                             return
                                 (map.AssetName.EndsWith(
                                     modifiedTestEntry.WorldEntry.MapContentName) &&
-                                (modifiedTestEntry.WorldEntry.ContentName == 
+                                (modifiedTestEntry.WorldEntry.ContentName ==
                                     entry.ContentName) &&
-                                (modifiedTestEntry.WorldEntry.MapPosition == 
+                                (modifiedTestEntry.WorldEntry.MapPosition ==
                                     entry.MapPosition));
                         });
                     // if the chest has been modified, apply the changes
@@ -938,17 +942,17 @@ namespace RolePlaying
             {
                 // check each removed-content entry
                 quest.ChestEntries.RemoveAll(
-                    delegate(WorldEntry<Chest> worldEntry)
+                    delegate (WorldEntry<Chest> worldEntry)
                     {
                         return (removedQuestChests.Exists(
-                            delegate(WorldEntry<Chest> removedEntry)
+                            delegate (WorldEntry<Chest> removedEntry)
                             {
                                 return
                                     (removedEntry.MapContentName.EndsWith(
                                         worldEntry.MapContentName) &&
-                                    (removedEntry.ContentName == 
+                                    (removedEntry.ContentName ==
                                         worldEntry.ContentName) &&
-                                    (removedEntry.MapPosition == 
+                                    (removedEntry.MapPosition ==
                                         worldEntry.MapPosition));
                             }));
                     });
@@ -960,17 +964,17 @@ namespace RolePlaying
             {
                 // check each removed-content entry
                 quest.FixedCombatEntries.RemoveAll(
-                    delegate(WorldEntry<FixedCombat> worldEntry)
+                    delegate (WorldEntry<FixedCombat> worldEntry)
                     {
                         return (removedQuestFixedCombats.Exists(
-                            delegate(WorldEntry<FixedCombat> removedEntry)
+                            delegate (WorldEntry<FixedCombat> removedEntry)
                             {
                                 return
                                     (removedEntry.MapContentName.EndsWith(
                                         worldEntry.MapContentName) &&
-                                    (removedEntry.ContentName == 
+                                    (removedEntry.ContentName ==
                                         worldEntry.ContentName) &&
-                                    (removedEntry.MapPosition == 
+                                    (removedEntry.MapPosition ==
                                         worldEntry.MapPosition));
                             }));
                     });
@@ -982,14 +986,14 @@ namespace RolePlaying
                 foreach (WorldEntry<Chest> entry in quest.ChestEntries)
                 {
                     ModifiedChestEntry modifiedEntry = modifiedQuestChests.Find(
-                        delegate(ModifiedChestEntry modifiedTestEntry)
+                        delegate (ModifiedChestEntry modifiedTestEntry)
                         {
                             return
-                                ((modifiedTestEntry.WorldEntry.MapContentName == 
+                                ((modifiedTestEntry.WorldEntry.MapContentName ==
                                     entry.MapContentName) &&
-                                (modifiedTestEntry.WorldEntry.ContentName == 
+                                (modifiedTestEntry.WorldEntry.ContentName ==
                                     entry.ContentName) &&
-                                (modifiedTestEntry.WorldEntry.MapPosition == 
+                                (modifiedTestEntry.WorldEntry.MapPosition ==
                                     entry.MapPosition));
                         });
                     // if the chest has been modified, apply the changes
@@ -1017,10 +1021,10 @@ namespace RolePlaying
             chest.Gold = modifiedChestEntry.Gold;
 
             // remove all contents not found in the modified version
-            chest.Entries.RemoveAll(delegate(ContentEntry<Gear> contentEntry)
+            chest.Entries.RemoveAll(delegate (ContentEntry<Gear> contentEntry)
             {
                 return !modifiedChestEntry.ChestEntries.Exists(
-                    delegate(ContentEntry<Gear> modifiedTestEntry)
+                    delegate (ContentEntry<Gear> modifiedTestEntry)
                     {
                         return (contentEntry.ContentName ==
                             modifiedTestEntry.ContentName);
@@ -1032,7 +1036,7 @@ namespace RolePlaying
             {
                 ContentEntry<Gear> modifiedGearEntry =
                     modifiedChestEntry.ChestEntries.Find(
-                        delegate(ContentEntry<Gear> modifiedTestEntry)
+                        delegate (ContentEntry<Gear> modifiedTestEntry)
                         {
                             return (contentEntry.ContentName ==
                                 modifiedTestEntry.ContentName);
@@ -1082,7 +1086,7 @@ namespace RolePlaying
             get { return (singleton == null ? null : singleton.hud); }
         }
 
-        
+
 
 
 
@@ -1173,7 +1177,7 @@ namespace RolePlaying
                 if (TileEngine.Map.CombatTexture != null)
                 {
                     spriteBatch.Begin();
-                    spriteBatch.Draw(TileEngine.Map.CombatTexture, Vector2.Zero, 
+                    spriteBatch.Draw(TileEngine.Map.CombatTexture, Vector2.Zero,
                         Color.White);
                     spriteBatch.End();
                 }
@@ -1257,7 +1261,7 @@ namespace RolePlaying
                 {
                     continue;
                 }
-                Vector2 position = 
+                Vector2 position =
                     TileEngine.GetScreenPosition(playerEntry.MapPosition);
                 playerEntry.Content.ResetAnimation(false);
                 switch (playerEntry.Content.State)
@@ -1298,7 +1302,7 @@ namespace RolePlaying
                 {
                     continue;
                 }
-                Vector2 position = 
+                Vector2 position =
                     TileEngine.GetScreenPosition(questNpcEntry.MapPosition);
                 questNpcEntry.Content.ResetAnimation(false);
                 switch (questNpcEntry.Content.State)
@@ -1318,7 +1322,7 @@ namespace RolePlaying
                         {
                             questNpcEntry.Content.WalkingSprite.UpdateAnimation(
                                 elapsedSeconds);
-                            questNpcEntry.Content.WalkingSprite.Draw(spriteBatch, 
+                            questNpcEntry.Content.WalkingSprite.Draw(spriteBatch,
                                 position,
                                 1f - position.Y / (float)TileEngine.Viewport.Height);
                         }
@@ -1336,15 +1340,15 @@ namespace RolePlaying
             // draw the fixed-combat monsters NPCs from the TileEngine.Map
             // -- since there may be many of the same FixedCombat object 
             //    on the TileEngine.Map, but their animations are handled differently
-            foreach (MapEntry<FixedCombat> fixedCombatEntry in 
+            foreach (MapEntry<FixedCombat> fixedCombatEntry in
                 TileEngine.Map.FixedCombatEntries)
             {
-                if ((fixedCombatEntry.Content == null) || 
+                if ((fixedCombatEntry.Content == null) ||
                     (fixedCombatEntry.Content.Entries.Count <= 0))
                 {
                     continue;
                 }
-                Vector2 position = 
+                Vector2 position =
                     TileEngine.GetScreenPosition(fixedCombatEntry.MapPosition);
                 fixedCombatEntry.MapSprite.UpdateAnimation(elapsedSeconds);
                 fixedCombatEntry.MapSprite.Draw(spriteBatch, position,
@@ -1357,10 +1361,10 @@ namespace RolePlaying
             if ((quest != null) && ((quest.Stage == Quest.QuestStage.InProgress) ||
                 (quest.Stage == Quest.QuestStage.RequirementsMet)))
             {
-                foreach (WorldEntry<FixedCombat> fixedCombatEntry 
+                foreach (WorldEntry<FixedCombat> fixedCombatEntry
                     in quest.FixedCombatEntries)
                 {
-                    if ((fixedCombatEntry.Content == null) || 
+                    if ((fixedCombatEntry.Content == null) ||
                         (fixedCombatEntry.Content.Entries.Count <= 0) ||
                         !TileEngine.Map.AssetName.EndsWith(
                             fixedCombatEntry.MapContentName))
@@ -1386,7 +1390,7 @@ namespace RolePlaying
                 spriteBatch.Draw(chestEntry.Content.Texture,
                     position, null, Color.White, 0f, Vector2.Zero, 1f,
                     SpriteEffects.None,
-                    MathHelper.Clamp(1f - position.Y / 
+                    MathHelper.Clamp(1f - position.Y /
                         (float)TileEngine.Viewport.Height, 0f, 1f));
             }
 
@@ -1396,17 +1400,17 @@ namespace RolePlaying
             {
                 foreach (WorldEntry<Chest> chestEntry in quest.ChestEntries)
                 {
-                    if ((chestEntry.Content == null) || 
+                    if ((chestEntry.Content == null) ||
                         !TileEngine.Map.AssetName.EndsWith(chestEntry.MapContentName))
                     {
                         continue;
                     }
-                    Vector2 position = 
+                    Vector2 position =
                         TileEngine.GetScreenPosition(chestEntry.MapPosition);
                     spriteBatch.Draw(chestEntry.Content.Texture,
                         position, null, Color.White, 0f, Vector2.Zero, 1f,
                         SpriteEffects.None,
-                        MathHelper.Clamp(1f - position.Y / 
+                        MathHelper.Clamp(1f - position.Y /
                             (float)TileEngine.Viewport.Height, 0f, 1f));
                 }
             }
@@ -1432,12 +1436,12 @@ namespace RolePlaying
             Player player = party.Players[0];
             if (player.ShadowTexture != null)
             {
-                spriteBatch.Draw(player.ShadowTexture, 
+                spriteBatch.Draw(player.ShadowTexture,
                     TileEngine.PartyLeaderPosition.ScreenPosition, null, Color.White, 0f,
                     new Vector2(
                         (player.ShadowTexture.Width - TileEngine.Map.TileSize.X) / 2,
-                        (player.ShadowTexture.Height - TileEngine.Map.TileSize.Y) / 2 - 
-                            player.ShadowTexture.Height / 6), 
+                        (player.ShadowTexture.Height - TileEngine.Map.TileSize.Y) / 2 -
+                            player.ShadowTexture.Height / 6),
                     1f, SpriteEffects.None, 1f);
             }
 
@@ -1450,15 +1454,15 @@ namespace RolePlaying
                 }
                 if (playerEntry.Content.ShadowTexture != null)
                 {
-                    Vector2 position = 
+                    Vector2 position =
                         TileEngine.GetScreenPosition(playerEntry.MapPosition);
                     spriteBatch.Draw(playerEntry.Content.ShadowTexture, position,
-                        null, Color.White, 0f, 
+                        null, Color.White, 0f,
                         new Vector2(
-                        (playerEntry.Content.ShadowTexture.Width - 
+                        (playerEntry.Content.ShadowTexture.Width -
                             TileEngine.Map.TileSize.X) / 2,
-                        (playerEntry.Content.ShadowTexture.Height - 
-                            TileEngine.Map.TileSize.Y) / 2 - 
+                        (playerEntry.Content.ShadowTexture.Height -
+                            TileEngine.Map.TileSize.Y) / 2 -
                             playerEntry.Content.ShadowTexture.Height / 6),
                         1f, SpriteEffects.None, 1f);
                 }
@@ -1473,25 +1477,25 @@ namespace RolePlaying
                 }
                 if (questNpcEntry.Content.ShadowTexture != null)
                 {
-                    Vector2 position = 
+                    Vector2 position =
                         TileEngine.GetScreenPosition(questNpcEntry.MapPosition);
                     spriteBatch.Draw(questNpcEntry.Content.ShadowTexture, position,
                         null, Color.White, 0f,
                         new Vector2(
-                            (questNpcEntry.Content.ShadowTexture.Width - 
+                            (questNpcEntry.Content.ShadowTexture.Width -
                                 TileEngine.Map.TileSize.X) / 2,
-                            (questNpcEntry.Content.ShadowTexture.Height - 
-                                TileEngine.Map.TileSize.Y) / 2 - 
+                            (questNpcEntry.Content.ShadowTexture.Height -
+                                TileEngine.Map.TileSize.Y) / 2 -
                                 questNpcEntry.Content.ShadowTexture.Height / 6),
                         1f, SpriteEffects.None, 1f);
                 }
             }
 
             // draw the fixed-combat monsters NPCs' shadows
-            foreach (MapEntry<FixedCombat> fixedCombatEntry in 
+            foreach (MapEntry<FixedCombat> fixedCombatEntry in
                 TileEngine.Map.FixedCombatEntries)
             {
-                if ((fixedCombatEntry.Content == null) || 
+                if ((fixedCombatEntry.Content == null) ||
                     (fixedCombatEntry.Content.Entries.Count <= 0))
                 {
                     continue;
@@ -1499,13 +1503,13 @@ namespace RolePlaying
                 Monster monster = fixedCombatEntry.Content.Entries[0].Content;
                 if (monster.ShadowTexture != null)
                 {
-                    Vector2 position = 
+                    Vector2 position =
                         TileEngine.GetScreenPosition(fixedCombatEntry.MapPosition);
                     spriteBatch.Draw(monster.ShadowTexture, position,
                         null, Color.White, 0f,
                         new Vector2(
                         (monster.ShadowTexture.Width - TileEngine.Map.TileSize.X) / 2,
-                        (monster.ShadowTexture.Height - TileEngine.Map.TileSize.Y) / 2 - 
+                        (monster.ShadowTexture.Height - TileEngine.Map.TileSize.Y) / 2 -
                             monster.ShadowTexture.Height / 6),
                         1f, SpriteEffects.None, 1f);
                 }
@@ -1520,7 +1524,7 @@ namespace RolePlaying
         /// <summary>
         /// Start a new session based on the data provided.
         /// </summary>
-        public static void StartNewSession(GameStartDescription gameStartDescription, 
+        public static void StartNewSession(GameStartDescription gameStartDescription,
             ScreenManager screenManager, GameplayScreen gameplayScreen)
         {
             // check the parameters
@@ -1550,10 +1554,15 @@ namespace RolePlaying
             ContentManager content = singleton.screenManager.Game.Content;
             singleton.party = new Party(gameStartDescription, content);
 
+            /* var loadedQuestLine = content.Load<QuestLine>(
+                Path.Combine(@"Quests\QuestLines",
+                gameStartDescription.QuestLineContentName)).Clone() as QuestLine;*/
+
+            var loadedQuestLine = QuestLine.Load(Path.Combine(@"Quests\QuestLines",
+                gameStartDescription.QuestLineContentName));
+
             // load the quest line
-            singleton.questLine = content.Load<QuestLine>(
-                Path.Combine(@"Quests\QuestLines", 
-                gameStartDescription.QuestLineContentName)).Clone() as QuestLine;
+            singleton.questLine = loadedQuestLine;
         }
 
 
@@ -1966,10 +1975,10 @@ namespace RolePlaying
         /// <summary>
         /// XML serializer for SaveGameDescription objects.
         /// </summary>
-        private static XmlSerializer saveGameDescriptionSerializer = 
+        private static XmlSerializer saveGameDescriptionSerializer =
             new XmlSerializer(typeof(SaveGameDescription));
 
-        
+
         /// <summary>
         /// Refresh the list of save-game descriptions.
         /// </summary>
@@ -2161,7 +2170,7 @@ namespace RolePlaying
 
 
 
-    
+
 
 
         /// <summary>
@@ -2176,7 +2185,5 @@ namespace RolePlaying
         {
             get { return random; }
         }
-
-
     }
-}
+}

+ 58 - 10
RolePlayingGame/RolePlayingGameData/Characters/CharacterClass.cs

@@ -7,6 +7,7 @@
 
 using System;
 using System.Collections.Generic;
+using System.Linq;
 using Microsoft.Xna.Framework.Content;
 
 namespace RolePlaying.Data
@@ -51,7 +52,7 @@ namespace RolePlaying.Data
             set { initialStatistics = value; }
         }
 
-        
+
 
 
 
@@ -74,7 +75,7 @@ namespace RolePlaying.Data
         /// <summary>
         /// Entries of the requirements and rewards for each level of this class.
         /// </summary>
-        private List<CharacterLevelDescription> levelEntries = 
+        private List<CharacterLevelDescription> levelEntries =
             new List<CharacterLevelDescription>();
 
         /// <summary>
@@ -166,9 +167,9 @@ namespace RolePlaying.Data
                 foreach (Spell spell in levelEntries[i].Spells)
                 {
                     Spell existingSpell = spells.Find(
-                        delegate(Spell testSpell)
+                        delegate (Spell testSpell)
                         {
-                            return spell.AssetName == testSpell.AssetName; 
+                            return spell.AssetName == testSpell.AssetName;
                         });
                     if (existingSpell == null)
                     {
@@ -184,6 +185,55 @@ namespace RolePlaying.Data
             return spells;
         }
 
+        internal static CharacterClass Load(string path)
+        {
+            var asset = XmlHelper.GetAssetElementFromXML(path);
+
+            var characterClass = new CharacterClass
+            {
+                Name = (string)asset.Element("Name"),
+                InitialStatistics = new StatisticsValue
+                {
+                    HealthPoints = (int?)asset.Element("InitialStatistics").Element("HealthPoints") ?? 0,
+                    MagicPoints = (int?)asset.Element("InitialStatistics").Element("MagicPoints") ?? 0,
+                    PhysicalOffense = (int?)asset.Element("InitialStatistics").Element("PhysicalOffense") ?? 0,
+                    PhysicalDefense = (int?)asset.Element("InitialStatistics").Element("PhysicalDefense") ?? 0,
+                    MagicalOffense = (int?)asset.Element("InitialStatistics").Element("MagicalOffense") ?? 0,
+                    MagicalDefense = (int?)asset.Element("InitialStatistics").Element("MagicalDefense") ?? 0,
+                },
+                LevelingStatistics = new CharacterLevelingStatistics
+                {
+                    HealthPointsIncrease = (int?)asset.Element("LevelingStatistics").Element("HealthPointsIncrease") ?? 0,
+                    LevelsPerHealthPointsIncrease = (int?)asset.Element("LevelingStatistics").Element("LevelsPerHealthPointsIncrease") ?? 0,
+                    MagicPointsIncrease = (int?)asset.Element("LevelingStatistics").Element("MagicPointsIncrease") ?? 0,
+                    LevelsPerMagicPointsIncrease = (int?)asset.Element("LevelingStatistics").Element("LevelsPerMagicPointsIncrease") ?? 0,
+                    PhysicalOffenseIncrease = (int?)asset.Element("LevelingStatistics").Element("PhysicalOffenseIncrease") ?? 0,
+                    LevelsPerPhysicalOffenseIncrease = (int?)asset.Element("LevelingStatistics").Element("LevelsPerPhysicalOffenseIncrease") ?? 0,
+                    PhysicalDefenseIncrease = (int?)asset.Element("LevelingStatistics").Element("PhysicalDefenseIncrease") ?? 0,
+                    LevelsPerPhysicalDefenseIncrease = (int?)asset.Element("LevelingStatistics").Element("LevelsPerPhysicalDefenseIncrease") ?? 0,
+                    MagicalOffenseIncrease = (int?)asset.Element("LevelingStatistics").Element("MagicalOffenseIncrease") ?? 0,
+                    LevelsPerMagicalOffenseIncrease = (int?)asset.Element("LevelingStatistics").Element("LevelsPerMagicalOffenseIncrease") ?? 0,
+                    MagicalDefenseIncrease = (int?)asset.Element("LevelingStatistics").Element("MagicalDefenseIncrease") ?? 0,
+                    LevelsPerMagicalDefenseIncrease = (int?)asset.Element("LevelingStatistics").Element("LevelsPerMagicalDefenseIncrease") ?? 0,
+                },
+                LevelEntries = asset.Element("LevelEntries")
+                    .Elements("Item")
+                    .Select(item => new CharacterLevelDescription
+                    {
+                        ExperiencePoints = (int?)item.Element("ExperiencePoints") ?? 0,
+                        SpellContentNames = item.Element("SpellContentNames")?
+                            .Elements("Item")
+                            .Select(x => (string)x)
+                            .ToList() ?? new List<string>()
+                    })
+                    .ToList(),
+                BaseExperienceValue = (int?)asset.Element("BaseExperienceValue") ?? 0,
+                BaseGoldValue = (int?)asset.Element("BaseGoldValue") ?? 0
+            };
+
+            return characterClass;
+        }
+
 
 
 
@@ -235,7 +285,7 @@ namespace RolePlaying.Data
             /// <summary>
             /// Reads a CharacterClass object from the content pipeline.
             /// </summary>
-            protected override CharacterClass Read(ContentReader input, 
+            protected override CharacterClass Read(ContentReader input,
                 CharacterClass existingInstance)
             {
                 CharacterClass characterClass = existingInstance;
@@ -247,9 +297,9 @@ namespace RolePlaying.Data
                 characterClass.AssetName = input.AssetName;
 
                 characterClass.Name = input.ReadString();
-                characterClass.InitialStatistics = 
+                characterClass.InitialStatistics =
                     input.ReadObject<StatisticsValue>();
-                characterClass.LevelingStatistics = 
+                characterClass.LevelingStatistics =
                     input.ReadObject<CharacterLevelingStatistics>();
                 characterClass.LevelEntries.AddRange(
                     input.ReadObject<List<CharacterLevelDescription>>());
@@ -259,7 +309,5 @@ namespace RolePlaying.Data
                 return characterClass;
             }
         }
-
-
     }
-}
+}

+ 28 - 34
RolePlayingGame/RolePlayingGameData/Characters/FightingCharacter.cs

@@ -45,7 +45,7 @@ namespace RolePlaying.Data
         public CharacterClass CharacterClass
         {
             get { return characterClass; }
-            set 
+            set
             {
                 characterClass = value;
                 ResetBaseStatistics();
@@ -64,8 +64,8 @@ namespace RolePlaying.Data
         public int CharacterLevel
         {
             get { return characterLevel; }
-            set 
-            { 
+            set
+            {
                 characterLevel = value;
                 ResetBaseStatistics();
                 spells = null;
@@ -83,7 +83,7 @@ namespace RolePlaying.Data
                 return characterLevel >= characterClass.LevelEntries.Count;
             }
         }
-        
+
 
         /// <summary>
         /// The cached list of spells for this level.
@@ -96,8 +96,8 @@ namespace RolePlaying.Data
         [ContentSerializerIgnore]
         public List<Spell> Spells
         {
-            get 
-            { 
+            get
+            {
                 if ((spells == null) && (characterClass != null))
                 {
                     spells = characterClass.GetAllSpellsForLevel(characterLevel);
@@ -124,8 +124,8 @@ namespace RolePlaying.Data
         public int Experience
         {
             get { return experience; }
-            set 
-            { 
+            set
+            {
                 experience = value;
                 while (experience >= ExperienceForNextLevel)
                 {
@@ -156,7 +156,7 @@ namespace RolePlaying.Data
 
 
 
-        
+
 
         /// <summary>
         /// The base statistics of this character, from the character class and level.
@@ -240,7 +240,7 @@ namespace RolePlaying.Data
         /// <remarks>There can only be one weapon equipped at the same time.</remarks>
         public Weapon GetEquippedWeapon()
         {
-            return equippedEquipment.Find(delegate(Equipment equipment)
+            return equippedEquipment.Find(delegate (Equipment equipment)
                 { return equipment is Weapon; }) as Weapon;
         }
 
@@ -292,7 +292,7 @@ namespace RolePlaying.Data
         /// </summary>
         public void UnequipWeapon()
         {
-            equippedEquipment.RemoveAll(delegate(Equipment equipment)
+            equippedEquipment.RemoveAll(delegate (Equipment equipment)
                 { return equipment is Weapon; });
             RecalculateEquipmentStatistics();
         }
@@ -303,7 +303,7 @@ namespace RolePlaying.Data
         /// </summary>
         public Armor GetEquippedArmor(Armor.ArmorSlot slot)
         {
-            return equippedEquipment.Find(delegate(Equipment equipment)
+            return equippedEquipment.Find(delegate (Equipment equipment)
                 {
                     Armor armor = equipment as Armor;
                     return ((armor != null) && (armor.Slot == slot));
@@ -351,7 +351,7 @@ namespace RolePlaying.Data
             // recalculate the statistics buffs from equipment
             RecalculateEquipmentStatistics();
 
-            return true;        
+            return true;
         }
 
 
@@ -360,7 +360,7 @@ namespace RolePlaying.Data
         /// </summary>
         public void UnequipArmor(Armor.ArmorSlot slot)
         {
-            equippedEquipment.RemoveAll(delegate(Equipment equipment)
+            equippedEquipment.RemoveAll(delegate (Equipment equipment)
                 {
                     Armor armor = equipment as Armor;
                     return ((armor != null) && (armor.Slot == slot));
@@ -382,7 +382,7 @@ namespace RolePlaying.Data
             return Equip(equipment, out oldEquipment);
         }
 
-            
+
         /// <summary>
         /// Equip a new piece of equipment, specifying any equipment auto-unequipped.
         /// </summary>
@@ -568,6 +568,7 @@ namespace RolePlaying.Data
         public List<ContentEntry<Gear>> Inventory
         {
             get { return inventory; }
+            set { inventory = value; }
         }
 
 
@@ -615,7 +616,7 @@ namespace RolePlaying.Data
         /// <summary>
         /// The default animation interval for the combat map sprite.
         /// </summary>
-        [ContentSerializer(Optional=true)]
+        [ContentSerializer(Optional = true)]
         public int CombatAnimationInterval
         {
             get { return combatAnimationInterval; }
@@ -630,30 +631,25 @@ namespace RolePlaying.Data
         {
             if (combatSprite != null)
             {
-                combatSprite.AddAnimation(new Animation("Idle", 37, 42, 
+                combatSprite.AddAnimation(new Animation("Idle", 37, 42,
                     CombatAnimationInterval, true));
                 combatSprite.AddAnimation(new Animation("Walk", 25, 30,
                     CombatAnimationInterval, true));
-                combatSprite.AddAnimation(new Animation("Attack", 1, 6, 
+                combatSprite.AddAnimation(new Animation("Attack", 1, 6,
                     CombatAnimationInterval, false));
-                combatSprite.AddAnimation(new Animation("SpellCast", 31, 36, 
+                combatSprite.AddAnimation(new Animation("SpellCast", 31, 36,
                     CombatAnimationInterval, false));
-                combatSprite.AddAnimation(new Animation("Defend", 13, 18, 
+                combatSprite.AddAnimation(new Animation("Defend", 13, 18,
                     CombatAnimationInterval, false));
-                combatSprite.AddAnimation(new Animation("Dodge", 13, 18, 
+                combatSprite.AddAnimation(new Animation("Dodge", 13, 18,
                     CombatAnimationInterval, false));
-                combatSprite.AddAnimation(new Animation("Hit", 19, 24, 
+                combatSprite.AddAnimation(new Animation("Hit", 19, 24,
                     CombatAnimationInterval, false));
-                combatSprite.AddAnimation(new Animation("Die", 7, 12, 
+                combatSprite.AddAnimation(new Animation("Die", 7, 12,
                     CombatAnimationInterval, false));
             }
         }
 
-
-
-
-
-
         /// <summary>
         /// Reads a FightingCharacter object from the content pipeline.
         /// </summary>
@@ -662,7 +658,7 @@ namespace RolePlaying.Data
             /// <summary>
             /// Reads a FightingCharacter object from the content pipeline.
             /// </summary>
-            protected override FightingCharacter Read(ContentReader input, 
+            protected override FightingCharacter Read(ContentReader input,
                 FightingCharacter existingInstance)
             {
                 FightingCharacter fightingCharacter = existingInstance;
@@ -691,7 +687,7 @@ namespace RolePlaying.Data
                             fightingCharacter.CharacterClassContentName));
 
                 // populate the equipment list
-                foreach (string gearName in 
+                foreach (string gearName in
                     fightingCharacter.InitialEquipmentContentNames)
                 {
                     fightingCharacter.Equip(input.ContentManager.Load<Equipment>(
@@ -702,7 +698,7 @@ namespace RolePlaying.Data
                 fightingCharacter.RecalculateTotalDefenseRanges();
 
                 // populate the inventory based on the content names
-                foreach (ContentEntry<Gear> inventoryEntry in 
+                foreach (ContentEntry<Gear> inventoryEntry in
                     fightingCharacter.Inventory)
                 {
                     inventoryEntry.Content = input.ContentManager.Load<Gear>(
@@ -712,7 +708,5 @@ namespace RolePlaying.Data
                 return fightingCharacter;
             }
         }
-
-
     }
-}
+}

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

@@ -5,9 +5,14 @@
 // Copyright (C) Microsoft Corporation. All rights reserved.
 //-----------------------------------------------------------------------------
 
-using System;
+using Microsoft.Xna.Framework;
 using Microsoft.Xna.Framework.Content;
 using Microsoft.Xna.Framework.Graphics;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Xml.Linq;
 
 namespace RolePlaying.Data
 {
@@ -142,6 +147,7 @@ namespace RolePlaying.Data
         public Texture2D ActivePortraitTexture
         {
             get { return activePortraitTexture; }
+            set { activePortraitTexture = value; }
         }
 
 
@@ -172,6 +178,7 @@ namespace RolePlaying.Data
         public Texture2D InactivePortraitTexture
         {
             get { return inactivePortraitTexture; }
+            set { inactivePortraitTexture = value; }
         }
 
 
@@ -202,6 +209,7 @@ namespace RolePlaying.Data
         public Texture2D UnselectablePortraitTexture
         {
             get { return unselectablePortraitTexture; }
+            set { unselectablePortraitTexture = value; }
         }
 
 
@@ -229,17 +237,17 @@ namespace RolePlaying.Data
                 player.JoinAcceptedDialogue = input.ReadString();
                 player.JoinRejectedDialogue = input.ReadString();
                 player.ActivePortraitTextureName = input.ReadString();
-                player.activePortraitTexture = 
+                player.activePortraitTexture =
                     input.ContentManager.Load<Texture2D>(
                         System.IO.Path.Combine(@"Textures\Characters\Portraits",
                         player.ActivePortraitTextureName));
                 player.InactivePortraitTextureName = input.ReadString();
-                player.inactivePortraitTexture = 
+                player.inactivePortraitTexture =
                     input.ContentManager.Load<Texture2D>(
                         System.IO.Path.Combine(@"Textures\Characters\Portraits",
                         player.InactivePortraitTextureName));
                 player.UnselectablePortraitTextureName = input.ReadString();
-                player.unselectablePortraitTexture = 
+                player.unselectablePortraitTexture =
                     input.ContentManager.Load<Texture2D>(
                         System.IO.Path.Combine(@"Textures\Characters\Portraits",
                         player.UnselectablePortraitTextureName));
@@ -296,6 +304,86 @@ namespace RolePlaying.Data
             return player;
         }
 
+        public static Player Load(string playerPath, ContentManager contentManager)
+        {
+            var asset = XmlHelper.GetAssetElementFromXML(playerPath);
+
+            var player = new Player
+            {
+                Name = (string)asset.Element("Name"),
+                MapSprite = new AnimatingSprite
+                {
+                    TextureName = (string)asset.Element("MapSprite").Element("TextureName"),
+                    Texture = contentManager.Load<Texture2D>(
+                        Path.Combine(@"Textures\", (string)asset.Element("MapSprite").Element("TextureName"))),
+                    FrameDimensions = new Point(
+                        int.Parse(asset.Element("MapSprite").Element("FrameDimensions").Value.Split(' ')[0]),
+                        int.Parse(asset.Element("MapSprite").Element("FrameDimensions").Value.Split(' ')[1])),
+                    FramesPerRow = (int)asset.Element("MapSprite").Element("FramesPerRow"),
+                    SourceOffset = new Vector2(
+                        int.Parse(asset.Element("MapSprite").Element("SourceOffset").Value.Split(' ')[0]),
+                        int.Parse(asset.Element("MapSprite").Element("SourceOffset").Value.Split(' ')[1])),
+                    // Handle Animations if needed
+                },
+                WalkingSprite = new AnimatingSprite
+                {
+                    TextureName = (string)asset.Element("WalkingSprite").Element("TextureName"),
+                    Texture = contentManager.Load<Texture2D>(
+                        Path.Combine(@"Textures\", (string)asset.Element("WalkingSprite").Element("TextureName"))),
+                    FrameDimensions = new Point(
+                        int.Parse(asset.Element("WalkingSprite").Element("FrameDimensions").Value.Split(' ')[0]),
+                        int.Parse(asset.Element("WalkingSprite").Element("FrameDimensions").Value.Split(' ')[1])),
+                    FramesPerRow = (int)asset.Element("WalkingSprite").Element("FramesPerRow"),
+                    SourceOffset = new Vector2(
+                        int.Parse(asset.Element("WalkingSprite").Element("SourceOffset").Value.Split(' ')[0]),
+                        int.Parse(asset.Element("WalkingSprite").Element("SourceOffset").Value.Split(' ')[1])),
+                    // Handle Animations if needed
+                },
+                MapIdleAnimationInterval = (int)asset.Element("MapIdleAnimationInterval"),
+                CharacterClassContentName = (string)asset.Element("CharacterClassContentName"),
+                CharacterLevel = (int)asset.Element("CharacterLevel"),
+                InitialEquipmentContentNames = asset.Element("InitialEquipmentContentNames")
+                    .Elements("Item").Select(x => (string)x).ToList(),
+                CombatSprite = new AnimatingSprite
+                {
+                    TextureName = (string)asset.Element("CombatSprite").Element("TextureName"),
+                    Texture = contentManager.Load<Texture2D>(
+                        Path.Combine(@"Textures\", (string)asset.Element("CombatSprite").Element("TextureName"))),
+                    FrameDimensions = new Point(
+                        int.Parse(asset.Element("CombatSprite").Element("FrameDimensions").Value.Split(' ')[0]),
+                        int.Parse(asset.Element("CombatSprite").Element("FrameDimensions").Value.Split(' ')[1])),
+                    FramesPerRow = (int)asset.Element("CombatSprite").Element("FramesPerRow"),
+                    SourceOffset = new Vector2(
+                        int.Parse(asset.Element("CombatSprite").Element("SourceOffset").Value.Split(' ')[0]),
+                        int.Parse(asset.Element("CombatSprite").Element("SourceOffset").Value.Split(' ')[1])),
+                    // Handle Animations if needed
+                },
+                Gold = (int)asset.Element("Gold"),
+                IntroductionDialogue = (string)asset.Element("IntroductionDialogue"),
+                JoinAcceptedDialogue = (string)asset.Element("JoinAcceptedDialogue"),
+                JoinRejectedDialogue = (string)asset.Element("JoinRejectedDialogue"),
+                ActivePortraitTextureName = (string)asset.Element("ActivePortraitTextureName"),
+                ActivePortraitTexture = contentManager.Load<Texture2D>(
+                    Path.Combine(@"Textures\Characters\Portraits", (string)asset.Element("ActivePortraitTextureName"))),
+                InactivePortraitTextureName = (string)asset.Element("InactivePortraitTextureName"),
+                InactivePortraitTexture = contentManager.Load<Texture2D>(
+                    Path.Combine(@"Textures\Characters\Portraits", (string)asset.Element("InactivePortraitTextureName"))),
+                UnselectablePortraitTextureName = (string)asset.Element("UnselectablePortraitTextureName"),
+                UnselectablePortraitTexture = contentManager.Load<Texture2D>(
+                    Path.Combine(@"Textures\Characters\Portraits", (string)asset.Element("UnselectablePortraitTextureName"))),
+                Inventory = asset.Element("Inventory")?.Elements("Item")
+                    .Select(x => new ContentEntry<Gear>
+                    {
+                        ContentName = (string)x.Element("ContentName"),
+                        Count = (int?)x.Element("Count") ?? 1 // Default to 1 if not specified
+                    })
+                    .ToList() ?? new List<ContentEntry<Gear>>()
+            };
+
+            // load the character class
+            player.CharacterClass = CharacterClass.Load(Path.Combine("CharacterClasses", player.CharacterClassContentName));
 
+            return player;
+        }
     }
-}
+}

+ 21 - 1
RolePlayingGame/RolePlayingGameData/GameStartDescription.cs

@@ -5,9 +5,12 @@
 // Copyright (C) Microsoft Corporation. All rights reserved.
 //-----------------------------------------------------------------------------
 
+using Microsoft.Xna.Framework;
+using Microsoft.Xna.Framework.Content;
 using System;
 using System.Collections.Generic;
-using Microsoft.Xna.Framework.Content;
+using System.Linq;
+using System.Xml.Linq;
 
 namespace RolePlaying.Data
 {
@@ -60,5 +63,22 @@ namespace RolePlaying.Data
             get { return questLineContentName; }
             set { questLineContentName = value; }
         }
+
+        public static GameStartDescription Load(string description)
+        {
+            XElement asset = XmlHelper.GetAssetElementFromXML(description);
+
+            var gameStartDescription = new GameStartDescription
+            {
+                MapContentName = (string)asset.Element("MapContentName"),
+                PlayerContentNames = asset.Element("PlayerContentNames")
+                    .Elements("Item")
+                    .Select(x => (string)x)
+                    .ToList(),
+                QuestLineContentName = (string)asset.Element("QuestLineContentName"),
+            };
+
+            return gameStartDescription;
+        }
     }
 }

+ 7 - 9
RolePlayingGame/RolePlayingGameData/Gear/Equipment.cs

@@ -28,17 +28,17 @@ namespace RolePlaying.Data
         /// The statistics buff applied by this equipment to its owner.
         /// </summary>
         /// <remarks>Buff values are positive, and will be added.</remarks>
-        [ContentSerializer(Optional=true)]
+        [ContentSerializer(Optional = true)]
         public StatisticsValue OwnerBuffStatistics
         {
             get { return ownerBuffStatistics; }
             set { ownerBuffStatistics = value; }
         }
 
-
-
-
-
+        public static Equipment Load(string equipmentAssetName)
+        {
+            throw new NotImplementedException();
+        }
 
         /// <summary>
         /// Read the Equipment type from the content pipeline.
@@ -48,7 +48,7 @@ namespace RolePlaying.Data
             /// <summary>
             /// Read the Equipment type from the content pipeline.
             /// </summary>
-            protected override Equipment Read(ContentReader input, 
+            protected override Equipment Read(ContentReader input,
                 Equipment existingInstance)
             {
                 Equipment equipment = existingInstance;
@@ -68,7 +68,5 @@ namespace RolePlaying.Data
                 return equipment;
             }
         }
-
-
     }
-}
+}

+ 3 - 10
RolePlayingGame/RolePlayingGameData/Gear/Gear.cs

@@ -261,7 +261,7 @@ namespace RolePlaying.Data
         /// </param>
         /// <param name="maximumLines">The maximum number of lines to draw.</param>
         public virtual void DrawDescription(SpriteBatch spriteBatch,
-            SpriteFont spriteFont, Color color, Vector2 position, 
+            SpriteFont spriteFont, Color color, Vector2 position,
             int maximumCharactersPerLine, int maximumLines)
         {
             // check the parameters
@@ -314,15 +314,10 @@ namespace RolePlaying.Data
             }
 
             // draw the string
-            spriteBatch.DrawString(spriteFont, stringBuilder.ToString(), 
+            spriteBatch.DrawString(spriteFont, stringBuilder.ToString(),
                 position, color);
         }
 
-
-
-
-
-
         /// <summary>
         /// Reads a Gear object from the content pipeline.
         /// </summary>
@@ -355,7 +350,5 @@ namespace RolePlaying.Data
                 return gear;
             }
         }
-
-
     }
-}
+}

+ 164 - 31
RolePlayingGame/RolePlayingGameData/Map/Map.cs

@@ -5,11 +5,13 @@
 // Copyright (C) Microsoft Corporation. All rights reserved.
 //-----------------------------------------------------------------------------
 
-using System;
-using System.Collections.Generic;
 using Microsoft.Xna.Framework;
-using Microsoft.Xna.Framework.Graphics;
 using Microsoft.Xna.Framework.Content;
+using Microsoft.Xna.Framework.Graphics;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
 
 namespace RolePlaying.Data
 {
@@ -37,11 +39,6 @@ namespace RolePlaying.Data
             set { name = value; }
         }
 
-
-
-
-
-
         /// <summary>
         /// The dimensions of the map, in tiles.
         /// </summary>
@@ -90,6 +87,7 @@ namespace RolePlaying.Data
         public int TilesPerRow
         {
             get { return tilesPerRow; }
+            set { tilesPerRow = value; }
         }
 
 
@@ -143,6 +141,7 @@ namespace RolePlaying.Data
         public Texture2D Texture
         {
             get { return texture; }
+            set { texture = value; }
         }
 
 
@@ -177,6 +176,7 @@ namespace RolePlaying.Data
         public Texture2D CombatTexture
         {
             get { return combatTexture; }
+            set { combatTexture = value; }
         }
 
 
@@ -249,7 +249,7 @@ namespace RolePlaying.Data
 
             return baseLayer[mapPosition.Y * mapDimensions.X + mapPosition.X];
         }
-        
+
 
         /// <summary>
         /// Retrieves the source rectangle for the tile in the given position
@@ -386,8 +386,8 @@ namespace RolePlaying.Data
                 (mapPosition.Y < 0) || (mapPosition.Y >= mapDimensions.Y))
             {
                 return Rectangle.Empty;
-            } 
-            
+            }
+
             int objectLayerValue = GetObjectLayerValue(mapPosition);
             if (objectLayerValue < 0)
             {
@@ -395,7 +395,7 @@ namespace RolePlaying.Data
             }
 
             return new Rectangle(
-                (objectLayerValue % tilesPerRow) * tileSize.X, 
+                (objectLayerValue % tilesPerRow) * tileSize.X,
                 (objectLayerValue / tilesPerRow) * tileSize.Y,
                 tileSize.X, tileSize.Y);
         }
@@ -476,7 +476,7 @@ namespace RolePlaying.Data
 
 
 
-        
+
 
         /// <summary>
         /// The content names and positions of the portals on this map.
@@ -504,12 +504,12 @@ namespace RolePlaying.Data
                 throw new ArgumentNullException("name");
             }
 
-            return portalEntries.Find(delegate(MapEntry<Portal> portalEntry)
+            return portalEntries.Find(delegate (MapEntry<Portal> portalEntry)
             {
                 return (portalEntry.ContentName == name);
             });
         }
-        
+
 
         /// <summary>
         /// The content names and positions of the treasure chests on this map.
@@ -563,7 +563,7 @@ namespace RolePlaying.Data
         /// <summary>
         /// The content names, positions, and orientations of quest Npcs on this map.
         /// </summary>
-        private List<MapEntry<QuestNpc>> questNpcEntries = 
+        private List<MapEntry<QuestNpc>> questNpcEntries =
             new List<MapEntry<QuestNpc>>();
 
         /// <summary>
@@ -579,7 +579,7 @@ namespace RolePlaying.Data
         /// <summary>
         /// The content names, positions, and orientations of player Npcs on this map.
         /// </summary>
-        private List<MapEntry<Player>> playerNpcEntries = 
+        private List<MapEntry<Player>> playerNpcEntries =
             new List<MapEntry<Player>>();
 
         /// <summary>
@@ -675,6 +675,141 @@ namespace RolePlaying.Data
             return map;
         }
 
+        public static Map Load(string mapContentName, ContentManager content)
+        {
+            var asset = XmlHelper.GetAssetElementFromXML(mapContentName);
+            var map = new Map
+            {
+                Name = asset.Element("Name").Value,
+                MapDimensions = new Point(
+                    int.Parse(asset.Element("MapDimensions").Value.Split(' ')[0]),
+                    int.Parse(asset.Element("MapDimensions").Value.Split(' ')[1])), // e.g. [20, 23]
+                TileSize = new Point(
+                    int.Parse(asset.Element("TileSize").Value.Split(' ')[0]),
+                    int.Parse(asset.Element("TileSize").Value.Split(' ')[1])), // e.g. [64, 64]
+                SpawnMapPosition = new Point(
+                    int.Parse(asset.Element("SpawnMapPosition").Value.Split(' ')[0]),
+                    int.Parse(asset.Element("SpawnMapPosition").Value.Split(' ')[1])), // e.g. [9, 7]
+                TextureName = (string)asset.Element("TextureName"),
+                Texture = content.Load<Texture2D>(
+                    Path.Combine(@"Textures\Maps\NonCombat", (string)asset.Element("TextureName"))),
+                CombatTextureName = (string)asset.Element("CombatTextureName"),
+                CombatTexture = content.Load<Texture2D>(
+                    Path.Combine(@"Textures\Maps\Combat", (string)asset.Element("CombatTextureName"))),
+                MusicCueName = (string)asset.Element("MusicCueName"),
+                CombatMusicCueName = (string)asset.Element("CombatMusicCueName"),
+                BaseLayer = asset.Element("BaseLayer").Value
+                    .Split(new[] { ' ', '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries)
+                    .Select(int.Parse)
+                    .ToArray(),
+                FringeLayer = asset.Element("FringeLayer").Value
+                    .Split(new[] { ' ', '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries)
+                    .Select(int.Parse)
+                    .ToArray(),
+                ObjectLayer = asset.Element("ObjectLayer").Value
+                    .Split(new[] { ' ', '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries)
+                    .Select(int.Parse)
+                    .ToArray(),
+                CollisionLayer = asset.Element("CollisionLayer").Value
+                    .Split(new[] { ' ', '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries)
+                    .Select(int.Parse)
+                    .ToArray(),
+                Portals = asset.Element("Portals")?.Elements("Item")
+                    .Select(item => new Portal
+                    {
+                        Name = (string)item.Element("Name"),
+                        LandingMapPosition = new Point(
+                            int.Parse(item.Element("LandingMapPosition").Value.Split(' ')[0]),
+                            int.Parse(item.Element("LandingMapPosition").Value.Split(' ')[1])),
+                        DestinationMapContentName = (string)item.Element("DestinationMapContentName"),
+                        DestinationMapPortalName = (string)item.Element("DestinationMapPortalName")
+                    }).ToList(),
+                PortalEntries = asset.Element("PortalEntries")?.Elements("Item")
+                    .Select(item => new MapEntry<Portal>
+                    {
+                        ContentName = (string)item.Element("ContentName"),
+                        MapPosition = new Point(
+                            int.Parse(item.Element("MapPosition").Value.Split(' ')[0]),
+                            int.Parse(item.Element("MapPosition").Value.Split(' ')[1]))
+                    }).ToList(),
+                ChestEntries = asset.Element("ChestEntries")?.Elements("Item")
+                    .Select(item => new MapEntry<Chest>
+                    {
+                        ContentName = (string)item.Element("ContentName"),
+                        MapPosition = new Point(
+                            int.Parse(item.Element("MapPosition").Value.Split(' ')[0]),
+                            int.Parse(item.Element("MapPosition").Value.Split(' ')[1]))
+                    }).ToList(),
+                FixedCombatEntries = asset.Element("FixedCombatEntries")?.Elements("Item")
+                    .Select(item => new MapEntry<FixedCombat>
+                    {
+                        ContentName = (string)item.Element("ContentName"),
+                        MapPosition = new Point(
+                            int.Parse(item.Element("MapPosition").Value.Split(' ')[0]),
+                            int.Parse(item.Element("MapPosition").Value.Split(' ')[1]))
+                    }).ToList(),
+                PlayerNpcEntries = asset.Element("PlayerNpcEntries")?.Elements("Item")
+                    .Select(item => new MapEntry<Player>
+                    {
+                        ContentName = (string)item.Element("ContentName"),
+                        MapPosition = new Point(
+                            int.Parse(item.Element("MapPosition").Value.Split(' ')[0]),
+                            int.Parse(item.Element("MapPosition").Value.Split(' ')[1]))
+                    }).ToList(),
+                QuestNpcEntries = asset.Element("QuestNpcEntries")?.Elements("Item")
+                    .Select(item => new MapEntry<QuestNpc>
+                    {
+                        ContentName = (string)item.Element("ContentName"),
+                        Direction = Enum.TryParse<Direction>((string)item.Element("Direction"), out var dir) ? dir : default,
+                        MapPosition = new Point(
+                            int.Parse(item.Element("MapPosition").Value.Split(' ')[0]),
+                            int.Parse(item.Element("MapPosition").Value.Split(' ')[1]))
+                    }).ToList(),
+                InnEntries = asset.Element("InnEntries")?.Elements("Item")
+                    .Select(item => new MapEntry<Inn>
+                    {
+                        ContentName = (string)item.Element("ContentName"),
+                        MapPosition = new Point(
+                            int.Parse(item.Element("MapPosition").Value.Split(' ')[0]),
+                            int.Parse(item.Element("MapPosition").Value.Split(' ')[1]))
+                    }).ToList(),
+                StoreEntries = asset.Element("StoreEntries")?.Elements("Item")
+                    .Select(item => new MapEntry<Store>
+                    {
+                        ContentName = (string)item.Element("ContentName"),
+                        MapPosition = new Point(
+                            int.Parse(item.Element("MapPosition").Value.Split(' ')[0]),
+                            int.Parse(item.Element("MapPosition").Value.Split(' ')[1]))
+                    }).ToList(),
+            };
+
+            var randomCombatElement = asset.Element("RandomCombat");
+            if (randomCombatElement != null)
+            {
+                map.RandomCombat = new RandomCombat
+                {
+                    CombatProbability = (int?)randomCombatElement.Element("CombatProbability") ?? 0,
+                    FleeProbability = (int?)randomCombatElement.Element("FleeProbability") ?? 0,
+                    MonsterCountRange = new Int32Range
+                    {
+                        Minimum = (int?)randomCombatElement.Element("MonsterCountRange")?.Element("Minimum") ?? 0,
+                        Maximum = (int?)randomCombatElement.Element("MonsterCountRange")?.Element("Maximum") ?? 0
+                    },
+                    Entries = randomCombatElement.Element("Entries")?.Elements("Item")
+                            .Select(item => new WeightedContentEntry<Monster>
+                            {
+                                ContentName = (string)item.Element("ContentName"),
+                                Count = (int?)item.Element("Count") ?? 0,
+                                Weight = (int?)item.Element("Weight") ?? 0
+                            }).ToList()
+                };
+            }
+
+            map.TilesPerRow = map.Texture.Width / map.TileSize.X;
+
+            return map;
+        }
+
 
 
 
@@ -723,7 +858,7 @@ namespace RolePlaying.Data
                     input.ReadObject<List<MapEntry<Portal>>>());
                 foreach (MapEntry<Portal> portalEntry in map.PortalEntries)
                 {
-                    portalEntry.Content = map.Portals.Find(delegate(Portal portal)
+                    portalEntry.Content = map.Portals.Find(delegate (Portal portal)
                         {
                             return (portal.Name == portalEntry.ContentName);
                         });
@@ -742,12 +877,12 @@ namespace RolePlaying.Data
                 Random random = new Random();
                 map.FixedCombatEntries.AddRange(
                     input.ReadObject<List<MapEntry<FixedCombat>>>());
-                foreach (MapEntry<FixedCombat> fixedCombatEntry in 
+                foreach (MapEntry<FixedCombat> fixedCombatEntry in
                     map.fixedCombatEntries)
                 {
-                    fixedCombatEntry.Content = 
+                    fixedCombatEntry.Content =
                         input.ContentManager.Load<FixedCombat>(
-                        System.IO.Path.Combine(@"Maps\FixedCombats", 
+                        System.IO.Path.Combine(@"Maps\FixedCombats",
                         fixedCombatEntry.ContentName));
                     // clone the map sprite in the entry, as there may be many entries
                     // per FixedCombat
@@ -755,7 +890,7 @@ namespace RolePlaying.Data
                         fixedCombatEntry.Content.Entries[0].Content.MapSprite.Clone()
                         as AnimatingSprite;
                     // play the idle animation
-                    fixedCombatEntry.MapSprite.PlayAnimation("Idle", 
+                    fixedCombatEntry.MapSprite.PlayAnimation("Idle",
                         fixedCombatEntry.Direction);
                     // advance in a random amount so the animations aren't synchronized
                     fixedCombatEntry.MapSprite.UpdateAnimation(
@@ -766,7 +901,7 @@ namespace RolePlaying.Data
 
                 map.QuestNpcEntries.AddRange(
                     input.ReadObject<List<MapEntry<QuestNpc>>>());
-                foreach (MapEntry<QuestNpc> questNpcEntry in 
+                foreach (MapEntry<QuestNpc> questNpcEntry in
                     map.questNpcEntries)
                 {
                     questNpcEntry.Content = input.ContentManager.Load<QuestNpc>(
@@ -778,7 +913,7 @@ namespace RolePlaying.Data
 
                 map.PlayerNpcEntries.AddRange(
                     input.ReadObject<List<MapEntry<Player>>>());
-                foreach (MapEntry<Player> playerNpcEntry in 
+                foreach (MapEntry<Player> playerNpcEntry in
                     map.playerNpcEntries)
                 {
                     playerNpcEntry.Content = input.ContentManager.Load<Player>(
@@ -790,28 +925,26 @@ namespace RolePlaying.Data
 
                 map.InnEntries.AddRange(
                     input.ReadObject<List<MapEntry<Inn>>>());
-                foreach (MapEntry<Inn> innEntry in 
+                foreach (MapEntry<Inn> innEntry in
                     map.innEntries)
                 {
                     innEntry.Content = input.ContentManager.Load<Inn>(
-                        System.IO.Path.Combine(@"Maps\Inns", 
+                        System.IO.Path.Combine(@"Maps\Inns",
                         innEntry.ContentName));
                 }
 
                 map.StoreEntries.AddRange(
                     input.ReadObject<List<MapEntry<Store>>>());
-                foreach (MapEntry<Store> storeEntry in 
+                foreach (MapEntry<Store> storeEntry in
                     map.storeEntries)
                 {
                     storeEntry.Content = input.ContentManager.Load<Store>(
-                        System.IO.Path.Combine(@"Maps\Stores", 
+                        System.IO.Path.Combine(@"Maps\Stores",
                         storeEntry.ContentName));
                 }
 
                 return map;
             }
         }
-
-
     }
-}
+}

+ 24 - 4
RolePlayingGame/RolePlayingGameData/Quests/QuestLine.cs

@@ -5,10 +5,13 @@
 // Copyright (C) Microsoft Corporation. All rights reserved.
 //-----------------------------------------------------------------------------
 
+using Microsoft.Xna.Framework;
+using Microsoft.Xna.Framework.Content;
 using System;
 using System.Collections.Generic;
 using System.IO;
-using Microsoft.Xna.Framework.Content;
+using System.Linq;
+using System.Xml.Linq;
 
 namespace RolePlaying.Data
 {
@@ -67,7 +70,7 @@ namespace RolePlaying.Data
         {
             get { return quests; }
         }
-    
+
 
 
 
@@ -80,7 +83,7 @@ namespace RolePlaying.Data
             /// <summary>
             /// Reads a QuestLine object from the content pipeline.
             /// </summary>
-            protected override QuestLine Read(ContentReader input, 
+            protected override QuestLine Read(ContentReader input,
                 QuestLine existingInstance)
             {
                 QuestLine questLine = existingInstance;
@@ -125,6 +128,23 @@ namespace RolePlaying.Data
             return questLine;
         }
 
+        public static QuestLine Load(string questPath)
+        {
+            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,
+            };
 
+            return loadedQuestLine;
+        }
     }
-}
+}

+ 23 - 0
RolePlayingGame/RolePlayingGameData/XmlHelper.cs

@@ -0,0 +1,23 @@
+using Microsoft.Xna.Framework;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Xml.Linq;
+
+namespace RolePlaying.Data
+{
+	public static class XmlHelper
+	{
+		public static XElement GetAssetElementFromXML(string filePath)
+		{
+			XDocument doc;
+			using (var stream = TitleContainer.OpenStream($"Content/{filePath}.xml"))
+			{
+				doc = XDocument.Load(stream);
+			}
+			return doc.Root.Element("Asset");
+		}
+	}
+}

Alguns ficheiros não foram mostrados porque muitos ficheiros mudaram neste diff