/*
 * File: x-spell.c
 * Purpose: Spell effect definitions and information about them
 *
 * Copyright (c) 1997 Ben Harrison, James E. Wilson, Robert A. Koeneke
 *
 * This work is free software; you can redistribute it and/or modify it
 * under the terms of either:
 *
 * a) the GNU General Public License as published by the Free Software
 *    Foundation, version 2, or
 *
 * b) the "Angband licence":
 *    This software may be copied and distributed for educational, research,
 *    and not for profit purposes provided that this copyright and statement
 *    are included in all such copies.  Other copyrights may also apply.
 */
#include "angband.h"
#include "effects.h"
#include "object/tvalsval.h"

/* TODO This code needs to be updated */
cptr get_spell_name(int spell)
{
	UNREFERENCED_PARAMETER(spell);
	return "T.B.D."; /* s_info[spell].name; */
}


#if 0
void extra_new_spell_info(char *p, s16b spellno)
{
   s16b plev = p_ptr->lev;

   /* Default */
   strcpy(p, "");

   if ( (cheat_spell_info) || (s_info[spellno].numcast >= (10 * s_info[spellno].level) ) )
   {

      /* Analyze the spell */
      switch (spellno)
      {
         case SV_SPELL_MMAGIC_MISSILE:         sprintf(p, " dam %dd4", 3+((plev-1)/5)); break;
         case SV_SPELL_MPHASE_DOOR:            sprintf(p, " range 10"); break;
         case SV_SPELL_MTREASURE_DETECTION:    sprintf(p, " range %dd2+%d", (plev / 2), (plev / 10) + 1); break;
         case SV_SPELL_MCURE_LIGHT_WOUNDS:     sprintf(p, " heal 2d8"); break;
         case SV_SPELL_MSTINKING_CLOUD:        sprintf(p, " dam %d rad 2", 10+(plev / 2)); break;
         case SV_SPELL_MLIGHTNING_BOLT:        sprintf(p, " dam %dd3+8", 3+(plev-5)/4); break;
         case SV_SPELL_MTELEPORT_SELF:         sprintf(p, " range %d", plev * 5); break;
         case SV_SPELL_MFROST_BOLT:            sprintf(p, " dam %dd8", 5+(plev-5)/4); break;
         case SV_SPELL_MFIRE_BOLT:             sprintf(p, " dam %dd8", 8+(plev-5)/5); break;
         case SV_SPELL_MFROST_BALL:            sprintf(p, " dam %d rad 2", 30+plev); break;
         case SV_SPELL_MFIRE_BALL:             sprintf(p, " dam %d rad 2", 55+plev); break;
         case SV_SPELL_MWORD_OF_DESTRUCTION:   sprintf(p, " rad 15"); break;
         case SV_SPELL_MEARTHQUAKE:            sprintf(p, " rad 10"); break;
         case SV_SPELL_MACID_BOLT:             sprintf(p, " dam %dd8", 6+(plev-5)/4); break;
         case SV_SPELL_MCLOUDKILL:             sprintf(p, " dam %d rad 3", 20+plev/2); break;
         case SV_SPELL_MACID_BALL:             sprintf(p, " dam %d rad 2", 40+plev); break;
         case SV_SPELL_MICE_STORM:             sprintf(p, " dam %d rad 3", 70+plev); break;
         case SV_SPELL_MMETEOR_SWARM:          sprintf(p, " dam %d rad 3", 65+plev); break;
         case SV_SPELL_MHELLFIRE:              sprintf(p, " dam %d rad 3", 300+plev*2); break;

         case SV_SPELL_PCURE_LIGHT_WOUNDS:     sprintf(p, " 2d10"); break;
         case SV_SPELL_PCALL_LIGHT:            sprintf(p, " dam 2d%d rad %d",plev/2, plev/10+1); break;
         case SV_SPELL_PPORTAL:                sprintf(p, " range %d", plev*3); break;
         case SV_SPELL_PCURE_MEDIUM_WOUNDS:    sprintf(p, " 4d10"); break;
         case SV_SPELL_PORB_OF_DRAINING:       sprintf(p, " 3d6+%d rad %d",
                                                         plev+(plev/((p_ptr->pclass==2)?2:4)),
                                                         (plev<30)?2:3); break;
         case SV_SPELL_PCURE_SER_WOUNDS:       sprintf(p, " 6d10"); break;
         case SV_SPELL_PEARTHQUAKE:            sprintf(p, " rad 10"); break;
         case SV_SPELL_PCURE_CRIT_WOUNDS:      sprintf(p, " 8d10"); break;
         case SV_SPELL_PHEAL:                  sprintf(p, " 300"); break;
         case SV_SPELL_PHOLY_WORD:             sprintf(p, " 1000"); break;
         case SV_SPELL_PBLINK:                 sprintf(p, " range 10"); break;
         case SV_SPELL_PTELEPORT:              sprintf(p, " range %d", plev*8); break;
         case SV_SPELL_PCURE_SER_WOUNDS_EASY:  sprintf(p, " heal 4d10"); break;
         case SV_SPELL_PCURE_CRIT_WOUNDS_EASY: sprintf(p, " heal 8d10"); break;
         case SV_SPELL_PHEALING:               sprintf(p, " heal 2000"); break;
         case SV_SPELL_PWORD_OF_DESTRUCTION:   sprintf(p, " rad 15"); break;
         case SV_SPELL_PANNIHILATION:          sprintf(p, " dam 200"); break;
      }
   }
}
#endif


void get_spell_info(int spell, char *p, size_t len)
{
	int plev = p_ptr->lev;

	/* Blank 'p' first */
	p[0] = '\0';


	/* Analyze the spell */
	switch (spell)
	{
	case SPELL_MAGIC_MISSILE:
		strnfmt(p, len, " dam %dd4", 3 + ((plev - 1) / 5));
		break;
	case SPELL_PHASE_DOOR:
		strnfmt(p, len, " range 10");
		break;
	case SPELL_LIGHT_AREA:
		strnfmt(p, len, " dam 2d%d", (plev / 2));
		break; 
	case SPELL_CURE_LIGHT_WOUNDS:  /* TODO Check how much healed by CURE_LIGHT_WOUNDS */
		strnfmt(p, len, " heal 2d8");
		break;
	case SPELL_STINKING_CLOUD:
		strnfmt(p, len, " dam %d", 10 + (plev / 2));
		break;
	case SPELL_LIGHTNING_BOLT:
		strnfmt(p, len, " dam %dd6", (3 + ((plev - 5) / 6)));
		break;
	case SPELL_FROST_BOLT:
		strnfmt(p, len, " dam %dd8", (5 + ((plev - 5) / 4)));
		break;
	case SPELL_ACID_BOLT:
		strnfmt(p, len, " dam %dd8", (8 + ((plev - 5) / 4)));
		break;
	case SPELL_FIRE_BOLT:
		strnfmt(p, len, " dam %dd8", (6 + ((plev - 5) / 4)));
		break;
	case SPELL_SPEAR_OF_LIGHT:
		strnfmt(p, len, " dam 6d8");
		break;
	case SPELL_HEROISM:
		strnfmt(p, len, " dur 25+d25");
		break;
	case SPELL_BERSERKER:
		strnfmt(p, len, " dur 25+d25");
		break;
	case SPELL_HASTE_SELF:
		strnfmt(p, len, " dur %d+d20", plev);
		break;
	case SPELL_TELEPORT_SELF: /* TODO Check how far TELEPORT_SELF goes */
		strnfmt(p, len, " range %d", plev * 5);
		break;
#if 0
	case SPELL_SHOCK_WAVE:
		strnfmt(p, len, " dam %d", 10 + plev);
		break; 
	case SPELL_EXPLOSION:
		strnfmt(p, len, " dam %d", 20 + plev * 2);
		break;
#endif
	case SPELL_CLOUD_KILL:
		strnfmt(p, len, " dam %d", 40 + (plev / 2));
		break;
#if 0
	case SPELL_REND_SOUL:
		strnfmt(p, len, " dam 11d%d", plev);
		break;
	case SPELL_CHAOS_STRIKE:
		strnfmt(p, len, " dam 13d%d", plev);
		break;
#endif
	case SPELL_RESIST_COLD:
		strnfmt(p, len, " dur 20+d20");
		break;
	case SPELL_RESIST_FIRE:
		strnfmt(p, len, " dur 20+d20");
		break;
	case SPELL_RESIST_POISON:
		strnfmt(p, len, " dur 20+d20");
		break;
	case SPELL_RESISTANCE:
		strnfmt(p, len, " dur 20+d20");
		break;
	case SPELL_SHIELD:
		strnfmt(p, len, " dur 30+d20");
		break;
	case SPELL_FROST_BALL:
		strnfmt(p, len, " dam %d", 30 + plev);
		break;
	case SPELL_ACID_BALL:
		strnfmt(p, len, " dam %d", 40 + plev);
		break;
	case SPELL_FIRE_BALL:
		strnfmt(p, len, " dam %d", 55 + plev);
		break;
	case SPELL_ICE_STORM:
		strnfmt(p, len, " dam %d", 50 + (plev * 2));
		break;
	case SPELL_METEOR_SWARM:
		strnfmt(p, len, " dam %dx%d", 30 + plev / 2, 2 + plev / 20);
		break;
#if 0
	case SPELL_RIFT:
		strnfmt(p, len, " dam 40+%dd7", plev);
		break;
	case SPELL_MANA_STORM:
		strnfmt(p, len, " dam %d", 300 + plev * 2);
		break;
#endif
	case SPELL_BLESS:
		my_strcpy(p, " dur 12+d12", len);
		break;
	case SPELL_CALL_LIGHT:
		strnfmt(p, len, " dam 2d%d", (plev / 2));
		break; 
	case SPELL_PORTAL:
		strnfmt(p, len, " range %d", 3 * plev);
		break;
	case SPELL_CURE_SERIOUS_WOUNDS:
		my_strcpy(p, " heal 4d10", len);
		break;
	case SPELL_CHANT:
		my_strcpy(p, " dur 24+d24", len);
		break;
#if 0
	case SPELL_RESIST_HEAT_COLD:
		my_strcpy(p, " dur 10+d10", len);
		break;
#endif
	case SPELL_ORB_OF_DRAINING:
		strnfmt(p, len, " %d+3d6", plev +
		        (plev / ((cp_ptr->flags & CF_BLESS_WEAPON) ? 2 : 4)));
		break;
	case SPELL_CURE_CRITICAL_WOUNDS:
		my_strcpy(p, " heal 6d10", len);
		break;
	case SPELL_SENSE_INVISIBLE:
		my_strcpy(p, " dur 24+d24", len);
		break;
	case SPELL_PROTECTION_FROM_EVIL:
		strnfmt(p, len, " dur %d+d25", 3 * plev);
		break;
#if 0
	case SPELL_CURE_MORTAL_WOUNDS:
		my_strcpy(p, " heal 8d10", len);
		break;
	case SPELL_PRAYER:
		my_strcpy(p, " dur 48+d48", len);
		break;
#endif
	case SPELL_DISPEL_UNDEAD:
		strnfmt(p, len, " dam d%d", 3 * plev);
		break;
	case SPELL_HEAL:
		my_strcpy(p, " heal 300", len);
		break;
	case SPELL_DISPEL_EVIL:
		strnfmt(p, len, " dam d%d", 3 * plev);
		break;
	case SPELL_HOLY_WORD:
		my_strcpy(p, " heal 1000", len);
		break;
#if 0
	case SPELL_CURE_SERIOUS_WOUNDS2:
		my_strcpy(p, " heal 4d10", len);
		break;
	case SPELL_CURE_MORTAL_WOUNDS2:
		my_strcpy(p, " heal 8d10", len);
		break;
#endif
	case SPELL_HEALING:
		my_strcpy(p, " heal 2000", len);
		break;
#if 0
	case SPELL_DISPEL_UNDEAD2:
		strnfmt(p, len, " dam d%d", 4 * plev);
		break;
	case SPELL_DISPEL_EVIL2:
		strnfmt(p, len, " dam d%d", 4 * plev);
		break;
#endif
	case SPELL_ANNIHILATION:
		my_strcpy(p, " dam 200", len);
		break;
	case SPELL_BLINK:
		my_strcpy(p, " range 10", len);
		break;
	}

	return;
}


static int beam_chance(void)
{
	int plev = p_ptr->lev;
	return ((cp_ptr->flags & CF_BEAM) ? plev : (plev / 2));
}


static void spell_wonder(int dir)
{
/* This spell should become more useful (more
   controlled) as the player gains experience levels.
   Thus, add 1/5 of the player's level to the die roll.
   This eliminates the worst effects later on, while
   keeping the results quite random.  It also allows
   some potent effects only at high level. */
	effect_wonder(dir, randint1(100) + p_ptr->lev / 5, beam_chance());
}

/*
 * execute a certain spell
 * return TRUE on abortion!
 */
#if 0
bool exec_spell(s16b spellno)
{
	bool beam;
	s16b dir, plev = p_ptr->lev;

	/* Hack -- chance of "beam" instead of "bolt" */
	beam = ((p_ptr->pclass == 1) ? plev : (plev / 2));

	/* Spells.  */
	switch (spellno)
	{
		case SPELL_MAGIC_MISSILE:
			if (!get_aim_dir(&dir)) return (TRUE);
			fire_bolt_or_beam(beam-10, GF_MISSILE, dir,
					damroll(3 + ((plev - 1) / 5), 4));
			break;
		case SPELL_DETECT_MONSTERS:
			(void)detect_monsters();
			break;
		case SPELL_PHASE_DOOR:
			teleport_player(10);
			break;
		case SPELL_LIGHT_AREA:
			(void)lite_area(damroll(2, (plev / 2)), (plev / 10) + 1);
			break;
		case SPELL_TREASURE_DETECTION:
			(void)detect_treasure();
			break;
		case SPELL_CURE_LIGHT_WOUNDS:
			(void)hp_player(damroll(2, 8));
			(void)set_cut(p_ptr->cut - 15);
			break;
		case SPELL_OBJECT_DETECTION:
			(void)detect_object();
			break;
		case SPELL_FIND_TRAPS_DOORS:
			(void)detect_sdoor();
			(void)detect_trap();
			break;
		case SPELL_STINKING_CLOUD:
			if (!get_aim_dir(&dir)) return (TRUE);
			fire_ball(GF_POIS, dir, 10 + (plev / 2), 2);
			break;
		case SPELL_CONFUSION:
			if (!get_aim_dir(&dir)) return (TRUE);
			(void)confuse_monster(dir, plev);
			break;
		case SPELL_LIGHTNING_BOLT:
			if (!get_aim_dir(&dir)) return (TRUE);
			fire_bolt_or_beam(beam-10, GF_ELEC, dir,
					damroll(min(3, 3+(plev-5)/4),8));
			break;
		case SPELL_TRAPDOOR_DESTRUCT:
			 (void)destroy_doors_touch();
			 break;
		case SPELL_SLEEP_I:
			 if (!get_aim_dir(&dir)) return (TRUE);
			 (void)sleep_monster(dir);
			 break;
		case SPELL_CURE_POISON:
			 (void)set_poisoned(0);
			 break;
		case SPELL_TELEPORT_SELF:
			 teleport_player(plev * 5);
			 break;
		case SPELL_SPEAR_OF_LIGHT:
			 if (!get_aim_dir(&dir)) return (TRUE);
			 msg_print("A line of blue shimmering light appears.");
			 lite_line(dir);
			 break;
		case SPELL_FROST_BOLT:
			 if (!get_aim_dir(&dir)) return (TRUE);
			 fire_bolt_or_beam(beam-10, GF_COLD, dir,
									 damroll(min(5, 5+(plev-5)/4),8));
			 break;
		case SPELL_TURN_STONE_TO_MUD:
			 if (!get_aim_dir(&dir)) return (TRUE);
			 (void)wall_to_mud(dir);
			 break;
		case SPELL_CREATE_FOOD:
			 (void)set_food(PY_FOOD_MAX - 1);
			 break;
		case SPELL_RECHARGE_ITEM_I:
			 (void)recharge(5);
			 break;
		case SPELL_SLEEP_II:
			 (void)sleep_monsters_touch();
			 break;
		case SPELL_POLYMORPH_OTHER:
			 if (!get_aim_dir(&dir)) return (TRUE);
			 (void)poly_monster(dir);
			 break;
		case SPELL_IDENTIFY:
			 (void)ident_spell();
			 break;
		case SPELL_SLEEP_III:
			 (void)sleep_monsters();
			 break;
		case SPELL_FIRE_BOLT:
			 if (!get_aim_dir(&dir)) return (TRUE);
			 fire_bolt_or_beam(beam, GF_FIRE, dir,
									 damroll(min(8, 8+(plev-5)/4),8));
			 break;
		case SPELL_SLOW_MONSTER:
			 if (!get_aim_dir(&dir)) return (TRUE);
			 (void)slow_monster(dir);
			 break;
		case SPELL_FROST_BALL:
			 if (!get_aim_dir(&dir)) return (TRUE);
			 fire_ball(GF_COLD, dir, 30 + plev, 2);
			 break;
		case SPELL_RECHARGE_ITEM_II:
			 (void)recharge(40);
			 break;
		case SPELL_TELEPORT_OTHER:
			 if (!get_aim_dir(&dir)) return (TRUE);
			 (void)teleport_monster(dir);
			 break;
		case SPELL_HASTE_SELF:
			 if (!p_ptr->fast)
				  (void)set_fast(randint(20) + plev);
			 else
				  (void)set_fast(p_ptr->fast + randint(5));
			 break;
		case SPELL_FIRE_BALL:
			 if (!get_aim_dir(&dir)) return (TRUE);
			 fire_ball(GF_FIRE, dir, 55 + plev, 2);
			 break;
		case SPELL_WORD_OF_DESTRUCTION:
			 destroy_area(px, py, 15, TRUE);
			 break;
		case SPELL_GENOCIDE_HARD:
			 (void)genocide();
			 break;
		case SPELL_RESIST_FIRE:
			 (void)set_oppose_fire(p_ptr->oppose_fire + randint(20) + 20);
			 break;
		case SPELL_RESIST_COLD:
			 (void)set_oppose_cold(p_ptr->oppose_cold + randint(20) + 20);
			 break;
		case SPELL_RESIST_ACID:
			 (void)set_oppose_acid(p_ptr->oppose_acid + randint(20) + 20);
			 break;
		case SPELL_RESIST_POISON:
			 (void)set_oppose_pois(p_ptr->oppose_pois + randint(20) + 20);
			 break;
		case SPELL_RESISTANCE:
			 (void)set_oppose_fire(p_ptr->oppose_fire + randint(20) + 20);
			 (void)set_oppose_cold(p_ptr->oppose_cold + randint(20) + 20);
			 (void)set_oppose_acid(p_ptr->oppose_acid + randint(20) + 20);
			 (void)set_oppose_pois(p_ptr->oppose_pois + randint(20) + 20);
			 break;
		case SPELL_DOOR_CREATION:
			 (void)door_creation();
			 break;
		case SPELL_STAIR_CREATION:
			 (void)stair_creation();
			 break;
		case SPELL_TELEPORT_LEVEL:
			 (void)teleport_player_level();
			 break;
		case SPELL_EARTHQUAKE:
			 earthquake(py, px, 10);
			 break;
		case SPELL_WORD_OF_RECALL:
			 if (!p_ptr->word_recall)
			 {
				  p_ptr->word_recall = rand_int(20) + 15;
				  msg_print("The air about you becomes charged...");
			 }
			 else
			 {
				  p_ptr->word_recall = 0;
				  msg_print("A tension leaves the air around you...");
			 }
			 break;
		case SPELL_DETECT_EVIL:
			 (void)detect_evil();
			 break;
		case SPELL_DETECT_ENCHANTMENT:
			 (void)detect_magic();
			 break;
		case SPELL_RECHARGE_ITEM_III:
			 recharge(100);
			 break;
		case SPELL_MASS_GENOCIDE:
			 (void)mass_genocide();
			 break;
		case SPELL_HEROISM:
			 (void)hp_player(10);
			 (void)set_hero(p_ptr->hero + randint(25) + 25);
			 (void)set_afraid(0);
			 break;
		case SPELL_SHIELD:
			 (void)set_shield(p_ptr->shield + randint(20) + 30);
			 break;
		case SPELL_BERSERKER:
			 (void)hp_player(30);
			 (void)set_shero(p_ptr->shero + randint(25) + 25);
			 (void)set_afraid(0);
			 break;
		case SPELL_ESSENCE_OF_SPEED:
			 if (!p_ptr->fast)
			 {
				  (void)set_fast(randint(30) + 30 + plev);
			 }
			 else
			 {
				  (void)set_fast(p_ptr->fast + randint(10));
			 }
			 break;
		case SPELL_INVULNERABILITY:
			 if (p_ptr->invuln)
			 {
				 msg_print("You feel that you are making a terrible mistake...");
				 (void)set_invuln(0);
			 }
			 else
			 {
				 (void)set_invuln(2000 + randint(p_ptr->lev * 60));
			 }
			 break;
		case SPELL_ACID_BOLT:
			 if (!get_aim_dir(&dir)) return (TRUE);
			 fire_bolt_or_beam(beam, GF_ACID, dir,
									 damroll(min(6, 6+(plev-5)/4), 8));
			 break;
		case SPELL_CLOUDKILL:
			 if (!get_aim_dir(&dir)) return (TRUE);
			 fire_ball(GF_POIS, dir,
						  20 + (plev / 2), min(3, 3 + (plev-10)/10));
			 break;
		case SPELL_ACID_BALL:
			 if (!get_aim_dir(&dir)) return (TRUE);
			 fire_ball(GF_ACID, dir,
						  40 + (plev), min(2, 2 + (plev-10) / 10));
			 break;
		case SPELL_ICE_STORM:
			 if (!get_aim_dir(&dir)) return (TRUE);
			 fire_ball(GF_COLD, dir,
						  70 + (plev), min(3, 3 + (plev-10) / 10));
			 break;
		case SPELL_METEOR_SWARM:
			 if (!get_aim_dir(&dir)) return (TRUE);
			 fire_ball(GF_METEOR, dir,
						  65 + (plev), min(3, 3 + (plev-20) / 10));
			 break;
		case SPELL_HELLFIRE:
			 if (!get_aim_dir(&dir)) return (TRUE);
			 fire_ball(GF_MANA, dir,
						  300 + (plev * 2), 3 + (plev>35)?1:0);
			 break;
		case SPELL_REFLECTION:
			 if (p_ptr->reflecting)
				 (void)set_reflecting(randint(10));
			 else
				 (void)set_reflecting(15+randint(20));
			 break;
		case SPELL_CREATESIMPLETRAP:
			 if (!make_trap_from_spell(0, FALSE)) return (TRUE);
			 break;
		case SPELL_CREATEEFFECTIVETRAP:
			 if (!make_trap_from_spell(1, FALSE)) return (TRUE);
			 break;
		case SPELL_CREATEDANGEROUSTRAP:
			 if (!make_trap_from_spell(2, FALSE)) return (TRUE);
			 break;
		case SPELL_CREATEDEATHTRAP:
			 if (!make_trap_from_spell(3, FALSE)) return (TRUE);
			 break;
		case SPELL_CREATECOMPLEXTRAP:
			 if (!make_trap_from_spell(3, FALSE)) return (TRUE);
			 break;

/* ***************************************************************************** */
/* Spells above here were 'mage' spells. Spells below here were 'priest' spells. */
/* ***************************************************************************** */

		case SPELL_DETECT_EVIL:
			 (void)detect_evil();
			 break;
		case SPELL_CURE_LIGHT_WOUNDS:
			 (void)hp_player(damroll(2, 10));
			 (void)set_cut(p_ptr->cut - 10);
			 break;
		case SPELL_BLESS:
			 (void)set_blessed(p_ptr->blessed + randint(12) + 12);
			 break;
		case SPELL_REMOVE_FEAR:
			 (void)set_afraid(0);
			 break;
		case SPELL_CALL_LIGHT:
			 (void)lite_area(damroll(2, (plev / 2)), (plev / 10) + 1);
			 break;
		case SPELL_FIND_TRAPS:
			 (void)detect_trap();
			 break;
		case SPELL_DET_DOORS_STAIRS:
			 (void)detect_sdoor();
			 break;
		case SPELL_SLOW_POISON:
			 (void)set_poisoned(p_ptr->poisoned / 2);
			 break;
		case SPELL_BLIND_CREATURE:
			 if (!get_aim_dir(&dir)) return (TRUE);
			 (void)fear_monster(dir, plev);
			 break;
		case SPELL_PORTAL:
			 teleport_player(plev * 3);
			 break;
		case SPELL_CURE_MEDIUM_WOUNDS:
			 (void)hp_player(damroll(4, 10));
			 (void)set_cut((p_ptr->cut / 2) - 20);
			 break;
		case SPELL_CHANT:
			 (void)set_blessed(p_ptr->blessed + randint(24) + 24);
			 break;
		case SPELL_SANCTUARY:
			 (void)sleep_monsters_touch();
			 break;
		case SPELL_CREATE_FOOD:
			 (void)set_food(PY_FOOD_MAX - 1);
			 break;
		case SPELL_REMOVE_CURSE:
			 remove_curse();
			 break;
		case SPELL_RESIST_HEAT_COLD:
			 (void)set_oppose_fire(p_ptr->oppose_fire + randint(10) + 10);
			 (void)set_oppose_cold(p_ptr->oppose_cold + randint(10) + 10);
			 break;
		case SPELL_NEUTRALIZE_POISON:
			 (void)set_poisoned(0);
			 break;
		case SPELL_ORB_OF_DRAINING:
			 if (!get_aim_dir(&dir)) return (TRUE);
			 fire_ball(GF_HOLY_ORB, dir,
						  (damroll(3,6) + plev +
							(plev / ((p_ptr->pclass == 2) ? 2 : 4))),
						  ((plev < 30) ? 2 : 3));
			 break;
		case SPELL_CURE_SER_WOUNDS:
			 (void)hp_player(damroll(6, 10));
			 (void)set_cut(0);
			 break;
		case SPELL_SENSE_INVISIBLE:
			 (void)set_tim_invis(p_ptr->tim_invis + randint(24) + 24);
			 break;
		case SPELL_PROT_FROM_EVIL:
			 (void)set_protevil(p_ptr->protevil + randint(25) + 3 * p_ptr->lev);
			 break;
		case SPELL_EARTHQUAKE:
			 earthquake(py, px, 10);
			 break;
		case SPELL_SENSE_SURROUNDINGS:
			 map_area();
			 break;
		case SPELL_CURE_CRIT_WOUNDS:
			 (void)hp_player(damroll(8, 10));
			 (void)set_stun(0);
			 (void)set_cut(0);
			 break;
		case SPELL_TURN_UNDEAD:
			 (void)turn_undead();
			 break;
		case SPELL_PRAYER:
			 (void)set_blessed(p_ptr->blessed + randint(48) + 48);
			 break;
		case SPELL_DISPEL_UNDEAD_SMALL:
			 (void)dispel_undead(plev * 3);
			 break;
		case SPELL_HEAL:
			 (void)hp_player(300);
			 (void)set_stun(0);
			 (void)set_cut(0);
			 break;
		case SPELL_DISPEL_EVIL:
			 (void)dispel_evil(plev * 3);
			 break;
		case SPELL_GLYPH_OF_WARDING:
			 warding_glyph();
			 break;
		case SPELL_HOLY_WORD:
			 (void)dispel_evil(plev * 4);
			 (void)hp_player(1000);
			 (void)set_afraid(0);
			 (void)set_poisoned(0);
			 (void)set_stun(0);
			 (void)set_cut(0);
			 break;
		case SPELL_BLINK:
			 teleport_player(10);
			 break;
		case SPELL_TELEPORT:
			 teleport_player(plev * 8);
			 break;
		case SPELL_TELEPORT_AWAY:
			 if (!get_aim_dir(&dir)) return (TRUE);
			 (void)teleport_monster(dir);
			 break;
		case SPELL_TELEPORT_LEVEL:
			 (void)teleport_player_level();
			 break;
		case SPELL_ALTER_REALITY:
			 msg_print("The world changes!");
			 new_level_flag = TRUE;
			 break;
		case SPELL_DETECT_MONSTERS:
			 (void)detect_monsters();
			 break;
		case SPELL_DETECTION:
			 (void)detection();
			 break;
		case SPELL_PERCEPTION:
			 (void)ident_spell();
			 break;
		case SPELL_PROBING:
			 (void)probing();
			 break;
		case SPELL_CLAIRVOYANCE:
			 wiz_lite();
			 break;
		case SPELL_CURE_SER_WOUNDS_EASY:
			 (void)hp_player(damroll(4, 10));
			 (void)set_cut(0);
			 break;
		case SPELL_CURE_CRIT_WOUNDS_EASY:
			 (void)hp_player(damroll(8, 10));
			 (void)set_stun(0);
			 (void)set_cut(0);
			 break;
		case SPELL_HEALING:
			 (void)hp_player(2000);
			 (void)set_stun(0);
			 (void)set_cut(0);
			 break;
		case SPELL_RESTORATION:
			 (void)do_res_stat(A_STR);
			 (void)do_res_stat(A_INT);
			 (void)do_res_stat(A_WIS);
			 (void)do_res_stat(A_DEX);
			 (void)do_res_stat(A_CON);
			 (void)do_res_stat(A_CHR);
			 break;
		case SPELL_REMEMBRANCE:
			 (void)restore_level();
			 break;
		case SPELL_UNBARRING_WAYS:
			 (void)destroy_doors_touch();
			 break;
		case SPELL_RECHARGING:
			 (void)recharge(15);
			 break;
		case SPELL_DISPEL_CURSE:
			 (void)remove_all_curse();
			 break;
		case SPELL_ENCHANT_WEAPON:
/* jk - *enchant* effects */
			 (void)enchant_spell(100+rand_int(4) + 1, 100+rand_int(4) + 1, 0);
			 break;
		case SPELL_ENCHANT_ARMOUR:
			 (void)enchant_spell(0, 0, 100+rand_int(3) + 2);
			 break;
		case SPELL_ELEMENTAL_BRAND:
			 brand_weapon();
			 break;
		case SPELL_DISPEL_UNDEAD_LARGE:
			 (void)dispel_undead(plev * 4);
			 break;
		case SPELL_DISPEL_EVIL_LARGE:
			 (void)dispel_evil(plev * 4);
			 break;
		case SPELL_BANISHMENT:
			 if (banish_evil(100))
			 {
				  msg_print("The power of your god banishes evil!");
			 }
			 break;
		case SPELL_WORD_OF_DESTRUCTION:
			 destroy_area(px, py, 15, TRUE);
			 break;
		case SPELL_ANNIHILATION:
			 if (!get_aim_dir(&dir)) return (TRUE);
			 drain_life(dir, 200);
			 break;

		default: msg_format("Unknown page spell no %d", spellno);
					break;
	}
	return (FALSE);
}
#endif

static bool cast_mage_spell(int spell)
{
	int py = p_ptr->py;
	int px = p_ptr->px;

	int dir;

	int plev = p_ptr->lev;

	/* Hack -- chance of "beam" instead of "bolt" */
	int beam = beam_chance();

	/* Spells. */
	switch (spell)
	{
		case SPELL_MAGIC_MISSILE:
		{
			if (!get_aim_dir(&dir)) return (FALSE);
			fire_bolt_or_beam(beam-10, GF_MISSILE, dir,
			                  damroll(3 + ((plev - 1) / 5), 4));
			break;
		}

		case SPELL_DETECT_MONSTERS:
		{
			(void)detect_monsters_normal(TRUE);
			break;
		}

		case SPELL_PHASE_DOOR:
		{
			teleport_player(10);
			break;
		}

		case SPELL_LIGHT_AREA:
		{
			(void)lite_area(damroll(2, (plev / 2)), (plev / 10) + 1);
			break;
		}

		case SPELL_TREASURE_DETECTION:
		{
			(void)detect_treasure(TRUE);
			break;
		}

		case SPELL_CURE_LIGHT_WOUNDS:
		{

			(void)hp_player(damroll(2, 8));
			(void)dec_timed(TMD_CUT, 15, TRUE);
			break;
		}

		case SPELL_FIND_TRAPS_DOORS:
		{
			(void)detect_traps(TRUE);
			(void)detect_doorstairs(TRUE);
			break;
		}

		case SPELL_STINKING_CLOUD:
		{
			if (!get_aim_dir(&dir)) return (FALSE);
			fire_ball(GF_POIS, dir, 10 + (plev / 2), 2);
			break;
		}

#if 0
		case SPELL_CONFUSE_MONSTER:
		{
			if (!get_aim_dir(&dir)) return (FALSE);
			(void)confuse_monster(dir, plev);
			break;
		}
#endif
		case SPELL_LIGHTNING_BOLT:
		{
			if (!get_aim_dir(&dir)) return (FALSE);
			fire_beam(GF_ELEC, dir,
			          damroll(3+((plev-5)/6), 6));
			break;
		}

		case SPELL_TRAP_DOOR_DESTRUCTION:
		{
			(void)destroy_doors_touch();
			break;
		}

#if 0
		case SPELL_SLEEP_MONSTER:
		{
			if (!get_aim_dir(&dir)) return (FALSE);
			(void)sleep_monster(dir);
			break;
		}
#endif
		case SPELL_CURE_POISON:
		{
			(void)clear_timed(TMD_POISONED, TRUE);
			break;
		}

		case SPELL_TELEPORT_SELF:
		{
			teleport_player(plev * 5);
			break;
		}

		case SPELL_SPEAR_OF_LIGHT: /* spear of light */
		{
			if (!get_aim_dir(&dir)) return (FALSE);
			msg_print("A line of blue shimmering light appears.");
			lite_line(dir);
			break;
		}

		case SPELL_FROST_BOLT:
		{
			if (!get_aim_dir(&dir)) return (FALSE);
			fire_bolt_or_beam(beam-10, GF_COLD, dir,
			                  damroll(5+((plev-5)/4), 8));
			break;
		}

		case SPELL_TURN_STONE_TO_MUD:
		{
			if (!get_aim_dir(&dir)) return (FALSE);
			(void)wall_to_mud(dir);
			break;
		}

		case SPELL_SATISFY_HUNGER:
		{
			(void)set_food(PY_FOOD_MAX - 1);
			break;
		}

		case SPELL_RECHARGE_ITEM_I:
		{
			return recharge(2 + plev / 5);
		}
#if 0
		case SPELL_WONDER: /* wonder */
		{
			if (!get_aim_dir(&dir)) return (FALSE);
			(void)spell_wonder(dir);
			break;
		}
#endif
		case SPELL_POLYMORPH_OTHER:
		{
			if (!get_aim_dir(&dir)) return (FALSE);
			(void)poly_monster(dir);
			break;
		}

		case SPELL_IDENTIFY:
		{
			return ident_spell();
		}
#if 0
		case SPELL_MASS_SLEEP:
		{
			(void)sleep_monsters();
			break;
		}
#endif
		case SPELL_FIRE_BOLT:
		{
			if (!get_aim_dir(&dir)) return (FALSE);
			fire_bolt_or_beam(beam, GF_FIRE, dir,
			                  damroll(6+((plev-5)/4), 8));
			break;
		}

		case SPELL_SLOW_MONSTER:
		{
			if (!get_aim_dir(&dir)) return (FALSE);
			(void)slow_monster(dir);
			break;
		}

		case SPELL_FROST_BALL:
		{
			if (!get_aim_dir(&dir)) return (FALSE);
			fire_ball(GF_COLD, dir, 30 + (plev), 2);
			break;
		}

		case SPELL_RECHARGE_ITEM_II: /* greater recharging */
		{
			return recharge(50 + plev);
		}

		case SPELL_TELEPORT_OTHER:
		{
			if (!get_aim_dir(&dir)) return (FALSE);
			(void)teleport_monster(dir);
			break;
		}
#if 0
		case SPELL_BEDLAM:
		{
			if (!get_aim_dir(&dir)) return (FALSE);
			fire_ball(GF_OLD_CONF, dir, plev, 4);
			break;
		}
#endif
		case SPELL_FIRE_BALL:
		{
			if (!get_aim_dir(&dir)) return (FALSE);
			fire_ball(GF_FIRE, dir, 55 + (plev), 2);
			break;
		}

		case SPELL_WORD_OF_DESTRUCTION:
		{
			destroy_area(py, px, 15, TRUE);
			break;
		}
#if 0
		case SPELL_BANISHMENT:
		{
			return banishment();
			break;
		}
#endif
		case SPELL_DOOR_CREATION:
		{
			(void)door_creation();
			break;
		}

		case SPELL_STAIR_CREATION:
		{
			(void)stair_creation();
			break;
		}

		case SPELL_TELEPORT_LEVEL:
		{
			(void)teleport_player_level();
			break;
		}

		case SPELL_EARTHQUAKE:
		{
			earthquake(py, px, 10);
			break;
		}

		case SPELL_WORD_OF_RECALL:
		{
			set_recall();
			break;
		}

		case SPELL_ACID_BOLT:
		{
			if (!get_aim_dir(&dir)) return (FALSE);
			fire_bolt_or_beam(beam, GF_ACID, dir, damroll(8+((plev-5)/4), 8));
			break;
		}

		case SPELL_CLOUD_KILL:
		{
			if (!get_aim_dir(&dir)) return (FALSE);
			fire_ball(GF_POIS, dir, 40 + (plev / 2), 3);
			break;
		}

		case SPELL_ACID_BALL:
		{
			if (!get_aim_dir(&dir)) return (FALSE);
			fire_ball(GF_ACID, dir, 40 + (plev), 2);
			break;
		}

		case SPELL_ICE_STORM:
		{
			if (!get_aim_dir(&dir)) return (FALSE);
			fire_ball(GF_ICE, dir, 50 + (plev * 2), 3);
			break;
		}

		case SPELL_METEOR_SWARM:
		{
			if (!get_aim_dir(&dir)) return (FALSE);
			fire_swarm(2 + plev / 20, GF_METEOR, dir, 30 + plev / 2, 1);
			break;
		}
#if 0
		case SPELL_MANA_STORM:
		{
			if (!get_aim_dir(&dir)) return (FALSE);
			fire_ball(GF_MANA, dir, 300 + (plev * 2), 3);
			break;
		}
		case SPELL_DETECT_INVISIBLE:
		{
			(void)detect_monsters_invis(TRUE);
			break;
		}
#endif

		case SPELL_DETECT_ENCHANTMENT:
		{
			(void)detect_objects_magic(TRUE);
			break;
		}
#if 0
		case SPELL_SHOCK_WAVE:
		{
			if (!get_aim_dir(&dir)) return (FALSE);
			fire_ball(GF_SOUND, dir, 10 + plev, 2);
			break;
		}
		case SPELL_EXPLOSION:
		{
			if (!get_aim_dir(&dir)) return (FALSE);
			fire_ball(GF_SHARD, dir, 20 + (plev * 2), 2);
			break;
		}

		case SPELL_MASS_BANISHMENT:
		{
			(void)mass_banishment();
			break;
		}
#endif

		case SPELL_RESIST_FIRE:
		{
			(void)inc_timed(TMD_OPP_FIRE, randint1(20) + 20, TRUE);
			break;
		}

		case SPELL_RESIST_COLD:
		{
			(void)inc_timed(TMD_OPP_COLD, randint1(20) + 20, TRUE);
			break;
		}
#if 0
		case SPELL_ELEMENTAL_BRAND: /* elemental brand */
		{
			return brand_ammo();
		}
#endif
		case SPELL_RESIST_POISON:
		{
			(void)inc_timed(TMD_OPP_POIS, randint1(20) + 20, TRUE);
			break;
		}

		case SPELL_RESISTANCE:
		{
			int time = randint1(20) + 20;
			(void)inc_timed(TMD_OPP_ACID, time, TRUE);
			(void)inc_timed(TMD_OPP_ELEC, time, TRUE);
			(void)inc_timed(TMD_OPP_FIRE, time, TRUE);
			(void)inc_timed(TMD_OPP_COLD, time, TRUE);
			(void)inc_timed(TMD_OPP_POIS, time, TRUE);
			break;
		}

		case SPELL_HEROISM:
		{
			(void)hp_player(10);
			(void)inc_timed(TMD_HERO, randint1(25) + 25, TRUE);
			(void)clear_timed(TMD_AFRAID, TRUE);
			break;
		}

		case SPELL_SHIELD:
		{
			(void)inc_timed(TMD_SHIELD, randint1(20) + 30, TRUE);
			break;
		}

		case SPELL_BERSERKER:
		{
			(void)hp_player(30);
			(void)inc_timed(TMD_SHERO, randint1(25) + 25, TRUE);
			(void)clear_timed(TMD_AFRAID, TRUE);
			break;
		}

		case SPELL_HASTE_SELF:
		{
			if (!p_ptr->timed[TMD_FAST])
			{
				(void)set_timed(TMD_FAST, randint1(20) + plev, TRUE);
			}
			else
			{
				(void)inc_timed(TMD_FAST, randint1(5), TRUE);
			}
			break;
		}
#if 0
		case SPELL_RIFT:
		{
			if (!get_aim_dir(&dir)) return (FALSE);
			fire_beam(GF_GRAVITY, dir,	40 + damroll(plev, 7));
			break;
		}
		case SPELL_REND_SOUL: /* rend soul */
		{
			if (!get_aim_dir(&dir)) return (FALSE);
			fire_bolt_or_beam(beam / 4, GF_NETHER, dir, damroll(11, plev));
			break;
		}

		case SPELL_CHAOS_STRIKE: /* chaos strike */
		{
			if (!get_aim_dir(&dir)) return (FALSE);
			fire_bolt_or_beam(beam, GF_CHAOS, dir, damroll(13, plev));
			break;
		}

		case SPELL_RUNE_OF_PROTECTION: /* rune of protection */
		{
			(void)warding_glyph();
			break;
		}

		case SPELL_ENCHANT_ARMOR: /* enchant armor */
		{
			return enchant_spell(0, 0, randint0(3) + plev / 20);
		}

		case SPELL_ENCHANT_WEAPON: /* enchant weapon */
		{
			return enchant_spell(randint0(4) + plev / 20,
			                     randint0(4) + plev / 20, 0);
		}
#endif
	}

	/* Success */
	return (TRUE);
}


static bool cast_priest_spell(int spell)
{
	int py = p_ptr->py;
	int px = p_ptr->px;

	int dir;

	int plev = p_ptr->lev;

	switch (spell)
	{
		case SPELL_DETECT_EVIL:
		{
			(void)detect_monsters_evil(TRUE);
			break;
		}

		case SPELL_CURE_LIGHT_WOUNDS:
		{
			(void)hp_player(damroll(2, 10));
			(void)dec_timed(TMD_CUT, 10, TRUE);
			break;
		}

		case SPELL_BLESS:
		{
			(void)inc_timed(TMD_BLESSED, randint1(12) + 12, TRUE);
			break;
		}

		case SPELL_REMOVE_FEAR:
		{
			(void)clear_timed(TMD_AFRAID, TRUE);
			break;
		}

		case SPELL_CALL_LIGHT:
		{
			(void)lite_area(damroll(2, (plev / 2)), (plev / 10) + 1);
			break;
		}

		case SPELL_FIND_TRAPS:
		{
			(void)detect_traps(TRUE);
			break;
		}

		case SPELL_DETECT_DOORS_STAIRS:
		{
			(void)detect_doorstairs(TRUE);
			break;
		}

		case SPELL_SLOW_POISON:
		{
			(void)set_timed(TMD_POISONED, p_ptr->timed[TMD_POISONED] / 2, TRUE);
			break;
		}

#if 0
		case SPELL_SCARE_MONSTER:
		{
			if (!get_aim_dir(&dir)) return (FALSE);
			(void)fear_monster(dir, plev);
			break;
		}
#endif
		case SPELL_PORTAL:
		{
			teleport_player(plev * 3);
			break;
		}

		case SPELL_CURE_SERIOUS_WOUNDS:
		{
			(void)hp_player(damroll(4, 10));
			(void)set_timed(TMD_CUT, (p_ptr->timed[TMD_CUT] / 2) - 20, TRUE);
			break;
		}

		case SPELL_CHANT:
		{
			(void)inc_timed(TMD_BLESSED, randint1(24) + 24, TRUE);
			break;
		}

		case SPELL_SANCTUARY:
		{
			(void)sleep_monsters_touch();
			break;
		}

		case SPELL_SATISFY_HUNGER:
		{
			(void)set_food(PY_FOOD_MAX - 1);
			break;
		}

		case SPELL_REMOVE_CURSE:
		{
			remove_curse();
			break;
		}
#if 0
		case SPELL_RESIST_HEAT_COLD:
		{
			(void)inc_timed(TMD_OPP_FIRE, randint1(10) + 10, TRUE);
			(void)inc_timed(TMD_OPP_COLD, randint1(10) + 10, TRUE);
			break;
		} 
#endif
		case SPELL_NEUTRALIZE_POISON:
		{
			(void)clear_timed(TMD_POISONED, TRUE);
			break;
		}

		case SPELL_ORB_OF_DRAINING:
		{
			if (!get_aim_dir(&dir)) return (FALSE);
			fire_ball(GF_HOLY_ORB, dir,
			          (damroll(3, 6) + plev +
			           (plev / ((cp_ptr->flags & CF_BLESS_WEAPON) ? 2 : 4))),
			          ((plev < 30) ? 2 : 3));
			break;
		}

		case SPELL_CURE_CRITICAL_WOUNDS:
		{
			(void)hp_player(damroll(6, 10));
			(void)clear_timed(TMD_CUT, TRUE);
			(void)clear_timed(TMD_AMNESIA, TRUE);
			break;
		}

		case SPELL_SENSE_INVISIBLE:
		{
			(void)inc_timed(TMD_SINVIS, randint1(24) + 24, TRUE);
			break;
		}

		case SPELL_PROTECTION_FROM_EVIL:
		{
			(void)inc_timed(TMD_PROTEVIL, randint1(25) + 3 * p_ptr->lev, TRUE);
			break;
		}

		case SPELL_EARTHQUAKE:
		{
			earthquake(py, px, 10);
			break;
		}

		case SPELL_SENSE_SURROUNDINGS:
		{
			map_area();
			break;
		}
#if 0
		case SPELL_CURE_MORTAL_WOUNDS:
		{
			(void)hp_player(damroll(8, 10));
			(void)clear_timed(TMD_STUN, TRUE);
			(void)clear_timed(TMD_CUT, TRUE);
			break;
		}
#endif
		case SPELL_TURN_UNDEAD:
		{
			(void)turn_undead();
			break;
		}
#if 0
		case SPELL_PRAYER:
		{
			(void)inc_timed(TMD_BLESSED, randint1(48) + 48, TRUE);
			break;
		}
#endif
		case SPELL_DISPEL_UNDEAD:
		{
			(void)dispel_undead(randint1(plev * 3));
			break;
		}

		case SPELL_HEAL:
		{
			(void)hp_player(300);
			(void)clear_timed(TMD_STUN, TRUE);
			(void)clear_timed(TMD_CUT, TRUE);
			break;
		}

		case SPELL_DISPEL_EVIL:
		{
			(void)dispel_evil(randint1(plev * 3));
			break;
		}

		case SPELL_GLYPH_OF_WARDING:
		{
			warding_glyph();
			break;
		}

		case SPELL_HOLY_WORD:
		{
			(void)dispel_evil(randint1(plev * 4));
			(void)hp_player(1000);
			(void)clear_timed(TMD_AFRAID, TRUE);
			(void)clear_timed(TMD_POISONED, TRUE);
			(void)clear_timed(TMD_STUN, TRUE);
			(void)clear_timed(TMD_CUT, TRUE);
			break;
		}

		case SPELL_DETECT_MONSTERS:
		{
			(void)detect_monsters_normal(TRUE);
			break;
		}

		case SPELL_DETECTION:
		{
			(void)detect_all(TRUE);
			break;
		}

		case SPELL_PERCEPTION:
		{
			return ident_spell();
		}

		case SPELL_PROBING:
		{
			(void)probing();
			break;
		}

		case SPELL_CLAIRVOYANCE:
		{
			wiz_lite();
			break;
		}
#if 0
		case SPELL_CURE_SERIOUS_WOUNDS2:
		{
			(void)hp_player(damroll(4, 10));
			(void)clear_timed(TMD_CUT, TRUE);
			break;
		}
		case SPELL_CURE_MORTAL_WOUNDS2:
		{
			(void)hp_player(damroll(8, 10));
			(void)clear_timed(TMD_STUN, TRUE);
			(void)clear_timed(TMD_CUT, TRUE);
			break;
		}
#endif

		case SPELL_HEALING:
		{
			(void)hp_player(2000);
			(void)clear_timed(TMD_STUN, TRUE);
			(void)clear_timed(TMD_CUT, TRUE);
			break;
		}

		case SPELL_RESTORATION:
		{
			(void)do_res_stat(A_STR);
			(void)do_res_stat(A_INT);
			(void)do_res_stat(A_WIS);
			(void)do_res_stat(A_DEX);
			(void)do_res_stat(A_CON);
			(void)do_res_stat(A_CHR);
			break;
		}

		case SPELL_REMEMBRANCE:
		{
			(void)restore_level();
			break;
		}
#if 0
		case SPELL_DISPEL_UNDEAD2:
		{
			(void)dispel_undead(randint1(plev * 4));
			break;
		}

		case SPELL_DISPEL_EVIL2:
		{
			(void)dispel_evil(randint1(plev * 4));
			break;
		}
		case SPELL_BANISH_EVIL:
		{
			if (banish_evil(100))
			{
				msg_print("The power of your god banishes evil!");
			}
			break;
		}
#endif

		case SPELL_WORD_OF_DESTRUCTION:
		{
			destroy_area(py, px, 15, TRUE);
			break;
		}

		case SPELL_ANNIHILATION:
		{
			if (!get_aim_dir(&dir)) return (FALSE);
			drain_life(dir, 200);
			break;
		}

		case SPELL_UNBARRING_WAYS:
		{
			(void)destroy_doors_touch();
			break;
		}

		case SPELL_RECHARGING:
		{
			return recharge(15);
		}

		case SPELL_DISPEL_CURSE:
		{
			(void)remove_all_curse();
			break;
		}
#if 0
		case SPELL_ENCHANT_WEAPON:
		{
			return enchant_spell(randint0(4) + 1, randint0(4) + 1, 0);
		}

		case SPELL_ENCHANT_ARMOR:
		{
			return enchant_spell(0, 0, randint0(3) + 2);
		}
#endif
		case SPELL_ELEMENTAL_BRAND:
		{
			brand_weapon();
			break;
		}

		case SPELL_BLINK:
		{
			teleport_player(10);
			break;
		}

		case SPELL_TELEPORT_SELF:
		{
			teleport_player(plev * 8);
			break;
		}

		case SPELL_TELEPORT_OTHER:
		{
			if (!get_aim_dir(&dir)) return (FALSE);
			(void)teleport_monster(dir);
			break;
		}

		case SPELL_TELEPORT_LEVEL:
		{
			(void)teleport_player_level();
			break;
		}

		case SPELL_WORD_OF_RECALL:
		{
			set_recall();
			break;
		}

		case SPELL_ALTER_REALITY:
		{
			msg_print("The world changes!");

			/* Leaving */
			p_ptr->leaving = TRUE;

			break;
		}
	}

	/* Success */
	return (TRUE);
}

/* TODO this function probably not required */
bool cast_spell(int index)
{
	return cast_mage_spell(index);
/*	return cast_priest_spell(index); */
}
