/
Crimson/
Crimson/lib/PFILE-BACKUPS/
Crimson/lib/areas/
Crimson/lib/boards/
Crimson/lib/rentfiles/A-E/
Crimson/lib/rentfiles/F-J/
Crimson/lib/rentfiles/P-T/
/* ************************************************************************
*  file: spell_parser.c , Basic routines and parsing      Part of DIKUMUD *
*  Usage : Interpreter of spells                                          *
*  Copyright (C) 1990, 1991 - see 'license.doc' for complete information. *
************************************************************************* */

#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <ctype.h>
#include <assert.h>

#include "structs.h"
#include "utility.h"
#include "comm.h"
#include "db.h"
#include "interpreter.h" 
#include "spells.h"
#include "handler.h"
#include "constants.h"
#include "ansi.h"

#define MANA_MU 1
#define MANA_CL 1

#define SPELLO(nr, beat, pos, mlev, clev, mana, tar, blev, klev, rlev, dlev, elev, func) { \
   spell_info[nr].spell_pointer = (func);      \
   spell_info[nr].beats = (beat);              \
   spell_info[nr].minimum_position = (pos);    \
   spell_info[nr].min_usesmana = (mana);       \
   spell_info[nr].min_level_cleric = (clev);   \
   spell_info[nr].min_level_magic = (mlev);    \
   spell_info[nr].min_level_bard = (blev);     \
   spell_info[nr].min_level_kai = (klev);      \
   spell_info[nr].min_level_drakkhar = (rlev); \
   spell_info[nr].min_level_dknight = (dlev);  \
   spell_info[nr].min_level_eknight = (elev);  \
   spell_info[nr].targets = (tar);             \
}

#define SPELL_LEVEL(ch, sn)                              \
  ( (GET_CLASS(ch) == CLASS_CLERIC) ? spell_info[sn].min_level_cleric :    \
   ( (GET_CLASS(ch) == CLASS_MAGIC_USER) ? spell_info[sn].min_level_magic : \
   ( (GET_CLASS(ch) == CLASS_BARD) ? spell_info[sn].min_level_bard :    \
   ( (GET_CLASS(ch) == CLASS_KAI) ? spell_info[sn].min_level_kai : \
   ( (GET_CLASS(ch) == CLASS_DRAKKHAR) ? spell_info[sn].min_level_drakkhar : \
   ( (GET_CLASS(ch) == CLASS_DKNIGHT) ? spell_info[sn].min_level_dknight : \
   ( (GET_CLASS(ch) == CLASS_EKNIGHT) ? spell_info[sn].min_level_eknight :                                             IMO_LEV)))))))


#define USE_MANA(ch, sn)                            \
  MAXV(spell_info[sn].min_usesmana, 100/(2+GET_LEVEL(ch)-SPELL_LEVEL(ch,sn)))

/* Global data */
extern int pulse; /* from comm.c */


struct spell_info_type spell_info[MAX_SPL_LIST];

const char *spells[]=
{
   "armor",               /* 1 */
   "teleport",
   "bless",
   "blindness",
   "burning hands",
   "call lightning",
   "charm person",
   "chill touch",
   "improved invisibility", /*used to be clones spot */
   "colour spray",
   "control weather",     /* 11 */
   "create food",
   "create water",
   "cure blind",
   "cure critic",
   "cure light",
   "curse",
   "detect evil",
   "detect invisibility",
   "detect magic",
   "detect poison",       /* 21 */
   "dispel evil",
   "earthquake",
   "enchant weapon",
   "energy drain",
   "fireball",
   "harm",
   "heal",
   "invisibility",
   "lightning bolt",
   "locate object",      /* 31 */
   "magic missile",
   "poison",
   "protection from evil",
   "remove curse",
   "sanctuary",
   "shocking grasp",
   "sleep",
   "strength",
   "summon",
   "ventriloquate",      /* 41 */
   "word of recall",
   "remove poison",
   "sense life",         /* 44 */
   "SKILL_SNEAK",        /* 45 */
   "SKILL_HIDE",
   "SKILL_STEAL",
   "SKILL_BACKSTAB",
   "SKILL_PICK_LOCK",
   "SKILL_KICK",         /* 50 */
   "SKILL_BASH",
   "SKILL_RESCUE",
   "identify",           /* 53 */
   "cause critic",
   "cause light",        /* 55 */
   "SKILL_DAMAGE",
   "SKILL_SLASH",
   "SKILL_PIERCE",
   "SKILL_BLUDGEON",
   "SKILL_PARRY",       /* 60 */
   "SKILL_DODGE",
   "SKILL_SCALES",
   "fire breath",
   "gas breath",
   "frost breath",
   "acid breath",      /* 66 */
   "lightning breath",
   "darksight",
   "SKILL_SECOND",
   "SKILL_THIRD",    /* 70 */
   "SKILL_FOURTH",
   "undetectable invisibility",
   "restoration",
   "regeneration",
   "minor wards", /* 75 */
   "major wards",
   "mordenkainens sword",
   "spiritual hammer",
   "turn undead",
   "succor",      /* 80 */
   "donate mana",
   "mana link",
   "magic resist",
   "magic immune",
   "dispel magic",   /* 85 */
   "conflagration", /* 86 */
   "breathwater", /* 87 */
   "sustenance",  /* 88 */
   "\n"
};


const sbyte saving_throws[MAX_CLASS][5][MAX_LEV] = {
{ /* Mage */
  {26,24,24,24,24,24,23,23,23,23,23,21,21,21,21,21,20,20,20,20,20,
      16,14,14,14,14,14,13,13,13,13,13,11,11,11,11,11,10,10,10,10, 1, 8, 6, 4, 0},
  {23,21,21,21,21,21,19,19,19,19,19,19,17,17,17,17,17,15,15,15,15,
      13,11,11,11,11,11, 9, 9, 9, 9, 9, 7, 7, 7, 7, 7, 5, 5, 5, 5, 5, 3, 2, 1, 0},
  {25,25,23,23,23,23,23,21,21,21,21,21,19,19,19,19,19,17,17,17,17,
      15,13,13,13,13,13,11,11,11,11,11, 9, 9, 9, 9, 9, 7, 7, 7, 7, 7, 5, 4, 2, 0},
  {27,27,25,25,25,25,25,23,23,23,23,23,21,21,21,21,21,19,19,19,19,
      17,15,15,15,15,15,13,13,13,13,13,11,11,11,11,11, 9, 9, 9, 9, 9, 7, 5, 3, 0},
  {24,24,22,22,22,22,22,20,20,20,20,20,18,18,18,18,18,16,16,16,16,
      14,12,12,12,12,12,10,10,10,10,10, 8, 8, 8, 8, 8, 6, 6, 6, 6, 6, 4, 3, 2, 0}
}, { /* Cleric */
  {21,21,20,20,20,19,19,19,17,17,17,16,16,16,15,15,15,14,14,14,12,
      11,10,10,10, 9, 9, 9, 7, 7, 7, 6, 6, 6, 5, 5, 5, 4, 4, 4, 2, 2, 2, 2, 1, 0},
  {26,26,24,24,24,23,23,23,21,21,21,20,20,20,19,19,19,18,18,18,17,
      16,14,14,14,13,13,13,11,11,11,10,10,10, 9, 9, 9, 8, 8, 8, 6, 6, 5, 4, 3, 0},
  {25,25,23,23,23,22,22,22,20,20,20,19,19,19,18,18,18,17,17,17,15,
      15,13,13,13,12,12,12,10,10,10, 9, 9, 9, 8, 8, 8, 7, 7, 7, 5, 5, 4, 3, 2, 0},
  {28,28,26,26,26,25,25,25,23,23,23,22,22,22,21,21,21,20,20,20,18,
      18,16,16,16,15,15,15,13,13,13,12,12,12,11,11,11,10,10,10, 8, 8, 7, 6, 5, 0},
  {27,27,25,25,25,24,24,24,22,22,22,21,21,21,20,20,20,19,19,19,17,
      17,15,15,15,14,14,14,12,12,12,11,11,11,10,10,10, 9, 9, 9, 7, 7, 6, 5, 4, 0}
}, { /* Thief */
  {25,23,23,23,23,23,22,22,22,22,21,21,21,21,20,20,20,20,19,19,19,
      15,13,13,13,13,12,12,12,12,11,11,11,11,10,10,10,10, 9, 9, 9, 9, 8, 7, 6, 0},
  {26,26,24,24,24,24,22,22,22,22,20,20,20,20,18,18,18,18,16,16,16,
      16,14,14,14,14,12,12,12,12,10,10,10,10, 8, 8, 8, 8, 6, 6, 6, 6, 4, 3, 2, 0},
  {24,24,22,22,22,22,21,21,21,21,20,20,20,20,19,19,19,19,18,18,18,
      14,12,12,12,12,11,11,11,11,10,10,10,10, 9, 9, 9, 9, 8, 8, 8, 8, 7, 5, 3, 0},
  {28,28,26,26,26,26,25,25,25,25,24,24,24,24,23,23,23,23,22,22,22,
      18,16,16,16,16,15,15,15,15,14,14,14,14,13,13,13,13,12,12,12,12,11, 9, 5, 0},
  {27,27,25,25,25,25,23,23,23,23,21,21,21,21,19,19,19,19,17,17,17,
      17,15,15,15,15,13,13,13,13,11,11,11,11, 9, 9, 9, 9, 7, 7, 7, 7, 5, 3, 1, 0}
}, { /* Warrior */
  {26,26,24,24,23,23,21,21,20,20,18,18,17,17,15,15,14,14,13,13,13,
      16,14,14,13,13,11,11,10,10, 8, 8, 7, 7, 5, 5, 4, 4, 3, 3, 3, 3, 2, 2, 1, 0},
  {28,28,26,26,25,25,23,23,22,22,20,20,19,19,17,17,16,16,15,15,15,
      18,16,16,15,15,13,13,12,12,10,10, 9, 9, 7, 7, 6, 6, 5, 5, 5, 5, 4, 3, 2, 0},
  {27,27,25,25,24,24,22,22,21,21,19,19,18,18,16,16,15,15,14,14,14,
      17,15,15,14,14,12,12,11,11, 9, 9, 8, 8, 6, 6, 5, 5, 4, 4, 4, 4, 3, 2, 1, 0},
  {30,30,27,27,26,26,23,23,22,22,19,19,18,18,15,15,14,14,14,14,14, 
      20,17,17,16,16,13,13,12,12, 9, 9, 8, 8, 5, 5, 4, 4, 4, 4, 4, 4, 3, 2, 1, 0},
  {29,29,27,27,26,26,24,24,23,23,21,21,20,20,18,18,17,17,16,16,16,
      19,17,17,16,16,14,14,13,13,11,11,10,10, 8, 8, 7, 7, 6, 6, 6, 6, 4, 2, 1, 0}
}, { /* Bard */
  {25,23,23,23,23,23,22,22,22,22,21,21,21,21,20,20,20,20,19,19,19,
      15,13,13,13,13,12,12,12,12,11,11,11,11,10,10,10,10, 9, 9, 9, 9, 8, 7, 6, 0},
  {26,26,24,24,24,24,22,22,22,22,20,20,20,20,18,18,18,18,16,16,16,
      16,14,14,14,14,12,12,12,12,10,10,10,10, 8, 8, 8, 8, 6, 6, 6, 6, 4, 3, 2, 0},
  {24,24,22,22,22,22,21,21,21,21,20,20,20,20,19,19,19,19,18,18,18,
      14,12,12,12,12,11,11,11,11,10,10,10,10, 9, 9, 9, 9, 8, 8, 8, 8, 7, 5, 3, 0},
  {28,28,26,26,26,26,25,25,25,25,24,24,24,24,23,23,23,23,22,22,22,
      18,16,16,16,16,15,15,15,15,14,14,14,14,13,13,13,13,12,12,12,12,11, 9, 5, 0},
  {27,27,25,25,25,25,23,23,23,23,21,21,21,21,19,19,19,19,17,17,17,
      17,15,15,15,15,13,13,13,13,11,11,11,11, 9, 9, 9, 9, 7, 7, 7, 7, 5, 3, 1, 0}
}, { /* Kai */
  {21,21,20,20,20,19,19,19,17,17,17,16,16,16,15,15,15,14,14,14,12,
      11,10,10,10, 9, 9, 9, 7, 7, 7, 6, 6, 6, 5, 5, 5, 4, 4, 4, 2, 2, 2, 2, 1, 0},
  {26,26,24,24,24,23,23,23,21,21,21,20,20,20,19,19,19,18,18,18,17,
      16,14,14,14,13,13,13,11,11,11,10,10,10, 9, 9, 9, 8, 8, 8, 6, 6, 5, 4, 3, 0},
  {25,25,23,23,23,22,22,22,20,20,20,19,19,19,18,18,18,17,17,17,15,
      15,13,13,13,12,12,12,10,10,10, 9, 9, 9, 8, 8, 8, 7, 7, 7, 5, 5, 4, 3, 2, 0},
  {28,28,26,26,26,25,25,25,23,23,23,22,22,22,21,21,21,20,20,20,18,
      18,16,16,16,15,15,15,13,13,13,12,12,12,11,11,11,10,10,10, 8, 8, 7, 6, 5, 0},
  {27,27,25,25,25,24,24,24,22,22,22,21,21,21,20,20,20,19,19,19,17,
      17,15,15,15,14,14,14,12,12,12,11,11,11,10,10,10, 9, 9, 9, 7, 7, 6, 5, 4, 0}
}, { /* Drakkhar */
  {21,21,20,20,20,19,19,19,17,17,17,16,16,16,15,15,15,14,14,14,12,
      11,10,10,10, 9, 9, 9, 7, 7, 7, 6, 6, 6, 5, 5, 5, 4, 4, 4, 2, 2, 2, 2, 1, 0},
  {26,26,24,24,24,23,23,23,21,21,21,20,20,20,19,19,19,18,18,18,17,
      16,14,14,14,13,13,13,11,11,11,10,10,10, 9, 9, 9, 8, 8, 8, 6, 6, 5, 4, 3, 0},
  {25,25,23,23,23,22,22,22,20,20,20,19,19,19,18,18,18,17,17,17,15,
      15,13,13,13,12,12,12,10,10,10, 9, 9, 9, 8, 8, 8, 7, 7, 7, 5, 5, 4, 3, 2, 0},
  {28,28,26,26,26,25,25,25,23,23,23,22,22,22,21,21,21,20,20,20,18,
      18,16,16,16,15,15,15,13,13,13,12,12,12,11,11,11,10,10,10, 8, 8, 7, 6, 5, 0},
  {27,27,25,25,25,24,24,24,22,22,22,21,21,21,20,20,20,19,19,19,17,
      17,15,15,15,14,14,14,12,12,12,11,11,11,10,10,10, 9, 9, 9, 7, 7, 6, 5, 4, 0}
}, { /* Demon Knight */
  {26,24,24,24,24,24,23,23,23,23,23,21,21,21,21,21,20,20,20,20,20,
      16,14,14,14,14,14,13,13,13,13,13,11,11,11,11,11,10,10,10,10, 1, 8, 6, 4, 0},
  {23,21,21,21,21,21,19,19,19,19,19,19,17,17,17,17,17,15,15,15,15,
      13,11,11,11,11,11, 9, 9, 9, 9, 9, 7, 7, 7, 7, 7, 5, 5, 5, 5, 5, 3, 2, 1, 0},
  {25,25,23,23,23,23,23,21,21,21,21,21,19,19,19,19,19,17,17,17,17,
      15,13,13,13,13,13,11,11,11,11,11, 9, 9, 9, 9, 9, 7, 7, 7, 7, 7, 5, 4, 2, 0},
  {27,27,25,25,25,25,25,23,23,23,23,23,21,21,21,21,21,19,19,19,19,
      17,15,15,15,15,15,13,13,13,13,13,11,11,11,11,11, 9, 9, 9, 9, 9, 7, 5, 3, 0},
  {24,24,22,22,22,22,22,20,20,20,20,20,18,18,18,18,18,16,16,16,16,
      14,12,12,12,12,12,10,10,10,10,10, 8, 8, 8, 8, 8, 6, 6, 6, 6, 6, 4, 3, 2, 0}
}, { /* Elfin Knight */
  {26,24,24,24,24,24,23,23,23,23,23,21,21,21,21,21,20,20,20,20,20,
      16,14,14,14,14,14,13,13,13,13,13,11,11,11,11,11,10,10,10,10, 1, 8, 6, 4, 0},
  {23,21,21,21,21,21,19,19,19,19,19,19,17,17,17,17,17,15,15,15,15,
      13,11,11,11,11,11, 9, 9, 9, 9, 9, 7, 7, 7, 7, 7, 5, 5, 5, 5, 5, 3, 2, 1, 0},
  {25,25,23,23,23,23,23,21,21,21,21,21,19,19,19,19,19,17,17,17,17,
      15,13,13,13,13,13,11,11,11,11,11, 9, 9, 9, 9, 9, 7, 7, 7, 7, 7, 5, 4, 2, 0},
  {27,27,25,25,25,25,25,23,23,23,23,23,21,21,21,21,21,19,19,19,19,
      17,15,15,15,15,15,13,13,13,13,13,11,11,11,11,11, 9, 9, 9, 9, 9, 7, 5, 3, 0},
  {24,24,22,22,22,22,22,20,20,20,20,20,18,18,18,18,18,16,16,16,16,
      14,12,12,12,12,12,10,10,10,10,10, 8, 8, 8, 8, 8, 6, 6, 6, 6, 6, 4, 3, 2, 0}
}, { /* Dragon-Kin Warrior */
  {26,26,24,24,23,23,21,21,20,20,18,18,17,17,15,15,14,14,13,13,13,
      16,14,14,13,13,11,11,10,10, 8, 8, 7, 7, 5, 5, 4, 4, 3, 3, 3, 3, 2, 2, 1, 0},
  {28,28,26,26,25,25,23,23,22,22,20,20,19,19,17,17,16,16,15,15,15,
      18,16,16,15,15,13,13,12,12,10,10, 9, 9, 7, 7, 6, 6, 5, 5, 5, 5, 4, 3, 2, 0},
  {27,27,25,25,24,24,22,22,21,21,19,19,18,18,16,16,15,15,14,14,14,
      17,15,15,14,14,12,12,11,11, 9, 9, 8, 8, 6, 6, 5, 5, 4, 4, 4, 4, 3, 2, 1, 0},
  {30,30,27,27,26,26,23,23,22,22,19,19,18,18,15,15,14,14,14,14,14, 
      20,17,17,16,16,13,13,12,12, 9, 9, 8, 8, 5, 5, 4, 4, 4, 4, 4, 4, 3, 2, 1, 0},
  {29,29,27,27,26,26,24,24,23,23,21,21,20,20,18,18,17,17,16,16,16,
      19,17,17,16,16,14,14,13,13,11,11,10,10, 8, 8, 7, 7, 6, 6, 6, 6, 4, 2, 1, 0}
}
};



void affect_update( void )
{
   static struct affected_type *af, *next_af_dude, ds_aff;
   static struct char_data *i;

   ds_aff.type = SPELL_DARKSIGHT; /* setup for l8r */
   ds_aff.modifier = 0;
   ds_aff.location = APPLY_NONE;
   ds_aff.bitvector = AFF_DARKSIGHT;

   for (i = character_list; i; i = i->next) {
      for (af = i->affected; af; af = next_af_dude) {
         next_af_dude = af->next;
         if (af->duration >= 1)
            af->duration--;
         else if (af->duration == 0) {
            if ((af->type > 0) && (af->type <= 100)) /* It must be a spell */
               if (!af->next  
                  || (af->next->type != af->type) 
                  || (af->next->duration > 0) )
                  if (*spell_wear_off_msg[af->type]
                      && !(af->type == SPELL_DARKSIGHT && GET_CLASS(i) == CLASS_DRAGONW)) {
                     /* dragon-kin dont get darksight expired messages */
                     send_to_char((char*)spell_wear_off_msg[af->type], i);
                     send_to_char("\n\r", i);
                  }

            affect_remove(i, af);
         }
      }
      /* If Dragon-Kin check to see if Darksight is working here */
      /* ie if !Darksight then check number 0-100 against skill
        and cast spell on char for duration of level if it succeeds */
      if (GET_CLASS(i) == CLASS_DRAGONW && !IS_AFFECTED(i, AFF_DARKSIGHT)) {
         if (number(0,100) < i->skills[SPELL_DARKSIGHT].learned) {
            ds_aff.duration = GET_LEVEL(i);
            affect_to_char(i, &ds_aff);
         }
      }
      if (GET_LEVEL(i) == IMO_LEV && !IS_AFFECTED(i,AFF_DARKSIGHT)){
         ds_aff.duration = -1;
         affect_to_char(i, &ds_aff);
      }
   }
}

#ifdef REENABLE_CLONE_CODE
void clone_char(struct char_data *ch)
{
   extern struct index_data *mob_index;
   struct char_data *clone;
   struct affected_type *af;
   int i;

   CREATE(clone, struct char_data, 1);


   clear_char(clone);       /* Clear EVERYTHING! (ASSUMES CORRECT) */

   clone->player    = ch->player;
   clone->abilities = ch->abilities;

   for (i=0; i<5; i++)
      clone->specials.apply_saving_throw[i] = ch->specials.apply_saving_throw[i];

   for (af=ch->affected; af; af = af->next)
      affect_to_char(clone, af);

   for (i=0; i<3; i++)
      GET_COND(clone,i) = GET_COND(ch, i);

   clone->points = ch->points;

   for (i=0; i<MAX_SKILLS; i++)
      clone->skills[i] = ch->skills[i];

   clone->specials = ch->specials;
   clone->specials.fighting = 0;

   GET_NAME(clone) = str_alloc(GET_NAME(ch));

   clone->player.short_descr =   str_alloc(ch->player.short_descr);

   clone->player.long_descr = str_alloc(ch->player.long_descr);

   clone->player.description = 0;
   /* REMEMBER EXTRA DESCRIPTIONS */

   GET_TITLE(clone) = str_alloc(GET_TITLE(ch));

   clone->nr = ch->nr;

   if (IS_NPC(clone))
      mob_index[clone->nr].number++;
   else { /* Make PC's into NPC's */
      clone->nr = -1;
      SET_BIT(clone->specials.act, ACT_ISNPC);
   }

   clone->desc = 0;
   clone->followers = 0;
   clone->master = 0;

   clone->next = character_list;
   character_list = clone;

   char_to_room(clone, ch->in_room);
}



void clone_obj(struct obj_data *obj)
{
   struct obj_data *clone;
   struct extra_descr_data *ed, temp;


   CREATE(clone, struct obj_data, 1);

   *clone = *obj;

   clone->name               = str_alloc(obj->name);
   clone->description        = str_alloc(obj->description);
   clone->short_description  = str_alloc(obj->short_description);
   clone->action_description = str_alloc(obj->action_description);
   clone->ex_description     = 0;

   /* REMEMBER EXTRA DESCRIPTIONS */
   clone->carried_by         = 0;
   clone->in_obj             = 0;
   clone->contains           = 0;
   clone->next_content       = 0;
   clone->next               = 0;

   /* VIRKER IKKE ENDNU */
}
#endif



void say_spell( struct char_data *ch, int si )
{
   char buf[MAX_STRING_LENGTH], splwd[MAX_BUF_LENGTH];
   char buf2[MAX_STRING_LENGTH];

   int j, offs;
   struct char_data *temp_char;


   struct syllable {
      char org[10];
      char new[10];
   };

   struct syllable syls[] = {
   { " ", " " },
   { "ar", "abra"   },
   { "au", "kada"    },
   { "bless", "fido" },
   { "blind", "nose" },
   { "bur", "mosa" },
   { "cu", "judi" },
   { "de", "oculo"},
   { "en", "unso" },
   { "light", "dies" },
   { "lo", "hi" },
   { "mor", "zak" },
   { "move", "sido" },
   { "ness", "lacri" },
   { "ning", "illa" },
   { "per", "duda" },
   { "ra", "gru"   },
   { "re", "candus" },
   { "son", "sabru" },
   { "tect", "infra" },
   { "tri", "cula" },
   { "ven", "nofo" },
   {"a", "a"},{"b","b"},{"c","q"},{"d","e"},{"e","z"},{"f","y"},{"g","o"},
   {"h", "p"},{"i","u"},{"j","y"},{"k","t"},{"l","r"},{"m","w"},{"n","i"},
   {"o", "a"},{"p","s"},{"q","d"},{"r","f"},{"s","g"},{"t","h"},{"u","j"},
   {"v", "z"},{"w","x"},{"x","n"},{"y","l"},{"z","k"}, {"",""}
   };



   strcpy(buf, "");
   strcpy(splwd, spells[si-1]);

   offs = 0;

   while(*(splwd+offs)) {
      for(j=0; *(syls[j].org); j++)
         if (strncmp(syls[j].org, splwd+offs, strlen(syls[j].org))==0) {
            strcat(buf, syls[j].new);
            if (strlen(syls[j].org))
               offs+=strlen(syls[j].org);
            else
               ++offs;
         }
   }


   sprintf(buf2,"$n utters the words, '%s'", buf);
   sprintf(buf, "$n utters the words, '%s'", spells[si-1]);

   for(temp_char = world[ch->in_room].people;
      temp_char;
      temp_char = temp_char->next_in_room)
      if(temp_char != ch) {
         if (!IS_NPC(ch) && GET_CLASS(ch) == GET_CLASS(temp_char))
	   act(buf, FALSE, ch, 0, temp_char, TO_VICT);
         else
	   act(buf2, FALSE, ch, 0, temp_char, TO_VICT);

      }

}



bool saves_spell(struct char_data *ch, sh_int save_type)
{
   int save;

   /* Negative apply_saving_throw makes saving throw better! */

   save = ch->specials.apply_saving_throw[save_type];

   if (!IS_NPC(ch)) {
      save += saving_throws[GET_CLASS(ch)-1][save_type][GET_LEVEL(ch)];
      if (GET_LEVEL(ch) > IMO_LEV)
         return(TRUE);
   }

   return(MAXV(1,save) < number(1,30));
}



char *skip_spaces(char *string)
{
   for(;*string && (*string)==' ';string++);

   return(string);
}



/* Assumes that *argument does start with first letter of chopped string */

void do_cast(struct char_data *ch, char *argument, int cmd)
{
  struct obj_data *tar_obj;
  struct char_data *tar_char;
  char name[MAX_STRING_LENGTH];
  char buf[MAX_INPUT_LENGTH];
  int qend, spl, i;
  bool target_ok;

  if (IS_NPC(ch))
    return;

  if (GET_LEVEL(ch) < IMO_LEV) {
      if (GET_CLASS(ch) == CLASS_WARRIOR) {
	send_to_char("Think you had better stick to fighting...\n\r", ch);
	return;
      }  else if (GET_CLASS(ch) == CLASS_THIEF) {
	send_to_char("Think you should stick to robbing and killing...\n\r", ch);
	return;
      }  else if (GET_CLASS(ch) == CLASS_DRAGONW) {
	send_to_char("Think you should stick to breathing fire...\n\r", ch);
	return;
      }
    }

  argument = skip_spaces(argument);

  /* If there is no chars in argument */
  if (!(*argument)) {
    send_to_char("Cast which what where?\n\r", ch);
    return;
  }

  if (*argument != '\'' && *argument != '\"') {
    for (qend=1; *(argument+qend) && isalpha(*(argument+qend)); qend++)
      *(argument+qend) = LOWER(*(argument+qend));
    spl = old_search_block(argument, 0, qend-1,spells, 0);
    --qend;
  } else {
    /* Locate the last quote && lowercase the magic words (if any) */
    for (qend=1; *(argument+qend) && (*(argument+qend) != '\'')
	 && (*(argument+qend) != '\"'); qend++)
      *(argument+qend) = LOWER(*(argument+qend));
 
    if (*(argument+qend) != '\'') {
      send_to_char("Come again? try something like cast \'a spell\'\n\r",ch);
      return;
    }
    spl = old_search_block(argument, 1, qend-1,spells, 0);
  }

  if (!spl) {
    send_to_char("Your lips do not move, no magic appears.\n\r",ch);
    return;
  }

  if ((ch->specials.fighting) && (pulse%PULSE_VIOLENCE)) {
    /* if we are fighting delay spell till start of next round */
    sprintf(buf, "cast %s", argument); /* queue command until next wait */
    WAIT_STATE(ch, PULSE_VIOLENCE - pulse%PULSE_VIOLENCE);
    write_to_head_q(buf, &ch->desc->input);
    return; /* we'll be back! */
  }
  if ((spl > 0) && (spl <= MAX_SPL_LIST) && spell_info[spl].spell_pointer) {
    if (GET_POS(ch) < spell_info[spl].minimum_position) {
      switch(GET_POS(ch)) {
      case POSITION_SLEEPING :
	send_to_char("You dream about great magical powers.\n\r", ch);
	break;
      case POSITION_RESTING :
	send_to_char("You can't concentrate enough while resting.\n\r",ch);
	break;
      case POSITION_SITTING :
	send_to_char("You can't do this sitting!\n\r", ch);
	break;
      case POSITION_FIGHTING :
	send_to_char("Impossible! You can't concentrate enough!.\n\r", ch);
	break;
      default:
	send_to_char("It seems like you're in a pretty bad shape!\n\r",ch);
	break;
      } /* Switch */
    }  else {

      if (GET_LEVEL(ch) < IMO_LEV) {
	if ((GET_CLASS(ch) == CLASS_MAGIC_USER) &&
	    (spell_info[spl].min_level_magic > GET_LEVEL(ch))) {
	  send_to_char("Sorry, you can't do that.\n\r", ch);
	  return;
	}
	if ((GET_CLASS(ch) == CLASS_CLERIC) &&
	    (spell_info[spl].min_level_cleric > GET_LEVEL(ch))) {
	  send_to_char("Sorry, you can't do that.\n\r", ch);
	  return;
	}
	if ((GET_CLASS(ch) == CLASS_BARD) &&
	    (spell_info[spl].min_level_bard > GET_LEVEL(ch))) {
	  send_to_char("Sorry, you can't do that.\n\r", ch);
	  return;
	}
	if ((GET_CLASS(ch) == CLASS_KAI) &&
	    (spell_info[spl].min_level_kai > GET_LEVEL(ch))) {
	  send_to_char("Sorry, you can't do that.\n\r", ch);
	  return;
	}
	if ((GET_CLASS(ch) == CLASS_DRAKKHAR) &&
	    (spell_info[spl].min_level_drakkhar > GET_LEVEL(ch))) {
	  send_to_char("Sorry, you can't do that.\n\r", ch);
	  return;
	}
	if ((GET_CLASS(ch) == CLASS_DKNIGHT) &&
	    (spell_info[spl].min_level_dknight > GET_LEVEL(ch))) {
	  send_to_char("Sorry, you can't do that.\n\r", ch);
	  return;
	}
	if ((GET_CLASS(ch) == CLASS_EKNIGHT) &&
	    (spell_info[spl].min_level_eknight > GET_LEVEL(ch))) {
	  send_to_char("Sorry, you can't do that.\n\r", ch);
	  return;
	}
      }

      argument+=qend+1; /* Point to the last ' */
      for(;*argument == ' '; argument++);

      /* **************** Locate targets **************** */

      target_ok = FALSE;
      tar_char = 0;
      tar_obj = 0;
      
      if (!IS_SET(spell_info[spl].targets, TAR_IGNORE)) {
	argument = one_argument(argument, name);
	if (*name) {
	  if (IS_SET(spell_info[spl].targets, TAR_CHAR_ROOM))
	    if ((tar_char = get_char_room_vis(ch, name)))
	      target_ok = TRUE;

	  if (!target_ok && IS_SET(spell_info[spl].targets, TAR_CHAR_WORLD))
	    if ((tar_char = get_char_vis(ch, name)))
	      target_ok = TRUE;

	  if (!target_ok && IS_SET(spell_info[spl].targets, TAR_OBJ_INV))
	    if ((tar_obj = get_obj_in_list_vis(ch, name, ch->carrying)))
	      target_ok = TRUE;

	  if (!target_ok && IS_SET(spell_info[spl].targets, TAR_OBJ_ROOM))
	    if ((tar_obj = get_obj_in_list_vis(ch, name, world[ch->in_room].contents)))
	      target_ok = TRUE;

	  if (!target_ok && IS_SET(spell_info[spl].targets, TAR_OBJ_WORLD))
	    if ((tar_obj = get_obj_vis(ch, name)))
	      target_ok = TRUE;

	  if (!target_ok && IS_SET(spell_info[spl].targets, TAR_OBJ_EQUIP)) {
	    for(i=0; i<MAX_WEAR && !target_ok; i++)
	      if (ch->equipment[i] 
		  && str_cmp(name, ch->equipment[i]->name) == 0) {
		tar_obj = ch->equipment[i];
		target_ok = TRUE;
	      }
	  }

	  if (!target_ok && IS_SET(spell_info[spl].targets, TAR_SELF_ONLY))
	    if (str_cmp(GET_NAME(ch), name) == 0) {
	      tar_char = ch;
	      target_ok = TRUE;
	    }
	} else { /* No argument was typed */
	  if (IS_SET(spell_info[spl].targets, TAR_FIGHT_SELF))
	    if (ch->specials.fighting) {
	      tar_char = ch;
	      target_ok = TRUE;
	    }
	  if (!target_ok && IS_SET(spell_info[spl].targets, TAR_FIGHT_VICT))
	    if (ch->specials.fighting) {
	      /* WARNING, MAKE INTO POINTER */
	      tar_char = ch->specials.fighting;
	      target_ok = TRUE;
	    }
	  if (!target_ok && IS_SET(spell_info[spl].targets, TAR_SELF_ONLY)) {
	    tar_char = ch;
	    target_ok = TRUE;
	  }
	}
      } else {
	target_ok = TRUE; /* No target, is a good target */
      }

      if (!target_ok) {
	if (*name) {
	  if (IS_SET(spell_info[spl].targets, TAR_CHAR_ROOM))
	    send_to_char("Nobody here by that name.\n\r", ch);
	  else if (IS_SET(spell_info[spl].targets, TAR_CHAR_WORLD))
	    send_to_char("Nobody playing by that name.\n\r", ch);
	  else if (IS_SET(spell_info[spl].targets, TAR_OBJ_INV))
	    send_to_char("You are not carrying anything like that.\n\r", ch);
	  else if (IS_SET(spell_info[spl].targets, TAR_OBJ_ROOM))
	    send_to_char("Nothing here by that name.\n\r", ch);
	  else if (IS_SET(spell_info[spl].targets, TAR_OBJ_WORLD))
	    send_to_char("Nothing at all by that name.\n\r", ch);
	  else if (IS_SET(spell_info[spl].targets, TAR_OBJ_EQUIP))
	    send_to_char("You are not wearing anything like that.\n\r", ch);
	  else if (IS_SET(spell_info[spl].targets, TAR_OBJ_WORLD))
	    send_to_char("Nothing at all by that name.\n\r", ch);
	} else { /* Nothing was given as argument */
	  if (spell_info[spl].targets < TAR_OBJ_INV)
	    send_to_char("Who should the spell be cast upon?\n\r", ch);
	  else
	    send_to_char("What should the spell be cast upon?\n\r", ch);
	}
	return;
      } else { /* TARGET IS OK */
	if ((tar_char==ch) && IS_SET(spell_info[spl].targets, TAR_SELF_NONO)) {
	  send_to_char("You cannot cast this spell upon yourself.\n\r", ch);
	  return;
	} else if ((tar_char != ch) 
		   && IS_SET(spell_info[spl].targets, TAR_SELF_ONLY)) {
	  send_to_char("You can only cast this spell upon yourself.\n\r", ch);
	  return;
	} else if (IS_AFFECTED(ch, AFF_CHARM) && (ch->master == tar_char)) {
	  send_to_char("You are afraid that it could harm your master.\n\r", ch);
	  return;
	}
      }

      if (GET_LEVEL(ch) < IMO_LEV3) {
	if (GET_MANA(ch) < USE_MANA(ch, spl)) {
	  send_to_char("You can't summon enough energy to cast the spell.\n\r", ch);
	  return;
	}
      }

      if (spl != SPELL_VENTRILOQUATE)  /* :-) */
	say_spell(ch, spl);

      /* synchronise spells with fighting */
      WAIT_STATE(ch, spell_info[spl].beats);
      
      if ((spell_info[spl].spell_pointer == 0) && spl>0)
	send_to_char("Sorry, this magic has not yet been implemented :(\n\r", ch);
      else {
	if (GET_LEVEL(ch) >= IMO_LEV3) {
	  ((*spell_info[spl].spell_pointer) 
	   (GET_LEVEL(ch), ch, argument, SPELL_TYPE_SPELL, tar_char, tar_obj));
	  return;
	}
	if (number(1,101) > ch->skills[spl].learned) { 
	  /* 101% is failure */
	  ansi_act("You lost your concentration!",FALSE,ch,0,0,TO_CHAR,WHITE);
	  GET_MANA(ch) -= (USE_MANA(ch, spl)>>1);
	  return;
	}
	GET_MANA(ch) -= (USE_MANA(ch, spl));
	sprintf(buf, "You use %d mana to cast the spell.", USE_MANA(ch, spl));
	ansi_act(buf, FALSE, ch, 0, 0, TO_CHAR,WHITE);
	((*spell_info[spl].spell_pointer) (GET_LEVEL(ch), ch, argument, SPELL_TYPE_SPELL, tar_char, tar_obj));
      }
    }  /* if GET_POS < min_pos */
    return;
  }

  switch (number(1,5)){
  case 1: send_to_char("Bylle Grylle Grop Gryf???\n\r", ch); break;
  case 2: send_to_char("Olle Bolle Snop Snyf?\n\r",ch); break;
  case 3: send_to_char("Olle Grylle Bolle Bylle?!?\n\r",ch); break;
  case 4: send_to_char("Gryffe Olle Gnyffe Snop???\n\r",ch); break;
  default: send_to_char("Bolle Snylle Gryf Bylle?!!?\n\r",ch); break;
  }
}


void assign_spell_pointers(void)
{
   int i;

   for(i=0; i<MAX_SPL_LIST; i++)
      spell_info[i].spell_pointer = 0;

   /* From spells1.c */
   /* Offensive spells */

   SPELLO(32,12,POSITION_FIGHTING, 1, IMO_LEV, 15, 
	  TAR_CHAR_ROOM | TAR_FIGHT_VICT,2,IMO_LEV,IMO_LEV,2,IMO_LEV,
	  cast_magic_missile);

   SPELLO( 8,12,POSITION_FIGHTING, 4, IMO_LEV, 15,
	  TAR_CHAR_ROOM | TAR_FIGHT_VICT,10,IMO_LEV,IMO_LEV,6,IMO_LEV,
	  cast_chill_touch);

   SPELLO( 5,12,POSITION_FIGHTING, 7, IMO_LEV, 15,
	  TAR_CHAR_ROOM | TAR_FIGHT_VICT,16,IMO_LEV,IMO_LEV,10,IMO_LEV,
	  cast_burning_hands);

   SPELLO(37,12,POSITION_FIGHTING, 10, IMO_LEV, 15,
	  TAR_CHAR_ROOM | TAR_FIGHT_VICT,18,IMO_LEV,IMO_LEV,14,IMO_LEV,
	  cast_shocking_grasp);

   SPELLO(30,12,POSITION_FIGHTING, 13, IMO_LEV, 15,
	  TAR_CHAR_ROOM | TAR_FIGHT_VICT,23,IMO_LEV,IMO_LEV,18,IMO_LEV,
	  cast_lightning_bolt);

   SPELLO(10,12,POSITION_FIGHTING, 16,IMO_LEV, 15,
	  TAR_CHAR_ROOM | TAR_FIGHT_VICT,27,IMO_LEV,IMO_LEV,22,IMO_LEV,
	  cast_colour_spray);

   SPELLO(25,12,POSITION_FIGHTING, 15,IMO_LEV, 35,
	  TAR_CHAR_ROOM | TAR_FIGHT_VICT,25,IMO_LEV,IMO_LEV,20,IMO_LEV,
	  cast_energy_drain);

   SPELLO(26,12,POSITION_FIGHTING, 19,IMO_LEV, 15,
	  TAR_CHAR_ROOM | TAR_FIGHT_VICT,35,IMO_LEV,IMO_LEV,26,IMO_LEV,
	  cast_fireball);

   SPELLO(23,12,POSITION_FIGHTING, IMO_LEV, 7, 10,
	  TAR_IGNORE,IMO_LEV,IMO_LEV,IMO_LEV,8,IMO_LEV,cast_earthquake);

   SPELLO(22,12,POSITION_FIGHTING, IMO_LEV, 10, 15,
	  TAR_CHAR_ROOM | TAR_FIGHT_VICT,IMO_LEV,15,IMO_LEV,IMO_LEV,IMO_LEV,
	  cast_dispel_evil);

   SPELLO( 6,12,POSITION_FIGHTING, IMO_LEV, 12, 15,
	  TAR_CHAR_ROOM | TAR_FIGHT_VICT,IMO_LEV,IMO_LEV,13,IMO_LEV,IMO_LEV,
	  cast_call_lightning);

   SPELLO(27,12,POSITION_FIGHTING, IMO_LEV, 15, 25,
	  TAR_CHAR_ROOM | TAR_FIGHT_VICT,IMO_LEV,IMO_LEV,19,IMO_LEV,IMO_LEV,
	  cast_harm);

   SPELLO(SPELL_CONFLAGRATION, 12,POSITION_FIGHTING, 25, IMO_LEV, 15,
	  TAR_CHAR_ROOM | TAR_FIGHT_VICT,IMP_LEV,IMP_LEV,30,IMP_LEV,IMP_LEV,
	  cast_conflagration);

   /* Spells2.c */

   SPELLO( 1,12,POSITION_STANDING, 5,  1, 5, 
	  TAR_CHAR_ROOM,6,5,5,IMO_LEV,6,cast_armor);

   SPELLO( 2,12,POSITION_FIGHTING, 8, IMO_LEV, 35,
	  TAR_SELF_ONLY,13,IMO_LEV,IMO_LEV,IMO_LEV,13,cast_teleport);

   SPELLO( 3,12,POSITION_STANDING,IMO_LEV,  5, 5,
	  TAR_OBJ_INV | TAR_OBJ_EQUIP | TAR_CHAR_ROOM,IMO_LEV,8,IMO_LEV,
	  IMO_LEV,IMO_LEV,cast_bless);

   SPELLO( 4,12,POSITION_STANDING, 8,  6, 5,
	  TAR_CHAR_ROOM,15,IMO_LEV,7,8,IMO_LEV,cast_blindness);

   SPELLO(7,12,POSITION_STANDING, 14, IMO_LEV, 5,
	  TAR_CHAR_ROOM | TAR_SELF_NONO,22,IMO_LEV,IMO_LEV,IMO_LEV,19,
	  cast_charm_person);

   SPELLO( 9,12,POSITION_STANDING,11, IMO_LEV, 20,
	  TAR_CHAR_ROOM,17,IMO_LEV,IMO_LEV,IMO_LEV,15,cast_improved_invis);

   SPELLO(11,12,POSITION_STANDING,10, 13, 25,
	  TAR_IGNORE,IMO_LEV,IMO_LEV,15,IMO_LEV,IMO_LEV,cast_control_weather);

   SPELLO(12,12,POSITION_STANDING,IMO_LEV,  3, 5,
	  TAR_IGNORE,IMO_LEV,IMO_LEV,IMO_LEV,IMO_LEV,IMO_LEV,cast_create_food);

   SPELLO(13,12,POSITION_STANDING,IMO_LEV,  2, 5,
	  TAR_OBJ_INV | TAR_OBJ_EQUIP,IMO_LEV,IMO_LEV,IMO_LEV,IMO_LEV,IMO_LEV,
	  cast_create_water);

   SPELLO(14,12,POSITION_STANDING,IMO_LEV,  4, 5,
	  TAR_CHAR_ROOM,IMO_LEV,7,IMO_LEV,IMO_LEV,IMO_LEV,cast_cure_blind);

   SPELLO(15,12,POSITION_FIGHTING,IMO_LEV,  9, 15,
	  TAR_CHAR_ROOM,IMO_LEV,9,IMO_LEV,IMO_LEV,IMO_LEV,cast_cure_critic);

   SPELLO(16,12,POSITION_FIGHTING,IMO_LEV,  1, 10,
	  TAR_CHAR_ROOM,IMO_LEV,1,IMO_LEV,IMO_LEV,IMO_LEV,cast_cure_light);

   SPELLO(17,12,POSITION_STANDING,12, 14, 20,
	  TAR_CHAR_ROOM | TAR_OBJ_ROOM | TAR_OBJ_INV | TAR_OBJ_EQUIP,20,
	  IMO_LEV,21,12,IMO_LEV,cast_curse);

   SPELLO(18,12,POSITION_STANDING,IMO_LEV,  4, 5,
	  TAR_CHAR_ROOM | TAR_SELF_ONLY,IMO_LEV,4,4,IMO_LEV,IMO_LEV,
	  cast_detect_evil);

   SPELLO(19,12,POSITION_STANDING, 2,  5, 5,
	  TAR_CHAR_ROOM | TAR_SELF_ONLY,4,6,6,IMO_LEV,4,
	  cast_detect_invisibility);

   SPELLO(20,12,POSITION_STANDING, 2,  3, 5,
	  TAR_CHAR_ROOM | TAR_SELF_ONLY,3,3,3,IMO_LEV,3,cast_detect_magic);

   SPELLO(21,12,POSITION_STANDING,IMO_LEV,  2, 5,
	  TAR_CHAR_ROOM | TAR_OBJ_INV | TAR_OBJ_EQUIP,IMO_LEV,2,2,IMO_LEV,
	  IMO_LEV,cast_detect_poison);

   SPELLO(24,12,POSITION_STANDING,12, IMO_LEV, 100,
	  TAR_OBJ_INV | TAR_OBJ_EQUIP,19,IMO_LEV,IMO_LEV,IMO_LEV,17,
	  cast_enchant_weapon);

   SPELLO(28,12,POSITION_FIGHTING,IMO_LEV, 14, 25,
	  TAR_CHAR_ROOM,IMO_LEV,19,IMO_LEV,IMO_LEV,IMO_LEV,cast_heal);

   SPELLO(29,12,POSITION_STANDING, 4, IMO_LEV, 5,
	  TAR_CHAR_ROOM | TAR_OBJ_INV | TAR_OBJ_ROOM | TAR_OBJ_EQUIP,7,IMO_LEV,
	  IMO_LEV,IMO_LEV,7,cast_invisibility);

   SPELLO(31,12,POSITION_STANDING, 6, IMO_LEV, 20,
	  TAR_OBJ_WORLD,9,IMO_LEV,17,IMO_LEV,9,cast_locate_object);

   SPELLO(33,12,POSITION_STANDING,IMO_LEV,  8, 10,
	  TAR_CHAR_ROOM | TAR_SELF_NONO | TAR_OBJ_INV | TAR_OBJ_EQUIP,IMO_LEV,
	  IMO_LEV,10,IMO_LEV,IMO_LEV,cast_poison);

   SPELLO(34,12,POSITION_STANDING,IMO_LEV,  6, 5,
	  TAR_CHAR_ROOM | TAR_SELF_ONLY,IMO_LEV,12,IMO_LEV,IMO_LEV,IMO_LEV,
	  cast_protection_from_evil);

   SPELLO(35,12,POSITION_STANDING,IMO_LEV, 12, 5,
	  TAR_CHAR_ROOM | TAR_OBJ_INV | TAR_OBJ_EQUIP | TAR_OBJ_ROOM,IMO_LEV,
	  17,IMO_LEV,IMO_LEV,IMO_LEV,cast_remove_curse);

   SPELLO(36,12,POSITION_STANDING,IMO_LEV, 13, 75,
	  TAR_CHAR_ROOM,IMO_LEV,25,25,IMO_LEV,IMO_LEV,cast_sanctuary);

   SPELLO(38,12,POSITION_STANDING,14, IMO_LEV, 20,
	  TAR_CHAR_ROOM,IMO_LEV,24,IMO_LEV,16,IMO_LEV,cast_sleep);

   SPELLO(39,12,POSITION_STANDING, 7, IMO_LEV, 20,
	  TAR_CHAR_ROOM,12,IMO_LEV,IMO_LEV,IMO_LEV,16,cast_strength);

   SPELLO(40,12,POSITION_STANDING,IMO_LEV,  8, 50,
	  TAR_CHAR_WORLD,IMO_LEV,IMO_LEV,12,IMO_LEV,IMO_LEV,cast_summon);

   SPELLO(41,12,POSITION_STANDING, 1, IMO_LEV, 5,
	  TAR_CHAR_ROOM | TAR_OBJ_ROOM | TAR_SELF_NONO,1,IMO_LEV,IMO_LEV,
	  IMO_LEV,2,cast_ventriloquate);

   SPELLO(42,12,POSITION_STANDING,IMO_LEV, 11, 5,
	  TAR_CHAR_ROOM | TAR_SELF_ONLY,IMO_LEV,IMO_LEV,IMO_LEV,IMO_LEV,
	  IMO_LEV,cast_word_of_recall);

   SPELLO(43,12,POSITION_STANDING,IMO_LEV,  9, 5,
	  TAR_CHAR_ROOM | TAR_OBJ_INV | TAR_OBJ_ROOM,IMO_LEV,10,IMO_LEV,
	  IMO_LEV,IMO_LEV,cast_remove_poison);

   SPELLO(44,12,POSITION_STANDING,IMO_LEV,  7, 5,
	  TAR_CHAR_ROOM | TAR_SELF_ONLY,IMO_LEV,13,IMO_LEV,IMO_LEV,IMO_LEV,
	  cast_sense_life);

   SPELLO(45,0,POSITION_STANDING,MAX_LEV,MAX_LEV,200, TAR_IGNORE,MAX_LEV,
	  MAX_LEV,MAX_LEV,MAX_LEV,MAX_LEV, 0);
   SPELLO(46,0,POSITION_STANDING,MAX_LEV,MAX_LEV,200, TAR_IGNORE,MAX_LEV,
	  MAX_LEV,MAX_LEV,MAX_LEV,MAX_LEV, 0);
   SPELLO(47,0,POSITION_STANDING,MAX_LEV,MAX_LEV,200, TAR_IGNORE,MAX_LEV,
	  MAX_LEV,MAX_LEV,MAX_LEV,MAX_LEV, 0);
   SPELLO(48,0,POSITION_STANDING,MAX_LEV,MAX_LEV,200, TAR_IGNORE,MAX_LEV,
	  MAX_LEV,MAX_LEV,MAX_LEV,MAX_LEV, 0);
   SPELLO(49,0,POSITION_STANDING,MAX_LEV,MAX_LEV,200, TAR_IGNORE,MAX_LEV,
	  MAX_LEV,MAX_LEV,MAX_LEV,MAX_LEV, 0);
   SPELLO(50,0,POSITION_STANDING,MAX_LEV,MAX_LEV,200, TAR_IGNORE,MAX_LEV,
	  MAX_LEV,MAX_LEV,MAX_LEV,MAX_LEV, 0);
   SPELLO(51,0,POSITION_STANDING,MAX_LEV,MAX_LEV,200, TAR_IGNORE,MAX_LEV,
	  MAX_LEV,MAX_LEV,MAX_LEV,MAX_LEV, 0);
   SPELLO(52,0,POSITION_STANDING,MAX_LEV,MAX_LEV,200, TAR_IGNORE,MAX_LEV,
	  MAX_LEV,MAX_LEV,MAX_LEV,MAX_LEV, 0);
 
   SPELLO(53,1,POSITION_STANDING,25,25, 100, TAR_OBJ_INV | TAR_OBJ_ROOM,
	  29,IMO_LEV,IMO_LEV,IMO_LEV,30,cast_identify);
   SPELLO(54,1,POSITION_FIGHTING,IMO_LEV,9, 15, TAR_CHAR_ROOM,
	  IMO_LEV,IMO_LEV,9,IMO_LEV,IMO_LEV,cast_cause_critic);
   SPELLO(55,1,POSITION_FIGHTING,IMO_LEV,1, 10, TAR_CHAR_ROOM,
	  IMO_LEV,IMO_LEV,1,IMO_LEV,IMO_LEV,cast_cause_light);

   SPELLO(56,0,POSITION_STANDING,MAX_LEV,MAX_LEV,200, TAR_IGNORE,MAX_LEV,
	  MAX_LEV,MAX_LEV,MAX_LEV,MAX_LEV, 0);
   SPELLO(57,0,POSITION_STANDING,MAX_LEV,MAX_LEV,200, TAR_IGNORE,MAX_LEV,
	  MAX_LEV,MAX_LEV,MAX_LEV,MAX_LEV, 0);
   SPELLO(58,0,POSITION_STANDING,MAX_LEV,MAX_LEV,200, TAR_IGNORE,MAX_LEV,
	  MAX_LEV,MAX_LEV,MAX_LEV,MAX_LEV, 0);
   SPELLO(59,0,POSITION_STANDING,MAX_LEV,MAX_LEV,200, TAR_IGNORE,MAX_LEV,
	  MAX_LEV,MAX_LEV,MAX_LEV,MAX_LEV, 0);
   SPELLO(60,0,POSITION_STANDING,MAX_LEV,MAX_LEV,200, TAR_IGNORE,MAX_LEV,
	  MAX_LEV,MAX_LEV,MAX_LEV,MAX_LEV, 0);
   SPELLO(61,0,POSITION_STANDING,MAX_LEV,MAX_LEV,200, TAR_IGNORE,MAX_LEV,
	  MAX_LEV,MAX_LEV,MAX_LEV,MAX_LEV, 0);
   SPELLO(62,0,POSITION_STANDING,MAX_LEV,MAX_LEV,200, TAR_IGNORE,MAX_LEV,
	  MAX_LEV,MAX_LEV,MAX_LEV,MAX_LEV, 0);
   SPELLO(63,0,POSITION_STANDING,MAX_LEV,MAX_LEV,200, TAR_IGNORE,MAX_LEV,
	  MAX_LEV,MAX_LEV,MAX_LEV,MAX_LEV, 0);
   SPELLO(64,0,POSITION_STANDING,MAX_LEV,MAX_LEV,200, TAR_IGNORE,MAX_LEV,
	  MAX_LEV,MAX_LEV,MAX_LEV,MAX_LEV, 0);
   SPELLO(65,0,POSITION_STANDING,MAX_LEV,MAX_LEV,200, TAR_IGNORE,MAX_LEV,
	  MAX_LEV,MAX_LEV,MAX_LEV,MAX_LEV, 0);
   SPELLO(66,0,POSITION_STANDING,MAX_LEV,MAX_LEV,200, TAR_IGNORE,MAX_LEV,
	  MAX_LEV,MAX_LEV,MAX_LEV,MAX_LEV, 0);
   SPELLO(67,0,POSITION_STANDING,MAX_LEV,MAX_LEV,200, TAR_IGNORE,MAX_LEV,
	  MAX_LEV,MAX_LEV,MAX_LEV,MAX_LEV, 0);

   SPELLO(SPELL_DARKSIGHT,3,POSITION_FIGHTING, 30, 20, 15, TAR_CHAR_ROOM,
	  39,IMO_LEV,IMO_LEV,IMO_LEV,IMO_LEV,cast_darksight);

   SPELLO(69,0,POSITION_STANDING,MAX_LEV,MAX_LEV,200, TAR_IGNORE,MAX_LEV,
	  MAX_LEV,MAX_LEV,MAX_LEV,MAX_LEV, 0);
   SPELLO(70,0,POSITION_STANDING,MAX_LEV,MAX_LEV,200, TAR_IGNORE,MAX_LEV,
	  MAX_LEV,MAX_LEV,MAX_LEV,MAX_LEV, 0);
   SPELLO(71,0,POSITION_STANDING,MAX_LEV,MAX_LEV,200, TAR_IGNORE,MAX_LEV,
	  MAX_LEV,MAX_LEV,MAX_LEV,MAX_LEV, 0);

   SPELLO(SPELL_RESTORATION,3,POSITION_FIGHTING, IMO_LEV, 27, 25, 
	  TAR_CHAR_ROOM,IMO_LEV,IMO_LEV,IMO_LEV,IMO_LEV,IMO_LEV,
	  cast_restoration);
   SPELLO(SPELL_REGENERATION,3,POSITION_FIGHTING, IMO_LEV, 27, 25, 
	  TAR_CHAR_ROOM, IMO_LEV,IMO_LEV,IMO_LEV,IMO_LEV,IMO_LEV,
	  cast_regeneration);
   SPELLO(SPELL_TURN_UNDEAD,3,POSITION_FIGHTING, IMO_LEV, 1, 10, 
	  TAR_CHAR_ROOM | TAR_FIGHT_VICT, IMO_LEV, 5, 5,IMO_LEV,IMO_LEV,
	  cast_turn_undead);
   SPELLO(SPELL_SUCCOR,3,POSITION_FIGHTING, 27,IMO_LEV, 50, 
	  TAR_CHAR_WORLD, 37,IMO_LEV,IMO_LEV,IMO_LEV,IMO_LEV,cast_succor);
   SPELLO(SPELL_DONATE_MANA,3,POSITION_FIGHTING, IMO_LEV, 29, 15, 
	  TAR_CHAR_ROOM, IMO_LEV,IMO_LEV,IMO_LEV,IMO_LEV,IMO_LEV,
	  cast_donate_mana);
   SPELLO(SPELL_MAGIC_RESIST,3,POSITION_FIGHTING, 29, 29, 50, TAR_CHAR_ROOM,
	  IMO_LEV,IMO_LEV,IMO_LEV,IMO_LEV,IMO_LEV,cast_magic_resist);
   SPELLO(SPELL_MAGIC_IMMUNE,3,POSITION_FIGHTING, 29, 35, 100, TAR_CHAR_ROOM,
	  IMO_LEV,IMO_LEV,IMO_LEV,IMO_LEV,IMO_LEV,cast_magic_immune);
   SPELLO(SPELL_BREATHWATER,3,POSITION_FIGHTING, 32,22, 15, TAR_CHAR_ROOM,
	  38,IMO_LEV,IMO_LEV,IMO_LEV,IMO_LEV,cast_breathwater);
   SPELLO(SPELL_SUSTENANCE,3,POSITION_FIGHTING, IMO_LEV, 33, 25, TAR_CHAR_ROOM,
	  IMO_LEV,IMO_LEV,IMO_LEV,IMO_LEV,IMO_LEV,cast_sustenance);
}