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; } } /// Activates the character. public virtual void Activate() { this.AttachLabel(""); } } }