roh/conf/area/
roh/game/talk/
roh/help/
roh/monsters/ocean/
roh/objects/ocean/
roh/player/
roh/rooms/area/1/
roh/rooms/misc/
roh/rooms/ocean/
roh/src-2.44b/
/*
 * magic.cpp
 *	 Additional spell-casting routines.
 *   ____            _
 *  |  _ \ ___  __ _| |_ __ ___  ___
 *  | |_) / _ \/ _` | | '_ ` _ \/ __|
 *  |  _ <  __/ (_| | | | | | | \__ \
 *  |_| \_\___|\__,_|_|_| |_| |_|___/
 *
 * 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-2009 Jason Mitchell, Randi Mitchell
 * 	   Contributions by Tim Callahan, Jonathan Hseu
 *  Based on Mordor (C) Brooke Paul, Brett J. Vickers, John P. Freeman
 *
 */
#include "mud.h"
#include "magic.h"

// Spells with -1 mp will not check mp and will leave it up to
// the spell function to do this check.
// The order of this array is important! "splno" must equal the
// spot of the struct in the array. The mud will check this on
// startup and will crash if it's not properly defined
struct {
    const char	*splstr;
    int		splno;
    int		(*splfn)(SpellFn);
    int		mp;
    SchoolOfMagic school;
} spllist[] = {
//	  Name					Spell Num				Spell Function				Mana	School of Magic
	{ "vigor",				S_VIGOR,				splVigor,					2,		HEALING	},
	{ "zephyr",				S_ZEPHYR, 				(int (*)(SpellFn))splOffensive,		-1,		EVOCATION	},
	{ "infravision",		S_INFRAVISION,			splInfravision,				-1,		TRANSMUTATION	},
	{ "slow-poison",		S_SLOW_POISON,			splSlowPoison,				8,		HEALING	},
	{ "bless",				S_BLESS,				splBless,					10,		ABJURATION	},
	{ "protection",			S_PROTECTION,			splProtection,				10,		ABJURATION	},
	{ "fireball",			S_FIREBALL, 			(int (*)(SpellFn))splOffensive,		-1,		EVOCATION	},
	{ "invisibility",		S_INVISIBILITY,			splInvisibility,			15,		ILLUSION	},
	{ "restore",			S_RESTORE,				splRestore,					-1,		HEALING	},
	{ "detect-invisibility",S_DETECT_INVISIBILITY,	splDetectInvisibility,		10,		DIVINATION	},
	{ "detect-magic",		S_DETECT_MAGIC,			splDetectMagic,				10,		DIVINATION	},
	{ "teleport",			S_TELEPORT,				splTeleport,				-1,		TRANSLOCATION	},
	{ "stun",				S_STUN,					splStun,					10,		ENCHANTMENT	},
	{ "cyclone",			S_CYCLONE, 				(int (*)(SpellFn))splOffensive,		-1,		EVOCATION	},
	{ "atrophy",			S_ATROPHY, 				(int (*)(SpellFn))splOffensive,		-1,		EVOCATION	},
	{ "enchant",			S_ENCHANT,				splEnchant,					25,		ENCHANTMENT	},
	{ "word-of-recall",		S_WORD_OF_RECALL,		splWordOfRecall,			25,		TRANSLOCATION	},
	{ "summon",				S_SUMMON,				splSummon,					28,		TRANSLOCATION	},
	{ "mend-wounds",		S_MEND_WOUNDS,			splMendWounds,				4,		HEALING	},
	{ "heal",				S_HEAL,					splHeal,					20,		HEALING	},
	{ "track",				S_TRACK,				splTrack,					13,		TRANSLOCATION	},
	{ "levitate",			S_LEVITATE,				splLevitate,				10,		TRANSMUTATION	},
	{ "heat-protection",	S_HEAT_PROTECTION,		splHeatProtection,			12,		ABJURATION	},
	{ "fly",				S_FLY,					splFly,						15,		TRANSMUTATION	},
	{ "resist-magic",		S_RESIST_MAGIC,			splResistMagic,				25,		ABJURATION	},
	{ "whirlwind",			S_WHIRLWIND, 			(int (*)(SpellFn))splOffensive,		-1,		EVOCATION	},
	{ "rumble",				S_RUMBLE, 				(int (*)(SpellFn))splOffensive,		-1,		EVOCATION	},
	{ "burn",				S_BURN, 				(int (*)(SpellFn))splOffensive,		-1,		EVOCATION	},
	{ "blister",			S_BLISTER, 				(int (*)(SpellFn))splOffensive,		-1,		EVOCATION	},
	{ "dustgust",			S_DUSTGUST, 			(int (*)(SpellFn))splOffensive,		-1,		EVOCATION	},
	{ "waterbolt",			S_WATERBOLT, 			(int (*)(SpellFn))splOffensive,		-1,		EVOCATION	},
	{ "crush",				S_CRUSH, 				(int (*)(SpellFn))splOffensive,		-1,		EVOCATION	},
	{ "shatterstone",		S_ENGULF, 				(int (*)(SpellFn))splOffensive,		-1,		EVOCATION	},
	{ "burstflame",			S_BURSTFLAME, 			(int (*)(SpellFn))splOffensive,		-1,		EVOCATION	},
	{ "steamblast",			S_STEAMBLAST, 			(int (*)(SpellFn))splOffensive,		-1,		EVOCATION	},
	{ "engulf",				S_SHATTERSTONE, 		(int (*)(SpellFn))splOffensive,		-1,		EVOCATION	},
	{ "immolate",			S_IMMOLATE, 			(int (*)(SpellFn))splOffensive,		-1,		EVOCATION	},
	{ "bloodboil",			S_BLOODBOIL, 			(int (*)(SpellFn))splOffensive,		-1,		EVOCATION	},
	{ "tempest",			S_TEMPEST, 				(int (*)(SpellFn))splOffensive,		-1,		EVOCATION	},
	{ "earth-tremor",		S_EARTH_TREMOR, 		(int (*)(SpellFn))splOffensive,		-1,		EVOCATION	},
	{ "flamefill",			S_FLAMEFILL, 			(int (*)(SpellFn))splOffensive,		-1,		EVOCATION	},
	{ "know-aura",			S_KNOW_AURA,			splKnowAura,				6,		DIVINATION	},
	{ "remove-curse",		S_REMOVE_CURSE,			splRemoveCurse,				18,		ABJURATION	},
	{ "resist-cold",		S_RESIST_COLD,			splResistCold,				13,		ABJURATION	},
	{ "breathe-water",		S_BREATHE_WATER,		splBreatheWater,			12,		TRANSMUTATION	},
	{ "earth-shield",		S_STONE_SHIELD,			splEarthShield,				12,		ABJURATION	},
	{ "clairvoyance",		S_CLAIRVOYANCE,			splClairvoyance,			15,		DIVINATION	},
	{ "drain-exp",			S_DRAIN_EXP,			drain_exp,					-1,		NECROMANCY	},
	{ "cure-disease",		S_CURE_DISEASE,			splCureDisease,				12,		HEALING	},
	{ "cure-blindness",		S_CURE_BLINDNESS,		splCureBlindness,			15,		HEALING	},
	{ "fear",				S_FEAR,					splFear,					15,		ENCHANTMENT	},
	{ "room-vigor",			S_ROOM_VIGOR,			splRoomVigor,				8,		HEALING	},
	{ "transport",			S_TRANSPORT,			splTransport,				-1,		TRANSLOCATION	},
	{ "blind",				S_BLINDNESS,			splBlind,					20,		TRANSMUTATION	},
	{ "silence",			S_SILENCE,				splSilence,					-1,		ENCHANTMENT	},
	{ "fortune",			S_FORTUNE,				splFortune,					12,		DIVINATION	},
	{ "curse",				S_CURSE,				splCurse,					25,		ENCHANTMENT	},
	{ "earthquake",			S_EARTHQUAKE, 			(int (*)(SpellFn))splMultiOffensive,-1,		EVOCATION	},
	{ "tsunami",			S_FLOOD, 				(int (*)(SpellFn))splMultiOffensive,-1,		EVOCATION	},
	{ "inferno",			S_FIRESTORM, 			(int (*)(SpellFn))splMultiOffensive,-1,		EVOCATION	},
	{ "hurricane",			S_HURRICANE, 			(int (*)(SpellFn))splMultiOffensive,-1,		EVOCATION	},
	{ "conjure",			S_CONJURE,				conjure,					-1,		CONJURATION	},
	{ "plane-shift",		S_PLANE_SHIFT,			splPlaneShift,				-1,		TRANSLOCATION	},
	{ "judgement",			S_JUDGEMENT,			splJudgement,				-1,		NO_SCHOOL	},
	{ "resist-water",		S_RESIST_WATER,			splResistWater,				13,		ABJURATION	},
	{ "resist-fire",		S_RESIST_FIRE,			splResistFire,				13,		ABJURATION	},
	{ "resist-air",			S_RESIST_AIR,			splResistAir,				13,		ABJURATION	},
	{ "resist-earth",		S_RESIST_EARTH,			splResistEarth,				13,		ABJURATION	},
	{ "reflect-magic",		S_REFLECT_MAGIC,		splReflectMagic,			30,		ABJURATION	},
	{ "animate-dead",		S_ANIMIATE_DEAD,		animate_dead,				-1,		NECROMANCY	},
	{ "annul-magic",		S_ANNUL_MAGIC,			splAnnulMagic,				30,		ABJURATION	},
	{ "true-sight",			S_TRUE_SIGHT,			splTrueSight,				18,		DIVINATION	},
	{ "remove-fear",		S_REMOVE_FEAR,			splRemoveFear,				10,		ABJURATION	},
	{ "remove-silence",		S_REMOVE_SILENCE,		splRemoveSilence,			15,		ABJURATION	},
	{ "camouflage",			S_CAMOUFLAGE,			splCamouflage,				15,		ILLUSION	},
	{ "ethereal-travel",	S_ETHREAL_TRAVEL,		splEtherealTravel,			31,		TRANSLOCATION	},
	{ "drain-shield",		S_DRAIN_SHIELD,			splDrainShield,				15,		ABJURATION	},
	{ "dispel-evil",		S_DISPEL_EVIL,			splDispelEvil,				25,		ABJURATION	},
	{ "dispel-good",		S_DISPEL_GOOD,			splDispelGood,				25,		ABJURATION	},
	{ "undead-ward",		S_UNDEAD_WARD,			splUndeadWard,				25,		ABJURATION	},
	{ "zap",				S_ZAP, 					(int (*)(SpellFn))splOffensive,		-1,		EVOCATION	},
	{ "lightning-bolt",		S_LIGHTNING_BOLT, 		(int (*)(SpellFn))splOffensive,		-1,		EVOCATION	},
	{ "shockbolt",			S_SHOCKBOLT, 			(int (*)(SpellFn))splOffensive,		-1,		EVOCATION	},
	{ "electrocution",		S_ELECTROCUTE, 			(int (*)(SpellFn))splOffensive,		-1,		EVOCATION	},
	{ "thunderbolt",		S_THUNDERBOLT, 			(int (*)(SpellFn))splOffensive,		-1,		EVOCATION	},
	{ "chain-lightning",	S_CHAIN_LIGHTNING, 		(int (*)(SpellFn))splMultiOffensive,-1,		EVOCATION	},
	{ "chill",				S_CHILL, 				(int (*)(SpellFn))splOffensive,		-1,		EVOCATION	},
	{ "frostbite",			S_FROSTBITE, 			(int (*)(SpellFn))splOffensive,		-1,		EVOCATION	},
	{ "sleet",				S_SLEET, 				(int (*)(SpellFn))splOffensive,		-1,		EVOCATION	},
	{ "cold-cone",			S_COLD_CONE, 			(int (*)(SpellFn))splOffensive,		-1,		EVOCATION	},
	{ "iceblade",			S_ICEBLADE, 			(int (*)(SpellFn))splOffensive,		-1,		EVOCATION	},
	{ "blizzard",			S_BLIZZARD, 			(int (*)(SpellFn))splMultiOffensive,-1,		EVOCATION	},
	{ "resist-electric",	S_RESIST_ELEC,			splResistLightning,			13,		ABJURATION	},
	{ "warmth",				S_WARMTH,				splWarmth,					12,		ABJURATION	},
	{ "cure-poison",		S_CURE_POISON,			splCurePoison,				10,		HEALING	},
	{ "haste",				S_HASTE,				splHaste,					30,		TRANSMUTATION	},
	{ "slow",				S_SLOW,					splSlow,					30,		TRANSMUTATION	},
	{ "comprehend-languages",S_COMPREHEND_LANGUAGES,splComprehendLanguages,		20,		DIVINATION	},
	{ "stone-to-flesh",		S_STONE_TO_FLESH,		splStoneToFlesh,			20,		TRANSMUTATION	},
	{ "scare",				S_SCARE,				splScare,					25,		ENCHANTMENT	},
	{ "hold-person",		S_HOLD_PERSON,			splHoldPerson,				20,		ENCHANTMENT	},
	{ "entangle",			S_ENTANGLE,				splEntangle,				20,		TRANSMUTATION	},
	{ "anchor",				S_DIMENSIONAL_ANCHOR,	splDimensionalAnchor,		-1,		TRANSLOCATION	},
	{ "strength",			S_STRENGTH,				splStrength,				30,		TRANSMUTATION	},
	{ "enfeeblement",		S_ENFEEBLEMENT,			splEnfeeblement,			30,		TRANSMUTATION	},
	{ "armor",				S_ARMOR,				splArmor,					-1,		ABJURATION	},
	{ "stoneskin",			S_STONESKIN,			splStoneskin,				-1,		ABJURATION	},
	{ "free-action",		S_FREE_ACTION,			splFreeAction,				15,		ABJURATION	},
	{ "rejuvenate",			S_REJUVENATE,			splRejuvenate,				-1,		HEALING	},
	{ "disintegrate",		S_DISINTEGRATE,			splDisintegrate,			50,		TRANSMUTATION	},
	{ "resurrect",			S_RESURRECT,			splResurrect,				-1,		HEALING	},
	{ "courage",			S_COURAGE,				splCourage,					20,		ENCHANTMENT	},
	{ "bloodfusion",		S_BLOODFUSION,			splBloodfusion,				-1,		HEALING	},
	{ "magic-missile",		S_MAGIC_MISSILE,		splMagicMissile,			-1,		EVOCATION	},
	{ "knock",				S_KNOCK,				splKnock,					-1,		TRANSMUTATION	},
	{ "blink",				S_BLINK,				splBlink,					20,		TRANSLOCATION	},
	{ "harm",				S_HARM,					splHarm,					30,		NECROMANCY	},
	{ "bind",				S_BIND,					splBind,					25,		TRANSLOCATION	},
	{ "darkness",			S_DARKNESS,				splDarkness,				-1,		EVOCATION	},
	{ "tongues",			S_TONGUES,				splTongues,					25,		DIVINATION	},
	{ "enlarge",			S_ENLARGE,				splEnlarge,					15,		TRANSMUTATION	},
	{ "reduce",				S_REDUCE,				splReduce,					15,		TRANSMUTATION	},
	{ "insight",			S_INSIGHT,				splInsight,					30,		TRANSMUTATION	},
	{ "feeblemind",			S_FEEBLEMIND,			splFeeblemind,				30,		TRANSMUTATION	},
	{ "prayer",				S_PRAYER,				splPrayer,					30,		TRANSMUTATION	},
	{ "damnation",			S_DAMNATION,			splDamnation,				30,		TRANSMUTATION	},
	{ "fortitude",			S_FORTITUDE,			splFortitude,				30,		TRANSMUTATION	},
	{ "weakness",			S_WEAKNESS,				splWeakness,				30,		TRANSMUTATION	},
	{ "pass-without-trace",	S_PASS_WITHOUT_TRACE,	splPassWithoutTrace,		8,		TRANSMUTATION	},
	{ "farsight",			S_FARSIGHT,				splFarsight,				10,		DIVINATION	},
	{ "wind-protection",	S_WIND_PROTECTION,		splWindProtection,			12,		ABJURATION	},
	{ "static-field",		S_STATIC_FIELD,			splStaticField,				12,		ABJURATION	},
	{ "portal",				S_PORTAL,				splPortal,					75,		TRANSLOCATION	},
	// anything after this line has been coded for the new magic system and needs player-testing
	{ "detect-hidden",		S_DETECT_HIDDEN,		splDetectHidden,			5,		DIVINATION	},
	{ "illusion",			S_ILLUSION,				splIllusion,				25,		ILLUSION	},
	{ "deafness",			S_DEAFNESS,				splDeafness,				30,		TRANSMUTATION	},
	{ "radiation",			S_RADIATION,			splRadiation,				6,		ABJURATION	},
	{ "fiery-retribution",	S_FIERY_RETRIBUTION,	splFieryRetribution,		12,		ABJURATION	},
	{ "aura-of-flame",		S_AURA_OF_FLAME,		splAuraOfFlame,				18,		ABJURATION	},
	{ "barrier-of-combustion",S_BARRIER_OF_COMBUSTION,splBarrierOfCombustion,	24,		ABJURATION	},
 	{ "bounce-magic",		S_BOUNCE_MAGIC,			splBounceMagic,				10,		ABJURATION	},
 	{ "rebound-magic",		S_REBOUND_MAGIC,		splReboundMagic,			20,		ABJURATION	},
 	{ "dense-fog",			S_DENSE_FOG,			splDenseFog,				10,		CONJURATION	},
 	{ "wall-of-fire",		S_WALL_OF_FIRE,			splWallOfFire,				30,		CONJURATION	},
 	{ "wall-of-force",		S_WALL_OF_FORCE,		splWallOfForce,				50,		CONJURATION	},
 	{ "wall-of-thorns",		S_WALL_OF_THORNS,		splWallOfThorns,			30,		CONJURATION	},
	{ "greater-invisibility",S_GREATER_INVIS,		splGreaterInvisibility,		30,		ILLUSION	},
	{ "hallow",				S_HALLOW,				splHallow,					20,		NO_SCHOOL	},
	{ "unhallow",			S_UNHALLOW,				splUnhallow,				20,		NO_SCHOOL	},
	{ "toxic-cloud",		S_TOXIC_CLOUD,			splToxicCloud,				20,		CONJURATION	},
	{ "blur",				S_BLUR,					splBlur,					10,		ILLUSION	},
	{ "illusory-wall",		S_ILLUSORY_WALL,		splIllusoryWall,			24,		ILLUSION	},
	{ "globe-of-silence",	S_GLOBE_OF_SILENCE,		splGlobeOfSilence,			45,		ENCHANTMENT	},
	{ "cancel-magic",		S_CANCEL_MAGIC,			splCancelMagic,				15,		ABJURATION	},
	{ "dispel-magic",		S_DISPEL_MAGIC,			splDispelMagic,				20,		ABJURATION	},
	{ "sap-life",			S_SAP_LIFE,				splNecroDrain,				-1,		NECROMANCY	},
	{ "lifetap",			S_LIFETAP,				splNecroDrain,				-1,		NECROMANCY	},
	{ "lifedraw",			S_LIFEDRAW,				splNecroDrain,				-1,		NECROMANCY	},
	{ "draw-spirit",		S_DRAW_SPIRIT,			splNecroDrain,				-1,		NECROMANCY	},
	{ "siphon-life",		S_SIPHON_LIFE,			splNecroDrain,				-1,		NECROMANCY	},
	{ "spirit-strike",		S_SPIRIT_STRIKE,		splNecroDrain,				-1,		NECROMANCY	},
	{ "soulsteal",			S_SOULSTEAL,			splNecroDrain,				-1,		NECROMANCY	},
	{ "touch-of-kesh",		S_TOUCH_OF_KESH,		splNecroDrain,				-1,		NECROMANCY	},
	{ "@",					-1,						0,							0,		NO_SCHOOL	}
};
int spllist_size = sizeof(spllist)/sizeof(*spllist);


//**********************************************************************
//						saveSpells
//**********************************************************************
// this creates spells.xml, which the Web Editor requests when it wants
// to know what spells it can use

bool Config::saveSpells() const {
	xmlDocPtr	xmlDoc;
	xmlNodePtr	rootNode, curNode;
	char		filename[80];

	xmlDoc = xmlNewDoc(BAD_CAST "1.0");
	rootNode = xmlNewDocNode(xmlDoc, NULL, BAD_CAST "Spells", NULL);
	xmlDocSetRootElement(xmlDoc, rootNode);

	for(int i=0 ; i < spllist_size-1; i++) {
		curNode = xml::newStringChild(rootNode, "Spell", spllist[i].splstr);
		xml::newNumProp(curNode, "Id", i+1);
	}

	sprintf(filename, "%s/spells.xml", CONFPATH);
	xml::saveFile(filename, xmlDoc);
	xmlFreeDoc(xmlDoc);
	return(true);
}


//**********************************************************************
//						initSpellList
//**********************************************************************
// Make sure someone hasn't messed up the spell table :)

void initSpellList() {
	for(int i=0 ; i<spllist_size; i++) {
		if(spllist[i].splno != i) {
			if(spllist[i].splno != -1) {
				printf("Error: Spell list mismatch: %d != %d\n", i, spllist[i].splno);
				abort();
			}
		}
	}
}

//*********************************************************************
//						get_spell_name
//*********************************************************************

const char *get_spell_name(int nIndex) {
    // do bounds checking
    ASSERTLOG(nIndex >= 0);
    ASSERTLOG(nIndex < spllist_size);

    nIndex = MAX(0, MIN(nIndex, spllist_size));
    return( spllist[nIndex].splstr );
}


//*********************************************************************
//						get_spell_num()
//*********************************************************************

int get_spell_num(int nIndex) {
    // do bounds checking
    ASSERTLOG(nIndex >= 0);
    ASSERTLOG(nIndex < spllist_size);

    nIndex = MAX(0, MIN(nIndex, spllist_size));
    return(spllist[nIndex].splno);
}

//*********************************************************************
//						get_spell_lvl
//*********************************************************************
// this also serves as a list of offensive spells to cast during combat
// (for pets - see Monster::castSpell)

int get_spell_lvl(int sflag) {
    int		slvl=0;

    ASSERTLOG(sflag >= 0 );
    ASSERTLOG(sflag < spllist_size );

    switch(sflag) {
    case S_RUMBLE:
    case S_ZEPHYR:
    case S_BURN:
    case S_BLISTER:
    case S_ZAP:
    case S_CHILL:
    case S_SAP_LIFE:
    case S_LIFETAP:
        slvl = 1;
        break;
    case S_CRUSH:
    case S_DUSTGUST:
    case S_FIREBALL:
    case S_WATERBOLT:
    case S_LIGHTNING_BOLT:
    case S_FROSTBITE:
    case S_LIFEDRAW:
        slvl = 2;
        break;
    case S_ENGULF:
    case S_WHIRLWIND:
    case S_BURSTFLAME:
    case S_STEAMBLAST:
    case S_SHOCKBOLT:
    case S_SLEET:
    case S_DRAW_SPIRIT:
        slvl = 3;
        break;
    case S_SHATTERSTONE:
    case S_CYCLONE:
    case S_IMMOLATE:
    case S_BLOODBOIL:
    case S_ELECTROCUTE:
    case S_COLD_CONE:
    case S_SIPHON_LIFE:
        slvl = 4;
        break;
    case S_EARTH_TREMOR:
    case S_TEMPEST:
    case S_FLAMEFILL:
    case S_ATROPHY:
    case S_THUNDERBOLT:
    case S_ICEBLADE:
    case S_SPIRIT_STRIKE:
        slvl = 5;
        break;
    case S_EARTHQUAKE:
    case S_HURRICANE:
    case S_FIRESTORM:
    case S_FLOOD:
    case S_CHAIN_LIGHTNING:
    case S_BLIZZARD:
    case S_SOULSTEAL:
    case S_TOUCH_OF_KESH:
        slvl = 6;
        break;
    default:
        slvl = 0;
        break;
    }

    return(slvl);
}

//*********************************************************************
//						get_spell_function
//*********************************************************************

SpellRet get_spell_function(int nIndex) {
    // do bounds checking
    ASSERTLOG(nIndex >= 0);
    ASSERTLOG(nIndex < spllist_size);

    nIndex = MAX(0, MIN(nIndex, spllist_size));

    return( spllist[nIndex].splfn );
}


//*********************************************************************
//						get_spell_school
//*********************************************************************

SchoolOfMagic get_spell_school(int nIndex) {
    // do bounds checking
    ASSERTLOG(nIndex >= 0);
    ASSERTLOG(nIndex < spllist_size);

    nIndex = MAX(0, MIN(nIndex, spllist_size));

    return( spllist[nIndex].school );
}
//*********************************************************************
//						get_spell_list_size
//*********************************************************************

int get_spell_list_size() {
    return(spllist_size);
}

//*********************************************************************
//						getSpellMp
//*********************************************************************
// Parameters:  <splNo>
int getSpellMp(int spellNum) {
    // do bounds checking
    ASSERTLOG(spellNum >= 0);
    ASSERTLOG(spellNum < spllist_size);

	return(spllist[spellNum].mp);
}


//*********************************************************************
//						checkMp
//*********************************************************************
// Parameters:  <target> The player casting
//				<reqMp>  The required amount of mp
// Return value: <true> - Has enough mp
//				 <false> - Doesn't have enough mp

bool Creature::checkMp(int reqMp) {
	if(getClass() != LICH && mp.getCur() < reqMp) {
		if(!isPet())
			print("You need %d magic points to cast that spell.\n", reqMp);
		else
			print("%M needs %d magic points to cast that spell.\n", this, reqMp);
		return(false);
	} else if(getClass() == LICH && hp.getCur() <= reqMp) {
		if(!isPet())
			print("Sure, and kill yourself in the process?\n");
		else
			print("Sure, and have %N kill %sself in the process?\n", this, himHer());
		return(false);
	}
	return(true);
}

//*********************************************************************
//						subMp
//*********************************************************************
// Parameters:  <target> The player casting
//				<reqMp>  The amount of mp to deduct

void Creature::subMp(int reqMp) {
	if(getClass() == LICH) {
		hp.decrease(reqMp);
	} else {
		mp.decrease(reqMp);
	}
}

//*********************************************************************
//						splLevitate
//*********************************************************************

bool checkRefusingMagic(Creature* player, Creature* target, bool healing, bool print) {
	if(player->isStaff() || !target->isPlayer())
		return(false);
	// linkdead players always want healing
	if(!healing && target->flagIsSet(P_LINKDEAD)) {
		if(print)
			player->print("%M doesn't want that cast on them right now.\n", target);
		return(0);
	}
	if(target->getPlayer()->isRefusing(player->name)) {
		if(print)
			player->print("%M is refusing your magical services.\n", target);
		return(true);
	}
	return(false);
}