//-----------------------------------------------------------------------------
// 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;
}
}
}