//----------------------------------------------------------------------------- // Player.cs // // Microsoft XNA Community Game Platform // Copyright (C) Microsoft Corporation. All rights reserved. //----------------------------------------------------------------------------- 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 { /// /// A member of the player's party, also represented in the world before joining. /// /// /// There is only one of a given Player in the game world at a time, and their /// current statistics persist after combat. Thererefore, current statistics /// are tracked here. /// public class Player : FightingCharacter #if WINDOWS , ICloneable #endif { /// /// The current set of persistent statistics modifiers - damage, etc. /// [ContentSerializerIgnore] public StatisticsValue StatisticsModifiers = new StatisticsValue(); /// /// The current set of statistics, including damage, etc. /// [ContentSerializerIgnore] public StatisticsValue CurrentStatistics { get { return CharacterStatistics + StatisticsModifiers; } } /// /// The amount of gold that the player has when it joins the party. /// private int gold; /// /// The amount of gold that the player has when it joins the party. /// public int Gold { get { return gold; } set { gold = value; } } /// /// The dialogue that the player says when it is greeted as an Npc in the world. /// private string introductionDialogue; /// /// The dialogue that the player says when it is greeted as an Npc in the world. /// public string IntroductionDialogue { get { return introductionDialogue; } set { introductionDialogue = value; } } /// /// The dialogue that the player says when its offer to join is accepted. /// private string joinAcceptedDialogue; /// /// The dialogue that the player says when its offer to join is accepted. /// public string JoinAcceptedDialogue { get { return joinAcceptedDialogue; } set { joinAcceptedDialogue = value; } } /// /// The dialogue that the player says when its offer to join is rejected. /// private string joinRejectedDialogue; /// /// The dialogue that the player says when its offer to join is rejected. /// public string JoinRejectedDialogue { get { return joinRejectedDialogue; } set { joinRejectedDialogue = value; } } /// /// The name of the active portrait texture. /// private string activePortraitTextureName; /// /// The name of the active portrait texture. /// public string ActivePortraitTextureName { get { return activePortraitTextureName; } set { activePortraitTextureName = value; } } /// /// The active portrait texture. /// private Texture2D activePortraitTexture; /// /// The active portrait texture. /// [ContentSerializerIgnore] public Texture2D ActivePortraitTexture { get { return activePortraitTexture; } set { activePortraitTexture = value; } } /// /// The name of the inactive portrait texture. /// private string inactivePortraitTextureName; /// /// The name of the inactive portrait texture. /// public string InactivePortraitTextureName { get { return inactivePortraitTextureName; } set { inactivePortraitTextureName = value; } } /// /// The inactive portrait texture. /// private Texture2D inactivePortraitTexture; /// /// The inactive portrait texture. /// [ContentSerializerIgnore] public Texture2D InactivePortraitTexture { get { return inactivePortraitTexture; } set { inactivePortraitTexture = value; } } /// /// The name of the unselectable portrait texture. /// private string unselectablePortraitTextureName; /// /// The name of the unselectable portrait texture. /// public string UnselectablePortraitTextureName { get { return unselectablePortraitTextureName; } set { unselectablePortraitTextureName = value; } } /// /// The unselectable portrait texture. /// private Texture2D unselectablePortraitTexture; /// /// The unselectable portrait texture. /// [ContentSerializerIgnore] public Texture2D UnselectablePortraitTexture { get { return unselectablePortraitTexture; } set { unselectablePortraitTexture = value; } } /// /// Read a Player object from the content pipeline. /// public class PlayerReader : ContentTypeReader { protected override Player Read(ContentReader input, Player existingInstance) { Player player = existingInstance; if (player == null) { player = new Player(); } input.ReadRawObject(player as FightingCharacter); player.Gold = input.ReadInt32(); player.IntroductionDialogue = input.ReadString(); player.JoinAcceptedDialogue = input.ReadString(); player.JoinRejectedDialogue = input.ReadString(); player.ActivePortraitTextureName = input.ReadString(); player.activePortraitTexture = input.ContentManager.Load( System.IO.Path.Combine(@"Textures\Characters\Portraits", player.ActivePortraitTextureName)); player.InactivePortraitTextureName = input.ReadString(); player.inactivePortraitTexture = input.ContentManager.Load( System.IO.Path.Combine(@"Textures\Characters\Portraits", player.InactivePortraitTextureName)); player.UnselectablePortraitTextureName = input.ReadString(); player.unselectablePortraitTexture = input.ContentManager.Load( System.IO.Path.Combine(@"Textures\Characters\Portraits", player.UnselectablePortraitTextureName)); return player; } } public object Clone() { Player player = new Player(); player.activePortraitTexture = activePortraitTexture; player.activePortraitTextureName = activePortraitTextureName; player.AssetName = AssetName; player.CharacterClass = CharacterClass; player.CharacterClassContentName = CharacterClassContentName; player.CharacterLevel = CharacterLevel; player.CombatAnimationInterval = CombatAnimationInterval; player.CombatSprite = CombatSprite.Clone() as AnimatingSprite; player.Direction = Direction; player.EquippedEquipment.AddRange(EquippedEquipment); player.Experience = Experience; player.gold = gold; player.inactivePortraitTexture = inactivePortraitTexture; player.inactivePortraitTextureName = inactivePortraitTextureName; player.InitialEquipmentContentNames.AddRange(InitialEquipmentContentNames); player.introductionDialogue = introductionDialogue; player.Inventory.AddRange(Inventory); player.joinAcceptedDialogue = joinAcceptedDialogue; player.joinRejectedDialogue = joinRejectedDialogue; player.MapIdleAnimationInterval = MapIdleAnimationInterval; player.MapPosition = MapPosition; player.MapSprite = MapSprite.Clone() as AnimatingSprite; player.MapWalkingAnimationInterval = MapWalkingAnimationInterval; player.Name = Name; player.ShadowTexture = ShadowTexture; player.State = State; player.unselectablePortraitTexture = unselectablePortraitTexture; player.unselectablePortraitTextureName = unselectablePortraitTextureName; player.WalkingSprite = WalkingSprite.Clone() as AnimatingSprite; player.RecalculateEquipmentStatistics(); player.RecalculateTotalDefenseRanges(); player.RecalculateTotalTargetDamageRange(); player.ResetAnimation(false); player.ResetBaseStatistics(); 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( 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( 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( 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( Path.Combine(@"Textures\Characters\Portraits", (string)asset.Element("ActivePortraitTextureName"))), InactivePortraitTextureName = (string)asset.Element("InactivePortraitTextureName"), InactivePortraitTexture = contentManager.Load( Path.Combine(@"Textures\Characters\Portraits", (string)asset.Element("InactivePortraitTextureName"))), UnselectablePortraitTextureName = (string)asset.Element("UnselectablePortraitTextureName"), UnselectablePortraitTexture = contentManager.Load( Path.Combine(@"Textures\Characters\Portraits", (string)asset.Element("UnselectablePortraitTextureName"))), Inventory = asset.Element("Inventory")?.Elements("Item") .Select(x => new ContentEntry { ContentName = (string)x.Element("ContentName"), Count = (int?)x.Element("Count") ?? 1 // Default to 1 if not specified }) .ToList() ?? new List>() }; // load the character class player.CharacterClass = CharacterClass.Load(Path.Combine("CharacterClasses", player.CharacterClassContentName)); return player; } } }