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/
/*
 * enchantment.cpp
 *	 Enchantment spells
 *   ____            _
 *  |  _ \ ___  __ _| |_ __ ___  ___
 *  | |_) / _ \/ _` | | '_ ` _ \/ __|
 *  |  _ <  __/ (_| | | | | | | \__ \
 *  |_| \_\___|\__,_|_|_| |_| |_|___/
 *
 * 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
 *
 */
#include "mud.h"


//*********************************************************************
//						splHoldPerson
//*********************************************************************

int splHoldPerson(Creature* player, cmd* cmnd, SpellData* spellData) {
	int		bns=0, nohold=0, dur=0;
	Creature* target=0;


	if(	player->getClass() != CLERIC &&
		player->getClass() != MAGE &&
		player->getClass() != LICH &&
		player->getClass() != PALADIN &&
	    !player->isCt() &&
	    spellData->how == CAST
	) {
		player->print("You are unable to cast that spell.\n");
		return(0);
	}


	if(cmnd->num == 2) {
		if(spellData->how != POTION) {
			player->print("Hold whom?\n");
			return(0);
		} else if(player->getClass() == LICH) {
			player->print("Nothing happens.\n");
			return(0);
		} else if(player->isEffected("vampirism") && !isDay()) {
			player->print("Nothing happens.\n");
			return(0);
		} else if(player->isEffected("mist")) {
			player->print("Nothing happens.\n");
			return(0);
		} else {

			player->print("You are suddenly unable to move!\n");
			broadcast(player->getSock(), player->getParent(), "%M becomes unable to move!", player);

			player->unhide();
			player->addEffect("hold-person", 0, 0, player, true, player);

		}

	} else {
		if(player->noPotion( spellData))
			return(0);

		cmnd->str[2][0] = up(cmnd->str[2][0]);

		target = player->getParent()->findCreature(player, cmnd->str[2], cmnd->val[2], true, true);
		if(!target) {
			player->print("Cast on whom?\n");
			return(0);
		}


		if(player->isPlayer() && target->isPlayer() && target->inCombat(false) && !player->flagIsSet(P_OUTLAW)) {
			player->print("Not in the middle of combat.\n");
			return(0);
		}

		if(player->isPlayer() && target->isPlayer() && !player->isCt() && target->isCt()) {
			player->printColor("^yYour spell failed.\n");
			return(0);
		}

		if(player->isPlayer() && target->isPlayer() && !player->isDm() && target->isDm()) {
			player->printColor("^yYour spell failed.\n");
			return(0);
		}

		player->print("You cast a hold-person spell on %N.\n", target);
		target->print("%M casts a hold-person spell on you.\n", player);
		broadcast(player->getSock(), target->getSock(), player->getParent(), "%M casts a hold-person spell on %N.", player, target);


		if(target->getClass() == LICH) {
			player->printColor("Liches cannot be held.\n^yYour spell failed.\n");
			return(0);
		}

		if(target->isEffected("vampirism") && !isDay()) {
			player->printColor("Vampires cannot be held at night.\n^yYour spell failed.\n");
			return(0);
		}

		if(target->isEffected("berserk")) {
			player->print("No one berserk can be held.\nYour spell failed.\n");
			return(0);
		}

		if(	target->isPlayer() &&
			(target->flagIsSet(P_UNCONSCIOUS) || target->isEffected("petrification") || target->isEffected("mist"))
		) {
			player->printColor("^yYour spell failed.\n");
			return(0);
		}

		if(target->isPlayer() && target->isEffected("hold-person")) {
			player->printColor("%M is already held fast.\n^yYour spell fails^x.\n", target);
			return(0);
		}

		if(target->isPlayer() && mrand(1,100) <= 50 && target->isEffected("resist-magic")) {
			player->printColor("^yYour spell failed.\n");
			return(0);
		}

		if(spellData->how == CAST)
			bns = 5*(spellData->level - target->getLevel()) + 2*crtWisdom(target) - 2*bonus((int)player->intelligence.getCur());

		if(target->isPlayer() && target->getClass() == CLERIC && target->getDeity() == ARES)
			bns += 25;

		if(target->isMonster()) {
			if(	target->flagIsSet(M_DM_FOLLOW) ||
				target->flagIsSet(M_PERMENANT_MONSTER) ||
				!target->getRace() ||
				target->isEffected("resist-magic") ||
				target->flagIsSet(M_RESIST_STUN_SPELL) ||
				target->isEffected("reflect-magic")
			)
				nohold = 1;

			if(	target->flagIsSet(M_LEVEL_BASED_STUN) &&
				(((int)target->getLevel() - (int)spellData->level) > ((player->getClass() == LICH || player->getClass() == MAGE) ? 6:4))
			)
				nohold = 1;
		}

		if(target->isMonster()) {
			player->smashInvis();
			if((!target->chkSave(SPL, player, bns) && !nohold) || player->isCt()) {

				if(spellData->how == CAST)
					dur = mrand(9,18) + 2*bonus((int)player->intelligence.getCur()) - crtWisdom(target);
				else
					dur = mrand(9,12);

				target->stun(dur);


				player->print("%M is held in place!\n", target);
				broadcast(player->getSock(), player->getParent(), "%M's spell holds %N in place!", player, target);

				if(player->isCt())
					player->print("*DM* %d seconds.\n", dur);

				if(target->isMonster())
					target->getAsMonster()->addEnemy(player);

			} else {
				player->print("%M resisted your spell.\n", target);
				broadcast(player->getSock(), target->getRoomParent(), "%M resisted %N's hold-person spell.",target, player);
				if(target->isMonster())
					target->getAsMonster()->addEnemy(player);
			}

		} else {
			player->smashInvis();
			if(!target->chkSave(SPL, player, bns) || player->isCt()) {

				if(spellData->how == CAST)
					dur = mrand(12,18) + 2*bonus((int)player->intelligence.getCur()) - crtWisdom(target);
				else
					dur = mrand(9,12);

				if(player->isCt())
					player->print("*DM* %d seconds.\n", dur);

				target->addEffect("hold-person", 0, 0, player, true, player);

			} else {
				player->print("%M resisted your spell.\n", target);
				broadcast(player->getSock(), target->getSock(), target->getRoomParent(), "%M resisted %N's hold-person spell.",target, player);
				target->print("%M tried to cast a hold-person spell on you.\n", player);
			}
		}
	}
	return(1);
}

//*********************************************************************
//						splScare
//*********************************************************************

int splScare(Creature* player, cmd* cmnd, SpellData* spellData) {
	Player	*target=0;
	int		bns=0;
	long	t = time(0);
	Object	*weapon=0, *weapon2=0;

	if(spellData->how == POTION &&
		player->getClass() == PALADIN &&
		(player->getDeity() == ENOCH || player->getDeity() == LINOTHAN)
	) {
		player->print("Your deity forbids such dishonorable actions!\n");
		return(0);
	}

	if(player->getClass() != CLERIC && player->getClass() != MAGE &&
		player->getClass() != LICH && player->getClass() != DEATHKNIGHT &&
		player->getClass() != BARD && !player->isEffected("vampirism") &&
		!player->isCt() && spellData->how == CAST
	) {
		player->print("You are unable to cast that spell.\n");
		return(0);
	}

	// Cast scare
	if(cmnd->num == 2) {
		if(spellData->how != POTION) {
			player->print("On whom?\n");
			return(0);
		}

		if(player->isEffected("berserk")) {
			player->print("You are too enraged to drink that right now.\n");
			return(0);
		}
		if(player->isEffected("courage")) {
			player->print("You feel a strange tingle.\n");
			return(0);
		}

		player->print("You are suddenly terrified to the bone!\n");
		broadcast(player->getSock(), player->getParent(), "%M becomes utterly terrified!", player);
		if(player->ready[WIELD-1]) {
			weapon = player->ready[WIELD-1];
			player->ready[WIELD-1] = 0;
		}
		if(player->ready[HELD-1]) {
			weapon2 = player->ready[HELD-1];
			player->ready[HELD-1] = 0;
		}

		target = player->getAsPlayer();

		// killed while fleeing?
		if(target->flee(true) == 2)
			return(1);

		if(weapon)
			player->ready[WIELD-1] = weapon;
		if(weapon2)
			player->ready[HELD-1] = weapon2;


	// Cast scare on another player
	} else {
		if(player->noPotion( spellData))
			return(0);

		cmnd->str[2][0] = up(cmnd->str[2][0]);

		target = player->getParent()->findPlayer(player, cmnd, 2);
		if(!target) {
			player->print("On whom?\n");
			return(0);
		}


		if(target->inCombat(false) && !player->flagIsSet(P_OUTLAW)) {
			player->print("Not in the middle of combat.\n");
			return(0);
		}

		if(!player->isCt() && target->isCt()) {
			player->printColor("^yYour spell failed.\n");
			return(0);
		}

		if(!player->isDm() && target->isDm()) {
			player->printColor("^yYour spell failed.\n");
			return(0);
		}

		if(!player->isCt() && !dec_daily(&player->daily[DL_SCARES])) {
			player->print("You cannot cast that again today.\n");
			return(0);
		}


		player->print("You cast a scare spell on %N.\n", target);
		target->print("%M casts a scare spell on you.\n", player);
		broadcast(player->getSock(), target->getSock(), player->getParent(), "%M casts a scare spell on %N.", player, target);


		if(target->getClass() == PALADIN) {
			player->printColor("Paladins are immune to magical fear.\n^yYour spell failed.\n");
			return(0);
		}

		if(target->isEffected("berserk") || target->isUnconscious() || target->isEffected("petrification")) {
			player->printColor("^yYour spell failed.\n");
			return(0);
		}

		if(target->isEffected("courage")) {
			player->print("Your spell is ineffective against %N right now.\n", target);
			return(0);
		}

		if(mrand(1,100) <= 50 && target->isEffected("resist-magic")) {
			player->printColor("^yYour spell failed.\n");
			return(0);
		}

		target->wake("Terrible nightmares disturb your sleep!");

		// Pets are immune.
		if(target->isPet()) {
			player->print("%M's %s is too loyal to be magically scared.\n", target->getMaster(), target->getCName());
			return(0);
		}

		bns = 5*((int)target->getLevel() - (int)spellData->level) + crtWisdom(target);
		if(!target->chkSave(SPL, player, bns) || player->isCt()) {

			if(spellData->how == CAST && player->isPlayer())
				player->getAsPlayer()->statistics.offensiveCast();

			target->clearFlag(P_SITTING);
			target->print("You are suddenly terrified to the bone!\n");
			broadcast(target->getSock(), player->getRoomParent(), "%M becomes utterly terrified!", target);

			target->updateAttackTimer(true, DEFAULT_WEAPON_DELAY);
		    target->lasttime[LT_SPELL].ltime = t;
		    target->lasttime[LT_SPELL].interval = 3L;


			/* the following code keeps jackasses from abusing re-wield triggers */
			/* to make people drop their weapons. Remove the weapon, store it in */
			/* temp variable...then have player attempt flee, then put weapons back. */
			//*********************************************************************
			if(target->ready[WIELD-1]) {
				weapon = target->ready[WIELD-1];
				target->ready[WIELD-1] = 0;
			}
			if(target->ready[HELD-1]) {
				weapon2 = target->ready[HELD-1];
				target->ready[HELD-1] = 0;
			}

			// killed while fleeing?
			if(target->flee(true) == 2)
				return(1);

			target->stun(mrand(5,8));

			if(weapon)
				target->ready[WIELD-1] = weapon;
			if(weapon2)
				target->ready[HELD-1] = weapon2;

			//*********************************************************************
		} else {
			player->print("%M resisted your spell.\n", target);
			broadcast(player->getSock(), target->getSock(), target->getRoomParent(), "%M resisted %N's scare spell.",target, player);
			target->print("%M tried to cast a scare spell on you.\n", player);
		}
	}
	return(1);
}

//*********************************************************************
//						splCourage
//*********************************************************************

int splCourage(Creature* player, cmd* cmnd, SpellData* spellData) {
	Creature* target=0;
	long	dur=0;
	int		noCast=0;

	if(spellData->how != POTION) {
		if(!player->isCt() && player->getClass() != PALADIN && player->getClass() != CLERIC) {
			player->print("Your class is unable to cast that spell.\n");
			return(0);
		}

		if(player->getClass() == CLERIC) {
			switch(player->getDeity()) {
			case CERIS:
			case ARAMON:
			case GRADIUS:
			case ARACHNUS:
			case JAKAR:
			case MARA:
				noCast=1;
			break;
			}
		}

		if(noCast) {
			player->print("%s does not allow you to cast that spell.\n", gConfig->getDeity(player->getDeity())->getName().c_str());
			return(0);
		}
	}

	if(cmnd->num == 2) {
		target = player;

		if(spellData->how == CAST || spellData->how == SCROLL || spellData->how == WAND) {
			player->print("Courage spell cast.\nYou feel unnaturally brave.\n");
			broadcast(player->getSock(), player->getParent(), "%M casts a courage spell on %sself.", player, player->himHer());
		} else if(spellData->how == POTION)
			player->print("You feel unnaturally brave.\n");

	} else {
		if(player->noPotion( spellData))
			return(0);

		cmnd->str[2][0] = up(cmnd->str[2][0]);

		target = player->getParent()->findCreature(player, cmnd->str[2], cmnd->val[2], false);

		if(!target) {
			player->print("You don't see that person here.\n");
			return(0);
		}

		if(checkRefusingMagic(player, target))
			return(0);

		player->print("Courage cast on %s.\n", target->getCName());
		target->print("%M casts a courage spell on you.\n", player);
		broadcast(player->getSock(), target->getSock(), player->getParent(), "%M casts a courage spell on %N.", player, target);
	}

	target->removeEffect("fear", true, false);

	if(target->isEffected("fear")) {
		player->print("Your spell fails.\n");
		target->print("The spell fails.\n");
		return(0);
	}

	if(spellData->how == CAST) {
		dur = MAX(300, 900 + bonus((int) player->intelligence.getCur()) * 300);

		if(player->getRoomParent()->magicBonus()) {
			player->print("The room's magical properties increase the power of your spell.\n");
			dur += 300L;
		}
	} else
		dur = 600;

	target->addEffect("courage", dur, 1, player, true, player);
	return(1);
}

//*********************************************************************
//						splFear
//*********************************************************************
// The fear spell causes the monster to have a high wimpy / flee
// percentage and a penality of -2 on all attacks

int splFear(Creature* player, cmd* cmnd, SpellData* spellData) {
	Creature* target=0;
	int		dur=0;

	if(spellData->how == CAST) {
		dur = 600 + mrand(1, 30) * 10 + bonus((int) player->intelligence.getCur()) * 150;
	} else if(spellData->how == SCROLL)
		dur = 600 + mrand(1, 15) * 10 + bonus((int) player->intelligence.getCur()) * 50;
	else
		dur = 600 + mrand(1, 30) * 10;

	if(spellData->how == POTION)
		dur = mrand(1,120) + 180L;

	if(player->spellFail( spellData->how))
		return(0);

	// fear on self
	if(cmnd->num == 2) {
		if(player->isEffected("resist-magic"))
			dur /= 2;

		if(spellData->how == CAST || spellData->how == WAND || spellData->how == SCROLL) {
			player->print("You cast a fear spell on yourself.\n");
			player->print("Nothing happens.\n");
			broadcast(player->getSock(), player->getParent(), "%M casts a fear spell on %sself.", player, player->himHer());
			return(0);
		}

		if(spellData->how == POTION && player->getClass() == PALADIN) {
			player->print("You feel a jitter, then shrug it off.\n");
			return(0);
		} else if(spellData->how == POTION)
			player->print("You begin to shake in terror.\n");

	// fear a monster or player
	} else {
		if(player->noPotion( spellData))
			return(0);

		target = player->getParent()->findCreature(player, cmnd->str[2], cmnd->val[2], false);
		if(!target || target == player) {
			player->print("That's not here.\n");
			return(0);
		}

		if(spellData->how == WAND || spellData->how == SCROLL || spellData->how == CAST) {
			if(	player->isPlayer() &&
				target->isPlayer() &&
				player->getRoomParent()->isPkSafe() &&
				!target->flagIsSet(P_OUTLAW)
			) {
				player->print("You cannot cast that spell here.\n");
				return(0);
			}
		}

		if(!player->canAttack(target))
			return(0);


		if(	(target->mFlagIsSet(M_PERMENANT_MONSTER)) ||
			(target->getClass() == PALADIN && target->isMonster())
		) {
			player->print("%M seems unaffected by fear.\n", target);
			broadcast(player->getSock(), target->getSock(), player->getParent(),
				"%M casts a fear spell on %N.\n", player, target);
			broadcast(player->getSock(), target->getSock(), player->getParent(),
				"%M brushes it off and attacks %N.\n", player, target);

			target->getAsMonster()->addEnemy(player, true);
			return(0);
		}



		if(	(target->isPlayer() && target->isEffected("resist-magic")) ||
			(target->isMonster() && target->isEffected("resist-magic"))
		)
			dur /= 2;

		player->smashInvis();
		target->wake("Terrible nightmares disturb your sleep!");

		if(target->isPlayer() && target->getClass() == PALADIN) {
			player->print("Fear spell cast on %s.\n", target->getCName());
			player->print("It doesn't do anything noticeable.\n");
			broadcast(player->getSock(), target->getSock(), player->getParent(), "%M casts fear on %N.",
				player, target);
			target->print("%M casts a fear spell on you.\n", player);
			target->print("It has no apparent effect.\n");
			return(0);
		}

		if(target->chkSave(SPL, player, 0) && !player->isCt()) {
			target->print("%M tried to cast a fear spell on you!\n", player);
			broadcast(player->getSock(), target->getSock(), player->getParent(), "%M tried to cast a fear spell on %N!", player, target);
			player->print("Your spell fizzles.\n");
			return(0);
		}

		if(spellData->how == CAST || spellData->how == SCROLL || spellData->how == WAND) {
			player->print("Fear spell cast on %s.\n", target->getCName());
			broadcast(player->getSock(), target->getSock(), player->getParent(), "%M casts fear on %N.",
				player, target);
			target->print("%M casts a fear spell on you.\n", player);
		}

		if(target->isMonster())
			target->getAsMonster()->addEnemy(player);
	}

	target->addEffect("fear", dur, 1, player, true, player);

	if(spellData->how == CAST && player->isPlayer())
		player->getAsPlayer()->statistics.offensiveCast();
	return(1);
}


//*********************************************************************
//						splSilence
//*********************************************************************
// Silence causes a player or monster to lose their voice, making them
// unable to casts spells, use scrolls, speak, yell, or broadcast

int splSilence(Creature* player, cmd* cmnd, SpellData* spellData) {
	Creature* target=0;
	int		bns=0, canCast=0, mpCost=0;
	long	dur=0;


	if(player->getClass() == BUILDER) {
		player->print("You cannot cast this spell.\n");
		return(0);
	}

	if(	player->getClass() == LICH ||
		player->getClass() == MAGE ||
		player->getClass() == CLERIC ||
		player->isCt()
	)
		canCast = 1;

	if(!canCast && player->isPlayer() && spellData->how == CAST) {
		player->print("You are unable to cast that spell.\n");
		return(0);
	}

	if(player->getClass() == MAGE || player->getClass() == LICH)
		mpCost = 35;
	else
		mpCost = 20;

	if(spellData->how == CAST && !player->checkMp(mpCost))
		return(0);

	player->smashInvis();

	if(spellData->how == CAST) {
		dur = mrand(180,300) + 3*bonus((int) player->intelligence.getCur());
	} else if(spellData->how == SCROLL)
		dur = mrand(30,120) + bonus((int) player->intelligence.getCur());
	else
		dur = mrand(30,60);



	if(player->spellFail( spellData->how))
		return(0);

	// silence on self
	if(cmnd->num == 2) {
		if(spellData->how == CAST)
			player->subMp(mpCost);

		target = player;
		if(player->isEffected("resist-magic"))
			dur /= 2;

		if(spellData->how == CAST || spellData->how == SCROLL || spellData->how == WAND) {
			broadcast(player->getSock(), player->getParent(), "%M casts silence on %sself.", player, player->himHer());
		} else if(spellData->how == POTION)
			player->print("Your throat goes dry and you cannot speak.\n");

	// silence a monster or player
	} else {
		if(player->noPotion( spellData))
			return(0);

		target = player->getParent()->findCreature(player, cmnd->str[2], cmnd->val[2], false);

		if(!target || target == player) {
			player->print("That's not here.\n");
			return(0);
		}

		if(!player->canAttack(target))
			return(0);

		if(player->isPlayer() && target->mFlagIsSet(M_PERMENANT_MONSTER)) {
			if(!dec_daily(&player->daily[DL_SILENCE]) && !player->isCt()) {
				player->print("You have done that enough times for today.\n");
				return(0);
			}
		}

		bns = ((int)target->getLevel() - (int)spellData->level)*10;

		if(	(target->isPlayer() && target->isEffected("resist-magic")) ||
			(target->isMonster() && target->isEffected("resist-magic"))
		) {
			bns += 50;
			dur /= 2;
		}

		if(target->isPlayer() && player->isCt())
			dur = 600L;

		if(target->mFlagIsSet(M_PERMENANT_MONSTER))
			bns = (target->saves[SPL].chance)/3;

		if(spellData->how == CAST)
			player->subMp(mpCost);

		target->wake("Terrible nightmares disturb your sleep!");

		if(target->chkSave(SPL, player, bns) && !player->isCt()) {
			target->print("%M tried to cast a silence spell on you!\n", player);
			broadcast(player->getSock(), target->getSock(), player->getParent(), "%M tried to cast a silence spell on %N!", player, target);
			player->print("Your spell fizzles.\n");
			return(0);
		}


		if(player->isPlayer() && target->isPlayer()) {
			if(!dec_daily(&player->daily[DL_SILENCE]) && !player->isCt()) {
				player->print("You have done that enough times for today.\n");
				return(0);
			}
		}


		if(spellData->how == CAST || spellData->how == SCROLL || spellData->how == WAND) {
			player->print("Silence casted on %s.\n", target->getCName());
			broadcast(player->getSock(), target->getSock(), player->getParent(), "%M casts a silence spell on %N.", player, target);

			logCast(player, target, "silence");

			target->print("%M casts a silence spell on you.\n", player);
		}

		if(target->isMonster())
			target->getAsMonster()->addEnemy(player);
	}

	target->addEffect("silence", dur, 1, player, true, player);

	if(spellData->how == CAST && player->isPlayer())
		player->getAsPlayer()->statistics.offensiveCast();
	if(player->isCt() && target->isPlayer())
		target->setFlag(P_DM_SILENCED);

	return(1);
}

//*********************************************************************
//						canEnchant
//*********************************************************************

bool canEnchant(Player* player, SpellData* spellData) {
	if(!player->isStaff()) {
		if(spellData->how == CAST && player->getClass() != MAGE && player->getClass() != LICH) {
			player->print("Only mages may enchant objects.\n");
			return(false);
		}
		if(spellData->how == CAST && player->getClass() == MAGE && player->getSecondClass()) {
			player->print("Only pure mages may enchant objects.\n");
			return(false);
		}
		
		if(spellData->level < 16 && !player->isCt()) {
			player->print("You are not experienced enough to cast that spell yet.\n");
			return(false);
		}
	}
	return(true);
}

bool canEnchant(Creature* player, Object* object) {
	if(player->isStaff())
		return(true);
	if(	object->flagIsSet(O_CUSTOM_OBJ) ||
		(object->getType() > ARMOR && object->getType() != MISC) ||
		object->flagIsSet(O_NULL_MAGIC) ||
		object->flagIsSet(O_NO_ENCHANT)
	) {
		player->print("That cannot be enchanted.\n");
		return(false);
	}
	if(object->getAdjustment()) {
		player->printColor("%O is already enchanted.\n", object);
		return(false);
	}
	return(true);
}

//*********************************************************************
//						decEnchant
//*********************************************************************

bool decEnchant(Player* player, int how) {
	if(how == CAST) {
		if(!dec_daily(&player->daily[DL_ENCHA]) && !player->isCt()) {
			player->print("You have enchanted enough today.\n");
			return(false);
		}
	}
	return(true);
}


//*********************************************************************
//						splEnchant
//*********************************************************************
// This function allows mages to enchant items.

int splEnchant(Creature* player, cmd* cmnd, SpellData* spellData) {
	Player* pPlayer = player->getAsPlayer();
	if(!pPlayer)
		return(0);

	Object	*object=0;
	int		adj=1;

	if(!canEnchant(pPlayer, spellData))
		return(0);

	if(cmnd->num < 3) {
		pPlayer->print("Cast the spell on what?\n");
		return(0);
	}

	object = pPlayer->findObject(pPlayer, cmnd, 2);
	if(!object) {
		pPlayer->print("You don't have that in your inventory.\n");
		return(0);
	}

	if(!canEnchant(pPlayer, object))
		return(1);

	if(!decEnchant(pPlayer, spellData->how))
		return(0);

	if((pPlayer->getClass() == MAGE || pPlayer->isStaff()) && spellData->how == CAST)
		adj = MIN(4, (spellData->level / 5));

	object->setAdjustment(MAX(adj, object->getAdjustment()));

	if(object->getType() == WEAPON) {
		object->setShotsMax(object->getShotsMax() + adj * 10);
		object->incShotsCur(adj * 10);
	}
	object->value.set(500 * adj, GOLD);

	pPlayer->printColor("%O begins to glow brightly.\n", object);
	broadcast(pPlayer->getSock(), pPlayer->getRoomParent(), "%M enchants %1P.", pPlayer, object);

	if(!pPlayer->isDm())
		log_immort(true, pPlayer, "%s enchants a %s^g in room %s.\n", pPlayer->getCName(), object->getCName(),
			pPlayer->getRoomParent()->fullName().c_str());

	return(1);
}


//*********************************************************************
//						cmdEnchant
//*********************************************************************
// This function enables mages to randomly enchant an item
// for a short period of time.

int cmdEnchant(Player* player, cmd* cmnd) {
	Object* object=0;
	int		dur;

	if(!player->ableToDoCommand())
		return(0);

	if(!player->knowsSkill("enchant") || player->getSecondClass()) {
		player->print("You lack the training to enchant objects.\n");
		return(0);
	}

	if(player->isBlind()) {
		player->printColor("^CYou can't do that! You're blind!\n");
		return(0);
	}
	if(cmnd->num < 2) {
		player->print("Enchant what?\n");
		return(0);
	}

	object = player->findObject(player, cmnd, 1);
	if(!object) {
		player->print("You don't have that item in your inventory.\n");
		return(0);
	}

	if(!canEnchant(player, object))
		return(0);

// I do suppose temp enchant sucks enough that we can let it go without daily limits -Bane

//	if(!dec_daily(&player->daily[DL_ENCHA]) && !player->isCt()) {
//		player->print("You have enchanted enough today.\n");
//		return(0);
//	}


	dur = MAX(600, MIN(7200, (int)(player->getSkillLevel("enchant")*100) + (int)bonus((int)player->intelligence.getCur())*100));
	object->lasttime[LT_ENCHA].interval = dur;
	object->lasttime[LT_ENCHA].ltime = time(0);

	object->randomEnchant((int)player->getSkillLevel("enchant")/2);

	player->printColor("%O begins to glow brightly.\n", object);
	broadcast(player->getSock(), player->getParent(), "%M enchants %1P.", player, object);
	player->checkImprove("enchant", true);
	if(!player->isDm())
		log_immort(true, player, "%s temp_enchants a %s in room %s.\n", player->getCName(), object->getCName(),
			player->getRoomParent()->fullName().c_str());

	object->setFlag(O_TEMP_ENCHANT);
	return(0);
}

//*********************************************************************
//						splStun
//*********************************************************************

int splStun(Creature* player, cmd* cmnd, SpellData* spellData) {
	Player	*pPlayer = player->getAsPlayer();
	Creature* target=0;
	Monster	*mTarget=0;
	int		dur=0, bns=0, mageStunBns=0;

	if(pPlayer)
		pPlayer->computeLuck();		// luck for stun

	player->smashInvis();

	if(	player->getClass() == LICH ||
		 (pPlayer && pPlayer->getClass() == MAGE && !pPlayer->getSecondClass()) ||
		 player->isCt())
		mageStunBns = mrand(1,5);

	if((target = player->findMagicVictim(cmnd->str[2], cmnd->val[2], spellData, true, false, "Cast on what?\n", "You don't see that here.\n")) == NULL)
		return(0);

	// stun self
	if(target == player) {

		if(spellData->how == CAST) {
			dur = bonus((int) player->intelligence.getCur()) * 2 +
			      (((Player*)player)->getLuck() / 10) + mageStunBns;
		} else
			dur = dice(2, 6, 0);

		dur = MAX(5, dur);
		player->updateAttackTimer(true, dur*10);

		if(spellData->how == CAST || spellData->how == SCROLL || spellData->how == WAND) {
			player->print("You're stunned.\n");
			broadcast(player->getSock(), player->getParent(), "%M casts a stun spell on %sself.",
				player, player->himHer());
		} else if(spellData->how == POTION)
			player->print("You feel dizzy.\n");

	// Stun a monster or player
	} else {
		mTarget = target->getAsMonster();

		if(mTarget) {
			if(player->flagIsSet(P_LAG_PROTECTION_SET))
				player->setFlag(P_LAG_PROTECTION_ACTIVE);
		}

		if(!player->canAttack(target))
			return(0);

		if(mTarget) {
			if(mrand(1,100) < mTarget->getMagicResistance()) {
				player->printColor("^MYour spell has no effect on %N.\n", mTarget);
				if(player->isPlayer())
					broadcast(player->getSock(), player->getParent(), "%M's spell has no effect on %N.", player, mTarget);
				return(0);
			}

		}


		if(mTarget && player->isPlayer()) {
			if(	!mTarget->flagIsSet(M_RESTRICT_EXP_LEVEL) &&
				mTarget->flagIsSet(M_LEVEL_RESTRICTED) &&
				mTarget->getMaxLevel() &&
				!mTarget->flagIsSet(M_AGGRESSIVE) &&
				!mTarget->isEnemy(player)
			) {
				if(	spellData->level > mTarget->getMaxLevel() &&
					!player->checkStaff("You shouldn't be picking on %s.\n", mTarget->himHer())
				)
					return(0);
			}
		}


		if(spellData->how == CAST) {
			dur = bonus((int) player->intelligence.getCur()) * 2 + dice(2, 6, 0) + mageStunBns;
		} else
			dur = dice(2, 5, 0);

		if(player->isPlayer() && !mTarget) {
			dur = ((spellData->level - target->getLevel()) +
					(bonus((int) player->intelligence.getCur()) -
					bonus((int) target->intelligence.getCur())));
			if(dur < 3)
				dur = 3;

			dur += mageStunBns;

			if(target->isEffected("resist-magic") || target->flagIsSet(P_RESIST_STUN))
				dur= 3;

		}

		if(	target->isEffected("resist-magic") ||
			target->flagIsSet(mTarget ? M_RESIST_STUN_SPELL : P_RESIST_STUN))
		{
			if(spellData->how != CAST)
				dur = 0;
			else
				dur = 3;
		} else
			dur = MAX(5, dur);

		if(mTarget) {

			if(mTarget->flagIsSet(M_MAGE_LICH_STUN_ONLY) && player->getClass() != MAGE && player->getClass() != LICH && !player->isStaff()) {
				player->print("Your training in magic is insufficient to properly stun %N!\n", mTarget);
				if(spellData->how != CAST)
				dur = 0;
				else
					dur = 3;
			}

			if(	player->isPlayer() &&
				!mTarget->isEffected("resist-magic") &&
				!mTarget->flagIsSet(M_RESIST_STUN_SPELL) &&
				mTarget->flagIsSet(M_LEVEL_BASED_STUN)
			) {
				if(((int)mTarget->getLevel() - (int)spellData->level) > ((player->getClass() == LICH || player->getClass() == MAGE) ? 6:4))
					dur = MAX(3, bonus((int) player->intelligence.getCur()));
				else
					dur = MAX(5, dur);
			}

			if(player->isEffected("reflect-magic") && mTarget->isEffected("reflect-magic")) {
				player->print("Your stun is cancelled by both your magical-shields!\n");
				mTarget->addEnemy(player);
				return(1);
			}
			if(mTarget->isEffected("reflect-magic")) {
				player->print("Your stun is reflected back at you!\n");
				broadcast(player->getSock(), mTarget->getSock(), player->getRoomParent(), "%M's stun is reflected back at %s!",
					player, player->himHer());
				if(mTarget->isDm() && !player->isDm())
					dur = 0;
				player->stun(dur);
				mTarget->addEnemy(player);
				return(1);
			}

		} else {
			if(player->isEffected("reflect-magic") && target->isEffected("reflect-magic")) {
				player->print("Your stun is cancelled by both your magical-shields!\n");
				target->print("Your magic-shield reflected %N's stun!\n", player);
				return(1);
			}
			if(target->isEffected("reflect-magic")) {
				player->print("Your stun is reflected back at you!\n");
				target->print("%M's stun is reflected back at %s!\n", player, player->himHer());
				if(player->flagIsSet(P_RESIST_STUN) || player->isEffected("resist-magic"))
					dur = 3;
				broadcast(player->getSock(), target->getSock(), player->getParent(), "%M's stun is reflected back at %s!",
					player, player->himHer());
				if(target->isDm() && !player->isDm())
					dur = 0;
				player->stun(dur);
				return(1);
			}
		}

		if(player->isMonster() && !mTarget && target->isEffected("reflect-magic")) {
			if(player->isEffected("reflect-magic")) {
				target->print("Your magic-shield reflects %N's stun!\n", player);
				target->print("%M's magic-shield cancels it!\n", player);
				return(1);
			}
			if(player->flagIsSet(M_RESIST_STUN_SPELL) || player->isEffected("resist-magic"))
				dur = 3;
			target->print("%M's stun is reflected back at %s!\n", player, player->himHer());
			if(target->isDm() && !player->isDm())
				dur = 0;
			player->stun(dur);
			return(1);
		}

		if(!mTarget && player->isEffected("berserk"))
			dur /= 2;

		if(target->isDm() && !player->isDm())
			dur = 0;

		if(spellData->how == CAST || spellData->how == SCROLL || spellData->how == WAND) {
			player->print("Stun cast on %s.\n", target->getCName());
			broadcast(player->getSock(), target->getSock(), player->getParent(),
				"%M casts stun on %N.", player, target);

			logCast(player, target, "stun");

			if(mTarget && player->isPlayer()) {
				if(mTarget->flagIsSet(M_YELLED_FOR_HELP) && (mrand(1,100) <= (MAX(25, mTarget->inUniqueRoom() ? mTarget->getUniqueRoomParent()->wander.getTraffic() : 25)))) {
					mTarget->summonMobs(player);
					mTarget->clearFlag(M_YELLED_FOR_HELP);
					mTarget->setFlag(M_WILL_YELL_FOR_HELP);
				}

				if(mTarget->flagIsSet(M_WILL_YELL_FOR_HELP) && !mTarget->flagIsSet(M_YELLED_FOR_HELP)) {
					mTarget->checkForYell(player);
				}

				if(mTarget->flagIsSet(M_LEVEL_BASED_STUN) && (((int)mTarget->getLevel() - (int)spellData->level) > ((player->getClass() == LICH || player->getClass() == MAGE) ? 6:4))) {
					player->printColor("^yYour magic is currently too weak to fully stun %N!\n", mTarget);

					switch(mrand(1,9)) {
					case 1:
						player->print("%M laughs wickedly at you.\n", target);
						break;
					case 2:
						player->print("%M shrugs off your weak attack.\n", target);
						break;
					case 3:
						player->print("%M glares menacingly at you.\n",target);
						break;
					case 4:
						player->print("%M grins defiantly at your weak stun magic.\n",target);
						break;
					case 5:
						player->print("What were you thinking?\n");
						break;
					case 6:
						player->print("Uh oh...you're in trouble now.\n");
						break;
					case 7:
						player->print("%M says, \"That tickled. Now it's my turn...\"\n",target);
						break;
					case 8:
						player->print("I hope you're prepared to meet your destiny.\n");
						break;
					case 9:
						player->print("Your stun just seemed to bounce off. Strange....\n");
						break;
					default:
						break;
					}
				}
			}

			player->wake("You awaken suddenly!");
			target->print("%M stunned you.\n", player);


			if((!(mTarget && mTarget->flagIsSet(M_RESIST_STUN_SPELL)) && (spellData->level <= target->getLevel())
				&& !target->isCt())
			) {

				if(mTarget && mTarget->flagIsSet(M_PERMENANT_MONSTER))
					bns = 10;

				if(!mTarget && target->getClass() == CLERIC && target->getDeity() == ARES)
					bns += 25;

				if(target->chkSave(SPL, player, bns)) {
					player->printColor("^y%M avoided the full power of your stun!\n", target);
					if(target->isPlayer())
						broadcast(player->getSock(), player->getParent(), "%M avoided a full stun.", target);
					dur /= 2;
					dur = MIN(5,dur);
					target->print("You avoided a full stun.\n");
				}
			}

			target->stun(dur);
		}

		if(mTarget)
			mTarget->addEnemy(player);
	}

	return(1);
}

//*********************************************************************
//						splGlobeOfSilence
//*********************************************************************

int splGlobeOfSilence(Creature* player, cmd* cmnd, SpellData* spellData) {
	int strength = 1;
	long duration = 600;

	if(player->noPotion( spellData))
		return(0);

	if(player->getRoomParent()->isPkSafe() && !player->isCt()) {
		player->print("That spell is not allowed here.\n");
		return(0);
	}

	player->print("You cast a globe of silence spell.\n");
	broadcast(player->getSock(), player->getParent(), "%M casts a globe of silence spell.", player);

	if(player->getRoomParent()->hasPermEffect("globe-of-silence")) {
		player->print("The spell didn't take hold.\n");
		return(0);
	}

	if(spellData->how == CAST) {
		if(player->getRoomParent()->magicBonus())
			player->print("The room's magical properties increase the power of your spell.\n");
	}

	player->getRoomParent()->addEffect("globe-of-silence", duration, strength, player, true, player);
	return(1);
}