#region Arthea License
/***********************************************************************
* Arthea MUD by R. Jennings (2007) http://arthea.googlecode.com/ *
* By using this code you comply with the Artistic and GPLv2 Licenses. *
***********************************************************************/
#endregion
using System.Xml.Serialization;
using Arthea.Affects;
using Arthea.Connections.Players;
using Arthea.Continents.Areas.Characters.Enums;
using Arthea.Continents.Areas.Items;
using Arthea.Continents.Areas.Items.Enums;
using Arthea.Continents.Areas.Rooms;
using Arthea.Creation.Attributes;
using Arthea.Environment;
using Arthea.Interfaces;
using Arthea.Races;
using Arthea.Scripts;
namespace Arthea.Continents.Areas.Characters
{
/// <summary>
/// An entity with a role to play in the game.
/// </summary>
public class Character : Scriptable
{
#region [rgn] Fields (24)
private const int defautVitals = 100;
private AffectList affects = new AffectList();
private int armor;
[EditShow] private ItemList carrying = new ItemList();
private string description;
[XmlIgnore, EditIgnore] private Character fighting;
private int hit = defautVitals;
[EditShow] private CharIndex index;
private byte level;
private int mana = defautVitals;
private int maxHit = defautVitals;
private int maxMana = defautVitals;
private int maxMove = defautVitals;
private int move = defautVitals;
private string name;
private Position position = Position.Standing;
private Race race;
[EditShow] private Room room;
private string roomDescr;
/// <summary>
/// True if RoomDescr should be serialized
/// </summary>
[EditIgnore, XmlIgnore] public bool RoomDescrSpecified = true;
private Sex sex;
private string shortDescr;
/// <summary>
/// True if ShortDescr should be serialized
/// </summary>
[EditIgnore, XmlIgnore] public bool ShortDescrSpecified = true;
/// <summary>
/// True if XmlIndex should be serialized
/// </summary>
[XmlIgnore, EditIgnore] public bool XmlIndexSpecified = true;
#endregion [rgn]
#region [rgn] Constructors (3)
/// <summary>
/// Initializes a new instance of the <see cref="Character"/> class.
/// </summary>
/// <param name="level">The level.</param>
/// <param name="name">The name.</param>
public Character(byte level, string name)
{
this.level = level;
this.name = name;
}
/// <summary>
/// Initializes a new instance of the <see cref="Character"/> class.
/// </summary>
/// <param name="index">The index.</param>
public Character(CharIndex index)
{
this.index = index;
level = index.Level;
name = index.Name;
shortDescr = index.ShortDescr;
roomDescr = index.RoomDescr;
description = index.Description;
hit = maxHit = index.MaxHit;
mana = maxMana = index.MaxMana;
move = maxMove = index.MaxMove;
position = index.Position;
sex = index.Sex;
race = index.Race;
affects = index.Affects;
affects.Add(index.Race.Affects);
}
/// <summary>
/// Default Constructor
/// </summary>
public Character()
{
}
#endregion [rgn]
#region [rgn] Properties (26)
/// <summary>
/// Gets or sets the affects.
/// </summary>
/// <value>The affects.</value>
public AffectList Affects
{
get { return affects; }
set { affects = value; }
}
/// <summary>
/// Gets the area.
/// </summary>
/// <value>The area.</value>
public virtual Area Area
{
get { return index.Area; }
}
/// <summary>
/// Gets or sets the armor.
/// </summary>
/// <value>The armor.</value>
public int Armor
{
get { return armor; }
set { armor = value; }
}
/// <summary>
/// Gets or sets the carrying.
/// </summary>
/// <value>The carrying.</value>
public ItemList Carrying
{
get { return carrying; }
set { carrying = value; }
}
/// <summary>
/// Gets or sets the description.
/// </summary>
/// <value>The description.</value>
public string Description
{
get { return description; }
set { description = value; }
}
/// <summary>
/// Gets or sets the fighting.
/// </summary>
/// <value>The fighting.</value>
[XmlIgnore]
public Character Fighting
{
get { return fighting; }
set
{
fighting = value;
if (value != null)
{
Lists.Fights.Add(this);
position = Position.Fighting;
}
else
{
Lists.Fights.Remove(this);
position = Position.Standing;
}
}
}
/// <summary>
/// Gets or sets the hit.
/// </summary>
/// <value>The hit.</value>
public int Hit
{
get { return hit; }
set
{
hit = value;
if (hit > maxHit)
hit = maxHit;
}
}
/// <summary>
/// Gets the id.
/// </summary>
/// <value>The id.</value>
public uint Id
{
get
{
if (index != null)
return index.Id;
else
return 0;
}
}
/// <summary>
/// Gets or sets the code.
/// </summary>
/// <value>The code.</value>
[XmlIgnore]
public CharIndex Index
{
get { return index; }
set { index = value; }
}
/// <summary>
/// Gets or sets the level.
/// </summary>
/// <value>The level.</value>
public byte Level
{
get { return level; }
set { level = value; }
}
/// <summary>
/// Gets or sets the mana.
/// </summary>
/// <value>The mana.</value>
public int Mana
{
get { return mana; }
set
{
mana = value;
if (mana > maxMana)
mana = maxMana;
}
}
/// <summary>
/// Gets or sets the max hit.
/// </summary>
/// <value>The max hit.</value>
public int MaxHit
{
get { return maxHit; }
set { maxHit = value; }
}
/// <summary>
/// Gets or sets the max mana.
/// </summary>
/// <value>The max mana.</value>
public int MaxMana
{
get { return maxMana; }
set { maxMana = value; }
}
/// <summary>
/// Gets or sets the max move.
/// </summary>
/// <value>The max move.</value>
public int MaxMove
{
get { return maxMove; }
set { maxMove = value; }
}
/// <summary>
/// Gets or sets the move.
/// </summary>
/// <value>The move.</value>
public int Move
{
get { return move; }
set
{
move = value;
if (move > maxMove)
move = maxMove;
}
}
/// <summary>
/// Gets or sets the position.
/// </summary>
/// <value>The position.</value>
public Position Position
{
get { return position; }
set { position = value; }
}
/// <summary>
/// Gets or sets the race.
/// </summary>
/// <value>The race.</value>
[XmlIgnore]
public Race Race
{
get { return race; }
set { race = value; }
}
/// <summary>
/// Gets/sets the character room.
/// </summary>
[XmlIgnore]
public Room Room
{
get { return room; }
set
{
if (room != null && room != value && room.Characters.Contains(this))
{
room.Characters.Remove(this);
if (this is Player)
room.Area.Players--;
}
room = value;
if (room != null && !room.Characters.Contains(this))
{
room.Characters.Add(this);
if (this is Player)
room.Area.Players++;
}
}
}
/// <summary>
/// Gets or sets the room descr.
/// </summary>
/// <value>The room descr.</value>
public virtual string RoomDescr
{
get { return roomDescr; }
set { roomDescr = value; }
}
/// <summary>
/// Gets or sets the sex.
/// </summary>
/// <value>The sex.</value>
public Sex Sex
{
get { return sex; }
set { sex = value; }
}
/// <summary>
/// Gets the size.
/// </summary>
/// <value>The size.</value>
public Size Size
{
get { return race == null ? Size.Medium : race.Size; }
}
/// <summary>
/// Gets or sets the code id.
/// </summary>
/// <value>The code id.</value>
[XmlElement("Code")]
public virtual uint XmlIndex
{
get { return index.Id; }
set { index = Lists.CharIndexes[value]; }
}
/// <summary>
/// Gets or sets the race as a string.
/// </summary>
/// <value>The race as a string.</value>
[XmlElement("Race")]
public string XmlRace
{
get { return race.Name; }
set { race = Lists.Races.FindName(value); }
}
/// <summary>
/// Gets or sets the room id.
/// </summary>
/// <value>The room id.</value>
[XmlElement("Room")]
public uint XmlRoom
{
get { return room != null ? room.Id : Globals.Limbo; }
set { Room = Lists.Rooms[value]; }
}
/// <summary>
/// Gets or sets the name.
/// </summary>
/// <value>The name.</value>
public string Name
{
get { return name; }
set { name = value; }
}
/// <summary>
/// Gets or sets the short descr.
/// </summary>
/// <value>The short descr.</value>
public virtual string ShortDescr
{
get { return shortDescr; }
set { shortDescr = value; }
}
#endregion [rgn]
#region [rgn] Methods (13)
// [rgn] Public Methods (13)
/// <summary>
/// Performs an action message.
/// </summary>
/// <param name="arg1">The arg1.</param>
/// <param name="arg2">The arg2.</param>
/// <param name="type">The type.</param>
/// <param name="text">The text.</param>
/// <param name="args">The args.</param>
public void Act(object arg1, object arg2, ulong type, string text, params object[] args)
{
Act(arg1, arg2, type, string.Format(text, args));
}
/// <summary>
/// Performs an action message
/// </summary>
/// <param name="arg1">The arg1.</param>
/// <param name="arg2">The arg2.</param>
/// <param name="type">The type.</param>
/// <param name="text">The text.</param>
public void Act(object arg1, object arg2, ulong type, string text)
{
Act bitArray = new Act(type);
Character vict = arg2 as Character;
if (bitArray.Has(Arthea.Act.ToPlayer))
{
Arthea.Act.Show(this, arg1, arg2, this, text);
}
if (bitArray.Has(Arthea.Act.ToVictim))
{
if (vict != null && vict != this)
Arthea.Act.Show(this, arg1, arg2, vict, text);
}
if (bitArray.Has(Arthea.Act.ToRoom | Arthea.Act.ToNotVict))
{
Item item1 = arg1 as Item;
Item item2 = arg2 as Item;
Room currentRoom = null;
if (Room != null)
{
currentRoom = Room;
}
else if (item1 != null && item1.Room != null)
{
currentRoom = item1.Room;
}
else if (item2 != null && item2.Room != null)
{
currentRoom = item2.Room;
}
else
{
Log.Bug("Act.Show: Bad room.");
}
if (currentRoom != null)
{
foreach (Character rch in currentRoom.Characters)
{
if (rch == this || rch == vict)
continue;
Arthea.Act.Show(this, arg1, arg2, rch, text);
}
}
}
if (bitArray.Has(Arthea.Act.ToWorld))
{
foreach (Player p in Lists.Players)
{
if (p == this)
continue;
Arthea.Act.Show(this, arg1, arg2, p, text);
}
}
}
/// <summary>
/// Attaches this instance.
/// </summary>
public virtual void Attach()
{
Lists.Characters.Add(this);
}
/// <summary>
/// Equips the specified item.
/// </summary>
/// <param name="item">The item.</param>
public void Equip(Item item)
{
item.WearLoc = item.Index.WearLoc;
affects.Add(item.Affects);
}
/// <summary>
/// Gets the equip.
/// </summary>
/// <param eqName="eqName">The eqName.</param>
/// <returns></returns>
public Item GetEquip(String eqName)
{
foreach (Item item in carrying)
{
if (item.WearLoc == WearLocation.None)
continue;
if (eqName.IsPrefixOf(item.Name))
{
return item;
}
}
return null;
}
/// <summary>
/// Removes character from lists
/// </summary>
public virtual void Release()
{
Lists.Characters.Remove(this);
if (room != null)
{
room.Characters.Remove(this);
room = null;
}
while (carrying.Count > 0)
{
carrying[0].Release();
}
Fighting = null;
}
/// <summary>
/// Returns a <see cref="T:System.String"></see> that represents the current <see cref="T:System.Object"></see>.
/// </summary>
/// <returns>
/// A <see cref="T:System.String"></see> that represents the current <see cref="T:System.Object"></see>.
/// </returns>
public override string ToString()
{
return shortDescr;
}
/// <summary>
/// A string representation for a character.
/// </summary>
/// <param name="looker">The looker.</param>
/// <returns></returns>
public string ToString(Character looker)
{
return ShortDescr;
}
/// <summary>
/// Uns the equip.
/// </summary>
/// <param name="item">The item.</param>
public void UnEquip(Item item)
{
item.WearLoc = WearLocation.None;
affects.Remove(item.Affects);
}
/// <summary>
/// Writes the specified text.
/// </summary>
/// <param name="text">The text.</param>
/// <param name="args">The args.</param>
public virtual void Write(string text, params object[] args)
{
Player player;
if (this is Player && (player = this as Player) != null)
{
player.Write(text, args);
}
}
/// <summary>
/// Writes the specified text.
/// </summary>
/// <param name="text">The text.</param>
public virtual void Write(string text)
{
Player player;
if (this is Player && (player = this as Player) != null)
{
player.Write(text);
}
}
/// <summary>
/// Writes a line.
/// </summary>
/// <param name="text">The text.</param>
/// <param name="args">The args.</param>
public virtual void WriteLine(string text, params object[] args)
{
Player player;
if (this is Player && (player = this as Player) != null)
player.WriteLine(text, args);
}
/// <summary>
/// Writes the line.
/// </summary>
public virtual void WriteLine()
{
Player player;
if (this is Player && (player = this as Player) != null)
{
player.WriteLine();
}
}
#endregion [rgn]
#region Scriptable Members
/// <summary>
/// Creates a script of proper type.
/// </summary>
/// <returns></returns>
public Script CreateScript(ScriptCode code, String trigger)
{
return new CharScript(code, trigger);
}
#endregion
}
}