Explorar el Código

RPG - Stores, Inns now working.

CartBlanche hace 1 mes
padre
commit
62a54a630c

+ 4 - 4
RolePlayingGame/Core/Content/Characters/Players/Kolatt.xml

@@ -19,10 +19,10 @@
       <MapIdleAnimationInterval>180</MapIdleAnimationInterval>
       <CharacterClassContentName>Warrior</CharacterClassContentName>
       <CharacterLevel>2</CharacterLevel>
-	  <InitialEquipmentContentNames>
-		  <Item>Weapons\Dagger</Item>
-		  <Item>Armor\HideArmor</Item>
-	  </InitialEquipmentContentNames>
+	    <InitialEquipmentContentNames>
+		    <Item>Weapons\Dagger</Item>
+		    <Item>Armor\HideArmor</Item>
+	    </InitialEquipmentContentNames>
       <Inventory />
       <CombatSprite>
           <TextureName>Characters\Warrior1AttackRight</TextureName>

+ 168 - 2
RolePlayingGame/Core/Content/Content.mgcb

@@ -8803,7 +8803,7 @@
 /processorParam:TextureFormat=Color
 /build:Textures/MainMenu/LoadingScreenStrip.png
 
-#begin Textures/MainMenu/MainMenu.jpg
+#begin Textures/MainMenu/MainMenu.png
 /importer:TextureImporter
 /processor:TextureProcessor
 /processorParam:ColorKeyColor=255,0,255,255
@@ -8813,7 +8813,7 @@
 /processorParam:ResizeToPowerOfTwo=False
 /processorParam:MakeSquare=False
 /processorParam:TextureFormat=Color
-/build:Textures/MainMenu/MainMenu.jpg
+/build:Textures/MainMenu/MainMenu.png
 
 #begin Textures/MainMenu/MainMenuInfoSpace.png
 /importer:TextureImporter
@@ -9499,6 +9499,172 @@
 /processorParam:TextureFormat=Color
 /build:Textures/Spells/SmallIcon.png
 
+#Player Characters
 /copy:Characters/Players/Kolatt.xml
+/copy:Characters/Players/Nykkas.xml
+/copy:Characters/Players/Shenidd.xml
+/copy:Characters/Players/Tyjavus.xml
+/copy:Characters/Players/Vashekk.xml
+
+#NPC Characters
+/copy:Characters/QuestNPCs/Ayttas.xml
+/copy:Characters/QuestNPCs/Dunkum.xml
+/copy:Characters/QuestNPCs/Ekin.xml
+/copy:Characters/QuestNPCs/HealingInn.xml
+/copy:Characters/QuestNPCs/HealTheSoul.xml
+/copy:Characters/QuestNPCs/JangElder.xml
+/copy:Characters/QuestNPCs/Sheddarr.xml
+/copy:Characters/QuestNPCs/Ujar.xml
+/copy:Characters/QuestNPCs/Itemania.xml
+/copy:Characters/QuestNPCs/Kneevan.xml
+/copy:Characters/QuestNPCs/Manny.xml
+/copy:Characters/QuestNPCs/NewAgeInn.xml
+/copy:Characters/QuestNPCs/Shejarr.xml
+/copy:Characters/QuestNPCs/Theaniv.xml
+/copy:Characters/QuestNPCs/TheWeaponSmith.xml
+/copy:Characters/QuestNPCs/ThisAnInn.xml
+/copy:Characters/QuestNPCs/ToPlotTown.xml
+/copy:Characters/QuestNPCs/Vejnas.xml
+/copy:Characters/QuestNPCs/WhoMe.xml
 
 /copy:Quests/QuestLines/MainQuestLine.xml
+
+#Quests
+/copy:Quests/DefeatTamar.xml
+/copy:Quests/HideArmor.xml
+/copy:Quests/LushVillage.xml
+/copy:Quests/SaveMercadia.xml
+/copy:Quests/ShortSword.xml
+/copy:Quests/TestBattle.xml
+/copy:Quests/TheBanditLeader.xml
+
+#Chests
+/copy:Maps/Chests/BronzeGear.xml
+/copy:Maps/Chests/Dagger.xml
+/copy:Maps/Chests/Gold.xml
+/copy:Maps/Chests/GoldPlus.xml
+/copy:Maps/Chests/Healing.xml
+/copy:Maps/Chests/Hide.xml
+/copy:Maps/Chests/IronGear.xml
+/copy:Maps/Chests/IronHelmet.xml
+/copy:Maps/Chests/IronShield.xml
+/copy:Maps/Chests/LeatherGear.xml
+/copy:Maps/Chests/LeatherShieldPlus.xml
+/copy:Maps/Chests/LegendaryArmor.xml
+/copy:Maps/Chests/LegendaryBlade.xml
+/copy:Maps/Chests/LegendaryBoots.xml
+/copy:Maps/Chests/LegendaryClub.xml
+/copy:Maps/Chests/LegendaryHelmet.xml
+/copy:Maps/Chests/LegendaryHood.xml
+/copy:Maps/Chests/LegendaryRobe.xml
+/copy:Maps/Chests/LegendaryShield.xml
+/copy:Maps/Chests/LegendaryStaff.xml
+/copy:Maps/Chests/LongBlade.xml
+/copy:Maps/Chests/LongSword.xml
+/copy:Maps/Chests/Mage.xml
+/copy:Maps/Chests/Magic.xml
+/copy:Maps/Chests/MajorHealing.xml
+/copy:Maps/Chests/MajorMagic.xml
+/copy:Maps/Chests/MDElixir.xml
+/copy:Maps/Chests/MinorGold.xml
+/copy:Maps/Chests/MinorHealing.xml
+/copy:Maps/Chests/MinorMagic.xml
+/copy:Maps/Chests/MOElixir.xml
+/copy:Maps/Chests/MoneyBags.xml
+/copy:Maps/Chests/PDElixir.xml
+/copy:Maps/Chests/PersianBlade.xml
+/copy:Maps/Chests/PersianSword.xml
+/copy:Maps/Chests/POElixir.xml
+/copy:Maps/Chests/Ruby.xml
+/copy:Maps/Chests/SageBoots.xml
+/copy:Maps/Chests/SageHood.xml
+/copy:Maps/Chests/SageStaff.xml
+/copy:Maps/Chests/SteelArmor.xml
+/copy:Maps/Chests/SteelBoots.xml
+/copy:Maps/Chests/SteelHelmet.xml
+/copy:Maps/Chests/SteelShield.xml
+
+#Inns
+/copy:Maps/Inns/HealingInn.xml
+/copy:Maps/Inns/NewAgeInn.xml
+/copy:Maps/Inns/SanctuaryInn.xml
+/copy:Maps/Inns/ThisAnInn.xml
+
+#Stores
+/copy:Maps/Stores/GearMan.xml
+/copy:Maps/Stores/Gearrific.xml
+/copy:Maps/Stores/HealTheSoul.xml
+/copy:Maps/Stores/Itemania.xml
+/copy:Maps/Stores/PotionsGalore.xml
+/copy:Maps/Stores/TheWeaponsmith.xml
+/copy:Maps/Stores/WhoMeShop.xml
+
+#Fixed Combats
+/copy:Maps/FixedCombats/BanditLeaders5.xml
+/copy:Maps/FixedCombats/BanditMage2.xml
+/copy:Maps/FixedCombats/BanditMage3.xml
+/copy:Maps/FixedCombats/BanditMage5.xml
+/copy:Maps/FixedCombats/BanditMasters5.xml
+/copy:Maps/FixedCombats/BanditMinor2.xml
+/copy:Maps/FixedCombats/BanditMinor3.xml
+/copy:Maps/FixedCombats/BanditMinor5.xml
+/copy:Maps/FixedCombats/BanditMisc3.xml
+/copy:Maps/FixedCombats/BanditMisc5.xml
+/copy:Maps/FixedCombats/BanditMisc5a.xml
+/copy:Maps/FixedCombats/BanditMisc5b.xml
+/copy:Maps/FixedCombats/BanditMisc5c.xml
+/copy:Maps/FixedCombats/BruteMasters1.xml
+/copy:Maps/FixedCombats/Brutes1.xml
+/copy:Maps/FixedCombats/GoblinGrunts.xml
+/copy:Maps/FixedCombats/GoblinGrunts2.xml
+/copy:Maps/FixedCombats/GoblinGrunts3.xml
+/copy:Maps/FixedCombats/GoblinGrunts5.xml
+/copy:Maps/FixedCombats/GoblinMages3.xml
+/copy:Maps/FixedCombats/GoblinMages5.xml
+/copy:Maps/FixedCombats/Goblins.xml
+/copy:Maps/FixedCombats/GoblinsMisc3.xml
+/copy:Maps/FixedCombats/GoblinsMisc5.xml
+/copy:Maps/FixedCombats/GoblinsMisc5a.xml
+/copy:Maps/FixedCombats/GoblinSoldiers5.xml
+/copy:Maps/FixedCombats/Misc1.xml
+/copy:Maps/FixedCombats/Misc4.xml
+/copy:Maps/FixedCombats/Misc5.xml
+/copy:Maps/FixedCombats/OrcBrutes1.xml
+/copy:Maps/FixedCombats/OrcBrutes2.xml
+/copy:Maps/FixedCombats/OrcBrutes3.xml
+/copy:Maps/FixedCombats/OrcBrutes5.xml
+/copy:Maps/FixedCombats/OrcCaptains1.xml
+/copy:Maps/FixedCombats/OrcCaptains3.xml
+/copy:Maps/FixedCombats/OrcCaptains5.xml
+/copy:Maps/FixedCombats/OrcGrunts3.xml
+/copy:Maps/FixedCombats/OrcGrunts5.xml
+/copy:Maps/FixedCombats/OrcMisc3.xml
+/copy:Maps/FixedCombats/OrcMisc3a.xml
+/copy:Maps/FixedCombats/OrcMisc3b.xml
+/copy:Maps/FixedCombats/OrcMisc3c.xml
+/copy:Maps/FixedCombats/OrcMisc3d.xml
+/copy:Maps/FixedCombats/OrcMisc5.xml
+/copy:Maps/FixedCombats/OrcMisc5a.xml
+/copy:Maps/FixedCombats/OrcMisc5b.xml
+/copy:Maps/FixedCombats/OrcSoldiers3.xml
+/copy:Maps/FixedCombats/OrcSoldiers5.xml
+/copy:Maps/FixedCombats/SirShire.xml
+/copy:Maps/FixedCombats/Tamar.xml
+
+#Monsters
+/copy:Characters/Monsters/BanditGuard.xml
+/copy:Characters/Monsters/BanditLeader.xml
+/copy:Characters/Monsters/BanditMage.xml
+/copy:Characters/Monsters/BanditMaster.xml
+/copy:Characters/Monsters/BanditMinor.xml
+/copy:Characters/Monsters/BruteMage.xml
+/copy:Characters/Monsters/BruteMaster.xml
+/copy:Characters/Monsters/CrimsonHood.xml
+/copy:Characters/Monsters/GoblinGrunt.xml
+/copy:Characters/Monsters/GoblinMage.xml
+/copy:Characters/Monsters/OrcBrute.xml
+/copy:Characters/Monsters/OrcCaptain.xml
+/copy:Characters/Monsters/OrcGrunt.xml
+/copy:Characters/Monsters/OrcSoldier.xml
+/copy:Characters/Monsters/SirShire.xml
+/copy:Characters/Monsters/Tamar.xml

+ 10 - 10
RolePlayingGame/Core/Content/Maps/Map001.xml

@@ -111,32 +111,32 @@
       </CollisionLayer>
       <Portals>
           <Item>
-			  <Name>P1</Name>
-			  <LandingMapPosition>8 20</LandingMapPosition>
+			        <Name>P1</Name>
+			        <LandingMapPosition>8 20</LandingMapPosition>
               <DestinationMapContentName>Map002</DestinationMapContentName>
               <DestinationMapPortalName>P1</DestinationMapPortalName>
           </Item>
           <Item>
-			  <Name>P2</Name>
-			  <LandingMapPosition>9 20</LandingMapPosition>
+			        <Name>P2</Name>
+			        <LandingMapPosition>9 20</LandingMapPosition>
               <DestinationMapContentName>Map002</DestinationMapContentName>
               <DestinationMapPortalName>P3</DestinationMapPortalName>
           </Item>
           <Item>
-			  <Name>P3</Name>
-			  <LandingMapPosition>10 20</LandingMapPosition>
+			        <Name>P3</Name>
+			        <LandingMapPosition>10 20</LandingMapPosition>
               <DestinationMapContentName>Map002</DestinationMapContentName>
               <DestinationMapPortalName>P4</DestinationMapPortalName>
           </Item>
           <Item>
-			  <Name>P4</Name>
-			  <LandingMapPosition>11 20</LandingMapPosition>
+			        <Name>P4</Name>
+			        <LandingMapPosition>11 20</LandingMapPosition>
               <DestinationMapContentName>Map002</DestinationMapContentName>
               <DestinationMapPortalName>P5</DestinationMapPortalName>
           </Item>
           <Item>
-			  <Name>P5</Name>
-			  <LandingMapPosition>11 3</LandingMapPosition>
+			        <Name>P5</Name>
+			        <LandingMapPosition>11 3</LandingMapPosition>
               <DestinationMapContentName>Map001</DestinationMapContentName>
               <DestinationMapPortalName>P1</DestinationMapPortalName>
           </Item>

BIN
RolePlayingGame/Core/Content/Textures/MainMenu/MainMenu.png


+ 3 - 35
RolePlayingGame/Core/GameScreens/DialogueScreen.cs

@@ -18,8 +18,6 @@ namespace RolePlaying
     /// </summary>
     class DialogueScreen : GameScreen
     {
-
-
         private Texture2D backgroundTexture;
         private Vector2 backgroundPosition;
         private Texture2D fadeTexture;
@@ -42,11 +40,6 @@ namespace RolePlaying
         private Vector2 titlePosition;
         private Vector2 dialogueStartPosition;
 
-
-
-
-
-
         /// <summary>
         /// The title text shown at the top of the screen.
         /// </summary>
@@ -61,7 +54,6 @@ namespace RolePlaying
             set { titleText = value; }
         }
 
-
         /// <summary>
         /// The dialogue shown in the main portion of this dialog.
         /// </summary>
@@ -96,7 +88,7 @@ namespace RolePlaying
                 }
                 else
                 {
-                    dialogueList = Fonts.BreakTextIntoList(dialogueText, 
+                    dialogueList = Fonts.BreakTextIntoList(dialogueText,
                         Fonts.DescriptionFont, maxWidth);
                 }
                 // set which lines ar edrawn
@@ -116,7 +108,6 @@ namespace RolePlaying
             }
         }
 
-
         /// <summary>
         /// The text shown next to the A button, if any.
         /// </summary>
@@ -128,7 +119,7 @@ namespace RolePlaying
         public string SelectText
         {
             get { return selectText; }
-            set 
+            set
             {
                 if (selectText != value)
                 {
@@ -143,7 +134,6 @@ namespace RolePlaying
             }
         }
 
-
         /// <summary>
         /// The text shown next to the B button, if any.
         /// </summary>
@@ -158,35 +148,26 @@ namespace RolePlaying
             set { backText = value; }
         }
 
-
         /// <summary>
         /// Maximum width of each line in pixels
         /// </summary>
         private const int maxWidth = 705;
 
-
         /// <summary>
         /// Starting index of the list to be displayed
         /// </summary>
         private int startIndex = 0;
 
-
         /// <summary>
         /// Ending index of the list to be displayed
         /// </summary>
         private int endIndex = drawMaxLines;
 
-
         /// <summary>
         /// Maximum number of lines to draw in the screen
         /// </summary>
         private const int drawMaxLines = 13;
 
-
-
-
-
-
         /// <summary>
         /// Construct a new DialogueScreen object.
         /// </summary>
@@ -196,7 +177,6 @@ namespace RolePlaying
             this.IsPopup = true;
         }
 
-
         /// <summary>
         /// Load the graphics content
         /// </summary>
@@ -248,11 +228,6 @@ namespace RolePlaying
             titlePosition.Y = backgroundPosition.Y + 70f;
         }
 
-
-
-
-
-
         /// <summary>
         /// Handles user input to the dialog.
         /// </summary>
@@ -286,11 +261,6 @@ namespace RolePlaying
             }
         }
 
-
-
-
-
-
         /// <summary>
         /// draws the dialog.
         /// </summary>
@@ -349,7 +319,5 @@ namespace RolePlaying
 
             spriteBatch.End();
         }
-
-
     }
-}
+}

+ 6 - 3
RolePlayingGame/Core/GameScreens/InnScreen.cs

@@ -297,15 +297,18 @@ namespace RolePlaying
 
             // Draw the background
             spriteBatch.Draw(backgroundTexture, backgroundPosition, Color.White);
+
             // Draw the wooden plank
             spriteBatch.Draw(plankTexture, plankPosition, Color.White);
+
             // Draw the select icon
             spriteBatch.Draw(selectIconTexture, selectIconPosition, Color.White);
+
             // Draw the back icon
             spriteBatch.Draw(backIconTexture, backIconPosition, Color.White);
+
             // Draw the inn name on the wooden plank
-            spriteBatch.DrawString(Fonts.HeaderFont, inn.Name, namePosition,
-                Fonts.DisplayColor);
+            spriteBatch.DrawString(Fonts.HeaderFont, inn.Name, namePosition, Fonts.DisplayColor, MathHelper.ToRadians(-3.0f), Vector2.Zero, 1.0f, SpriteEffects.None, 0f);
 
             // Draw the stay and leave option texts based on the current selection
             if (selectionMark == 1)
@@ -323,7 +326,7 @@ namespace RolePlaying
                 spriteBatch.Draw(arrowTexture, leaveArrowPosition, Color.White);
                 spriteBatch.DrawString(Fonts.GearInfoFont, stayString, stayPosition,
                     Fonts.DisplayColor);
-                spriteBatch.DrawString(Fonts.GearInfoFont, leaveString, leavePosition, 
+                spriteBatch.DrawString(Fonts.GearInfoFont, leaveString, leavePosition,
                     Fonts.HighlightColor);
             }
             // Draw the amount of gold

+ 0 - 2
RolePlayingGame/Core/GameScreens/ListScreen.cs

@@ -645,7 +645,5 @@ namespace RolePlaying
                 spriteBatch.DrawString(Fonts.HeaderFont, titleText, position, Fonts.TitleColor, MathHelper.ToRadians(-3.0f), Vector2.Zero, 1.0f, SpriteEffects.None, 0f);
             }
         }
-
-
     }
 }

+ 0 - 3
RolePlayingGame/Core/GameScreens/NpcScreen.cs

@@ -23,9 +23,6 @@ namespace RolePlaying
         protected MapEntry<T> mapEntry = null;
         protected Character character = null;
 
-
-
-
         /// <summary>
         /// Create a new NpcScreen object.
         /// </summary>

+ 3 - 3
RolePlayingGame/Core/Session/Session.cs

@@ -72,10 +72,10 @@ namespace RolePlaying
             }
 
             // load the map
-            ContentManager content = singleton.screenManager.Game.Content;
+            ContentManager contentManager = singleton.screenManager.Game.Content;
 
-            //Map map = content.Load<Map>(mapContentName).Clone() as Map;
-            var map = Map.Load(mapContentName, content);
+            //TODO Map map = content.Load<Map>(mapContentName).Clone() as Map;
+            var map = Map.Load(mapContentName, contentManager);
 
             // modify the map based on the world changes (removed chests, etc.).
             singleton.ModifyMap(map);

+ 21 - 72
RolePlayingGame/RolePlayingGameData/Characters/Character.cs

@@ -19,52 +19,8 @@ namespace RolePlaying.Data
 #if !XBOX
     [DebuggerDisplay("Name = {name}")]
 #endif
-    public abstract class Character : WorldObject
+    public abstract partial class Character : WorldObject
     {
-
-
-        /// <summary>
-        /// The state of a character.
-        /// </summary>
-        public enum CharacterState
-        {
-            /// <summary>
-            /// Ready to perform an action, and playing the idle animation
-            /// </summary>
-            Idle,
-
-            /// <summary>
-            /// Walking in the world.
-            /// </summary>
-            Walking,
-
-            /// <summary>
-            /// In defense mode
-            /// </summary>
-            Defending,
-
-            /// <summary>
-            /// Performing Dodge Animation
-            /// </summary>
-            Dodging,
-
-            /// <summary>
-            /// Performing Hit Animation
-            /// </summary>
-            Hit,
-
-            /// <summary>
-            /// Dead, but still playing the dying animation.
-            /// </summary>
-            Dying,
-
-            /// <summary>
-            /// Dead, with the dead animation.
-            /// </summary>
-            Dead,
-        }
-
-
         /// <summary>
         /// The state of this character.
         /// </summary>
@@ -88,7 +44,7 @@ namespace RolePlaying.Data
         {
             get
             {
-                return ((State == CharacterState.Dying) || 
+                return ((State == CharacterState.Dying) ||
                     (State == CharacterState.Dead));
             }
         }
@@ -164,7 +120,7 @@ namespace RolePlaying.Data
         /// <remarks>
         /// If this object is null, then the animations are taken from MapSprite.
         /// </remarks>
-        [ContentSerializer(Optional=true)]
+        [ContentSerializer(Optional = true)]
         public AnimatingSprite WalkingSprite
         {
             get { return walkingSprite; }
@@ -232,7 +188,7 @@ namespace RolePlaying.Data
         /// <summary>
         /// The default idle-animation interval for the animating map sprite.
         /// </summary>
-        [ContentSerializer(Optional=true)]
+        [ContentSerializer(Optional = true)]
         public int MapIdleAnimationInterval
         {
             get { return mapIdleAnimationInterval; }
@@ -243,25 +199,25 @@ namespace RolePlaying.Data
         /// <summary>
         /// Add the standard character idle animations to this character.
         /// </summary>
-        private void AddStandardCharacterIdleAnimations()
+        internal void AddStandardCharacterIdleAnimations()
         {
             if (mapSprite != null)
             {
-                mapSprite.AddAnimation(new Animation("IdleSouth", 1, 6, 
+                mapSprite.AddAnimation(new Animation("IdleSouth", 1, 6,
                     MapIdleAnimationInterval, true));
-                mapSprite.AddAnimation(new Animation("IdleSouthwest", 7, 12, 
+                mapSprite.AddAnimation(new Animation("IdleSouthwest", 7, 12,
                     MapIdleAnimationInterval, true));
-                mapSprite.AddAnimation(new Animation("IdleWest", 13, 18, 
+                mapSprite.AddAnimation(new Animation("IdleWest", 13, 18,
                     MapIdleAnimationInterval, true));
-                mapSprite.AddAnimation(new Animation("IdleNorthwest", 19, 24, 
+                mapSprite.AddAnimation(new Animation("IdleNorthwest", 19, 24,
                     MapIdleAnimationInterval, true));
-                mapSprite.AddAnimation(new Animation("IdleNorth", 25, 30, 
+                mapSprite.AddAnimation(new Animation("IdleNorth", 25, 30,
                     MapIdleAnimationInterval, true));
-                mapSprite.AddAnimation(new Animation("IdleNortheast", 31, 36, 
+                mapSprite.AddAnimation(new Animation("IdleNortheast", 31, 36,
                     MapIdleAnimationInterval, true));
-                mapSprite.AddAnimation(new Animation("IdleEast", 37, 42, 
+                mapSprite.AddAnimation(new Animation("IdleEast", 37, 42,
                     MapIdleAnimationInterval, true));
-                mapSprite.AddAnimation(new Animation("IdleSoutheast", 43, 48, 
+                mapSprite.AddAnimation(new Animation("IdleSoutheast", 43, 48,
                     MapIdleAnimationInterval, true));
             }
         }
@@ -286,35 +242,30 @@ namespace RolePlaying.Data
         /// <summary>
         /// Add the standard character walk animations to this character.
         /// </summary>
-        private void AddStandardCharacterWalkingAnimations()
+        internal void AddStandardCharacterWalkingAnimations()
         {
             AnimatingSprite sprite = (walkingSprite == null ? mapSprite : walkingSprite);
             if (sprite != null)
             {
-                sprite.AddAnimation(new Animation("WalkSouth", 1, 6, 
+                sprite.AddAnimation(new Animation("WalkSouth", 1, 6,
                     MapWalkingAnimationInterval, true));
-                sprite.AddAnimation(new Animation("WalkSouthwest", 7, 12, 
+                sprite.AddAnimation(new Animation("WalkSouthwest", 7, 12,
                     MapWalkingAnimationInterval, true));
-                sprite.AddAnimation(new Animation("WalkWest", 13, 18, 
+                sprite.AddAnimation(new Animation("WalkWest", 13, 18,
                     MapWalkingAnimationInterval, true));
                 sprite.AddAnimation(new Animation("WalkNorthwest", 19, 24,
                     MapWalkingAnimationInterval, true));
                 sprite.AddAnimation(new Animation("WalkNorth", 25, 30,
                     MapWalkingAnimationInterval, true));
-                sprite.AddAnimation(new Animation("WalkNortheast", 31, 36, 
+                sprite.AddAnimation(new Animation("WalkNortheast", 31, 36,
                     MapWalkingAnimationInterval, true));
                 sprite.AddAnimation(new Animation("WalkEast", 37, 42,
                     MapWalkingAnimationInterval, true));
-                sprite.AddAnimation(new Animation("WalkSoutheast", 43, 48, 
+                sprite.AddAnimation(new Animation("WalkSoutheast", 43, 48,
                     MapWalkingAnimationInterval, true));
             }
         }
 
-
-
-
-
-
         /// <summary>
         /// Reads a Character object from the content pipeline.
         /// </summary>
@@ -323,7 +274,7 @@ namespace RolePlaying.Data
             /// <summary>
             /// Reads a Character object from the content pipeline.
             /// </summary>
-            protected override Character Read(ContentReader input, 
+            protected override Character Read(ContentReader input,
                 Character existingInstance)
             {
                 Character character = existingInstance;
@@ -364,7 +315,5 @@ namespace RolePlaying.Data
                 return character;
             }
         }
-
-
     }
-}
+}

+ 53 - 0
RolePlayingGame/RolePlayingGameData/Characters/CharacterState.cs

@@ -0,0 +1,53 @@
+//-----------------------------------------------------------------------------
+// CharacterState.cs
+//
+// Microsoft XNA Community Game Platform
+// Copyright (C) Microsoft Corporation. All rights reserved.
+//-----------------------------------------------------------------------------
+
+namespace RolePlaying.Data
+{
+    public abstract partial class Character : WorldObject
+    {
+        /// <summary>
+        /// The state of a character.
+        /// </summary>
+        public enum CharacterState
+        {
+            /// <summary>
+            /// Ready to perform an action, and playing the idle animation
+            /// </summary>
+            Idle,
+
+            /// <summary>
+            /// Walking in the world.
+            /// </summary>
+            Walking,
+
+            /// <summary>
+            /// In defense mode
+            /// </summary>
+            Defending,
+
+            /// <summary>
+            /// Performing Dodge Animation
+            /// </summary>
+            Dodging,
+
+            /// <summary>
+            /// Performing Hit Animation
+            /// </summary>
+            Hit,
+
+            /// <summary>
+            /// Dead, but still playing the dying animation.
+            /// </summary>
+            Dying,
+
+            /// <summary>
+            /// Dead, with the dead animation.
+            /// </summary>
+            Dead,
+        }
+    }
+}

+ 1 - 1
RolePlayingGame/RolePlayingGameData/Characters/FightingCharacter.cs

@@ -627,7 +627,7 @@ namespace RolePlaying.Data
         /// <summary>
         /// Add the standard character walk animations to this character.
         /// </summary>
-        private void AddStandardCharacterCombatAnimations()
+        internal void AddStandardCharacterCombatAnimations()
         {
             if (combatSprite != null)
             {

+ 61 - 0
RolePlayingGame/RolePlayingGameData/Characters/Monster.cs

@@ -7,8 +7,11 @@
 
 using System;
 using System.Collections.Generic;
+using System.IO;
+using System.Linq;
 using Microsoft.Xna.Framework;
 using Microsoft.Xna.Framework.Content;
+using Microsoft.Xna.Framework.Graphics;
 
 namespace RolePlaying.Data
 {
@@ -90,6 +93,64 @@ namespace RolePlaying.Data
             return gearRewards;
         }
 
+        internal static Monster Load(string monsterContentName, ContentManager contentManager)
+        {
+            var asset = XmlHelper.GetAssetElementFromXML(monsterContentName);
+            var monster = new Monster
+            {
+                AssetName = monsterContentName,
+                Name = (string)asset.Element("Name"),
+                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
+                },
+                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
+                },
+                GearDrops = asset.Element("GearDrops")?.Elements("Item")
+                    .Select(item => new GearDrop
+                    {
+                        GearName = (string)item.Element("GearName"),
+                        DropPercentage = (int)item.Element("DropPercentage")
+                    }).ToList()
+            };
+
+            monster.CharacterClass = CharacterClass.Load(Path.Combine("CharacterClasses", monster.CharacterClassContentName));
+
+            monster.AddStandardCharacterCombatAnimations();
+            monster.AddStandardCharacterIdleAnimations();
+            monster.AddStandardCharacterWalkingAnimations();
+
+            monster.ResetAnimation(false);
+
+            return monster;
+        }
+
 
 
 

+ 14 - 4
RolePlayingGame/RolePlayingGameData/Characters/Player.cs

@@ -304,12 +304,14 @@ namespace RolePlaying.Data
             return player;
         }
 
-        public static Player Load(string playerPath, ContentManager contentManager)
+        public static Player Load(string contentName, ContentManager contentManager)
         {
-            var asset = XmlHelper.GetAssetElementFromXML(playerPath);
-
-            var player = new Player
+            var asset = XmlHelper.GetAssetElementFromXML(contentName);
+            
+			// Create a new Player instance and populate it with data from the XML asset
+			var player = new Player
             {
+                AssetName = contentName,
                 Name = (string)asset.Element("Name"),
                 MapSprite = new AnimatingSprite
                 {
@@ -383,6 +385,14 @@ namespace RolePlaying.Data
             // load the character class
             player.CharacterClass = CharacterClass.Load(Path.Combine("CharacterClasses", player.CharacterClassContentName));
 
+            player.AddStandardCharacterCombatAnimations();
+            player.AddStandardCharacterIdleAnimations();
+            player.AddStandardCharacterWalkingAnimations();
+            
+            player.ResetAnimation(false);
+
+            // TODO Looks like player is floating. Offset issue.player.ShadowTexture = contentManager.Load<Texture2D>(@"Textures\Characters\CharacterShadow");
+
             return player;
         }
     }

+ 44 - 8
RolePlayingGame/RolePlayingGameData/Characters/QuestNpc.cs

@@ -6,7 +6,10 @@
 //-----------------------------------------------------------------------------
 
 using System;
+using System.IO;
+using Microsoft.Xna.Framework;
 using Microsoft.Xna.Framework.Content;
+using Microsoft.Xna.Framework.Graphics;
 
 namespace RolePlaying.Data
 {
@@ -31,17 +34,52 @@ namespace RolePlaying.Data
             set { introductionDialogue = value; }
         }
 
-
-
-
-
+        public static QuestNpc Load(string npcPath, ContentManager contentManager)
+        {
+            var asset = XmlHelper.GetAssetElementFromXML(npcPath);
+            
+            var questNpc = new QuestNpc
+            {
+                AssetName = npcPath,
+                Name = (string)asset.Element("Name"),
+                IntroductionDialogue = (string)asset.Element("IntroductionDialogue"),
+                MapIdleAnimationInterval = asset.Element("MapIdleAnimationInterval") != null
+                    ? int.TryParse((string)asset.Element("MapIdleAnimationInterval"), out var interval) ? interval : default
+                    : default,
+                MapSprite = asset.Element("MapSprite") != null
+                    ? 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
+                        }
+                    : null,
+            };
+
+            questNpc.AddStandardCharacterIdleAnimations();
+            questNpc.AddStandardCharacterWalkingAnimations();
+
+            questNpc.ResetAnimation(false);
+
+            // TODO Looks like player is floating. Offset issue. questNpc.ShadowTexture = contentManager.Load<Texture2D>(@"Textures\Characters\CharacterShadow");
+
+            return questNpc;
+        }
 
         /// <summary>
         /// Read a QuestNpc object from the content pipeline.
         /// </summary>
         public class QuestNpcReader : ContentTypeReader<QuestNpc>
         {
-            protected override QuestNpc Read(ContentReader input, 
+            protected override QuestNpc Read(ContentReader input,
                 QuestNpc existingInstance)
             {
                 QuestNpc questNpc = existingInstance;
@@ -57,7 +95,5 @@ namespace RolePlaying.Data
                 return questNpc;
             }
         }
-
-
     }
-}
+}

+ 1 - 0
RolePlayingGame/RolePlayingGameData/Gear/Gear.cs

@@ -221,6 +221,7 @@ namespace RolePlaying.Data
         public Texture2D IconTexture
         {
             get { return iconTexture; }
+            set { iconTexture = value; }
         }
 
 

+ 30 - 0
RolePlayingGame/RolePlayingGameData/Map/FixedCombat.cs

@@ -8,6 +8,7 @@
 using System;
 using System.Collections.Generic;
 using System.IO;
+using System.Linq;
 using Microsoft.Xna.Framework.Content;
 
 namespace RolePlaying.Data
@@ -31,6 +32,35 @@ namespace RolePlaying.Data
             set { entries = value; }
         }
 
+        internal static FixedCombat Load(string contentName, ContentManager contentManager)
+        {
+            var asset = XmlHelper.GetAssetElementFromXML(contentName);
+
+            // Create a new FixedCombat instance and populate it with data from the XML asset
+            var fixedCombat = new FixedCombat()
+            {
+                AssetName = contentName,
+                Name = (string)asset.Element("Name"),
+                Entries = asset.Element("Entries")?.Elements("Item")
+                    .Select(entry =>
+                    {
+                        var monsterContentName = (string)entry.Element("ContentName");
+                        var monsterCount = (int?)entry.Element("Count") ?? 1;
+
+                        var monster = Monster.Load(Path.Combine(@"Characters\Monsters", monsterContentName), contentManager);
+
+                        return new ContentEntry<Monster>
+                        {
+                            ContentName = monsterContentName,
+                            Count = monsterCount,
+                            Content = monster
+                        };
+                    }).ToList(),
+            };
+
+            return fixedCombat;
+        }
+
 
 
 

+ 19 - 1
RolePlayingGame/RolePlayingGameData/Map/Inn.cs

@@ -113,6 +113,7 @@ namespace RolePlaying.Data
         public Texture2D ShopkeeperTexture
         {
             get { return shopkeeperTexture; }
+            set { shopkeeperTexture = value; }
         }
 
 
@@ -148,6 +149,23 @@ namespace RolePlaying.Data
             }
         }
 
-
+        internal static Inn Load(string contentName, ContentManager contentManager)
+        {
+            var asset = XmlHelper.GetAssetElementFromXML(contentName);
+            var inn = new Inn
+            {
+                AssetName = contentName,
+                Name = asset.Element("Name").Value,
+                ChargePerPlayer = int.Parse(asset.Element("ChargePerPlayer").Value),
+                WelcomeMessage = asset.Element("WelcomeMessage").Value,
+                PaidMessage = asset.Element("PaidMessage").Value,
+                NotEnoughGoldMessage = asset.Element("NotEnoughGoldMessage").Value,
+                ShopkeeperTextureName = asset.Element("ShopkeeperTextureName").Value,
+                ShopkeeperTexture = contentManager.Load<Texture2D>(
+                    System.IO.Path.Combine(@"Textures\Characters\Portraits",
+                    asset.Element("ShopkeeperTextureName").Value)),
+            };
+            return inn;
+        }
     }
 }

+ 168 - 55
RolePlayingGame/RolePlayingGameData/Map/Map.cs

@@ -623,11 +623,6 @@ namespace RolePlaying.Data
             set { storeEntries = value; }
         }
 
-
-
-
-
-
         public object Clone()
         {
             Map map = new Map();
@@ -675,11 +670,12 @@ namespace RolePlaying.Data
             return map;
         }
 
-        public static Map Load(string mapContentName, ContentManager content)
+        public static Map Load(string mapContentName, ContentManager contentManager)
         {
             var asset = XmlHelper.GetAssetElementFromXML(mapContentName);
             var map = new Map
             {
+                AssetName = mapContentName,
                 Name = asset.Element("Name").Value,
                 MapDimensions = new Point(
                     int.Parse(asset.Element("MapDimensions").Value.Split(' ')[0]),
@@ -691,10 +687,10 @@ namespace RolePlaying.Data
                     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>(
+                Texture = contentManager.Load<Texture2D>(
                     Path.Combine(@"Textures\Maps\NonCombat", (string)asset.Element("TextureName"))),
                 CombatTextureName = (string)asset.Element("CombatTextureName"),
-                CombatTexture = content.Load<Texture2D>(
+                CombatTexture = contentManager.Load<Texture2D>(
                     Path.Combine(@"Textures\Maps\Combat", (string)asset.Element("CombatTextureName"))),
                 MusicCueName = (string)asset.Element("MusicCueName"),
                 CombatMusicCueName = (string)asset.Element("CombatMusicCueName"),
@@ -725,62 +721,179 @@ namespace RolePlaying.Data
                         DestinationMapPortalName = (string)item.Element("DestinationMapPortalName")
                     }).ToList(),
                 PortalEntries = asset.Element("PortalEntries")?.Elements("Item")
-                    .Select(item => new MapEntry<Portal>
+                    .Select(item =>
                     {
-                        ContentName = (string)item.Element("ContentName"),
-                        MapPosition = new Point(
+                        var contentName = (string)item.Element("ContentName");
+                        var direction = Enum.TryParse<Direction>((string)item.Element("Direction"), out var dir) ? dir : default;
+                        var mapPosition = new Point(
                             int.Parse(item.Element("MapPosition").Value.Split(' ')[0]),
-                            int.Parse(item.Element("MapPosition").Value.Split(' ')[1]))
+                            int.Parse(item.Element("MapPosition").Value.Split(' ')[1]));
+
+                        // Load the QuestNpc asset XML using contentName
+                        var portalItem = asset.Element("Portals")?.Elements("Item").FirstOrDefault(p => (string)p.Element("Name") == contentName);
+
+                        var portal = new Portal
+						{
+                            Name = (string)portalItem.Element("Name"),
+							LandingMapPosition = new Point(
+							    int.Parse(portalItem.Element("LandingMapPosition").Value.Split(' ')[0]),
+							    int.Parse(portalItem.Element("LandingMapPosition").Value.Split(' ')[1])),
+							DestinationMapContentName = (string)portalItem.Element("DestinationMapContentName"),
+							DestinationMapPortalName = (string)portalItem.Element("DestinationMapPortalName")
+						};
+
+                        return new MapEntry<Portal>
+                        {
+                            ContentName = contentName,
+                            Content = portal,
+                            Direction = direction,
+                            MapPosition = mapPosition
+                        };
                     }).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(),
+                    .Select(item => {
+						var contentName = (string)item.Element("ContentName");
+						var direction = Enum.TryParse<Direction>((string)item.Element("Direction"), out var dir) ? dir : default;
+						var mapPosition = new Point(
+							int.Parse(item.Element("MapPosition").Value.Split(' ')[0]),
+							int.Parse(item.Element("MapPosition").Value.Split(' ')[1]));
+
+						// Load the QuestNpc asset XML using contentName
+						var chestAsset = XmlHelper.GetAssetElementFromXML(Path.Combine(@"Maps/Chests", contentName));
+						var chest = new Chest
+						{
+							Name = (string)chestAsset.Element("Name"),
+                            Gold = (int)chestAsset.Element("Gold"),
+							Entries = chestAsset.Element("Entries")?.Elements("Item").Select(chestItem => {
+								var contentName = (string)chestItem.Element("ContentName");
+								var gearAsset = XmlHelper.GetAssetElementFromXML(Path.Combine(@"Gear", contentName));
+								var gear = new Equipment
+								{
+                                    AssetName = contentName,
+									Name = (string)gearAsset.Element("Name"),
+									Description = (string)gearAsset.Element("Description"),
+									GoldValue = (int?)gearAsset.Element("GoldValue") ?? 0,
+									IconTextureName = (string)gearAsset.Element("IconTextureName"),
+									IconTexture = contentManager.Load<Texture2D>(
+										Path.Combine(@"Textures\Gear", (string)gearAsset.Element("IconTextureName"))),
+									// Add other properties as needed
+								};
+
+								return new ContentEntry<Gear>
+								{
+									ContentName = contentName,
+									Content = gear,
+									Count = (int?)chestItem.Element("Count") ?? 1,
+								};
+							}).ToList(),
+							TextureName = (string)chestAsset.Element("TextureName"),
+							Texture = contentManager.Load<Texture2D>(
+					            Path.Combine(@"Textures\Chests", (string)chestAsset.Element("TextureName"))),
+						};
+
+						return new MapEntry<Chest>
+						{
+							ContentName = contentName,
+							Content = chest,
+							Direction = direction,
+							MapPosition = mapPosition
+						};
+					}).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(),
+                    .Select(item => {
+						var contentName = (string)item.Element("ContentName");
+						var direction = Enum.TryParse<Direction>((string)item.Element("Direction"), out var dir) ? dir : default;
+						var mapPosition = new Point(
+							int.Parse(item.Element("MapPosition").Value.Split(' ')[0]),
+							int.Parse(item.Element("MapPosition").Value.Split(' ')[1]));
+
+						// Load the fixed combat asset XML using contentName
+                        var fixedCombat = FixedCombat.Load(Path.Combine(@"Maps/FixedCombats", contentName), contentManager);
+
+						return new MapEntry<FixedCombat>
+                        {
+                            ContentName = contentName,
+                            Content = fixedCombat,
+                            Direction = direction,
+                            MapPosition = mapPosition
+                        };
+					}).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(),
+                    .Select(item => {
+						var contentName = (string)item.Element("ContentName");
+						var direction = Enum.TryParse<Direction>((string)item.Element("Direction"), out var dir) ? dir : default;
+						var mapPosition = new Point(
+							int.Parse(item.Element("MapPosition").Value.Split(' ')[0]),
+							int.Parse(item.Element("MapPosition").Value.Split(' ')[1]));
+
+						// Load the PlayerNpc asset XML using contentName
+                        var playerNpc = Player.Load(Path.Combine(@"Characters/Players", contentName), contentManager);
+
+                        return new MapEntry<Player>
+                        {
+                            ContentName = contentName,
+                            Content = playerNpc,
+                            Direction = direction,
+                            MapPosition = mapPosition
+                        };
+					}).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(),
+                    .Select(item => {
+						var contentName = (string)item.Element("ContentName");
+						var direction = Enum.TryParse<Direction>((string)item.Element("Direction"), out var dir) ? dir : default;
+						var mapPosition = new Point(
+							int.Parse(item.Element("MapPosition").Value.Split(' ')[0]),
+							int.Parse(item.Element("MapPosition").Value.Split(' ')[1]));
+
+						// Load the QuestNpc asset XML using contentName
+                        var questNpc = QuestNpc.Load(Path.Combine(@"Characters/QuestNPCs", contentName), contentManager);
+                        
+						return new MapEntry<QuestNpc>
+                        {
+                            ContentName = contentName,
+                            Content = questNpc,
+                            Direction = direction,
+                            MapPosition = mapPosition
+                        };
+					}).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(),
+                    .Select(item => {
+						var contentName = (string)item.Element("ContentName");
+						var direction = Enum.TryParse<Direction>((string)item.Element("Direction"), out var dir) ? dir : default;
+						var mapPosition = new Point(
+							int.Parse(item.Element("MapPosition").Value.Split(' ')[0]),
+							int.Parse(item.Element("MapPosition").Value.Split(' ')[1]));
+
+						// Load the Inn asset XML using contentName
+                        var inn = Inn.Load(Path.Combine(@"Maps/Inns", contentName), contentManager);
+
+						return new MapEntry<Inn>
+                        {
+                            ContentName = contentName,
+                            Content = inn,
+                            Direction = direction,
+                            MapPosition = mapPosition
+                        };
+					}).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(),
+                    .Select(item => {
+						var contentName = (string)item.Element("ContentName");
+						var direction = Enum.TryParse<Direction>((string)item.Element("Direction"), out var dir) ? dir : default;
+						var mapPosition = new Point(
+							int.Parse(item.Element("MapPosition").Value.Split(' ')[0]),
+							int.Parse(item.Element("MapPosition").Value.Split(' ')[1]));
+
+						// Load the Store asset XML using contentName
+                        var store = Store.Load(Path.Combine(@"Maps/Stores", contentName), contentManager);
+
+						return new MapEntry<Store>
+                        {
+                            ContentName = contentName,
+                            Content = store,
+                            Direction = direction,
+                            MapPosition = mapPosition
+                        };
+					}).ToList(),
             };
 
             var randomCombatElement = asset.Element("RandomCombat");

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

@@ -7,6 +7,7 @@
 
 using System;
 using System.Collections.Generic;
+using System.Linq;
 using Microsoft.Xna.Framework.Content;
 using Microsoft.Xna.Framework.Graphics;
 
@@ -114,12 +115,37 @@ namespace RolePlaying.Data
         public Texture2D ShopkeeperTexture
         {
             get { return shopkeeperTexture; }
+            set { shopkeeperTexture = value; }
         }
 
-
-
-
-
+        internal static Store Load(string contentName, ContentManager contentManager)
+        {
+            var asset = XmlHelper.GetAssetElementFromXML(contentName);
+            var store = new Store
+            {
+                AssetName = contentName,
+                Name = asset.Element("Name").Value,
+                BuyMultiplier = float.Parse(asset.Element("BuyMultiplier").Value),
+                SellMultiplier = float.Parse(asset.Element("SellMultiplier").Value),
+                WelcomeMessage = asset.Element("WelcomeMessage").Value,
+                ShopkeeperTextureName = asset.Element("ShopkeeperTextureName").Value,
+                ShopkeeperTexture = contentManager.Load<Texture2D>(
+                    System.IO.Path.Combine(@"Textures\Characters\Portraits",
+                    asset.Element("ShopkeeperTextureName").Value)),
+                StoreCategories = asset.Element("StoreCategories")
+                    .Elements("StoreCategory")
+                    .Select(storeCategory => new StoreCategory
+                    {
+                        Name = storeCategory.Element("Name").Value,
+                        AvailableContentNames = storeCategory.Element("AvailableContentNames")
+                            .Elements("ContentName")
+                            .Select(contentNameElement => contentNameElement.Value)
+                            .ToList(),
+                    }).ToList(),
+            };
+
+            return store;
+        }
 
         /// <summary>
         /// Reads an Store object from the content pipeline.
@@ -142,13 +168,11 @@ namespace RolePlaying.Data
                 store.WelcomeMessage = input.ReadString();
                 store.ShopkeeperTextureName = input.ReadString();
                 store.shopkeeperTexture = input.ContentManager.Load<Texture2D>(
-                    System.IO.Path.Combine(@"Textures\Characters\Portraits", 
+                    System.IO.Path.Combine(@"Textures\Characters\Portraits",
                     store.ShopkeeperTextureName));
 
                 return store;
             }
         }
-
-
     }
-}
+}