roh/conf.old/area/
roh/config/code/python/
roh/config/game/area/
roh/config/game/signs/
roh/help/dmhelp/
roh/help/help/
roh/log/
roh/log/staff/
roh/monsters/ocean/
roh/objects/misc/
roh/objects/ocean/
roh/player/
roh/rooms/area/1/
roh/rooms/misc/
roh/rooms/ocean/
roh/src-2.47e/
/*
 * creatures.h
 *	 Header file for creature / monster / player classes
 *   ____            _
 *  |  _ \ ___  __ _| |_ __ ___  ___
 *  | |_) / _ \/ _` | | '_ ` _ \/ __|
 *  |  _ <  __/ (_| | | | | | | \__ \
 *  |_| \_\___|\__,_|_|_| |_| |_|___/
 *
 * Permission to use, modify and distribute is granted via the
 *  Creative Commons - Attribution - Non Commercial - Share Alike 3.0 License
 *    http://creativecommons.org/licenses/by-nc-sa/3.0/
 *
 * 	Copyright (C) 2007-2012 Jason Mitchell, Randi Mitchell
 * 	   Contributions by Tim Callahan, Jonathan Hseu
 *  Based on Mordor (C) Brooke Paul, Brett J. Vickers, John P. Freeman
 *
 */
#ifndef CREATURES_H_
#define CREATURES_H_

#include "damage.h"
#include "threat.h"
#include "group.h"
#include "creatureStreams.h"

enum mType {
    INVALID        = -1,
    PLAYER          = 0,
    MONSTER         = 1,

    NPC             = 2,
    HUMANOID        = 2,

    GOBLINOID       = 3,
    MONSTROUSHUM    = 4,
    GIANTKIN        = 5,
    ANIMAL          = 6,
    DIREANIMAL      = 7,
    INSECT          = 8,
    INSECTOID       = 9,
    ARACHNID        = 10,
    REPTILE         = 11,
    DINOSAUR        = 12,
    AUTOMATON       = 13,
    AVIAN           = 14,
    FISH            = 15,
    PLANT           = 16,
    DEMON           = 17,
    DEVIL           = 18,
    DRAGON          = 19,
    BEAST           = 20,
    MAGICALBEAST    = 21,
    GOLEM           = 22,
    ETHEREAL        = 23,
    ASTRAL          = 24,
    GASEOUS         = 25,
    ENERGY          = 26,
    FAERIE          = 27,
    DEVA            = 28,
    ELEMENTAL       = 29,
    PUDDING         = 30,
    SLIME           = 31,
    UNDEAD          = 32,

    MAX_MOB_TYPES
};

#include "monType.h"

enum AttackType {
	ATTACK_NORMAL,
	ATTACK_BACKSTAB,
	ATTACK_AMBUSH,
	ATTACK_BASH,
	ATTACK_MAUL,
	ATTACK_KICK,

	ATTACK_TYPE_MAX
};
enum AttackResult {
	ATTACK_MISS,
	ATTACK_DODGE,
	ATTACK_PARRY,
	ATTACK_RIPOSTE,
	ATTACK_GLANCING,
	ATTACK_BLOCK,
	ATTACK_CRITICAL,
	ATTACK_FUMBLE,
	ATTACK_HIT,

	ATTACK_MAX
};

// prototype because calendar.h hasnt been called yet
class cDay;
class StartLoc;
class Monster;
class Recipe;
class TalkResponse;
class QuestInfo;
class QuestCompletion;
class QuestCatRef;
class SpellData;

// NOTE: It is important to use these defines for loading in an array of aray of *chars*
// ie: attack[3][30].  The size in the structure and the size passed to the loadStringArray
// function must be the same, this ensures it.  If creating any more arrays of this type use
// a similar define and use it in files-xml-read.c as well.
// -- Bane
#define CRT_ATTACK_LENGTH		30
#define CRT_KEY_LENGTH			20
#define CRT_MOVETYPE_LENGTH		52
#define CRT_FLAG_ARRAY_SIZE		32

#define NUM_ASSIST_MOB			8
#define NUM_ENEMY_MOB			4

#define DEL_ROOM_DESTROYED		1
#define DEL_PORTAL_DESTROYED	2
#define NUM_RESCUE			    2

class SkillGain;
class SpecialAttack;

enum DamageType {
	DMG_NONE = 0,
	PHYSICAL_DMG = 1,
	MENTAL_DMG = 2,
	MAGICAL_DMG = 3
};

enum DeathCheck {
	NO_CHECK,
	CHECK_DIE,
	CHECK_DIE_ROB,
	MAX_CHECK
};

#include "timer.h"


class CustomCrt {
public:
	CustomCrt();

	short	community;

	short	parents;
	short	brothers;
	short	sisters;

	short	social;
	short	education;
	short	height;
	short	weight;

	bstring hair;
	bstring eyes;
	bstring skin;


	static const int PARENTS_UNKNOWN = -1;
	static const int PARENTS_DEAD = 0;
	static const int PARENTS_MOTHER_DEAD = 1;
	static const int PARENTS_FATHER_DEAD = 2;
	static const int PARENTS_ALIVE = 3;

	static const int COMMUNITY_OUTCAST = 1;
	static const int COMMUNITY_HAMLET = 2;
	static const int COMMUNITY_VILLAGE = 3;
	static const int COMMUNITY_LARGE_VILLAGE = 4;
	static const int COMMUNITY_CITY = 5;

	static const int SOCIAL_OUTCAST = 1;
	static const int SOCIAL_CRIMINAL = 2;
	static const int SOCIAL_POOR = 3;
	static const int SOCIAL_LOWER = 4;
	static const int SOCIAL_MIDDLE = 5;
	static const int SOCIAL_UPPER = 6;
	static const int SOCIAL_NOBLE = 7;

	static const int EDUCATION_NONE = 1;
	static const int EDUCATION_APPRENTICE = 2;
	static const int EDUCATION_BASIC = 3;
	static const int EDUCATION_NORMAL = 4;
	static const int EDUCATION_UNIVERSITY = 5;
};

typedef std::list<Monster*> PetList;
typedef std::map<bstring, Skill*> SkillMap;
//*********************************************************************
//						Creature
//*********************************************************************

class Creature: public virtual MudObject, public Streamable, public Container, public Containable {

protected:
	void CopyCommon(const Creature& cr);
	void crtDestroy();
	void crtReset();

protected:
// Data
	unsigned short level;
	unsigned short cClass;
	unsigned short race;
	short alignment;
	mType type; // creature type
	unsigned int attackPower; // Attack power increases base damage of a creature
	unsigned int armor;
	unsigned long experience;
	unsigned long temp_experience; // Temp experience.
	unsigned short deity;
	Size size;
	unsigned short clan;
	unsigned short poison_dur;
	unsigned short poison_dmg;
	bstring description;
	bstring version; // Version of the mud this creature was saved under
	char flags[CRT_FLAG_ARRAY_SIZE]; // Max flags - 256
	unsigned long realm[MAX_REALM-1]; // Magic Spell realms
	char spells[32]; // more spells
	char quests[32]; // more quests
	static const short OFFGUARD_REMOVE;
	static const short OFFGUARD_NOREMOVE;
	static const short OFFGUARD_NOPRINT;
	DeathType deathtype;
	bstring poisonedBy;		// displayed to player, if this is a player, they get credit for pkill

	Group* group;
	GroupStatus groupStatus;


public:
// Constructors, Deconstructors, etc
	Creature();
	Creature(Creature& cr);
	Creature(const Creature& cr);
	Creature& operator=(const Creature& cr);
	//virtual bool operator< (const MudObject& t) const = 0;
	virtual ~Creature() {};

//	Monster* getMonster();
//	Player* getPlayer();
//

	virtual void upgradeStats() {};
	virtual Socket* getSock() const;
	Location getLocation();
	void delayedAction(bstring action, int delay, MudObject* target=0);
	void delayedScript(bstring script, int delay);

//	const Monster* getConstMonster() const;
//	const Player* getConstPlayer() const;

	Creature* getMaster();
	const Creature* getConstMaster() const;

	Player* getPlayerMaster();
	const Player* getConstPlayerMaster() const;


	bool isPlayer() const;
	bool isMonster() const;
	bool checkMp(int reqMp);
	bool checkResource(ResourceType resType, int resCost);
	void subResource(ResourceType resType, int resCost);
	void subMp(int reqMp);

	Creature* myTarget;
    PetList pets;
	std::list<Creature*> targetingThis;

	MagicType getCastingType() const;
	int doHeal(Creature* target, int amt, double threatFactor = 0.5);

	bstring doReplace(bstring fmt, const MudObject* actor=NULL, const MudObject* applier=NULL) const;

	void unApplyTongues();
	void unSilence();
	void unBlind();
	void stand();

	bool inSameRoom(Creature* target);


	Creature* findVictim(cmd* cmnd, int cmndNo, bool aggressive=true, bool selfOk=false, bstring noVictim="", bstring notFound="");
	Creature* findVictim(bstring toFind, int num, bool aggressive=true, bool selfOk=false, bstring noVictim="", bstring notFound="");
	Creature* findMagicVictim(bstring toFind, int num, SpellData* spellData, bool aggressive=true, bool selfOk=false, bstring noVictim="", bstring notFound="");

	bool hasAttackableTarget();
	bool isAttackingTarget();
	Creature* getTarget();
	Creature* addTarget(Creature* toTarget);
	void checkTarget(Creature* toTarget);
	void addTargetingThis(Creature* targeter);
	void clearTarget(bool clearTargetsList = true);
	void clearTargetingThis(Creature* targeter);

	long getLTLeft(int myLT, long t = -1); // gets the time left on a LT
	void setLastTime(int myLT, long t, long interval); // Sets a LT



public:
// Data
	bstring plural;
	std::map<bstring, long> factions;
	SkillMap skills;
	char key[3][CRT_KEY_LENGTH];
	short fd; // Socket number
	short current_language;
	long proficiency[6]; // Weapon proficiencies: 6 now..added cleaving weapons
	int afterProf;
	Dice damage;
	Money coins;
	//CatRef room;
#define 				NUMHITS quests[0]
	short questnum; // Quest fulfillment number (M)
	Object *ready[MAXWEAR];// Worn/readied items
	//etag *first_enm; // List of enemies
	ttag *first_tlk; // List of talk responses

	struct saves saves[6]; // Saving throws struct. POI, DEA, BRE, MEN, SPL, x, x
	char languages[16];
	char movetype[3][CRT_MOVETYPE_LENGTH]; // Movement types..."flew..oozed...etc.."
	Stat strength;
	Stat dexterity;
	Stat constitution;
	Stat intelligence;
	Stat piety;
	Stat hp;
	Stat mp;
	Stat pp; // psi points for psionicists
	Stat rp; // recovery points for weaponless classes
	struct daily daily[20]; // added more daily limits
	struct lasttime lasttime[128]; // added more timers

	// future new tic amount code
	struct tic hpTic;
	struct tic mpTic;
	struct tic ppTic;
	struct tic rpTic;

	struct spellTimer spellTimer[16]; // spell effect timers (specific to magic)
	char misc[21]; // miscellaneous space

	//EffectList effects; // List of all effects on this creature
	Timer attackTimer;
	std::list<SpecialAttack*> specials; // List of all special attack this creature has
	std::list<bstring> minions; // vampire minions


	Location currentLocation;
	Location previousRoom; // last room they were in
	void setPreviousRoom();

// Groups & Pets

    void setGroup(Group* newGroup);
    void setGroupStatus(GroupStatus newStatus);

    Group* getGroup(bool inGroup = true);
    GroupStatus getGroupStatus();
    Creature* getGroupLeader();

    void addToGroup(Group* toJoin, bool announce = true);
    void createGroup(Creature* crt);
    bool removeFromGroup(bool announce = true);

    bool inSameGroup(Creature* target);

    void dismissPet(Monster* toDismiss);
    void dismissAll();
    void displayPets();
	void addPet(Monster* newPet, bool setPetFlag = true);
	void delPet(Monster* toDel);
	bool hasPet() const;

	Monster* findPet(Monster* toFind);
	Monster* findPet(bstring pName, int pNum);

// XML: loading and saving
	int saveToXml(xmlNodePtr rootNode, int permOnly, LoadType saveType, bool saveID = true) const;
    void savePets(xmlNodePtr curNode) const;
	void saveSkills(xmlNodePtr rootNode) const;
	void saveFactions(xmlNodePtr rootNode) const;
	void saveAttacks(xmlNodePtr rootNode) const;
	int readFromXml(xmlNodePtr rootNode);
	void loadAttacks(xmlNodePtr rootNode);
	void loadFactions(xmlNodePtr rootNode);
	bool loadFaction(xmlNodePtr rootNode);
	void loadSkills(xmlNodePtr rootNode);
	void loadStats(xmlNodePtr curNode);

	bool pulseEffects(time_t t);

	void convertOldEffects();
	bool convertFlag(int flag);
	bool convertToEffect(const bstring& effect, int flag, int lt);
	bool addStatModEffect(EffectInfo* effect);
	bool remStatModEffect(EffectInfo* effect);
	void removeStatEffects();
	bool doPetrificationDmg();
	bool willIgnoreIllusion() const;
	bool isInvisible() const; // *

// Skills
	bool knowsSkill(const bstring& skillName) const; // *
	double getSkillLevel(const bstring& skillName, bool useBase = true) const; // *
	double getSkillGained(const bstring& skillName, bool useBase = true) const; // *
	double getTradeSkillGained(const bstring& skillName, bool useBase = true) const; // *
	Skill* getSkill(const bstring& skillName, bool useBase = true) const;
	void addSkill(const bstring& skillName, int gained); // *
	void remSkill(const bstring& skillName); // *
	void checkSkillsGain(std::list<SkillGain*>::const_iterator begin, std::list<SkillGain*>::const_iterator end, bool setToLevel = false);
	void checkImprove(const bstring& skillName, bool success, int attribute = INT, int bns = 0); // *
	bool setSkill(const bstring skill, int gained); // *

// Formatting
	virtual void escapeText() {};
	bstring getCrtStr(const Creature* viewer = NULL, int flags = 0, int num = 0) const;
	bstring statCrt(int statFlags);
	int displayFlags() const;
	bstring alignColor() const;
	bstring fullName() const;
	const char *hisHer() const;
	const char *himHer() const;
	const char *heShe() const;
	const char *upHisHer() const;
	const char *upHeShe() const;
	void pleaseWait(long duration) const;
	void pleaseWait(int duration) const;
	void pleaseWait(double duration) const;
	const char* getStatusStr(int dmg=0);
	virtual const bstring customColorize(bstring text, bool caret=true) const = 0;

	void bPrint(bstring toPrint) const;
	void print(const char *fmt, ...) const;
	void printColor(const char *fmt, ...) const;
	virtual void vprint(const char *fmt, va_list ap) const {};

// Combat & Death
	Creature *findFirstEnemyCrt(Creature *pet);
	bool checkDie(Creature *killer); // *
	bool checkDie(Creature *killer, bool &freeTarget); // *
	int checkDieRobJail(Monster *killer); // *
	int checkDieRobJail(Monster *killer, bool &freeTarget); // *
	void checkDoctorKill(Creature *victim);
	void die(Creature *killer); // *
	void die(Creature *killer, bool &freeTarget); // *
	void clearAsPetEnemy();
	virtual void gainExperience(Monster* victim, Creature* killer, int expAmount, bool groupExp = false) {} ;
	void adjustExperience(Monster* victim, int& expAmount, int& holidayExp);
	int doWeaponResist(int dmg, bstring weaponCategory) const;
	int doDamage(Creature* target, int dmg, DeathCheck shouldCheckDie = CHECK_DIE, DamageType dmgType = PHYSICAL_DMG);
	int doDamage(Creature* target, int dmg, DeathCheck shouldCheckDie, DamageType dmgType, bool &freeTarget);
	int chkSave(short savetype, Creature* target, short bns);
	int castWeapon(Creature* target, Object* weapon, bool &meKilled);
	void castDelay(long delay);
	void attackDelay(long delay);
	void stun(int delay);
	int doLagProtect();
	bool hasCharm(bstring charmed);
	bool inCombat(bool countPets) const;
	bool inCombat(const Creature* target=0, bool countPets=0) const;
	bool canAttack(Creature* target, bool stealing=false);
	int checkRealmResist(int dmg, Realm realm) const;
	void knockUnconscious(long duration);
	void clearAsEnemy();
	bool checkAttackTimer(bool displayFail = true);
	void updateAttackTimer(bool setDelay = true, int delay = 0);
	time_t getLTAttack() const;
	void modifyAttackDelay(int amt);
	void setAttackDelay(int newDelay);
	int getAttackDelay() const;
	unsigned int getBaseDamage() const;
	float getDamageReduction(const Creature* target) const; // How much is our damage reduced attacking the target
	AttackResult getAttackResult(Creature* victim, const Object* weapon = NULL, int resultFlags = 0, int altSkillLevel = -1);
	bool kamiraLuck(Creature *attacker);
	virtual int computeDamage(Creature* victim, Object* weapon,
			AttackType attackType, AttackResult& result, Damage& attackDamage,
			bool computeBonus, int& drain, float multiplier = 1.0) = 0;
	bool canRiposte() const;
	bool canParry(Creature* attacker);
	bool canDodge(Creature* attacker);
	int dodge(Creature* target);
	int parry(Creature* target);
	double getFumbleChance(const Object* weapon);
	double getCriticalChance(const int& difference);
	double getBlockChance(Creature* attacker, const int& difference);
	double getGlancingBlowChance(Creature* attacker, const int& difference);
	double getParryChance(Creature* attacker, const int& difference);
	double getDodgeChance(Creature* attacker, const int& difference);
	double getMissChance(const int& difference);
	virtual int getWeaponSkill(const Object* weapon = NULL) const = 0;
	virtual int getDefenseSkill() const = 0;
	int adjustChance(const int &difference);
	int computeBlock(int dmg);
	bool getsGroupExperience(Monster* target);
	bool canHit(Creature* target, Object* weapon = NULL, bool glow = true, bool showFail = true);
	bool doReflectionDamage(Damage damage, Creature* target, ReflectedDamageType printZero=REFLECTED_NONE);
	static void simultaneousDeath(Creature* attacker, Creature* target, bool freeAttacker, bool freeTarget);
	bool canBeDrained() const;


	int spellFail(int how);
	bool isMageLich();
	bool noPotion(SpellData* spellData);
	int doMpCheck(int splno);
	int getTurnChance(Creature* target);

// Special Attacks
	bstring getSpecialsFullList() const;
	bool useSpecial(const bstring& special, Creature* victim);
	bool useSpecial(SpecialAttack* attack, Creature* victim);
	bool runOpeners(Creature* victim); // Run any opening attacks
	bool runSpecialAttacks(Creature* victim); // Pick a special attack and do it on the target
	bstring getSpecialsList() const;
	SpecialAttack* addSpecial(const bstring specialName);
	bool delSpecials();
	SpecialAttack* getSpecial(const bstring& special);

	// Do Special should only be run from useSpecial, should not be called from elsewhere
	bool doSpecial(SpecialAttack* attack, Creature* victim); // Do the selected attack on the given victim

// Traits
	bool doesntBreathe() const;
	bool immuneCriticals() const; // *
	bool isUndead() const; // *
	bool hasMp();
	bool isAntiGradius() const;
	bool countForWeightTrap() const;
	bool isRace(int r) const; // *
	bool isBrittle() const; // *
	bool isUnconscious() const; // *
	bool isBraindead() const; // *

	bool isHidden() const; // *
	bool canSpeak() const;

	bool negAuraRepel() const;
	bool canBuildObjects() const;
	bool canBuildMonsters() const;

	bool isPublicWatcher() const;
	bool isPet() const; // *
	bool isWatcher() const; // *
	bool isStaff() const; // *
	bool isCt() const; // *
	bool isDm() const; // *
	bool isAdm() const; // *

	bool isPureCaster() const;
	bool isHybridCaster() const;

// Equipment / Inventory
	void addObj(Object* object);
	void delObj(Object* object, bool breakUnique=false, bool removeUnique=false, bool darkmetal=true, bool darkness=true, bool keep=false);
	void finishDelObj(Object* object, bool breakUnique, bool removeUnique, bool darkmetal, bool darkness, bool keep);
	int getWeight() const;
	int maxWeight();
	bool tooBulky(int n) const;
	int getTotalBulk() const;
	int getMaxBulk() const;
	unsigned long getInventoryValue() const;
	void killDarkmetal();
	bool equip(Object* object, bool showMessage=true);
	Object* unequip(int wearloc, UnequipAction action = UNEQUIP_ADD_TO_INVENTORY, bool darkness=true, bool showEffect=true);
	void printEquipList(const Player* viewer);
	void checkDarkness();
	int countBagInv();
	int countInv(bool permOnly = false);

// Afflictions
	void poison(Creature* enemy, unsigned int damagePerPulse, unsigned int duration);
	bool immuneToPoison() const; // *
	bool isPoisoned() const;
	bool curePoison();
	void disease(Creature* enemy, unsigned int damagePerPulse);
	bool poisonedByMonster() const;
	bool poisonedByPlayer() const;
	bool immuneToDisease() const; // *
	bool isDiseased() const; // *
	bool cureDisease();
	bool removeCurse();
	bool isBlind() const; // *
	bool isNewVampire() const; // *
	bool isNewWerewolf() const; // *
	void makeVampire();
	bool willBecomeVampire() const;
	bool vampireCharmed(Player* master);
	void clearMinions();
	bool addPorphyria(Creature *killer, int chance);
	bool sunlightDamage();
	void makeWerewolf();
	bool willBecomeWerewolf() const;
	bool addLycanthropy(Creature *killer, int chance);


// Get
	unsigned short getClass() const; // *
	unsigned short getLevel() const; // *
	short getAlignment() const; // *
	unsigned int getArmor() const; // *
	unsigned long getExperience() const; // *

	unsigned short getClan() const; // *
	mType getType() const;
	unsigned short getRace() const; // *
	unsigned short getDeity() const; // *
	Size getSize() const; // *
	unsigned int getAttackPower() const; // *
	bstring getDescription() const; // *
	bstring getVersion() const; // *
	unsigned short getPoisonDuration() const;
	unsigned short getPoisonDamage() const;
	Sex getSex() const;
	unsigned long getRealm(Realm r) const;
	bstring getPoisonedBy() const;
	unsigned short getDisplayRace() const;
	bool inJail() const;

// Set
	void setClass(unsigned short c); // *
	void setClan(unsigned short c); // *
	void setRace(unsigned short r); // *
	void addExperience(unsigned long e); // *
	void subExperience(unsigned long e); // *
	void setExperience(unsigned long e);
	void setLevel(unsigned short l, bool isDm=false);
	void setAlignment(short a);
	void subAlignment(unsigned short a); // *
	void setArmor(unsigned int a);
	void setAttackPower(unsigned int a);
	void setDeity(unsigned short d);
	void setSize(Size s);
	void setType(unsigned short t);
	void setType(mType t);
	void setDescription(const bstring& desc);
	void setVersion(bstring v = "");
	void setVersion(xmlNodePtr rootNode);
	void setPoisonDuration(unsigned short d);
	void setPoisonDamage(unsigned short d);
	void setSex(Sex sex);
	void setDeathType(DeathType d);
	void setPoisonedBy(const bstring& p);

	void setRealm(unsigned long num, Realm r);
	void addRealm(unsigned long num, Realm r);
	void subRealm(unsigned long num, Realm r);





// Miscellaneous
	bool pFlagIsSet(int flag) const;
	void pSetFlag(int flag);
	void pClearFlag(int flag);

	bool mFlagIsSet(int flag) const;
	void mSetFlag(int flag);
	void mClearFlag(int flag);


	bool flagIsSet(int flag) const;  // *
	void setFlag(int flag); // *
	void clearFlag(int flag); // *
	bool toggleFlag(int flag); // *

	bool spellIsKnown(int spell) const; // *
	void learnSpell(int spell); // *
	void forgetSpell(int spell); // *

	bool languageIsKnown(int lang) const; // *
	void learnLanguage(int lang); // *
	void forgetLanguage(int lang); // *

	bool inSameRoom(const Creature *b) const;
	virtual int getAdjustedAlignment() const=0;
	bool checkDimensionalAnchor() const;
	bool checkStaff(const char *failStr, ...) const;
	int smashInvis(); // *
	bool unhide(bool show = true); // *
	void unmist(); // *
	void adjustStats();
	void fixLts();
	void doDispelMagic(int num=-1);
	bool changeSize(int oldStrength, int newStrength, bool enlarge);

	bool addStatModifier(bstring statName, bstring modifierName, int modAmt, ModifierType modType);
	bool addStatModifier(bstring statName, StatModifier* statModifier);
	bool setStatDirty(bstring statName);
	Stat* getStat(bstring statName);

	// these handle total invisibility, no concealment (ie, being hidden)
	bool canSee(const MudObject* target, bool skip=false) const;

	bool canSeeRoom(const BaseRoom* room, bool p=false) const;
	bool canEnter(const Exit *ext, bool p=false, bool blinking=false) const;
	bool canEnter(const UniqueRoom* room, bool p=false) const;
	bool willFit(const Object* object) const;
	bool canWield(const Object* object, int n) const;
	bool canFlee(bool displayFail = false, bool checkTimer = true);
	bool canFleeToExit(const Exit *exit, bool skipScary=false, bool blinking=false);
	Exit* getFleeableExit();
	BaseRoom* getFleeableRoom(Exit* exit);
	int flee(bool magicTerror=false, bool wimpyFlee = false);
	bool doFlee(bool magicTerror=false);

	bool isSitting();

	bool ableToDoCommand(const cmd* cmnd=NULL) const;
	void wake(bstring str = "", bool noise=false);
	void modifyDamage(Creature* enemy, int atype, Damage& damage, Realm realm=NO_REALM, Object* weapon=0, int saveBonus=0, short offguard=OFFGUARD_REMOVE, bool computingBonus=false);
	bool checkResistPet(Creature *pet, bool& resistPet, bool& immunePet, bool& vulnPet);

	void doHaggling(Creature *vendor, Object* object, int trans);

	BaseRoom* recallWhere();
	BaseRoom* teleportWhere();
	Location getLimboRoom() const;
	Location getRecallRoom() const;
	int deleteFromRoom(bool delPortal=true);
protected:
	virtual int doDeleteFromRoom(BaseRoom* room, bool delPortal) = 0;
public:

	int doResistMagic(int dmg, Creature* enemy=0);
	virtual void pulseTick(long t) = 0;

	MudObject* findTarget(int findWhere, int findFlags, bstring str, int val);
	MudObject* findObjTarget(ObjectSet &set, int findFlags, bstring str, int val, int* match);
	//MudObject* findTarget(cmd* cmnd, TargetType targetType, bool offensive);

	// New songs
	bool isPlaying();
	Song* getPlaying();
	bool setPlaying(Song* newSong, bool echo = true);
	bool stopPlaying(bool echo = true);
	bool pulseSong(long t);
	Song* playing;

};

//*********************************************************************
//						Monster
//*********************************************************************

class Monster : public Creature {
protected:
	void doCopy(const Monster& cr);
	void reset();
	int doDeleteFromRoom(BaseRoom* room, bool delPortal);

public:
// Constructors, Deconstructors, etc
	Monster();
	Monster(Monster& cr);
	Monster(const Monster& cr);
	Monster& operator=(const Monster& cr);
	bool operator< (const Monster& t) const;
	~Monster();
	void readXml(xmlNodePtr curNode);
	void saveXml(xmlNodePtr curNode) const;
	int saveToFile();
	void validateId();
	void upgradeStats();

protected:
// Data
	unsigned short updateAggro;
	unsigned short loadAggro;
	unsigned short numwander;
	unsigned short magicResistance;
	unsigned short mobTrade;
	int skillLevel;
	unsigned short maxLevel;
	unsigned short cast;
	Realm baseRealm; // For pets/elementals -> What realm they are
	bstring primeFaction;
	bstring talk;
	// Not giving monsters skills right now, so store it on their character
	int weaponSkill;
	int defenseSkill;

	Creature* myMaster;

public:
// Data
	char last_mod[25]; // last staff member to modify creature.
	char ttalk[72];
	char aggroString[80];
	char attack[3][CRT_ATTACK_LENGTH];
	std::list<TalkResponse*> responses;
	char cClassAggro[4]; // 32 max
	char raceAggro[4]; // 32 max
	char deityAggro[4]; // 32 max
	CatRef info;
	CatRef assist_mob[NUM_ASSIST_MOB];
	CatRef enemy_mob[NUM_ENEMY_MOB];
	CatRef jail;
	CatRef rescue[NUM_RESCUE];
	Carry carry[10]; // Random items monster carries


// Combat & Death
//	int addEnmName(const char* enemy);
//	int addEnmCrt(Creature* target, bool print=false);
//	int delEnmCrt(const char* enemy, const char* owner = 0);
//	void endEnmCrt(const char* enemy);
//	void addEnmDmg(const Creature* enemy, int dmg);
//	bool isEnmCrt(const char* enemy) const;
    bool addEnemy(Creature* target, bool print=false);
    long clearEnemy(Creature* target);

    bool isEnemy(const Creature* target) const;
    bool hasEnemy() const;

    long adjustThreat(Creature* target, long modAmt, double threatFactor = 1.0);
    long adjustContribution(Creature* target, long modAmt);
    void clearEnemyList();
    int checkForYell(Creature* target);

    Creature* getTarget(bool sameRoom=true);
	bool nearEnemy(const Creature* target) const;

	ThreatTable* threatTable;

    void setMaster(Creature* pMaster);
    Creature* getMaster() const;

	Player* whoToAggro() const;
	bool willAggro(const Player *player) const;
	int getAdjustedAlignment() const;
	int toJail(Player* player);
	void dieToPet(Monster *killer, bool &freeTarget);
	void dieToMonster(Monster *killer, bool &freeTarget);
	void dieToPlayer(Player *killer, bool &freeTarget);
	void mobDeath(Creature *killer=0);
	void mobDeath(Creature *killer, bool &freeTarget);
	void finishMobDeath(Creature *killer);
	void logDeath(Creature *killer);
	void dropCorpse(Creature *killer);
	void cleanFollow(Creature *killer);
	void distributeExperience(Creature *killer);
	void monsterCombat(Monster *target);
	bool nearEnemy() const;
	bool nearEnmPly() const;
	bool checkEnemyMobs();
	int updateCombat();
	bool checkAssist();
	bool willAssist(const Monster *victim) const;
	void adjust(int buffswitch);
	bool tryToDisease(Creature* target, SpecialAttack* attack = NULL);
	bool tryToStone(Creature* target, SpecialAttack* attack = NULL);
	bool tryToPoison(Creature* target, SpecialAttack* attack = NULL);
	bool tryToBlind(Creature* target, SpecialAttack* attack = NULL);
	bool tryToConfuse(Creature* target, SpecialAttack* attack = NULL);
	int zapMp(Creature *victim, SpecialAttack* attack = NULL);
	int petrify(Player *victim);
	void regenerate();
	int steal(Player *victim);
	void berserk();
	int summonMobs(Creature *victim);
	int castSpell(Creature *target);
	bool petCaster();
	int mobDeathScream();
	bool possibleEnemy();
	int doHarmfulAuras();
	void validateAc();
	bool isRaceAggro(int x, bool checkInvert) const;
	void setRaceAggro(int x);
	void clearRaceAggro(int x);
	bool isClassAggro(int x, bool checkInvert) const;
	void setClassAggro(int x);
	void clearClassAggro(int x);
	bool isDeityAggro(int x, bool checkInvert) const;
	void setDeityAggro(int x);
	void clearDeityAggro(int x);
	void gainExperience(Monster* victim, Creature* killer, int expAmount,
		bool groupExp = false);
	int powerEnergyDrain(Creature *victim, SpecialAttack* attack = NULL);
	int computeDamage(Creature* victim, Object* weapon, AttackType attackType,
		AttackResult& result, Damage& attackDamage, bool computeBonus,
		int& drain, float multiplier = 1.0);
	int mobWield();
	int checkScrollDrop();
	int grabCoins(Player* player);
	bool isEnemyMob(const Monster* target) const;
	void diePermCrt();

// Get
	unsigned short getMobTrade() const;
	int getSkillLevel() const;
	unsigned int getMaxLevel() const;
	unsigned short getNumWander() const;
	unsigned short getLoadAggro() const;
	unsigned short getUpdateAggro() const;
	unsigned short getCastChance() const;
	unsigned short getMagicResistance() const;
	bstring getPrimeFaction() const;
	bstring getTalk() const;
	int getWeaponSkill(const Object* weapon = NULL) const;
	int getDefenseSkill() const;

// Set
	void setMaxLevel(unsigned short l);
	void setCastChance(unsigned short c);
	void setMagicResistance(unsigned short m);
	void setLoadAggro(unsigned short a);
	void setUpdateAggro(unsigned short a);
	void setNumWander(unsigned short n);
	void setSkillLevel(int l);
	void setMobTrade(unsigned short t);
	void setPrimeFaction(bstring f);
	void setTalk(bstring t);
	void setWeaponSkill(int amt);
	void setDefenseSkill(int amt);


// Miscellaneous
	bool swap(Swap s);
	bool swapIsInteresting(Swap s) const;
	
	void killUniques();
	void escapeText();
	void convertOldTalks();
	void addToRoom(BaseRoom* room, int num=1);

	void checkSpellWearoff();
	void checkScavange(long t);
	int checkWander(long t);
	bool canScavange(Object* object);

	bool doTalkAction(Player* target, bstring action);
	void sayTo(const Player* player, const bstring& message);
	void pulseTick(long t);
	void beneficialCaster();
	int initMonster(bool loadOriginal = false, bool prototype = false);

	int mobileCrt();
	void getMobSave();
	int getNumMobs() const;
	void clearMobInventory();
	int cleanMobForSaving();

	Realm getBaseRealm() const;
	void setBaseRealm(Realm toSet);
	const bstring customColorize(bstring text, bool caret=true) const;
};

//--------------------------------------------------------------------------------
// #Player
//--------------------------------------------------------------------------------

#include "statistics.h"

//*********************************************************************
//						Player
//*********************************************************************

class Player : public Creature {
public:
	static bstring hashPassword(bstring pass);

protected:
	void doCopy(const Player& cr);
	void reset();

	bool inList(const std::list<bstring>* list, bstring name) const;
	bstring showList(const std::list<bstring>* list) const;
	void addList(std::list<bstring>* list, bstring name);
	void delList(std::list<bstring>* list, bstring name);
	int doDeleteFromRoom(BaseRoom* room, bool delPortal);
	void finishAddPlayer(BaseRoom* room);
	long getInterest(long principal, double annualRate, long seconds);

public:
	// Constructors, Deconstructors, etc
	Player();
	Player(Player& cr);
	Player(const Player& cr);
	Player& operator=(const Player& cr);
	bool operator< (const Player& t) const;
	~Player();
	int save(bool updateTime=false, LoadType saveType=LS_NORMAL);
	int saveToFile(LoadType saveType=LS_NORMAL);
	void loadAnchors(xmlNodePtr curNode);
	void readXml(xmlNodePtr curNode);
	void saveXml(xmlNodePtr curNode) const;
	void bug(const char *fmt, ...) const;
	void validateId();
	void upgradeStats();
	void recordLevelInfo();

protected:
// Data

	bstring proxyName;
	bstring proxyId;

	char customColors[CUSTOM_COLOR_SIZE];
	unsigned short warnings;
	unsigned short actual_level;
	unsigned short tickDmg;
	unsigned short negativeLevels;
	unsigned short guild; // Guild this player is in
	unsigned short guildRank; // Rank this player holds in their guild
	unsigned short cClass2;
	unsigned short wimpy;
	short barkskin;
	unsigned short pkin;
	unsigned short pkwon;
	int wrap;
	int luck;
	int ansi;
	unsigned short weaponTrains; // Number of weapons they are able to train in
	long lastLogin;
	long lastInterest;
	unsigned long timeout;
	bstring lastPassword;
	bstring afflictedBy;	// used to determine master with vampirism/lycanthropy
	int tnum[5];
	std::list<bstring> ignoring;
	std::list<bstring> gagging;
	std::list<bstring> refusing;
	std::list<bstring> dueling;
	std::list<bstring> maybeDueling;
	std::list<bstring> watching;
	bstring password;
	bstring title;
	bstring tempTitle;	// this field is purposely not saved
	Socket* mySock;
	bstring surname;
	bstring oldCreated;
	long created;
	bstring lastCommand;
	bstring lastCommunicate;
	bstring forum;		// forum account this character is associated with
	char songs[32];
	struct vstat tstat;
	Anchor *anchor[MAX_DIMEN_ANCHORS];
	cDay *birthday;
	Monster* alias_crt;
	std::list<CatRef> roomExp; // rooms they have gotten exp from
	unsigned short thirst;
	Object* lastPawn;
	int uniqueObjId;
	typedef std::map<bstring, bool> KnownAlchemyEffectsMap;
	KnownAlchemyEffectsMap knownAlchemyEffects;

	bool fleeing = false;

public:
// Data
	std::list<CatRef> storesRefunded;   // Shops the player has refunded an item in
	                                    // (No haggling allowed until a full priced purchase has been made)
	std::list<CatRef> objIncrease; // rooms they have gotten exp from

	// TODO: Rework first_charm and get rid of etag
	etag *first_charm;
	int *scared_of;

	std::list<CatRef> lore;
	std::list<int> recipes;
	std::map<int, QuestCompletion*> questsInProgress;
	std::map<int,int> questsCompleted;	  // List of all quests we've finished and how many times

	Money bank;
	Stat focus; // Battle focus points for fighters
	CustomCrt custom;
	Location bound; // the room the player is bound to
	Statistics statistics;
	Range	bRange[MAX_BUILDER_RANGE];


	bool checkProxyAccess(Player* proxy);

	void setProxy(Player* proxy);
	void setProxy(bstring pProxyName, bstring pProxyId);
	void setProxyName(bstring pProxyName);
	void setProxyId(bstring pProxyId);

	bstring getProxyName() const;
	bstring getProxyId() const;

	// Combat & Death
	int computeAttackPower();
	void dieToPet(Monster *killer);
	void dieToMonster(Monster *killer);
	void dieToPlayer(Player *killer);
	void loseExperience(Monster *killer);
	void dropEquipment(bool dropAll=false, Socket* killSock = NULL);
	void dropBodyPart(Player *killer);
	bool isGuildKill(const Player *killer) const;
	bool isClanKill(const Player *killer) const;
	bool isGodKill(const Player *killer) const;
	int guildKill(Player *killer);
	int godKill(Player *killer);
	int clanKill(Player *killer);
	int checkLevel();
	void updatePkill(Player *killer);
	void logDeath(Creature *killer);
	void resetPlayer(Creature *killer);
	void getPkilled(Player *killer, bool dueling, bool reset=true);
	void die(DeathType dt);
	bool dropWeapons();
	int checkPoison(Creature* target, Object* weapon);
	int attackCreature(Creature *victim, AttackType attackType = ATTACK_NORMAL);
	void adjustAlignment(Monster *victim);
	void checkWeaponSkillGain();
	void loseAcid();
	void dissolveItem(Creature* creature);
	int computeDamage(Creature* victim, Object* weapon, AttackType attackType,
		AttackResult& result, Damage& attackDamage, bool computeBonus,
		int& drain, float multiplier = 1.0);
	int packBonus();
	int getWeaponSkill(const Object* weapon = NULL) const;
	int getDefenseSkill() const;
	void damageArmor(int dmg);
	void checkArmor(int wear);
	void gainExperience(Monster* victim, Creature* killer, int expAmount, bool groupExp = false);
	void disarmSelf();
	int lagProtection();
	void computeAC();
	void alignAdjustAcThaco();
	void checkOutlawAggro();
	bstring getUnarmedWeaponSkill() const;
	double winterProtection() const;
	bool isHardcore() const;
	bool canMistNow() const;
	bool autoAttackEnabled() const;
	bool isFleeing() const;
	void setFleeing(bool pFleeing);

// Lists
	bool isIgnoring(bstring name) const;
	bool isGagging(bstring name) const;
	bool isRefusing(bstring name) const;
	bool isDueling(bstring name) const;
	bool isWatching(bstring name) const;
	void clearIgnoring();
	void clearGagging();
	void clearRefusing();
	void clearDueling();
	void clearMaybeDueling();
	void clearWatching();
	void addIgnoring(bstring name);
	void addGagging(bstring name);
	void addRefusing(bstring name);
	void addDueling(bstring name);
	void addMaybeDueling(bstring name);
	void addWatching(bstring name);
	void delIgnoring(bstring name);
	void delGagging(bstring name);
	void delRefusing(bstring name);
	void delDueling(bstring name);
	void delMaybeDueling(bstring name);
	void delWatching(bstring name);
	bstring showIgnoring() const;
	bstring showGagging() const;
	bstring showRefusing() const;
	bstring showDueling() const;
	bstring showWatching() const;
    void addRefundedInStore(CatRef& store);
    void removeRefundedInStore(CatRef& store);
    bool hasRefundedInStore(CatRef& store);

// Quests
	bool addQuest(QuestInfo* toAdd);
	bool hasQuest(int questId) const;
	bool hasQuest(const QuestInfo *quest) const;
	bool hasDoneQuest(int questId) const;
	void updateMobKills(Monster* monster);
	int countItems(const QuestCatRef& obj);
	void updateItems(Object* object);
	void updateRooms(UniqueRoom* room);
	void saveQuests(xmlNodePtr rootNode) const;
	bool questIsSet(int quest) const;
	void setQuest(int quest);
	void clearQuest(int quest);

// Get
	unsigned short getSecondClass() const;
	unsigned short getGuild() const;
	unsigned short getGuildRank() const;
	unsigned short getActualLevel() const;
	unsigned short getNegativeLevels() const;
	unsigned short getWimpy() const;
	unsigned short getTickDamage() const;
	unsigned short getWarnings() const;
	unsigned short getPkin() const;
	unsigned short getPkwon() const;
	bstring getBankDisplay() const;
	bstring getCoinDisplay() const;
	int getWrap() const;

	short getLuck() const;
	unsigned short getWeaponTrains() const;
	long getLastLogin() const;
	long getLastInterest() const;
	bstring getLastPassword() const;
	bstring getAfflictedBy() const;
	bstring getTitle() const;
	bstring getCustomTitle() const;
	bstring getTempTitle() const;
	bstring getLastCommunicate() const;
	bstring getLastCommand() const;
	bstring getSurname() const;
	bstring getForum() const;
	long getCreated() const;
	bstring getCreatedStr() const;
	Monster* getAlias() const;
	cDay* getBirthday() const;
	bstring getAnchorAlias(int i) const;
	bstring getAnchorRoomName(int i) const;
	const Anchor* getAnchor(int i) const;
	bool hasAnchor(int i) const;
	bool isAnchor(int i, const BaseRoom* room) const;
	unsigned short getThirst() const;
	bstring getCustomColor(CustomColor i, bool caret) const;
	int numDiscoveredRooms() const;
	int getUniqueObjId() const;

// Set
	void setTickDamage(unsigned short t);
	void setWarnings(unsigned short w);
	void addWarnings(unsigned short w);
	void subWarnings(unsigned short w);
	void setWimpy(unsigned short w);
	void setActualLevel(unsigned short l);
	void setSecondClass(unsigned short c);
	void setGuild(unsigned short g);
	void setGuildRank(unsigned short g);
	void setNegativeLevels(unsigned short l);
	void setLuck(int l);
	void setWeaponTrains(unsigned short t);
	void subWeaponTrains(unsigned short t);
	void setLostExperience(unsigned long e);
	void setLastPassword(bstring p);
	void setAfflictedBy(bstring a);
	void setLastLogin(long l);
	void setLastInterest(long l);
	void setTitle(bstring newTitle);
	void setTempTitle(bstring newTitle);
	void setLastCommunicate(bstring c);
	void setLastCommand(bstring c);
	void setCreated();
	void setSurname(bstring s);
	void setForum(bstring f);
	void setAlias(Monster* m);
	void setBirthday();
	void delAnchor(int i);
	void setAnchor(int i, bstring a);
	void setThirst(unsigned short t);
	void setCustomColor(CustomColor i, char c);
	int setWrap(int newWrap);

// Factions
	int getFactionStanding(bstring factionStr) const;
	bstring getFactionMessage(bstring factionStr) const;
	void adjustFactionStanding(const std::map<bstring, long>& factionList);

// Staff
	bool checkRangeRestrict(CatRef cr, bool reading=true) const;
	bool checkBuilder(UniqueRoom* room, bool reading=true) const;
	bool checkBuilder(CatRef cr, bool reading=true) const;
	void listRanges(const Player* viewer) const;
	void initBuilder();
	bool builderCanEditRoom(bstring action);

// Movement
	Location getBound();
	void bind(const StartLoc* location);
	void dmPoof(BaseRoom* room, BaseRoom *newRoom);
	void doFollow(BaseRoom* oldRoom);
	void doPetFollow();
	void doRecall(int roomNum = -1);
	void addToSameRoom(Creature* target);
	void addToRoom(BaseRoom* room);
	void addToRoom(AreaRoom* aUoom);
	void addToRoom(UniqueRoom* uRoom);
	bool showExit(const Exit* exit, int magicShowHidden=0) const;
	int checkTraps(UniqueRoom* room, bool self=true, bool isEnter=true);
	int doCheckTraps(UniqueRoom* room);
	bool checkHeavyRestrict(const bstring& skill) const;

// Recipes
	void unprepareAllObjects() const;
	void removeItems(const std::list<CatRef>* list, int numIngredients);
	void learnRecipe(int id);
	void learnRecipe(Recipe* recipe);
	bool knowsRecipe(int id) const;
	bool knowsRecipe(Recipe* recipe) const;
	Recipe* findRecipe(cmd* cmnd, bstring skill, bool* searchRecipes, Size recipeSize=NO_SIZE, int numIngredients=1) const;

	// Alchemy
	bool alchemyEffectVisible(Object* obj, const bstring effect);
	bool learnAlchemyEffect(Object* obj, const bstring effect);
	int endConsume(Object* object, bool forceDelete=false);
	int consume(Object* object, cmd* cmnd);
	void recallLog(bstring name, bstring cname, bstring room);
	int recallCheckBag(Object *cont, cmd* cmnd, int show, int log);
	int useRecallPotion(int show, int log);


// Stats & Ticking
	long tickInterval(Stat& stat, bool fastTick, bool deathSickness, bool vampAndDay, const bstring& effectName);
	void pulseTick(long t);
	int getHpTickBonus() const;
	int getMpTickBonus() const;
	void calcStats(vstat sendStat, vstat *toStat);
	void changeStats();
	void changingStats(bstring str);

	bool isPureFighter();
	void decreaseFocus();
	void increaseFocus(FocusAction action, int amt = 0, Creature* target = NULL);
	void clearFocus();
	bool doPlayerHarmRooms();
	bool doDoTs();
	void loseRage();
	void losePray();
	void loseFrenzy();
	bool statsAddUp() const;
	bool canDefecate() const;

// Formating
	bstring getWhoString(bool whois=false, bool color=true, bool ignoreIllusion=false) const;
	bstring getTimePlayed() const;
	bstring consider(Creature* creature) const;
	int displayCreature(Creature* target);
	void sendPrompt();
	void defineColors();
	void setSockColors();
	void vprint(const char *fmt, va_list ap) const;
	void escapeText();
	bstring getClassString() const;
	void score(const Player* viewer);
	void information(const Player* viewer=0, bool online=true);
	void showAge(const Player* viewer) const;
	const bstring customColorize(bstring text, bool caret=true) const;
	void resetCustomColors();

// Misellaneous
	bool swap(Swap s);
	bool swapIsInteresting(Swap s) const;
	
	void doRemove(int i);
	int getAge() const;
	unsigned long expToLevel() const;
	bstring expToLevel(bool addX) const;
	bstring expInLevel() const;
	bstring expForLevel() const;
	bstring expNeededDisplay() const;
	int getAdjustedAlignment() const;
	void hasNewMudmail() const;
	bool checkConfusion();
	int autosplit(long amt);

	void courageous();
	void init();
	void uninit();
	void checkEffectsWearingOff();
	void update();
	void upLevel();
	void downLevel();
	void initLanguages();
	void setMonkDice();

	bool checkForSpam();
	void silenceSpammer();
	int getDeityClan() const;
	int chooseItem();
	//	int countResistSpells();
	void checkNumResistSpells();
	bool checkOppositeResistSpell(bstring effect);

	int computeLuck();
	int getArmorWeight() const;
	int getFallBonus();
	int getSneakChance();
	int getLight() const;
	int getVision() const;

	bool halftolevel() const;
	bool canWear(const Object* object, bool all=false) const;
	bool canUse(Object* object, bool all=false);
	void checkInventory();
	void checkTempEnchant(Object* object);
	void checkEnvenom(Object* object);
	bool breakObject(Object* object, int loc);
	void wearCursed();
	bool canChooseCustomTitle() const;
	bool alignInOrder() const;

	Socket* getSock() const;
	bool isConnected() const;
	void setSock(Socket* pSock);

	bool songIsKnown(int song) const;
	void learnSong(int song);
	void forgetSong(int song);

	bstring getPassword() const;
	bool isPassword(bstring pass) const;
	void setPassword(bstring pass);

	static bool exists(bstring name);
	time_t getIdle();
	int delCharm(Creature* creature);
	int addCharm(Creature* creature);

	void setLastPawn(Object* object);
	bool restoreLastPawn();
	void checkFreeSkills(bstring skill);
	void computeInterest(long t, bool online);
};


#endif /*CREATURES_H_*/