using System;
using System.IO;
using SFML.Graphics;
using SFML.Window;
namespace Blashyrkh.Game {
public enum MotionType : int
{
Walking = 0,
Jogging = 1
}
public abstract class Character : GameObject, Activatable, Movable {
private IniParser CommonTraits;
private IniParser RaceTraits;
protected string Race;
protected Attribute[] Attributes;
protected float[] Speed;
public Attribute this[AttributeName name] {
get { return this.Attributes[(int)name]; }
set { this.Attributes[(int)name] = value; }
}
public Character()
{
// DO NOTHING.
}
// FIXME: This function needs to be cleaned up.
public Character(string name, string race, Vector2u position)
: base(name, TextureType.Sprite, position)
{
// Load attributes/traits.
new LogMessage("Loading attributes for race {0}.", race);
this.CommonTraits = new IniParser(Path.Combine(Game.BasePath, "Data/Data/Races/Common.ini"));
this.RaceTraits = new IniParser(Path.Combine(Game.BasePath, "Data/Data/Races/", race + ".ini"));
// Set up the attributes.
this.Speed = new float[] {
float.Parse(this.CommonTraits["Speed"]["Walking"]),
float.Parse(this.CommonTraits["Speed"]["Jogging"])
};
this.Size = new Vector2u(
uint.Parse(this.RaceTraits["Size"]["Width"]),
uint.Parse(this.RaceTraits["Size"]["Height"])
);
AttributeName[] attribs = (AttributeName[])Enum.GetValues(typeof(AttributeName));
this.Attributes = new Attribute[attribs.Length];
foreach(AttributeName attrib in attribs) {
string attribName = ((AttributeName)attrib).ToString();
// Find the second capital letter. This is the
// start of the property name. Everything before
// that is the section name.
// FIXME: It's not good to have the format of
// the strings hard-coded like this, nor to have
// a total lack of error-checking.
string section = "", property = "";
for (int i = 1; i < attribName.Length; ++i) {
if (Char.IsUpper(attribName[i])) {
section = attribName.Substring(0, i);
property = attribName.Substring(i);
break;
}
}
// Store the values. Some of these variables
// could do with renaming..
string valuesStr = this.RaceTraits[section][property];
string[] strValues = valuesStr.Split(' ');
this[attrib] = new Attribute();
this[attrib].Current = float.Parse(strValues[0]);
this[attrib].Maximum = float.Parse(strValues[1]);
this[attrib].Experience = float.Parse(strValues[2]);
}
}
public void DamageAttribute(AttributeName attribute, float damage)
{
int index = (int)attribute;
this.Attributes[index].Current -= damage;
// Make sure the value is between 0 and the maximum
// inclusive.
if (this.Attributes[index].Current < 0)
this.Attributes[index].Current = 0;
else if (this.Attributes[index].Current > this.Attributes[index].Maximum)
this.Attributes[index].Current = this.Attributes[index].Maximum;
}
public virtual void Move(Direction direction, float time, FloatRect rect)
{
uint distance = (uint)(this.CurrentSpeed * time);
switch(direction) {
case Direction.Down:
this.Position = new Vector2u(this.Position.X,
this.Position.Y + distance);
break;
case Direction.Left:
this.Position = new Vector2u(this.Position.X - distance,
this.Position.Y);
break;
case Direction.Right:
this.Position = new Vector2u(this.Position.X + distance,
this.Position.Y);
break;
case Direction.Up:
this.Position = new Vector2u(this.Position.X,
this.Position.Y - distance);
break;
}
}
/// <summary> Activates the character. </summary>
public virtual void Activate()
{
this.AttachLabel("");
}
}
}