/*

filename    spells
password    release
changedby   Darg
EmailAdd    Mark Pringle darg@valhalla.com
request     compile
version     2
END HEADER*/

#include

#define RIFT_RISK 100

%zone spells
reset RESET_NOT
weather 1040
creators {"whistler"}

notes "This is the spells zone. Dont let any rooms point to this zone, or use
any objects from this zone without special permission. Do not slime objects from
this zone."

%dil


dilbegin bob_code();
var
 arg:string;
 pc:unitptr;
 pars:string;
 item:unitptr;
 ex_ptr:extraptr;
 splstr:string;
 splno:integer;
code
{
heartbeat:=PULSE_SEC*4;
if (self.value[2]!=1) quit;
interrupt (SFB_PRE,((command ("cast")) and
(target==self)),bl_animate);

:start:
unsecure(pc);
unsecure(item);
interrupt (SFB_CMD, command("get") or command("take"), get_shit);

wait (SFB_CMD, command("get") or command("take"));
:get_shit:
pc:=activator;
secure (pc,start);

arg:=argument;

pars:=getword(argument);
while ((pars!="") and (pars!="from"))
 {
 pars:=getword (argument);
 }

if (pars=="") goto start;

item:=findunit (pc,argument, FIND_UNIT_SURRO,null);
if ( item ==null)
 goto start;
secure (item,start);

if (item!=self) goto start;

if ((pc.type==UNIT_ST_NPC) and
(pc.master))
{
block;
goto start;
}

if ((("a statue of "+pc.name) == item.title)) goto start;

if (not(isset(pc.pcflags, PC_PK_RELAXED)))
{
block;
act ("You can't loot other player statues without first signing the book.",
A_ALWAYS,pc,null,null,TO_CHAR);
goto start;
}

ex_ptr:="$BOB" in self.extra;
if (ex_ptr!=null) goto start;

:bob_block:
block;

act ("You can't loot that.", A_ALWAYS,pc,null,null,TO_CHAR);
goto start;

:bl_animate:
if (self!=target) goto start;
splstr:= getword(argument);
splno:= atoi(splstr);
if (splno==81)
{
power:=-1;
 block;
 act ("Making a Zombie from a fellow player is forbidden.",
 A_ALWAYS,activator,null,null,TO_CHAR);
 goto start;
 }
}
dilend

dilbegin mana_boost(medi:unitptr, tgt : unitptr, arg : string,
                       hm : integer, effect : string);
external
  add_mana@spells(u : unitptr, i : integer);
  integer hit_limit@spells(i : integer);

var
 mboost : integer;

code
{
if ((tgt==self) and (medi.type!=UNIT_ST_OBJ))
{
act ("Your magical essence circles your body and returns into you.",
A_ALWAYS,self,null,null,TO_CHAR);
act ("$1n's Magical essence circles $1s body and then returns into $1m.",
A_SOMEONE,self,null,null,TO_REST);
self.mana:=self.mana+100;
quit;
}
  if ((not RACE_IS_HUMANOID(tgt.race)) and (not RACE_IS_MAMMAL(tgt.race)))
    hm := -1;

       if (hm < 0)
  {
     act("Nothing happens.", A_ALWAYS, self, null, null, TO_CHAR);
     quit;
  }

  mboost := hit_limit@spells(1 + hm);
  mboost := mboost / 4;
if (mboost >100)
mboost:=100;
  add_mana@spells(tgt, mboost);
 if (self==tgt)
  {
  act("$3n appears to be filled with essence.", A_SOMEONE, self, null,
      tgt, TO_REST);
  act("You are filled with essence.", A_ALWAYS, self, null, tgt,
      TO_VICT);
   }
  else
   {
  act("$3n appears to be filled with essence.", A_SOMEONE, self, null,
      tgt, TO_CHAR);
  act("You are filled with essence.", A_ALWAYS, self, null, tgt,
      TO_VICT);
   }

  quit;
}
dilend

dilbegin add_mana(ch : unitptr, pm : integer);
code
{
  ch.mana := ch.mana + pm;
  if (ch.mana > ch.max_mana)
    ch.mana := ch.max_mana;
  return;
}
dilend


/* gate_dil */


dilbegin raise_hpp(medi:unitptr, tgt : unitptr, arg : string,
                  hm : integer, effect : string);
code
{
  if (self.spells[SPL_RAISE_HPP] <= 0)
  {
    act("You must practice first.",
        A_ALWAYS, self, null, null, TO_CHAR);
    quit;
  }

if ((isaff(tgt,ID_SPL_RAISE_HPP)) or
(hm<0))
  {
        if (tgt!=self)
          act ("The magic disapates as it is cast on $2n",
               A_ALWAYS,self,tgt,null,TO_CHAR);
        else
          act ("The magic disapates as it is cast on you.",
               A_ALWAYS,self,tgt,null,TO_CHAR);
     if (effect != "")
        effect(tgt, medi, -1);
        quit;
        }

     hm := hm/10+1;
     if (hm>10)
       hm := 10;

       addaff(tgt, ID_SPL_RAISE_HPP, 20, WAIT_SEC*30,
              ABIL_HP, hm, 0, TIF_HIT_INC, TIF_NONE, TIF_HIT_DEC,
              APF_ABILITY);

  if (effect != "")
     effect(tgt, medi, hm);

  quit;
}
dilend /* raise_hpp */

dilbegin indiv_tele(tstr : string, mast : string);
var
  targ : unitptr;

code
{
  targ := findroom(tstr);

  if (targ == null)
  {
     act("There is a disturbance in the powers of magic...",
         A_ALWAYS, self, null, null, TO_CHAR);
     quit;
  }
if (self.type==UNIT_ST_PC)
if (not(paycheck(self,targ)))
  {
     act("There is a disturbance in the powers of magic...",
         A_ALWAYS, self, null, null, TO_CHAR);
     quit;
  }

  act("$1n vanishes in a puff of blue smoke!",
      A_SOMEONE, self, null, null, TO_REST);
  act("You are surrounded by a flash of blue light!",
      A_ALWAYS, self, null, null, TO_CHAR);

     link(self, targ);

  act("$1n appears from a puff of blue smoke!",
       A_SOMEONE, self, null, null, TO_REST);

  exec("look", self);

  quit;
}
dilend /* indiv_tele */

/* Basically magic_summoned + a bit */
dilbegin undead_timer(i : integer);
var
time : integer;
dispel : stringlist;
exq : extraptr;
mast : unitptr;
code
{

interrupt(SFB_DEAD, activator == self, byebye);

heartbeat := PULSE_SEC * 15;

time := (i / 3) + 2;
while(time > 0)
{

:loop:
wait(SFB_TICK | SFB_MSG, TRUE);

if(command(CMD_AUTO_TICK))
{
 time := time - 1;
 if(time == 1)
 {
 act("$1n begins to tremble.",
 A_SOMEONE, self, null, null, TO_ROOM);
 }
}
else
{
dispel := getwords(argument);
if(dispel.[0] == "spl_dispel")
 {
 if (atoi(dispel.[1]) >= i)
  goto loop;
 }
else goto byebye;
}
   }

exq := "$undead control" in self.extra;

mast := findunit(self,exq.descr,FIND_UNIT_SURRO,null);

if(mast == null)
{
act("$1n howls furiously and vanishes.",
 A_SOMEONE, self, null, null, TO_ROOM);
while(self.inside != null)
 link(self.inside, self.outside);

destroy(self);
quit;
}
else
{
act("$1n howls and rebels against $1 master!",
 A_SOMEONE, self, null, mast, TO_NOTVICT);
act("$1n howls and rebels against you!",
 A_SOMEONE, self, null, mast, TO_VICT);

if(self.fighting)
 stop_fighting(self,null);

if(self.position != POSITION_STANDING)
 self.position := POSITION_STANDING;

exec("kill "+mast.name, self);

while(self.fighting)
 pause;
}
:byebye:
act("$1n vanishes into thin air!",
 A_SOMEONE, self, null, null, TO_ROOM);
while(self.inside)
 link(self.inside,self.outside);

destroy(self);
quit;
}
dilend





dilbegin undead_obey(i : integer);
var ext : extraptr;
targ: unitptr;
   s   : string;
   arg : string;

code
{
interrupt(SFB_MSG, TRUE, test);
priority;

:loop:
wait(SFB_CMD, command("tell"));

ext:= "$undead control" in self.extra;

if ((ext == null) or (activator.name != ext.descr))
   goto loop;

arg:= argument;
s:= getword(arg);

if (s == "horde")
   {
   block;
   if (arg == "")
       {
       act("Command the horde to do what?",
           A_ALWAYS, activator, null, null, TO_CHAR);
       goto loop;
       }

   act ("You command the horde to '"+arg+"'.",
       A_ALWAYS, activator, null, null, TO_CHAR);

   foreach (UNIT_ST_NPC, targ)
       {
       ext := "$undead control" in targ.extra;

       if (((targ.nameidx == "zombie") or (targ.nameidx == "skeleton") or
           (targ.nameidx == "skel_champ")) and (ext.descr == activator.name))
           exec(arg, targ);
       }
   goto loop;
   }

targ:= findunit(activator, argument, FIND_UNIT_SURRO, null);

if (not targ or (targ != self))
   goto loop;

block;

if (argument == "")
   {
   act("Command $3n to do what?",
       A_ALWAYS, activator, null, self, TO_CHAR);
   goto loop;
   }

act ("You command $3n to '"+argument+"'.",
   A_ALWAYS, activator, null, self, TO_CHAR);

subextra (self.extra, "$pc obey");
addextra (self.extra,{"$pc obey"},activator.name);
exec(argument, self);
goto loop;

:test:
if (getword(argument) == "spl_dispel")
 if (atoi(getword(argument)) >= i)
   goto stop;
goto loop;

:stop:
i:= dildestroy("undead_exec@spells", self);
subextra (self.extra, "$undead control");
exec("follow", self);
quit;
}
dilend

/*
dilbegin aware undead_obey(i : integer);
var
  argi : string;
  u    : unitptr;

code
{
  interrupt(SFB_MSG, TRUE, test);
  on_activation(self.master == null, stop);
  priority;

  :loop:
  wait(SFB_CMD, command("tell"));

  argi := getword(argument);

  if (activator != self.master)
    goto loop;

  if ((findunit(self.master, argi, FIND_UNIT_SURRO, null) != self) and
      (not(argi in "horde")))
    goto loop;

  if (not visible(self, self.master))
    goto loop;

block;

subextra (self.extra, "$pc obey");
addextra (self.extra,{"$pc obey"},self.master.name);
  exec(argument, self);

if (argi in "horde")
{
  foreach(UNIT_ST_NPC, u)
  {
     if (u == self)
        continue;
     if (u.outside != u.master.outside)
        continue;
     if (((u.nameidx == "zombie") or (u.nameidx == "skeleton") or
          (u.nameidx == "skel_champ")) and (u.master == self.master))
        exec(argument, u);
  }
}
goto loop;

  :test:
  if (getword(argument) == "spl_dispel")
    if (atoi(getword(argument)) >= i)
      goto stop;
  goto loop;

  :stop:
  i := dildestroy("undead_exec@spells", self);
  exec("follow", self);
  quit;
}
dilend*/

dilbegin wiz_eye(medi : unitptr, tgt : unitptr, arg : string, hm : integer,
                effect : string);

var
  item      : unitptr;
  nxt       : unitptr;
  place     : unitptr;
  i         : integer;
  end_str   : string;
  tmp_str   : string;
  str_list  : stringlist; /* Normal list, except for rooms where it is N/PCs */
  str_list2 : stringlist; /* Only used in rooms - OBJS */
  dir_list  : stringlist;

  temp_int  : integer;
  dir       : integer;
  there     : unitptr;

code
{
  if (hm < 0) goto find_failed;

  if (tgt.minv > self.level)
     {
        act("Nothing called '" + arg + "' here.",
            A_ALWAYS, self, null, null, TO_CHAR);
        goto find_failed;
     }

  dir_list := {"north","east","south","west","up","down"};

  place := tgt.outside;

  if (place.type != UNIT_ST_ROOM)
     {
        if ((place.minv > self.level)
             and ((place.type == UNIT_ST_PC) or
                  (place.type == UNIT_ST_NPC)))
           {
              act("Nothing called '" + arg + "' here.",
                  A_ALWAYS, self, null, null, TO_CHAR);
              goto find_failed;
           }
        else if (place.type == UNIT_ST_OBJ)
           {
              end_str := "An image forms in your mind of &cc" +
                         place.title + "&cw and you see:";
              act(end_str,
                  A_ALWAYS, self, null, null, TO_CHAR);
              item := place.inside;
              while( item )
              {
                 nxt := item.next;
                 if ((not(item.minv > self.level)) and
                     (not(isset (item.flags,UNIT_FL_BURIED))))
                    {
                       addstring(str_list, item.name);
                    }
                 item := nxt;
              }
              i := 0;
              while( length(str_list) > 0 )
              {
                 tmp_str := str_list.[0];
                 substring(str_list, tmp_str);
                 i := i + 1;
                 while (tmp_str in str_list)
                    {
                       i := i + 1;
                       substring(str_list, tmp_str);
                    }
                 if (i > 1)
                    {
                       end_str := "[x" + itoa(i) + "] " +
                                  tmp_str;
                       act(end_str,
                           A_ALWAYS, self, null, null, TO_CHAR);
                       i := 0;
                    }
                 else
                    {
                       end_str := tmp_str;
                       act(end_str,
                           A_ALWAYS, self, null, null, TO_CHAR);
                       i := 0;
                    }
              }
           }
        else if (place.type == UNIT_ST_PC)
           {
              end_str := "An image forms in your mind and you see &cc" +
                          place.name + "'s&cw inventory:";
              act(end_str,
                  A_ALWAYS, self, null, null, TO_CHAR);
              item := place.inside;
              while( item )
              {
                 nxt := item.next;
                 if ((not(item.minv > self.level)) and
                     (not(isset (item.flags,UNIT_FL_BURIED))))
                    {
                       addstring(str_list, item.title);
                    }
                 item := nxt;
              }
              i := 0;
              while( length(str_list) > 0 )
              {
                 tmp_str := str_list.[0];
                 substring(str_list, tmp_str);
                 i := i + 1;
                 while (tmp_str in str_list)
                    {
                       i := i + 1;
                       substring(str_list, tmp_str);
                    }
                 if (i > 1)
                    {
                       end_str := "[x" + itoa(i) + "] " +
                                  tmp_str;
                       act(end_str,
                           A_ALWAYS, self, null, null, TO_CHAR);
                       i := 0;
                    }
                 else
                    {
                       end_str := tmp_str;
                       act(end_str,
                           A_ALWAYS, self, null, null, TO_CHAR);
                       i := 0;
                    }
              }
           }
        else if (place.type == UNIT_ST_NPC) /* We use title for Mobs */
           {
              end_str := "An image forms in your mind and you see &cc" +
                         place.title + "'s&cw inventory:";
              act(end_str,
                  A_ALWAYS, self, null, null, TO_CHAR);
              item := place.inside;
              while( item )
              {
                 nxt := item.next;
                 if ((not(item.minv > self.level)) and
                     (not(isset (item.flags,UNIT_FL_BURIED))))
                    {
                       addstring(str_list, item.title);
                    }
                 item := nxt;
              }
              i := 0;
              while( length(str_list) > 0 )
              {
                 tmp_str := str_list.[0];
                 substring(str_list, tmp_str);
                 i := i + 1;
                 while (tmp_str in str_list)
                    {
                       i := i + 1;
                       substring(str_list, tmp_str);
                    }
                 if (i > 1)
                    {
                       end_str := "[x" + itoa(i) + "] " +
                                  tmp_str;
                       act(end_str,
                           A_ALWAYS, self, null, null, TO_CHAR);
                       i := 0;
                    }
                 else
                    {
                       end_str := tmp_str;
                       act(end_str,
                           A_ALWAYS, self, null, null, TO_CHAR);
                       i := 0;
                    }
              }
           }
     }
  else /* We're looking inside a room. Something a bit special for this. */
     {
        end_str := "An image forms in your mind:";
        act(end_str,
            A_ALWAYS, self, null, null, TO_CHAR);
        end_str := "&c+b" + place.title + "&cw&n" +
                   place.inside_descr;
        act(end_str,
            A_ALWAYS, self, null, null, TO_CHAR);
/*
        i := 0;
        end_str := "&c+gExits:&cw&s2";
        temp_int := 0;
        while(i < 6)
        {
           place := tgt.outside;
           there := place.exit_to[i];
           if ((there) and (not(isset (place.exit_info[i], EX_HIDDEN))))
              {
                 end_str := end_str + "&c+c" + dir_list.[i] + "&cw ";
                 temp_int := 1;
              }
              i := i + 1;
        }

        if (temp_int < 1)
           act("&c+gExits:&cw&s2&c+cNone&cw",
               A_ALWAYS, self, null, null, TO_CHAR);
        if (temp_int > 0)
           act(end_str,
               A_ALWAYS, self, null, null, TO_CHAR);
*/

        temp_int := 0;
        i := 0;
        item := place.inside;
        while( item )
        {
           nxt := item.next;
           if ((not(item.minv > self.level)) and
               (not(isset (item.flags,UNIT_FL_BURIED))))
              {
                 if (item.type == UNIT_ST_PC)
                    {
/*
                       temp_int := item.position;
                       if (temp_int == POSITION_MORTALLYW)
                       tmp_str := "&cc" + item.name + " " + item.title +
                                   "&cc is lying here, mortally wounded.&cw";
                       else if (temp_int == POSITION_INCAP)
                       tmp_str := "&cc" + item.name + " " + item.title +
                                   "&cc is lying here, incapacitated.&cw";
                       else if (temp_int == POSITION_STUNNED)
                       tmp_str := "&cc" + item.name + " " + item.title +
                                   "&cc is lying here, stunned.&cw";
                       else if (temp_int == POSITION_SLEEPING)
                       tmp_str := "&cc" + item.name + " " + item.title +
                                   "&cc is sleeping here.&cw";
                       else if (temp_int == POSITION_RESTING)
                       tmp_str := "&cc" + item.name + " " + item.title +
                                   "&cc is resting here.&cw";
                       else if (temp_int == POSITION_SITTING)
                       tmp_str := "&cc" + item.name + " " + item.title +
                                   "&cc is sitting here.&cw";
                       else if (temp_int == POSITION_FIGHTING)
                       tmp_str := "&cc" + item.name + " " + item.title +
                                  "&cc is here, fighting " +
                                  item.fighting.name + " here.&cw";
                       else*/
                       tmp_str := "&cc" + item.name + " " + item.title +
                                   "&cc is here.&cw";

                       addstring(str_list, tmp_str);
                    }
                 if (item.type == UNIT_ST_NPC)
                    {
                       tmp_str := "&cc" + item.outside_descr + "&cw";
                       addstring(str_list, tmp_str);
                    }
                 if (item.type == UNIT_ST_OBJ)
                    {
                       tmp_str := "&cw" + item.outside_descr + "&cw";
                       addstring(str_list2, tmp_str);
                    }
              }
           item := nxt;
        }
        i := 0;
        while( length(str_list2) > 0 )
        {
           tmp_str := str_list2.[length(str_list2) - 1];
           substring(str_list2, tmp_str);
           i := i + 1;
           while (tmp_str in str_list2)
              {
                 i := i + 1;
                 substring(str_list2, tmp_str);
              }
           if (i > 1)
              {
                 end_str := "[x" + itoa(i) + "] " +
                            tmp_str;
                 act(end_str,
                     A_ALWAYS, self, null, null, TO_CHAR);
                 i := 0;
              }
           else
              {
                 end_str := tmp_str;
                 act(end_str,
                     A_ALWAYS, self, null, null, TO_CHAR);
                 i := 0;
              }
        }
        while( length(str_list) > 0 )
        {
           tmp_str := str_list.[length(str_list) - 1];
           substring(str_list, tmp_str);
           i := i + 1;
           while (tmp_str in str_list)
              {
                 i := i + 1;
                 substring(str_list, tmp_str);
              }
           if (i > 1)
              {
                 end_str := "&cc[x" + itoa(i) + "] " +
                            tmp_str;
                 act(end_str,
                     A_ALWAYS, self, null, null, TO_CHAR);
                 i := 0;
              }
           else
              {
                 end_str := tmp_str;
                 act(end_str,
                     A_ALWAYS, self, null, null, TO_CHAR);
                 i := 0;
              }
        }
     }

:find_failed:
  quit;
}
dilend /* wiz_eye */


dilbegin string dirstring (dr:integer);
var
 dirlist:stringlist;
code
{
dirlist
:={"north","east","south","west","up","down","northeast","northwest",
"southeast","southwest","enter","exit","impossible","here"};
return (dirlist.[dr]);
}
dilend


dilbegin aware catchit(pk:integer);
var
pc:unitptr;
code
{
:there:
wait (SFB_PRE,(( command (CMD_AUTO_DAMAGE)) and
(self==activator)));
if (target.type!=UNIT_ST_PC) goto there;
if ((isset (target.pcflags,PC_PK_RELAXED)) and
(pk==1)) goto there;
else
{
 power:=-1;
 block;
 }
 goto there;
}
dilend


dilbegin aware undead_exec();
var
  cancast : integer;
code
{
  cancast := dilfind("combat_mag ", self);

  :loop:
  wait(SFB_CMD, activator == self);

  /* This is what the undeads cant do... */
  if (command("sneak") or command("hide") or
      command("steal") or command("recite") or command("use") or
      command ("shout") or command ("tell") or command ("pick") or
      command ("filch") or command ("pickpocket") or
      command("aid") or command("trip"))
  {
     block;
     exec("moan", self);
  }
  else if ((command("cast")) and (cancast!=1))
  {
     block;
     exec("moan", self);
  }
  goto loop;
}
dilend

dilbegin integer skillresist(aa : integer, ad : integer,
       sa : integer, sd : integer);
code
{
  return (openroll(100, 5) + aa + sa - ad - sd - 50);
}
dilend


dilbegin provoked_attack(victim : unitptr, ch : unitptr);
code
{
  if (not (victim.type & (UNIT_ST_NPC|UNIT_ST_PC)))
    return; /* FALSE */

  if (not (ch.type & (UNIT_ST_PC|UNIT_ST_NPC)))
    return; /* FALSE */

  if (victim.level >= 200)
    return; /* FALSE */

  if (ch.level >= 200)
    return; /* FALSE */

  if (not isset(ch.charflags, CHAR_SELF_DEFENCE))
  {
     if ((ch.fighting == null) and
  (not isset(victim.charflags, CHAR_LEGAL_TARGET)))
       set(victim.charflags, CHAR_SELF_DEFENCE);
  }

  /* Test for LEGAL_TARGET bit */
  if (isset(victim.charflags, CHAR_PROTECTED))
  {
      if ((not isset(victim.charflags, CHAR_LEGAL_TARGET)) and
          (not isset(ch.charflags, CHAR_SELF_DEFENCE)))
        set(ch.charflags, CHAR_LEGAL_TARGET);
  }

  if (victim.position <= POSITION_SLEEPING)
    return; /* FALSE */

  if (isset(victim.charflags, CHAR_PEACEFUL))
    return; /* FALSE */

  if (opponent(victim, ch))
    return; /* TRUE */

  set_fighting(victim, ch);

  return; /* TRUE */
}
dilend

dilbegin integer may_tele_away(u : unitptr);
code
{
  while (u)
  {
     if (u.flags & UNIT_FL_NO_TELEPORT)
       return(FALSE);
     u := u.outside;
  }

  return(TRUE);
}
dilend
dilbegin integer skill_duration(hm : integer);
code
{
  if (hm < 20)
    return (2);
  else if (hm > 150)
    return (15);
  else
    return (hm / 10);
}
dilend
dilbegin unitptr unit_room(u : unitptr);
code
{
  while (u.type != UNIT_ST_ROOM)
    u := u.outside;

  return(u);
}
dilend
dilbegin unitptr unit_char(u : unitptr);
code
{
  while ((u.type & (UNIT_ST_NPC | UNIT_ST_PC)) == 0)
    u := u.outside;

  return(u);
}
dilend



/* Copy of function from limits.c */
dilbegin integer hit_limit(i : integer);
code
{
  return (i * 3);
}
dilend


/* You can add any number of hitpoints, even negative. Excess are chopped
  off to max_hp, negative may kill because of the position_update */

dilbegin add_hitpoints(ch : unitptr, php : integer);
code
{
  ch.hp := ch.hp + php;
  if (ch.hp > ch.max_hp)
    ch.hp := ch.max_hp;
  position_update(ch);
  return;
}
dilend




/***************************************************************************
***/
dilbegin aware no_flee();
code{
    heartbeat:=PULSE_SEC*3;
    interrupt(SFB_CMD,command("flee") and (activator==self),noflee);
  :loop:
    wait(SFB_TICK,TRUE);
    if(command(CMD_AUTO_TICK))
    {
     if(not(self.fighting))
     {
      act("The yellow aura around you fades away."
          ,A_ALWAYS,self,null,null,TO_CHAR);
      act("The yellow aura around $1n fades away."
          ,A_HIDEINV,self,null,null,TO_REST);
      quit;
     }
    }
    goto loop;

  :noflee:
    block;
    act("You panic and try to flee, but some strange power holds you back.",
           A_ALWAYS,self,null,null,TO_CHAR);
    act("$1n panics but is unable to flee."
           ,A_HIDEINV,self,null,null,TO_REST);
    goto loop;
}
dilend

/***************************************************************************
***/

/* Important SPELL messages that should be intercepted by the various
  spells are:

    spl_dispel       (caused by a dispel magic)
    spl_awaken       (caused by an awakening spell)

    spl_cure_blind  
    spl_cure_disease

*/



/*
========================================================================= */
/*                       SPELL UTILITY FUNCTIONS
*/
/*
*/
/* Mainly copied onto spell targets to affect them (e.g. sleep).
*/
/*
========================================================================= */


dilbegin simulate_spell(arg : string);
var
  t : unitptr;
  p : integer;
  s : string;

code
{
  t := findunit(self, arg, FIND_UNIT_SURRO|FIND_UNIT_WORLD, null);

  if (not t)
  {
     act("No such target to fire spell on.",
  A_ALWAYS, self, null, null, TO_CHAR);
     quit;
  }

  p := atoi(getword(arg));

  s := getword(arg);

  act("You fire the spell '"+s+"' on $2n with power "+itoa(p)+
" and argument '"+arg+"'.",
      A_ALWAYS, self, t, null, TO_CHAR);

  s (self, t, arg, p);

  quit;
}
dilend



/* Send message: "spl_awaken " to remove a sleep spell.    */
/* Power is checkked against the power of the sleep spell         */

dilbegin aware recall spl_sleep(pwr : integer);
var
  i : integer;
  j : integer;
  parse : stringlist;

code
{
  interrupt(SFB_MSG, TRUE, check);
  interrupt(SFB_DEAD, activator == self, stop);

  heartbeat := PULSE_SEC * 30;
  j := 1 + pwr / 10;

  while (i < j)
  {
     if (self.position > POSITION_SLEEPING)
     {
       if (self.position != POSITION_FIGHTING)
       {
          act("You lay down and go to sleep.",
              A_ALWAYS, self, null, null, TO_CHAR);
          act("$1n lays down and goes to sleep.",
              A_HIDEINV, self, null, null, TO_REST);
          self.position := POSITION_SLEEPING;
       }
       else
       {
          act("You try to go asleep...",
              A_ALWAYS, self, null, null, TO_CHAR);
          act("$1n tries to go asleep...",
              A_HIDEINV, self, null, null, TO_REST);
       }
     }
     else
       exec("snore", self);

     :loop:
     wait(SFB_TICK | SFB_CMD, TRUE);

     if (command(CMD_AUTO_TICK))
     {
 i := i + 1;
     }
     else
     {
 if (command("wake") and (activator == self))
 {
    block;
    act("You dream about waking up.",
 A_ALWAYS, self, null, null, TO_CHAR);
 }

 goto loop;
     }
  }

  :check:
  parse := getwords(argument);
  if ((parse.[0] == "spl_awaken") or (parse.[0] == "spl_dispel"))
  {
     if (atoi(parse.[1]) >= pwr)
goto the_end;
  }
  goto loop;

  :the_end:
  act("You feel less sleepy.", A_ALWAYS, self, null, null, TO_CHAR);
  :stop:
  if (self.type ==UNIT_ST_NPC)
   {
   exec ("wake",self);
   exec ("stand",self);
   }
  quit;
}
dilend


dilbegin aware recall spl_poison(pwr : integer);
var
  i : integer;
  j : integer;
  parse : stringlist;

code
{
  if (not (self.type & (UNIT_ST_PC|UNIT_ST_NPC)))
     quit;

  interrupt(SFB_DEAD, activator == self, stop);
  interrupt(SFB_MSG, TRUE, check);

  heartbeat := PULSE_POINTS / 2;
  j := 1 + pwr / 10;

  while (i < j)
  {
     :loop:
     wait(SFB_TICK, TRUE);

     i := i + 1;

     self.hp := self.hp - j;
     self.mana := self.mana - 2*j;
     self.endurance := self.endurance - 2*j;
     if (self.hp >= -10)
         position_update(self);

     if (self.hp < -10)
     {
 act("$1n dies from the powerful poison in $1s blood.",
            A_HIDEINV, self, null, null, TO_ROOM);
        act("You die from the powerful poison burning in your veins.",
     A_HIDEINV, self, null, null, TO_CHAR);
 position_update(self);
 goto the_end;
     }

     act("$1n looks very ill.", A_HIDEINV, self, null, null, TO_ROOM);
     act("You feel poison burning in your veins.",
  A_HIDEINV, self, null, null, TO_CHAR);

     position_update(self);
  }

  goto the_end;

  :check:
  parse := getwords(argument);
  if ((parse.[0] == "spl_rem_poison") or (parse.[0] == "spl_dispel"))
  {
     if (atoi(parse.[1]) >= pwr)
goto the_end;
  }
  goto loop;


  :the_end:
  act("The burning in your veins ends.",
      A_ALWAYS, self, null, null, TO_CHAR);
  :stop:
  quit;
}
dilend

dilbegin aware recall spl_plague(pwr : integer);
external
  integer skillresist (aa : integer, ad : integer,
                            sa : integer, sd : integer);
var
 state : integer;
 i     : integer;
 j     : integer;
 u     : unitptr;
 parse : stringlist;
code
{
  interrupt(SFB_MSG, TRUE, check);
  interrupt(SFB_DEAD, activator == self, stop);

  heartbeat := PULSE_SEC * 60 * 3;

  :loop:
  if (state >= 24)
    goto the_end;
  wait(SFB_TICK, TRUE);

  state := state + 1;
  i := state + 5;
  if (i > 10) i := 10;

  on rnd(1, i) goto
    case1, case2, case3, case4, case5,
    case6, case7, case8, case9, case10;

  :case1:
  :case2:
  :case3:
  act("You feel sick.",
      A_ALWAYS, self, null, null, TO_CHAR);
  act("$1n look very pale.",
      A_HIDEINV,self,null,null,TO_ROOM);
  if (self.type == UNIT_ST_PC)
  {
     if (self.full > 0)
self.full := 0;
     if (self.thirst > 0)
self.thirst := 0;
  }
  goto loop;

  :case4:
  :case5:
  :case6:
  :case7:
  :case8:
  act("You feel painfull cramps run through your body.",
      A_ALWAYS, self, null, null, TO_CHAR);

  act("$1n lies down in cramps.",
      A_HIDEINV,self,null,null,TO_ROOM);

  if (self.endurance > 0)
    self.endurance := 0;

  self.hp := self.hp - 2;
  act("$1n contracts in painful cramps.",
      A_ALWAYS, self, null, null, TO_ROOM);
  position_update(self);
  exec("rest", self);
  goto loop;


  :case9:
  :case10:
  /* Only contaminates when coughing blood (9-10) */
  act("A painfull series of coughs causes you to cough up blood.",
      A_ALWAYS, self, null, null, TO_CHAR);
  act("$1n cougs up blood - some hits you.",
      A_HIDEINV,self,null,null,TO_ROOM);

  u := findrndunit(self, FIND_UNIT_SURRO, UNIT_ST_PC|UNIT_ST_NPC);

  if (dilfind("spl_plague@spells", u))
    goto loop;

  j :=skillresist (pwr, u.abilities[ABIL_CON], pwr, u.abilities[ABIL_CHA]);

  if (j < 0)
    goto loop;

  dilcopy("spl_plague@spells("+itoa((3*pwr)/5)+")", u);

  self.hp := self.hp - self.max_hp / 5;
  position_update(self);
  goto loop;


  :check:
  parse := getwords(argument);
  if ((parse.[0] == "spl_rem_disease") or (parse.[0] == "spl_dispel"))
  {
     if (atoi(parse.[1]) >= pwr)
goto the_end;
  }
  goto loop;


  :the_end:
  act("You feel much better.", A_ALWAYS, self, null, null, TO_CHAR);
  :stop:
  quit;
}
dilend

dilbegin aware recall spl_madness(pwr : integer);
var
  i : integer;
  j : integer;
  degree : integer;
  parse : stringlist;
  u : unitptr;
code
{
  interrupt(SFB_DEAD, activator == self, stop);
  interrupt(SFB_MSG, TRUE, check);

  heartbeat := PULSE_POINTS;
  j := 1 + pwr / 10;

  :loop:
  if (i >= 64)
    goto the_end;

  wait(SFB_TICK, TRUE);

  i := i + 1;

  if (self.position < POSITION_SLEEPING)
    goto loop;

  if (self.position == POSITION_SLEEPING)
  {
     act("You have horrible nightmares.",
  A_ALWAYS, self, null, null, TO_CHAR);
     act("$1n mumbles in $1s sleep.",
  A_SOMEONE, self, null, null, TO_ROOM);
     goto loop;
  }

  degree := 32 - i / 2;

  act("The mad look in $1n's eyes intensifies",
      A_HIDEINV, self, null, null,TO_ROOM);

  on rnd(degree, degree + 10) goto
    case0, case1, case2, case3, case4, case5, case6, case7, case8,
    case9, case10, case11, case12, case13, case14, case15, case16,
    case17, case18, case19, case20, case21, case22, case23, case24,
    case25, case26, case27, case28, case29, case30, case31, case32,
    case33, case34, case35, case36, case37, case38, case39, case40,
    case41, case42;

  :case0:
  :case1:
  :case2:
  u := findrndunit(self, FIND_UNIT_SURRO, UNIT_ST_NPC|UNIT_ST_PC);

  if (visible(self, u))
  {
     act("You sudden realise that $2n has betrayed you.",
  A_SOMEONE, self, u, null, TO_CHAR);
     act("$1n screams 'You evil thing of betrayal' "+
  "and growls at $2n.", A_SOMEONE, self, u, null, TO_ROOM);
     exec("kill "+u.name, self);
  }
  goto loop;

  :case3:
  act("You are burdened by the weight of your money.",
      A_ALWAYS, self, null, null, TO_CHAR);
  exec("drop money", self);
  goto loop;

  :case4:
  if (findunit(self, "corpse", FIND_UNIT_HERE, null))
  {
     act("You see a CORPSE! RUN AWAY!",
  A_ALWAYS, self, null, null, TO_CHAR);
     act("$1n screams 'A CORPSE! A CORPSE!'",
  A_HIDEINV, self, null, null, TO_ROOM);
     exec("n", self);
     exec("e", self);
     exec("s", self);
     exec("w", self);
     exec("u", self);
     exec("d", self);
     exec("puke", self);
  }
  goto loop;

  :case5:
  act("Certainly, you need no earthly goods...",
      A_ALWAYS, self,null,null,TO_CHAR);
  exec("remove all", self);
  exec("drop all", self);
  goto loop;

  :case6:
  act("You feel inspired, so you decide to write a poem!",
      A_ALWAYS, self, null, null, TO_CHAR);
  exec("sit", self);

  u := findunit(self, "letter", FIND_UNIT_HERE, null);
  if (not u)
    u := findunit(self, "paper", FIND_UNIT_HERE, null);

  if (u and (u.type == UNIT_ST_OBJ))
  {
     if (self.name in self.extra)
     {
 act("You despair, as you see, the other text written "+
     " on the page.", A_ALWAYS, self, null, null, TO_CHAR);
 act("You spit at the page.", A_ALWAYS, self, null, null, TO_CHAR);
 act("$1n looks desperate and spits at $2n.",
     A_HIDEINV, self,u,null,TO_ROOM);
     }
     else
     {
 act("You despair, as you can't remember anything.",
     A_ALWAYS, self, null, null, TO_CHAR);
 act("$1n looks desperately at a $2n.",
     A_HIDEINV, self,u,null,TO_ROOM);
     }
     exec("drop letter", self);
  }
  else
  {
     act("You despair, as you can't find any paper.",
  A_ALWAYS, self, null, null, TO_CHAR);
     act("$1n looks desperate.",
  A_HIDEINV, self,u,null,TO_ROOM);
     exec("cry", self);
  }
  goto loop;

  :case7:
  :case8:
  :case20:
  :case21:
  :case9:
  act("You sing 'Hare Khrisna Hare Khrisna Hare "+
      "Rama Hare Hare Hare Hare Hare'.",
      A_ALWAYS, self, null, null, TO_CHAR);

  act("$1n sing 'Hare Khrisna Hare Khrisna Hare "+
      "Rama Hare Hare Hare Hare Hare'.",
      A_HIDEINV, self, null, null, TO_ROOM);
  goto loop;

  :case10:
  :case11:
  if (findunit(self, "guard", FIND_UNIT_HERE, null))
  {
     act("You love guards... they look so masculine!",
  A_ALWAYS, self, null, null, TO_CHAR);
     exec("french guard", self);
  }
  else
  {
     act("You miss the company of your friends, the guards.",
  A_ALWAYS, self, null, null, TO_CHAR);
     exec("sniff", self);
  }
  goto loop;

  :case12:
  act("You decide that you need no equipment.",
      A_ALWAYS, self, null, null, TO_CHAR);
  exec("remove all", self);
  goto loop;

  :case13:
  :case14:
  act("You feel generous, and leave some gold for the poor.",
      A_ALWAYS, self, null, null, TO_CHAR);
  exec("drop 10 gold", self);
  goto loop;

  :case15:
  :case16:
  :case17:
  act("You are almost driven insane by the "+
      "humming tone you keep hearing.",
      A_ALWAYS, self, null, null, TO_CHAR);

  act("$1n puts $1s fingers in $1s ears and looks tormented.",
      A_HIDEINV,self,null,null,TO_ROOM);
  goto loop;

  :case18:
  :case19:
  act("You suddenly feel sick.",
      A_ALWAYS, self, null, null, TO_CHAR);
  exec("puke", self);
  goto loop;

  :case22:
  act("There is no room! You have to get out! NOW!",
      A_ALWAYS, self, null, null, TO_CHAR);
  act("$1n gets a claustrofobic look in $1s eyes.",
      A_HIDEINV,self,null,null,TO_ROOM);
  exec("flee", self);
  goto loop;

  :case23:
  act("You hear a voice commanding you north.",
      A_ALWAYS, self, null, null, TO_CHAR);
  exec("n", self);
  goto loop;

  :case24:
  act("You are urged to go south from here.",
      A_ALWAYS, self, null, null, TO_CHAR);
  exec("s", self);
  goto loop;

  :case25:
  act("You are urged to go east from here.",
      A_ALWAYS, self, null, null, TO_CHAR);
  exec("e", self);
  goto loop;

  :case26:
  act("You are urged to go west from here.",
      A_ALWAYS, self, null, null, TO_CHAR);
  exec("w", self);
  goto loop;

  :case27:
  exec("scream", self);
  goto loop;

  :case28:
  :case29:
  :case30:
  :case31:
  :case32:
  act("$1n mumbles something to $1mself.",
      A_HIDEINV,self,null,null,TO_ROOM);
  act("You talk to all the voices you hear.",
      A_ALWAYS, self, null, null, TO_CHAR);
  goto loop;

  :case33:
  act("Nobody likes you any more...",
      A_ALWAYS, self, null, null, TO_CHAR);
  exec("cry", self);
  goto loop;

  :case34:
  act("Someone is following you around!",
      A_ALWAYS, self, null, null, TO_CHAR);
  act("$1n looks paraniodly at everyone.",
      A_HIDEINV,self,null,null,TO_ROOM);
  goto loop;

  :case35:
  :case36:
  act("This is funny...",
      A_ALWAYS, self, null, null, TO_CHAR);
  act("$1n laughs like he heard something extremely funny.",
      A_SOMEONE,self,null,null,TO_ROOM);
  goto loop;

  :case37:
  :case38:
  :case39:
  act("This seems like a great spot to sit down.",
      A_ALWAYS, self, null, null, TO_CHAR);
  exec("sit", self);
  goto loop;

  :case40:
  :case41:
  :case42:
  act("You feel so happy.",
      A_ALWAYS, self, null, null, TO_CHAR);
  act("$1n smiles madly.",
      A_HIDEINV,self,null,null,TO_ROOM);
  goto loop;


  :check:
  parse := getwords(argument);
  if ((parse.[0] == "spl_rem_disease") or (parse.[0] == "spl_dispel"))
  {
     if (atoi(parse.[1]) >= pwr)
goto the_end;
  }
  goto loop;


  :the_end:
  act("The battle with your own mind is over.",
      A_ALWAYS, self, null, null, TO_CHAR);
  :stop:
  quit;
}
dilend

/* Used to determine if a summoner has summoned more than one creature */

dilbegin aware sum_check();
var
  fol : unitptr;
code
{
  heartbeat := PULSE_SEC*3;
  while(self.master==null)
  {
     pause;
  }
  interrupt(SFB_MSG,(argument=="piss_off") and (activator!=self),byebye);
  heartbeat := PULSE_SEC * 10;

  :loop:
subextra (self.extra, "$pc obey");
addextra (self.extra,{"$pc obey"},self.master.name);
  fol := self.outside.inside;
  while(fol!=null)
  {
     if (dilfind("sum_check@spells",fol))
if ((fol!=self) and (fol.master==self.master))
  sendto("piss_off",fol);
     fol := fol.next;
  }
  pause;
  goto loop;

  :byebye:
  exec("emote howls in pain as it loses his link to the real world.",self);
  exec("emote vanishes in a cloud of grey dust.",self);
  destroy(self);
  quit;
}
dilend


dilbegin recall magic_summoned(pwr : integer);
var
 d : integer;
 parse : stringlist;

code
{
  interrupt(SFB_DEAD, activator == self, vanish);

  heartbeat := PULSE_SEC * 10;
  d := pwr / 20 + 2;

  while (d > 0)
  {
     :loop:
     wait(SFB_TICK | SFB_MSG, TRUE);

     if (command(CMD_AUTO_TICK))
     {
        d := d - 1;
     }
     else
     {
 parse := getwords(argument);
 if (parse.[0] == "spl_dispel")
 {
    if (atoi(parse.[1]) >= pwr)
      goto loop;
 }
     }
  }

  :vanish:
 /* The while statement is to prevent people from destroying eq with summoned mobs */

  while(self.inside != null)
  link(self.inside, self.outside);


  act("$1n vanishes in a puff of smoke.",
      A_SOMEONE, self, null, null, TO_ROOM);

  destroy(self);
}
dilend


/* Assists the 'master' which has summoned it! */
dilbegin master_servant();
var
 d : integer;
 parse : stringlist;

code
{
  heartbeat := PULSE_VIOLENCE;

  :loop:
  wait(SFB_COM, activator == self.master);

  if (self.master.fighting == null)
    goto loop;

  if (self.fighting == null)
  {
     exec("hit " + self.master.fighting.name, self);
  }

  pause;

  while (self.master.hp <= self.master.max_hp / 3)
  {
     exec("rescue " + self.master.name, self);
     pause;
  }
  goto loop;
}
dilend

dilbegin recall base_recall(dest : string, pwr : integer,t_recall:integer);
external
integer may_tele_away (u : unitptr);
var
 u : unitptr;
 i : integer;
code
{
  interrupt(SFB_DEAD, activator == self, stop);
  interrupt(SFB_MSG,  (getword(argument) == "spl_dispel") and
                      (atoi(getword(argument)) > pwr), stop);

  heartbeat := PULSE_SEC * 10;

  act("Tiny blue sparks spring from $1n's head.",
      A_ALWAYS,self,null,null,TO_ROOM);
  act("There is a static feeling in the air.",
      A_ALWAYS,self,null,null,TO_CHAR);
  pause;
if (t_recall==0)
  act("The air begins to feel rather strange.",
      A_ALWAYS,self,null,null,TO_ROOM);
  act("The magical buildup slowly increases.",
      A_ALWAYS,self,null,null,TO_CHAR);
  pause;
if (t_recall==0)
  act("The air feels thick with magic and there are strange, "+
      "flickering lights.",
      A_ALWAYS,self,null,null,TO_ROOM);
  act("The air around you is charged with magic.",
      A_ALWAYS,self,null,null,TO_CHAR);
  pause;

  u := findsymbolic(dest);
  if (not u)
  {
     u := findsymbolic(self.hometown);
     if (not u)
     {
 u := findsymbolic("temple@udgaard");
 if (not u)
   goto stop;
     }
  }

  i := may_tele_away (self);
  if (not i)
    goto stop;

  act("$1n disappears in a cloud of blue sparks.",
      A_ALWAYS,self,null,null,TO_ROOM);

  act("You are transferred home.",
      A_ALWAYS,self,null,null,TO_CHAR);

  link(self, u);
  act("$1n appears in a cloud of blue sparks.",
      A_ALWAYS,self,null,null,TO_ROOM);

  exec("look", self);

  quit;

  :stop:
  act("The magic feeling fades away.",
      A_ALWAYS,self,null,null,TO_CHAR);
  quit;
}
dilend

dilbegin total_recall(medi:unitptr, tgt : unitptr,
                     arg : string, hm : integer, effect : string);
var
  u : unitptr;
  any : integer;
  s : string;
code
{
  any := FALSE;

  if (hm < 0)
    goto nothing;

  s := self.hometown;
  if ((s == null) or (s == ""))
    s := "temple@udgaard";

  foreach (UNIT_ST_PC|UNIT_ST_NPC, u)
  {
     if (((u == self) or (u.master == self)) and
         (not dilfind("base_recall@spells", u)))
     {
 dilcopy("base_recall@spells("+s+","+itoa(hm)+",1)", u);
 any := TRUE;
     }
  }
  if (not any)
    goto nothing;

  quit;

  :nothing:
  act("Nothing happens.", A_ALWAYS, self, null, null, TO_CHAR);
  quit;
}
dilend

dilbegin loc_want(medi:unitptr, tgt : unitptr, arg : string,
   hm : integer, effect : string);
external
 unitptr unit_room (u : unitptr);

var
 u : unitptr;

code
{

  if (hm < 0)
  {
     act("You feel confused.", A_ALWAYS, self, null, null, TO_CHAR);

     if (hm < -50)
     {
 act("You realize that $2n attempted to locate you.",
     A_ALWAYS, tgt, self, null, TO_CHAR);
     }
     quit;
  }

  u := unit_room (tgt);

  if (isset (tgt.charflags,CHAR_OUTLAW))
    act("$2n at $3t", A_SOMEONE, self, tgt, u.title, TO_CHAR);
  else
    act("$2n doesn't seem to be wanted.", A_ALWAYS, self, tgt, null,
TO_CHAR);
  quit;
}
dilend



dilbegin find_want(medi:unitptr, tgt : unitptr, arg : string,
    hm : integer, effect : string);
external
 string dirstring   (dr:integer);

var
 dir_string:string;
 i:integer;
code
{
  if (hm < 0)
  {
     act("You feel confused.", A_ALWAYS, self, null, null, TO_CHAR);
     quit;
  }

  if (not isset(tgt.charflags,CHAR_OUTLAW))
  {
     act("$2n doesn't seem to be wanted.",
  A_ALWAYS, self, tgt, null, TO_CHAR);
     quit;
  }

  i := pathto (self,tgt);
  if (i==DIR_IMPOSSIBLE)
  {
     act ("You get the feeling it is impossible from here.",
   A_ALWAYS,self,null,null,TO_CHAR);
  }
  else if (i==DIR_HERE)
  {
     act ("This is the place.",
   A_ALWAYS,self,null,null,TO_CHAR);
  }
  else if (i == DIR_ENTER)
  {
     act ("You should enter something here.",
   A_ALWAYS,self,null,null,TO_CHAR);
  }
  else if (i == DIR_EXIT)
  {
     act ("You should exit this place.",
   A_ALWAYS,self,null,null,TO_CHAR);
  }
  else
  {
     dir_string := dirstring  (i);
     act ("You should leave $2t.",
   A_ALWAYS,self,dir_string,null,TO_CHAR);
  }
  quit;
}
dilend

dilbegin find_path(medi:unitptr, tgt : unitptr, arg : string,
    hm : integer, effect : string);
external
 string dirstring   (dr:integer);

var
 dir_string:string;
 i : integer;
code
{

  if (hm < 0)
  {
     act("You feel confused.", A_ALWAYS, self, null, null, TO_CHAR);
     act ("$1n is trying to find you.",A_SOMEONE,self,null,tgt,TO_VICT);
     quit;
  }

  i := pathto (self,tgt);

  if (i==DIR_IMPOSSIBLE)
  {
     act ("You get the feeling it is impossible from here.",
   A_ALWAYS,self,null,null,TO_CHAR);
  }
  else if (i==DIR_HERE)
  {
     act ("This is the place.",
   A_ALWAYS,self,null,null,TO_CHAR);
  }
  else if (i == DIR_ENTER)
  {
     act ("You should enter something here.",
   A_ALWAYS,self,null,null,TO_CHAR);
  }
  else if (i == DIR_EXIT)
  {
     act ("You should exit this place.",
   A_ALWAYS,self,null,null,TO_CHAR);
  }
  else
  {
     dir_string := dirstring  (i);
     act ("You should leave $2t.",
   A_ALWAYS,self,dir_string,null,TO_CHAR);
  }
  quit;
}
dilend


dilbegin refit(medi:unitptr, tgt : unitptr, arg : string,
       hm : integer, effect : string);
var
  size:string;
  pc:unitptr;
code
{
  if (isset (tgt.flags,UNIT_FL_MAGIC))
  {
     act("That item is too magicly enchanted to resize.",
  A_ALWAYS, self, null, null, TO_CHAR);
     quit;
  }

  if (arg == "")
    pc := null;
  else
  {
     pc := findunit(self, arg, FIND_UNIT_SURRO, null);
     if (pc==null)
     {
        act("No such person here?",
     A_ALWAYS, self, null, null, TO_CHAR);
        quit;
     }
  }

  secure (pc,lostpc);

  if ((tgt.objecttype != ITEM_ARMOR) and
      (tgt.objecttype != ITEM_SHIELD) and
      (tgt.objecttype != ITEM_WEAPON) and
      (tgt.objecttype != ITEM_WORN))
  {
     if ((tgt.manipulate & (MANIPULATE_WEAR_FINGER | MANIPULATE_WEAR_NECK  |
       MANIPULATE_WEAR_BODY   | MANIPULATE_WEAR_HEAD  |
       MANIPULATE_WEAR_LEGS   | MANIPULATE_WEAR_FEET  |
       MANIPULATE_WEAR_HANDS  | MANIPULATE_WEAR_ARMS  |
       MANIPULATE_WEAR_SHIELD | MANIPULATE_WEAR_ABOUT |
       MANIPULATE_WEAR_WAIST  | MANIPULATE_WEAR_WRIST |
       MANIPULATE_WIELD       | MANIPULATE_WEAR_EAR   |
       MANIPULATE_WEAR_BACK   | MANIPULATE_WEAR_CHEST |
       MANIPULATE_WEAR_ANKLE)) == 0)
     {
 act ("The magic disperses on the $3N.",
      A_ALWAYS, self, null, tgt, TO_CHAR);
 quit;
     }
  }

  if ((tgt.objecttype == ITEM_ARMOR) or
      (tgt.objecttype == ITEM_SHIELD) or
      (tgt.objecttype == ITEM_WEAPON))
  {
     /* Material quality makes it harder / easier */
     hm := hm - (2*tgt.value[2]);
  }

  if ("$resized" in tgt.extra)
  {
     act("The $2N appear to quiver for a moment, "+
         "but nothing seems to happen.",
   A_ALWAYS,self,tgt,null,TO_CHAR);
     quit;
  }

  if (pc.height > tgt.height)
    hm := hm - 2*(pc.height - tgt.height);
  else
    hm := hm + 2*(pc.height - tgt.height);

  if (hm < 0)
  {
     act("Nothing happens.", A_ALWAYS, self, null, null, TO_CHAR);
     quit;
  }

  dilcopy ("refit_aff@spells("+itoa(hm)+","+itoa(pc.height)+")",tgt);
  if (pc.height>tgt.height)
    size := "enlarges"
  else
    size := "shrinks";
  act("Your $2n glows brightly as it $3t",
      A_ALWAYS, self, tgt, size, TO_CHAR);
  act("$1n's $2n glows as it $3t",
      A_ALWAYS, self, tgt, size, TO_REST);
  :lostpc:
  quit;
}
dilend

dilbegin recall refit_aff(pwr :integer,size:integer);
var
  i : integer;
  j : integer;
  oldheight:integer;
  parse : stringlist;

code
{
  addextra(self.extra, {"$resized"}, "");

  interrupt(SFB_MSG, TRUE, check);

  heartbeat := PULSE_SEC * 60;
  j:=60;
  oldheight:=self.height;
  self.height:=size;
  set (self.flags,UNIT_FL_MAGIC);
  i:=0;
  while (i < j)
  {
     :loop:
     wait(SFB_TICK , TRUE);
     i := i + 1;
  }

  :check:
  parse := getwords(argument);
  if (parse.[0] == "spl_dispel")
  {
     if (atoi(parse.[1]) >= pwr)
goto the_end;
  }
  goto loop;

  :the_end:
  subextra(self.extra, "$resized");
  if (self.equip==0)
    act ("$2n returns to its normal size.",
  A_ALWAYS, self.outside, self, null, TO_CHAR);
  else
  {
     act ("$2n returns to its normal size and falls off.",
   A_ALWAYS, self.outside, self, null, TO_CHAR);
     act ("$2n returns to its normal size and falls off $1n.",
   A_ALWAYS, self.outside, self, null, TO_CHAR);
  }
  self.height:=oldheight;
  unset (self.flags,UNIT_FL_MAGIC);
  unequip (self);

  :stop:
  quit;
}
dilend

dilbegin string quality_str(i : integer);
code
{

if(i <= -10) return("worthless");
else if(i <= 0) return("horrible");
else if(i <= 5) return("poor");
else if(i <= 10) return("good");
else if(i <= 15) return("really good");
else if(i <= 20) return("great");
else return("godly");
}
dilend

dilbegin identify_1(medi : unitptr, tgt : unitptr,
     arg : string,
     hm : integer, effect : string);
external
string quality_str(i : integer);
var
 exd : extraptr;
 craft_str : string;
 mag_str : string;
code
{
  if (hm < 0)
  {
     act("Nothing happens.", A_ALWAYS, self, null, null, TO_CHAR);
     quit;
  }

  exd := "$identify" in tgt.extra;

  if (exd)
  {
     act(exd.descr, A_ALWAYS, self, null, null, TO_CHAR);
     quit;
  }

  if (tgt.objecttype == ITEM_LIGHT)
  {
     act("$3n is lightsource with "+itoa(tgt.value[0])+" hours left, "+
            "and an illumination of "+itoa(tgt.value[1])+".",
  A_SOMEONE, self, medi, tgt, TO_CHAR);
  }
  else if (tgt.objecttype == ITEM_SCROLL)
  {
     act("$3n is a scroll with a magical power of "+itoa(tgt.value[0]),
  A_SOMEONE, self, medi, tgt, TO_CHAR);
  }
  else if (tgt.objecttype == ITEM_WAND)
  {
     act("$3n is a wand with a magical power of "+itoa(tgt.value[0])+
" and "+itoa(tgt.value[1])+" charges left.",
  A_SOMEONE, self, medi, tgt, TO_CHAR);
  }
  else if (tgt.objecttype == ITEM_STAFF)
  {
     act("$3n is a staff with power "+itoa(tgt.value[0])+
     " and "+itoa(tgt.value[1])+" charges left.",
  A_SOMEONE, self, medi, tgt, TO_CHAR);
  }
  else if (tgt.objecttype == ITEM_WEAPON)
  {
     craft_str := quality_str(tgt.value[1]);
     mag_str := quality_str(tgt.value[2]);
     act("$3n is a weapon of "+craft_str+" craftsmanship "+
" and has a "+mag_str+" magical modifier.",
  A_SOMEONE, self, medi, tgt, TO_CHAR);
  }
  else if (tgt.objecttype == ITEM_TREASURE)
  {
     act("$3n appears to be nothing less than a treasure!",
  A_SOMEONE, self, medi, tgt, TO_CHAR);
  }
  else if (tgt.objecttype == ITEM_ARMOR)
  {
     craft_str := quality_str(tgt.value[1]);
     mag_str := quality_str(tgt.value[2]);
     act("$3n is an armour with "+craft_str+" craftsmanship"+
     " and has a "+mag_str+" magical modifier.",
  A_SOMEONE, self, medi, tgt, TO_CHAR);
  }
  else if (tgt.objecttype == ITEM_POTION)
  {
     act("$3n is a potion with power "+itoa(tgt.value[0]),
  A_SOMEONE, self, medi, tgt, TO_CHAR);
  }
  else if (tgt.objecttype == ITEM_WORN)
  {
     act("$3n appears to be an item designed to be worn.",
  A_SOMEONE, self, medi, tgt, TO_CHAR);
  }
  else if (tgt.objecttype == ITEM_NOTE)
  {
     act("$3n seems to be of litterary value.",
  A_SOMEONE, self, medi, tgt, TO_CHAR);
  }
  else if (tgt.objecttype == ITEM_FOOD)
  {
     act("$3n is consumable.",
  A_SOMEONE, self, medi, tgt, TO_CHAR);
     if (tgt.value[3] > 0)
act("It is poisoned.", A_SOMEONE, self, medi, tgt, TO_CHAR);
  }
  else if (tgt.objecttype == ITEM_DRINKCON)
  {
     act("$3n is a drink container.",
  A_SOMEONE, self, medi, tgt, TO_CHAR);

     if (tgt.value[3] > 0)
act("It is poisoned.", A_SOMEONE, self, medi, tgt, TO_CHAR);
  }
  else if (tgt.objecttype == ITEM_KEY)
  {
     act("$3n is a key.",
  A_SOMEONE, self, medi, tgt, TO_CHAR);
  }
  else if (tgt.objecttype == ITEM_MONEY)
  {
     act("$3n is money.",
  A_SOMEONE, self, medi, tgt, TO_CHAR);
  }
  else if (tgt.objecttype == ITEM_PEN)
  {
     act("$3n is a pen.",
  A_SOMEONE, self, medi, tgt, TO_CHAR);
  }
  else if (tgt.objecttype == ITEM_BOAT)
  {
     act("$3n is a boat which can carry "+itoa(tgt.capacity)+" pounds.",
  A_SOMEONE, self, medi, tgt, TO_CHAR);
  }
  else if (tgt.objecttype == ITEM_SHIELD)
  {
     craft_str := quality_str(tgt.value[1]);
     mag_str := quality_str(tgt.value[2]);
     act("$3n is a shield of "+craft_str+" craftsmanship"+
  " and a "+mag_str+" magical bonus.",
  A_SOMEONE, self, medi, tgt, TO_CHAR);
  }
  else if (tgt.objecttype == ITEM_CONTAINER)
  {
     if (isaff(tgt, ID_CORPSE))
act("It is a dead body.", A_SOMEONE, self, medi, tgt, TO_CHAR);
     else
act("It is a container.", A_SOMEONE, self, medi, tgt, TO_CHAR);
  }
  else
  {
     act("You gain no additional insight into this item.",
  A_SOMEONE, self, medi, tgt, TO_CHAR);
  }

  quit;
}
dilend


dilbegin identify_2(medi : unitptr, tgt : unitptr,
     arg : string,
     hm : integer, effect : string);
var
 exd : extraptr;
 i   : integer;

code
{
  if (hm < 0)
  {
     act("Nothing happens.", A_ALWAYS, self, null, null, TO_CHAR);
     quit;
  }

  i := 0;

  exd := "$identify" in tgt.extra;

  if (exd)
  {
     act(exd.descr, A_ALWAYS, self, null, null, TO_CHAR);
     i := 1;
  }


  exd := "$improved identify" in tgt.extra;

  if (exd)
  {
     act(exd.descr, A_ALWAYS, self, null, null, TO_CHAR);
     i := 1;
  }

  if (i == 0)
    act("There is nothing exceptional to learn about this item.",
 A_ALWAYS, self, null, null, TO_CHAR);

  quit;
}
dilend

dilbegin control_undead(medi : unitptr, tgt : unitptr,
  arg : string,
  hm : integer, effect : string);
external
  provoked_attack (victim : unitptr, ch : unitptr);
var
 i : integer;
code
{
  if (not RACE_IS_UNDEAD(tgt.race)) {
 act("Nothing happens.",A_ALWAYS,self,null,tgt,TO_CHAR);
    quit;
 }

if (self.alignment>-1000)
{
self.alignment := self.alignment - 50;
if (self.alignment<-1000) self.alignment:=-1000;
}

/* poor admins can't test this spell with that equation*/
if(self.level < IMMORTAL_LEVEL)
{
if (tgt.level > self.level)
 hm := hm - (5*(tgt.level - self.level));
}

if (hm >= 0)
{
     i := dildestroy("undead_obey@spells", tgt);
     i := dildestroy("catchit@spells", tgt);
     i := dildestroy("undead_exec@spells", tgt);
     exec("follow "+self.name, tgt);
     if (tgt.master == self)
     {
 act("$3n is controlled by $1n.",
 A_HIDEINV, self, null, tgt, TO_ROOM);
 dilcopy("undead_obey@spells("+itoa(hm)+")", tgt);
 dilcopy("undead_exec@spells", tgt);
 dilcopy("undead_timer@spells("+itoa(hm)+")", tgt);
 addextra(tgt.extra,{"$undead control"},self.name);
 if (isset(self.pcflags,PC_PK_RELAXED))
 dilcopy ("catchit@spells(1)",tgt);
 else
 dilcopy ("catchit@spells(0)",tgt);
 }
}
else
 provoked_attack (tgt, self);

quit;
}
dilend

dilbegin plague(medi : unitptr, tgt : unitptr,
 arg : string,
 hm : integer, effect : string);
external
  provoked_attack (victim : unitptr, ch : unitptr);

code
{
  provoked_attack (tgt, self);

  if ((not RACE_IS_HUMANOID(tgt.race)) and (not RACE_IS_MAMMAL(tgt.race)))
    return;

  if (dilfind("spl_plague@spells", tgt) or (hm < 0))
  {
     act("Nothing happens.",
  A_ALWAYS, self, null, null, TO_CHAR);
     quit;
  }

  act("You feel very ill.", A_ALWAYS, tgt, null, null, TO_CHAR);
  dilcopy("spl_plague@spells("+itoa(hm)+")", tgt);
  quit;
}
dilend

dilbegin madness(medi : unitptr, tgt : unitptr,
  arg : string,
  hm : integer, effect : string);
external
  provoked_attack (victim : unitptr, ch : unitptr);
code
{
  provoked_attack (tgt, self);

  if ((not RACE_IS_HUMANOID(tgt.race)) and
      (not RACE_IS_MAMMAL(tgt.race)))
    quit;

  if (hm >= 0)
  {
     act("You feel a battle with your own mind begins.",
  A_ALWAYS, tgt, null, null, TO_CHAR);
     act("A mad look appears on $1n's face",
  A_HIDEINV, tgt, null, null, TO_ROOM);
     dilcopy("spl_madness@spells("+itoa(hm)+")", tgt);
  }

  quit;
}
dilend

dilbegin poison(medi : unitptr, tgt : unitptr,
 arg : string,
 hm : integer, effect : string);
external
  provoked_attack (victim : unitptr, ch : unitptr);
code
{
provoked_attack (tgt, self);

if (effect != "")
 effect(medi, tgt, hm);

if (hm >= 0)
   {
   if ((tgt.type == UNIT_ST_OBJ) and
       ((tgt.objecttype == ITEM_FOOD) or
       (tgt.objecttype == ITEM_DRINKCON)) and
       (tgt.value[3] == 0))
         tgt.value[3] := 1 + hm / 10;

   else if (tgt.type & (UNIT_ST_PC|UNIT_ST_NPC))
       dilcopy("spl_poison@spells("+itoa(hm)+")", tgt);

   else
       act ("This spell must be cast on someone or food or drinks.",
           A_ALWAYS, self, null, null, TO_CHAR);
   }

quit;
}
dilend



dilbegin remove_poison(medi : unitptr, tgt : unitptr,
        arg : string,
        hm : integer, effect : string);
code
{
  if (hm < 0)
  {
     act("Nothing happens.",
         A_ALWAYS, self, null, null, TO_CHAR);
     quit;
  }

  if (tgt.type == UNIT_ST_OBJ)
  {
     if ((tgt.objecttype == ITEM_FOOD) or
  (tgt.objecttype == ITEM_DRINKCON))
tgt.value[3] := 0;
  }
  else if (tgt.type & UNIT_ST_PC|UNIT_ST_NPC)
    sendto("spl_rem_poison "+itoa(4*hm), tgt);

  quit;
}
dilend


/* Can be cast on self while asleep! */
dilbegin remove_disease(medi : unitptr, tgt : unitptr,
  arg : string,
  hm : integer, effect : string);
code
{
  if (hm < 0)
  {
     act("Nothing happens.",
         A_ALWAYS, self, null, null, TO_CHAR);
     quit;
  }

  sendto("spl_rem_disease "+itoa(2*hm), tgt);
  quit;
}
dilend


dilbegin charge_wand(med : unitptr, targ : unitptr, arg : string,
                    hm : integer, effect : string);

var
  chance    : integer;
  ranroll   : integer;
  c         : integer;
  u         : unitptr;
code
{
  if ((targ == null) or (targ.objecttype != ITEM_WAND))
  {
     act("You don't have a wand to charge!", A_SOMEONE, self, null, null,
  TO_CHAR);
     quit;
  }

  if (hm <= -20)
  {
     act("The wand glows steadily then suddenly flares in a brilliant " +
  "purple light!", A_SOMEONE, self, null, null, TO_ALL);
     act("The wand emmits a piercing screech and explodes in a sphere of " +
  "searing, uncontrolled mana!", A_SOMEONE, self, null, null, TO_ALL);
     foreach(UNIT_ST_PC | UNIT_ST_NPC, u)
     {
 cast_spell(SPL_LIGHTNING_2, self, targ, u);
     }
     destroy(targ);
     quit;
  }

  if (hm <= 0)
  {
     act("The wand glows slightly then sputters and goes dim.", A_SOMEONE,
  self, null, null, TO_ALL);
     act("You fail to charge the wand.", A_SOMEONE, self, null, null,
  TO_CHAR);
     quit;
  }

  act("The wand glows in a soft white light which slowly subsides.",
      A_SOMEONE, self, null, null, TO_ALL);
  c := (hm / 25);

  if (c < 1) c := 1;

  if ( (targ.value[1] + c) > targ.value[4])
  {
     act("You have recharged the wand enough to use it " +
  itoa((targ.value[4] - targ.value[1]))+
  " more times.", A_SOMEONE, self, null, null, TO_CHAR);
     targ.value[1] := targ.value[4];
  }
  else
  {
     targ.value[1] := (targ.value[1] + c);
     act("You have recharged the wand enough to use it " +itoa(c)+
  " more times.", A_SOMEONE, self, null, null, TO_CHAR);
  }
  quit;
}
dilend



dilbegin charge_staff(med : unitptr, targ : unitptr, arg : string,
                    hm : integer, effect : string);
/* charge staff should only be castable while standing and not in combat */
var
  chance    : integer;
  ranroll   : integer;
  c         : integer;
  u         : unitptr;
code
{
  if ((targ == null) or (targ.objecttype != ITEM_STAFF))
  {
     act("You don't have a staff to charge!", A_SOMEONE, self, null, null,
         TO_CHAR);
     quit;
  }

  if (hm <= -20)
  {
     act("The staff glows steadily then suddenly flares in a brilliant "+
  "purple light!", A_SOMEONE, self, null, null, TO_ALL);
     act("The staff emmits a piercing screech and explodes in a sphere of " +
         "searing, uncontrolled mana!", A_SOMEONE, self, null, null, TO_ALL);
     foreach(UNIT_ST_PC | UNIT_ST_NPC, u)
     {
 cast_spell(SPL_LIGHTNING_2, self, targ, u);
     }
     destroy(targ);
     quit;
  }

  if (hm <= 0)
  {
     act("The staff glows slightly then sputters and goes dim.", A_SOMEONE,
         self, null, null, TO_ALL);
     act("You fail to charge the staff.", A_SOMEONE, self, null, null,
         TO_CHAR);
     quit;
  }

  act("The staff glows in a soft white light which slowly subsides.",
      A_SOMEONE, self, null, null, TO_ALL);
  c := (hm / 25);
  if ( c < 1) c := 1;
  if ( (targ.value[1] + c) > targ.value[4])
  {
     act("You have recharged the wand enough to use " +
         itoa((targ.value[4] - targ.value[1]))+
         " more time(s).", A_SOMEONE, self, null, null, TO_CHAR);
     targ.value[1] := targ.value[4];
  }
  else
  {
     targ.value[1] := (targ.value[1] + c);
     act("You have recharged the wand enough to use " +itoa(c)+
  " more time(s).", A_SOMEONE, self, null, null, TO_CHAR);
  }
  quit;
}
dilend


dilbegin mending(med : unitptr, targ : unitptr, arg : string, hm : integer,
  effect : string);
var
  fix_ran : integer;

code
{
 if (hm <= 0)
 {
    act("You fail.", A_SOMEONE, self, null, null, TO_CHAR);
    quit;
 }

  if (targ.hp == -1)
  {
     act("You cannot mend indestructible items.",
     A_SOMEONE, self, targ, null, TO_CHAR);
     quit;
  }

 if (targ.hp >= targ.max_hp)
 {
    act("Your spell does nothing more for the item.", A_SOMEONE, self,
 null, null, TO_CHAR);
    quit;
 }

 if (targ.hp <= 0)
 {
    act("Your spell is too weak to mend the $2N",
 A_SOMEONE, self, targ, null, TO_CHAR);
    quit;
 }

 if (targ.hp <= (targ.max_hp / 2))
 {
    act("Your spell is too weak to mend an item so badly damaged.",
 A_SOMEONE, self, targ, null, TO_CHAR);
    quit;
 }

 targ.max_hp := ( (7 *(targ.max_hp / 8)) );
 fix_ran := rnd(1, (targ.max_hp / 6));
 if ( (targ.hp + fix_ran) > (targ.max_hp) )
   targ.hp := (targ.max_hp);
 else targ.hp := (targ.hp + fix_ran);

 act("Your $2n glows with a warm light...", A_SOMEONE, self, targ, null,
     TO_CHAR);

 act("$1n's $2n glows with a warm light...", A_SOMEONE, self, targ, null,
     TO_ROOM);
 quit;
}
dilend


dilbegin repair(med : unitptr, targ : unitptr, arg : string, hm : integer,
 effect : string);
var
  fix_ran : integer;

code
{
  if (hm <= 0)
  {
     act("You fail.", A_SOMEONE, self, null, null, TO_CHAR);
     quit;
  }

  if (targ.hp == -1)
  {
     act("You cannot mend indestructible items.",
     A_SOMEONE, self, targ, null, TO_CHAR);
     quit;
  }

  if (targ.hp >= targ.max_hp)
  {
     act("Your spell does nothing more for the item.", A_SOMEONE, self,
         null, null, TO_CHAR);
     quit;
  }

  if (targ.hp <= 0)
  {
     act("Your spell is too weak to mend the $2N",
  A_SOMEONE, self, targ, null, TO_CHAR);
     quit;
  }

  if (targ.hp <= (targ.max_hp / 4))
  {
     act("Your spell is too weak to mend an item so badly damaged.",
  A_SOMEONE, self, targ, null, TO_CHAR);
     quit;
  }

  targ.max_hp := ( (7 * (targ.max_hp / 8)) );
  fix_ran := rnd( (targ.max_hp / 6), (targ.max_hp / 3) );
  if ( (targ.hp + fix_ran) > (targ.max_hp) )
    targ.hp := (targ.max_hp);
  else targ.hp := (targ.hp + fix_ran);
  act("Your $2n glows with a warm light...", A_SOMEONE, self, targ, null,
      TO_CHAR);
  act("$1n's $2n glows with a warm light...", A_SOMEONE, self, targ, null,
      TO_ROOM);
  quit;
}
dilend


dilbegin reconstruct(med : unitptr, targ : unitptr, arg : string,
                   hm : integer, effect: string);

var
  max_heal : integer;
  new_item : unitptr;
  fix_ran  : integer;
  old_max  : integer;

code
{
  if (hm <= 0)
  {
     act("You fail.", A_SOMEONE, self, null, null, TO_CHAR);
     quit;
  }

  if (targ.hp == -1)
  {
     act("You cannot mend indestructible items.",
     A_SOMEONE, self, targ, null, TO_CHAR);
     quit;
  }

  if (targ.hp >= targ.max_hp)
  {
     act("Your spell does nothing more for the item.", A_SOMEONE, self,
         null, null, TO_CHAR);
     quit;
  }

  if (targ.hp <= 0)
  {
     act("Your spell is too weak to mend the $2N",
  A_SOMEONE, self, targ, null, TO_CHAR);
     quit;
  }

  if (targ.hp <= (targ.max_hp / 4))
  {
     act("Your spell is too weak to mend an item so badly damaged.",
  A_SOMEONE, self, targ, null, TO_CHAR);
     quit;
  }

  targ.max_hp := ( (15 * (targ.max_hp / 16)) );
  fix_ran := rnd( (targ.max_hp / 6), (targ.max_hp / 3) );
  if ( (targ.hp + fix_ran) > (targ.max_hp) )
    targ.hp := (targ.max_hp);
  else targ.hp := (targ.hp + fix_ran);
  act("Your $2n glows with a warm light...", A_SOMEONE, self, targ, null,
      TO_CHAR);
  act("$1n's $2n glows with a warm light...", A_SOMEONE, self, targ, null,
      TO_ROOM);
  quit;
}
dilend


dilbegin sending(med : unitptr, targ : unitptr, arg : string, hm : integer,
  effect : string);

var
  room   : unitptr;
  recept : unitptr;
  i      : integer;

code
{
  heartbeat := (PULSE_SEC*6);

  if (hm <= 0)
  {
     act("Nothing happens.", A_SOMEONE, self, null, null, TO_CHAR);
     quit;
  }

  recept := findunit(self, arg, FIND_UNIT_SURRO | FIND_UNIT_WORLD, null);

  if ( (recept == null))
/*   or (not (visible(self, recept))) )*/
  {
     act("You cannot locate the target's destination.", A_SOMEONE, self,
  targ, recept, TO_CHAR);
     quit;
  }

  if ( (recept.type != UNIT_ST_PC) and (recept.type != UNIT_ST_NPC) )
  {
     act("You can only send items to players or monsters.", A_SOMEONE, self,
  targ, recept, TO_CHAR);
     quit;
  }

  room := targ.outside;
  while ( (room.type != UNIT_ST_ROOM) and
  (not(isset(room.flags, UNIT_FL_NO_TELEPORT))) )
  {
     room := room.outside;
  }

  if ( (isset(targ.flags, UNIT_FL_NO_TELEPORT)) or
      (isset(room.flags, UNIT_FL_NO_TELEPORT)) )
  {
     act("Something here prevents your spell.", A_SOMEONE,
  self, targ, recept, TO_CHAR);
     quit;
  }

  room := recept.outside;
  while ( (room.type != UNIT_ST_ROOM) and
         (not(isset(room.flags, UNIT_FL_NO_TELEPORT))) )
  {
     room := room.outside;
  }

  if ( (isset(recept.flags, UNIT_FL_NO_TELEPORT)) or
      (isset(room.flags, UNIT_FL_NO_TELEPORT)) )
  {
     act("Something prevents you from sending to that person.", A_SOMEONE,
  self, targ, recept, TO_CHAR);
     quit;
  }

  if (hm <= 5)
  {
     act("A small swirling disk of gray forms above you...", A_SOMEONE, self,
  targ, null, TO_CHAR);
     act("A small swirling disk of gray forms above $1n.", A_SOMEONE, self,
  targ, null, TO_ROOM);
     act("Slowly, your $2n rises toward the disk...", A_SOMEONE, self, targ,
  null, TO_CHAR);
     act("Slowly, $1n's $2n rises toward the disk...", A_SOMEONE, self, targ,
  null, TO_ROOM);
     act("As it touches the disk, you feel something go wrong!", A_SOMEONE,
  self, targ, null, TO_CHAR);
     act("The swirling rift turns a violent red and suddenly explodes " +
  "in a brilliant light, taking $2n with it!", A_SOMEONE, self, targ,
  null, TO_ALL);
     destroy(targ);
     quit;
  }

  act("A small swirling disk of gray forms above you...", A_SOMEONE, self,
      targ, null, TO_CHAR);
  act("A small swirling disk of gray forms above $1n.", A_SOMEONE, self,
      targ, null, TO_ROOM);
  act("Slowy, your $2n rises toward the disk...", A_SOMEONE, self, targ,
      null, TO_CHAR);
  act("Slowly, $1n's $2n rises toward the disk...", A_SOMEONE, self, targ,
      null, TO_ROOM);
  act("$2n touches the swirling rift and vanishes in a flash of light!",
      A_SOMEONE, self, targ, null, TO_ALL);

  link(targ, recept.outside);

  act("Suddenly, a swirling grey rift forms above you...", A_SOMEONE, recept,
      targ, null, TO_CHAR);
  act("Suddenly, a swirling grey rift forms above $1n...", A_SOMEONE, recept,
      targ, null, TO_ROOM);
  act("$2n falls from the rift and lands at your feet.",
      A_SOMEONE, recept, targ,
      null, TO_CHAR);
  act("$2n falls from the rift and lands at $1n's feet.",
      A_SOMEONE, recept, targ,
      null, TO_ROOM);
  act("The swirling rift disappears in a flash of light!", A_SOMEONE, recept,
      targ, null, TO_ALL);
  quit;
}
dilend


dilbegin summon_earth(medi : unitptr, tgt : unitptr, arg : string,
       hm : integer, effect : string);
var
  u : unitptr;
code
{
  if (hm < 0)
  {
     act("The ground shakes a bit.", A_SOMEONE,self,null,null,
  TO_ALL);
     quit;
  }

  u := load("earth_elm@spells");
  link(u, self.outside);

  act("The earth opens as $2n is summoned before you.",
      A_HIDEINV, self, u, null, TO_CHAR);

  act("The earth opens and $2n appears before $1n", A_HIDEINV,
      self, u, null, TO_ROOM);

  dilcopy("magic_summoned@spells("+itoa(hm)+")", u);
  dilcopy("master_servant@spells()", u);
  if (isset(self.pcflags,PC_PK_RELAXED))
  dilcopy ("catchit@spells(1)",u);
  else
  dilcopy ("catchit@spells(0)",u);

  exec("follow "+self.name, u);
  quit;
}
dilend



dilbegin summon_air(medi : unitptr, tgt : unitptr, arg : string,
   hm : integer, effect : string);
var
  u : unitptr;
code
{
  if (hm < 0)
  {
     act("The ground shakes a bit.", A_SOMEONE,self,null,null,
  TO_ALL);
     quit;
  }

  u := load("air_elm@spells");
  link(u, self.outside);

  act("The portal of air opens and $2n appears before you.",
      A_HIDEINV, self, u, null, TO_CHAR);

  act("The portal of air opens, and $2n emerges before $1n",
      A_HIDEINV, self, u, null, TO_ROOM);

  dilcopy("magic_summoned@spells("+itoa(hm)+")", u);
  dilcopy("master_servant@spells()", u);
  if (isset(self.pcflags,PC_PK_RELAXED))
  dilcopy ("catchit@spells(1)",u);
  else
  dilcopy ("catchit@spells(0)",u);

  exec("follow "+self.name, u);
  quit;
}
dilend


dilbegin summon_water(medi : unitptr, tgt : unitptr, arg : string,
   hm : integer, effect : string);
var
u : unitptr;
code
{
  if (hm < 0)
  {
     act("The ground shakes a bit.", A_SOMEONE,self,null,null,
  TO_ALL);
     quit;
  }

  u := load("water_elm@spells");
  link(u, self.outside);

  act("From the column of water $2n emerges to stand"+
      " before you.", A_HIDEINV, self, u, null, TO_CHAR);

  act("From the column of water $2n emerges to stand"+
      " before $1n.", A_HIDEINV, self, u, null, TO_ROOM);

  dilcopy("magic_summoned@spells("+itoa(hm)+")", u);
  dilcopy("master_servant@spells()", u);
  if (isset(self.pcflags,PC_PK_RELAXED))
  dilcopy ("catchit@spells(1)",u);
  else
  dilcopy ("catchit@spells(0)",u);


  exec("follow "+self.name, u);
  quit;

}
dilend


dilbegin summon_fire(medi : unitptr, tgt : unitptr, arg : string,
   hm : integer, effect : string);
var
  u : unitptr;
code
{
  if (hm < 0)
  {
     act("The ground shakes a bit.", A_SOMEONE,self,null,null,
  TO_ALL);
     quit;
  }

  u := load("fire_elm@spells");
  link(u, self.outside);

  act("In a flash of fire and light, $2n emerges to stand before"+
      " you!", A_HIDEINV, self, u, null, TO_CHAR);

  act("In a flash of fire and light $2n appears to stand before "+
      "$1n.", A_HIDEINV, self, u, null, TO_ROOM);

  dilcopy("magic_summoned@spells("+itoa(hm)+")", u);
  dilcopy("master_servant@spells()", u);
  if (isset(self.pcflags,PC_PK_RELAXED))
  dilcopy ("catchit@spells(1)",u);
  else
  dilcopy ("catchit@spells(0)",u);


  exec("follow "+self.name, u);
  quit;

}
dilend


dilbegin demon_summon(medi : unitptr, tgt : unitptr, arg : string,
       hm : integer, effect : string);
var
  u : unitptr;

code
{
  if (hm < 0)
  {
     act("You lose control of the portal!",
  A_HIDEINV, self, u, null, TO_CHAR);

     act("A large portal opens and a beast emerges!",
  A_HIDEINV, self, u, null, TO_ROOM);
     u := load("demon@spells");
     exec("follow "+self.name, u);
     exec("say Thank you "+self.name+", for bringing me here "+
   "unbonded!", u);
     exec("kill "+self.name, u);
     quit;
  }

  u := load("demon@spells");
  link(u, self.outside);

  act("A large portal opens, and $2n steps through to stand before you.",
      A_HIDEINV, self, u, null, TO_CHAR);

  act("A large portal of fire opens, and $2n steps through to stand "+
      "before $1n.", A_HIDEINV, self, u, null, TO_REST);

  dilcopy("magic_summoned@spells("+itoa(hm)+")", u);
  dilcopy("master_servant@spells()", u);
  if (isset(self.pcflags,PC_PK_RELAXED))
  dilcopy (" catchit@spells(1)",u);
  else
  dilcopy ("catchit@spells(0)",u);


  exec("follow "+self.name, u);
  quit;
}
dilend


dilbegin devil_summon(medi : unitptr, tgt : unitptr, arg : string,
       hm : integer, effect : string);
var
  u : unitptr;
code
{
  if (hm < 0)
  {
     act("A portal of fire opens and a beast steps through!",
  A_SOMEONE, self, null, null, TO_ALL);
     u := load("devil@spells");
     link(u, self.outside);
     exec("follow "+self.name, u);
     exec("say Ahh, to be summoned here and free!", u);
     exec("kill "+self.name, u);
     quit;
  }

  u := load("devil@spells");
  link(u, self.outside);

  act("A portal of fire opens and $2n emerges to stand before you.",
      A_HIDEINV, self, u, null, TO_CHAR);

  act("A portal of fire opens and $2n emerges to stand before $1n.",
      A_HIDEINV, self, u, null, TO_REST);

  dilcopy("magic_summoned@spells("+itoa(hm)+")", u);
  dilcopy("master_servant@spells()", u);
  if (isset(self.pcflags,PC_PK_RELAXED))
  dilcopy ("catchit@spells(1)",u);
  else
  dilcopy ("catchit@spells(0)",u);


  exec("follow "+self.name, u);
  quit;
}
dilend


dilbegin energy_bolt(medi : unitptr, tgt : unitptr, arg : string,
       hm : integer, effect : string);
var
  u : unitptr;

code
{
  hm := attack_spell(SPL_ENERGY_BOLT, self, medi, tgt, 0, effect);
  quit;
}
dilend

dilbegin clenched_fist(medi : unitptr, tgt : unitptr, arg : string,
        hm : integer, effect : string);
var
  u : unitptr;
code
{
  hm := attack_spell(SPL_CLENCHED_FIST, self, medi, tgt, 0, effect);
  quit;
}
dilend


dilbegin dispel_magic(medi : unitptr, tgt : unitptr,
       arg : string,
       hm : integer, effect : string);
         var
         count:integer;
code
{
  if ((hm < 0) or (self.endurance<=20))
  {
     act("Nothing happens.",
  A_ALWAYS, self, null, null, TO_CHAR);
     quit;
  }

     hm := hm/10+1;
     if (hm>15)
hm := 15;

count:=0;
interrupt (SFB_MSG , "inc despel counter" == argument,inc_count);
  sendto("spl_dispel "+itoa(hm), tgt);
  interrupt(SFB_DEAD, activator == tgt, stop);

  :loop:
  count:=count+1;
  if (isaff(tgt, ID_BLESS))
    subaff(tgt, ID_BLESS);
  else if (isaff(tgt, ID_DETECT_ALIGN))
    subaff(tgt, ID_DETECT_ALIGN);
  else if (isaff(tgt, ID_DETECT_INVISIBLE))
    subaff(tgt, ID_DETECT_INVISIBLE);
  else if (isaff(tgt, ID_DETECT_MAGIC))
    subaff(tgt, ID_DETECT_MAGIC);
  else if (isaff(tgt, ID_DETECT_POISON))
    subaff(tgt, ID_DETECT_POISON);
  else if (isaff(tgt, ID_DETECT_UNDEAD))
    subaff(tgt, ID_DETECT_UNDEAD);
  else if (isaff(tgt, ID_DETECT_CURSE))
    subaff(tgt, ID_DETECT_CURSE);
  else if (isaff(tgt, ID_DETECT_LIFE))
    subaff(tgt, ID_DETECT_LIFE);
  else if (isaff(tgt, ID_ENCHANT_WEAPON))
    subaff(tgt, ID_ENCHANT_WEAPON);
  else if (isaff(tgt, ID_ENCHANT_ARMOUR))
    subaff(tgt, ID_ENCHANT_ARMOUR);
  else if (isaff(tgt, ID_ABSORBTION))
    subaff(tgt, ID_ABSORBTION);
  else if (isaff(tgt, ID_INVISIBILITY))
    subaff(tgt, ID_INVISIBILITY);
  else if (isaff(tgt, ID_HOLD))
    subaff(tgt, ID_HOLD);
  else if (isaff(tgt, ID_CHARM))
    subaff(tgt, ID_CHARM);
  else if (isaff(tgt, ID_MAGIC_LIGHT))
    subaff(tgt, ID_MAGIC_LIGHT);
  else if (isaff(tgt, ID_MAGIC_DARK))
    subaff(tgt, ID_MAGIC_DARK);
  else if (isaff(tgt, ID_SPL_RAISE_MAG))
    subaff(tgt, ID_SPL_RAISE_MAG);
  else if (isaff(tgt, ID_SPL_RAISE_DIV))
    subaff(tgt, ID_SPL_RAISE_DIV);
  else if (isaff(tgt, ID_SPL_RAISE_STR))
    subaff(tgt, ID_SPL_RAISE_STR);
  else if (isaff(tgt, ID_SPL_RAISE_DEX))
    subaff(tgt, ID_SPL_RAISE_DEX);
  else if (isaff(tgt, ID_SPL_RAISE_CON))
    subaff(tgt, ID_SPL_RAISE_CON);
  else if (isaff(tgt, ID_SPL_RAISE_CHA))
    subaff(tgt, ID_SPL_RAISE_CHA);
  else if (isaff(tgt, ID_SPL_RAISE_BRA))
    subaff(tgt, ID_SPL_RAISE_BRA);
  else if (isaff(tgt, ID_SPL_RAISE_HPP))
    subaff(tgt, ID_SPL_RAISE_HPP);
  else if (isaff(tgt, ID_SPL_RAISE_DIVINE))
    subaff(tgt, ID_SPL_RAISE_DIVINE);
  else if (isaff(tgt, ID_SPL_RAISE_SUMMONING))
    subaff(tgt, ID_SPL_RAISE_SUMMONING);
  else if (isaff(tgt, ID_SPL_RAISE_MIND))
    subaff(tgt, ID_SPL_RAISE_MIND);
  else if (isaff(tgt, ID_SPL_RAISE_HEAT))
    subaff(tgt, ID_SPL_RAISE_HEAT);
  else if (isaff(tgt, ID_SPL_RAISE_COLD))
    subaff(tgt, ID_SPL_RAISE_COLD);
  else if (isaff(tgt, ID_SPL_RAISE_CELL))
    subaff(tgt, ID_SPL_RAISE_CELL);
  else if (isaff(tgt, ID_SPL_RAISE_INTERNAL))
    subaff(tgt, ID_SPL_RAISE_INTERNAL);
  else if (isaff(tgt, ID_SPL_RAISE_EXTERNAL))
    subaff(tgt, ID_SPL_RAISE_EXTERNAL);
  else if (isaff(tgt, ID_RAISE_MAG))
    subaff(tgt, ID_RAISE_MAG);
  else if (isaff(tgt, ID_RAISE_DIV))
    subaff(tgt, ID_RAISE_DIV);
  else if (isaff(tgt, ID_RAISE_STR))
    subaff(tgt, ID_RAISE_STR);
  else if (isaff(tgt, ID_RAISE_DEX))
    subaff(tgt, ID_RAISE_DEX);
  else if (isaff(tgt, ID_RAISE_CON))
    subaff(tgt, ID_RAISE_CON);
  else if (isaff(tgt, ID_RAISE_CHA))
    subaff(tgt, ID_RAISE_CHA);
  else if (isaff(tgt, ID_RAISE_BRA))
    subaff(tgt, ID_RAISE_BRA);
  else if (isaff(tgt, ID_RAISE_HPP))
    subaff(tgt, ID_RAISE_HPP);
  else if (isaff(tgt, ID_RAISE_DIVINE))
    subaff(tgt, ID_RAISE_DIVINE);
  else if (isaff(tgt, ID_RAISE_SUMMONING))
    subaff(tgt, ID_RAISE_SUMMONING);
  else if (isaff(tgt, ID_RAISE_MIND))
    subaff(tgt, ID_RAISE_MIND);
  else if (isaff(tgt, ID_RAISE_HEAT))
    subaff(tgt, ID_RAISE_HEAT);
  else if (isaff(tgt, ID_RAISE_COLD))
    subaff(tgt, ID_RAISE_COLD);
  else if (isaff(tgt, ID_RAISE_CELL))
    subaff(tgt, ID_RAISE_CELL);
  else if (isaff(tgt, ID_RAISE_INTERNAL))
    subaff(tgt, ID_RAISE_INTERNAL);
  else if (isaff(tgt, ID_RAISE_EXTERNAL))
    subaff(tgt, ID_RAISE_EXTERNAL);
  else if (isaff(tgt, ID_POISON))
    subaff(tgt, ID_POISON);
  else if (isaff(tgt, ID_SPEED))
    subaff(tgt, ID_SPEED);
  else if (isaff(tgt, ID_FOCUS))
    subaff(tgt, ID_FOCUS);
  else
    quit;
:inc_count:
if (self.endurance<20) self.endurance:=0;
else
self.endurance:=self.endurance-20;
if (self.endurance==0)
 {
  self.position:=POSITION_STUNNED;
  quit;
  }

if (count==hm)
 quit;

  goto loop;

:stop:
quit;
}
dilend
dilbegin fire_breath(medi : unitptr, tgt : unitptr, arg : string,
      hm : integer, effect : string);
var
  u : unitptr;
  i : integer;
  mast:unitptr;
code
{
  if (medi.level <= 20)
     i := SPL_FIREBALL_1;
  else if (medi.level <= 40)
     i := SPL_FIREBALL_2;
  else if (medi.type==UNIT_ST_NPC)
     i := SPL_FIRE_BREATH;
else
     i := SPL_FIREBALL_3;
  mast := self.master;
  if (not(self.master))
    mast := self;

  foreach(UNIT_ST_PC|UNIT_ST_NPC, u)
  {
  if (u.minv>=200) continue;
  if(u.level <= 20) continue;
  if (((u.type==UNIT_ST_PC) and
  (self.type==UNIT_ST_PC)) and
  ((not (isset(u.pcflags,PC_PK_RELAXED))) or
  (not (isset (self.pcflags,PC_PK_RELAXED))))) continue;

  if ((u.master != mast) and (u != mast) and (u != self))
      hm := attack_spell(i, self, medi, u, 0, effect);
      }

  quit;
}
dilend

/* Adjust fire type against the level of the caster - if no level the */
/* toughest is chosen                                                 */
dilbegin frost_breath(medi : unitptr, tgt : unitptr, arg : string,
       hm : integer, effect : string);
var
  u : unitptr;
  i : integer;
  mast:unitptr;
code
{
  if (medi.level <= 20)
     i := SPL_FROSTBALL_1;
  else if (medi.level <= 40)
     i := SPL_FROSTBALL_2;
  else if (medi.type==UNIT_ST_NPC)
     i := SPL_FROST_BREATH;
  else
     i := SPL_FROSTBALL_3;

  mast := self.master;
  if (not(self.master))
    mast := self;

  foreach(UNIT_ST_PC|UNIT_ST_NPC, u)
  {
  if (u.minv>=200) continue;
  if(u.level <= 20) continue;
  if (((u.type==UNIT_ST_PC) and
  (self.type==UNIT_ST_PC)) and
  ((not (isset(u.pcflags,PC_PK_RELAXED))) or
  (not (isset (self.pcflags,PC_PK_RELAXED))))) continue;

  if ((u.master != mast) and (u != mast) and (u != self))
       hm := attack_spell(i, self, medi, u, 0, effect);
  }
  quit;
}
dilend

/* Adjust fire type against the level of the caster - if no level the */
/* toughest is chosen                                                 */
dilbegin lightning_br(medi : unitptr, tgt : unitptr,
               arg : string,
       hm : integer, effect : string);
external provoked_attack (victim : unitptr, ch : unitptr);
var
  u : unitptr;
  i : integer;
mast:unitptr;
code
{
  if (medi.level <= 20)
     i := SPL_LIGHTNING_1;
  else if (medi.level <= 40)
     i := SPL_LIGHTNING_2;
  else if (medi.type==UNIT_ST_NPC)
     i := SPL_LIGHTNING_BREATH;
  else
     i := SPL_LIGHTNING_3;

  mast := self.master;
  if (not(self.master))
    mast := self;

  foreach(UNIT_ST_PC|UNIT_ST_NPC, u)
  {
  if (u.minv>=200) continue;
  if(u.level <= 20) continue;
  if (((u.type==UNIT_ST_PC) and
  (self.type==UNIT_ST_PC)) and
  ((not (isset(u.pcflags,PC_PK_RELAXED))) or
  (not (isset (self.pcflags,PC_PK_RELAXED))))) continue;
  if ((u.master != mast) and (u != mast) and (u != self))
       hm := attack_spell(i, self, medi, u, 0, effect);
  }
  quit;
}
dilend


/* Adjust fire type against the level of the caster - if no level the */
/* toughest is chosen                                                 */
dilbegin acid_breath(medi : unitptr, tgt : unitptr,
              arg : string,
      hm : integer, effect : string);
var
  u : unitptr;
  i : integer;
mast:unitptr;
code
{
  if (medi.level <= 20)
     i := SPL_ACIDBALL_1;
  else if (medi.level <= 40)
     i := SPL_ACIDBALL_2;
  else if (medi.type==UNIT_ST_NPC)
     i := SPL_ACID_BREATH;
  else
     i := SPL_ACIDBALL_3;

  mast := self.master;
  if (not(self.master))
    mast := self;

  foreach(UNIT_ST_PC|UNIT_ST_NPC, u)
  {
  if (u.minv>=200) continue;
  if(u.level <= 20) continue;
  if (((u.type==UNIT_ST_PC) and
  (self.type==UNIT_ST_PC)) and
  ((not (isset(u.pcflags,PC_PK_RELAXED))) or
  (not (isset (self.pcflags,PC_PK_RELAXED))))) continue;
  if ((u.master != mast) and (u != mast) and (u != self))
       hm := attack_spell(i, self, medi, u, 0, effect);
  }
  quit;
}
dilend


/* Adjust fire type against the level of the caster - if no level the */
/* toughest is chosen                                                 */
dilbegin gas_breath(medi : unitptr, tgt : unitptr,
             arg : string,
     hm : integer, effect : string);
var
  u : unitptr;
  i : integer;
mast:unitptr;
code
{
  if (medi.level <= 20)
     i := SPL_STINKING_CLOUD_1;
  else if (medi.level <= 40)
     i := SPL_STINKING_CLOUD_2;
  else if (medi.type==UNIT_ST_NPC)
     i := SPL_GAS_BREATH;
  else
     i := SPL_STINKING_CLOUD_3;

  mast := self.master;
  if (not(self.master))
    mast := self;

  foreach(UNIT_ST_PC|UNIT_ST_NPC, u)
  {
  if (u.minv>=200) continue;
  if(u.level <= 20) continue;
  if (((u.type==UNIT_ST_PC) and
  (self.type==UNIT_ST_PC)) and
  ((not (isset(u.pcflags,PC_PK_RELAXED))) or
  (not (isset (self.pcflags,PC_PK_RELAXED))))) continue;
  if ((u.master != mast) and (u != mast) and (u != self))
       hm := attack_spell(i, self, medi, u, 0, effect);
  }
  quit;
}
dilend


/* Adjust fire type against the level of the caster - if no level the */
/* toughest is chosen                                                 */
dilbegin light_breath(medi : unitptr, tgt : unitptr,
               arg : string,
       hm : integer, effect : string);
var
  u : unitptr;
  i : integer;
mast:unitptr;
code
{
  if (medi.level <= 20)
     i := SPL_COLOURSPRAY_1;
  else if (medi.level <= 40)
     i := SPL_COLOURSPRAY_2;
  else if (medi.type==UNIT_ST_NPC)
     i := SPL_LIGHT_BREATH;
  else
     i := SPL_COLOURSPRAY_3;

  mast := self.master;
  if (not(self.master))
    mast := self;

  foreach(UNIT_ST_PC|UNIT_ST_NPC, u)
  {
  if (u.minv>=200) continue;
  if(u.level <= 20) continue;
  if (((u.type==UNIT_ST_PC) and
  (self.type==UNIT_ST_PC)) and
  ((not (isset(u.pcflags,PC_PK_RELAXED))) or
  (not (isset (self.pcflags,PC_PK_RELAXED))))) continue;
  if ((u.master != mast) and (u != mast) and (u != self))
       hm := attack_spell(i, self, medi, u, 0, effect);
  }
  quit;
}
dilend

dilbegin cone_shard(medi : unitptr, tgt : unitptr, arg : string,
       hm : integer, effect : string);
var
code
{
  hm := attack_spell(SPL_CONE_SHARD, self, medi, tgt, 0, effect);
  quit;
}
dilend

dilbegin shard_breath(medi : unitptr, tgt : unitptr,
               arg : string,
       hm : integer, effect : string);
var
  u : unitptr;
  i : integer;
mast:unitptr;
code
{
     i := SPL_SHARD_BREATH;

  mast := self.master;
  if (not(self.master))
    mast := self;

  foreach(UNIT_ST_PC|UNIT_ST_NPC, u)
  {
  if (u.minv>=200) continue;
  if(u.level <= 20) continue;
  if (((u.type==UNIT_ST_PC) and
  (self.type==UNIT_ST_PC)) and
  ((not (isset(u.pcflags,PC_PK_RELAXED))) or
  (not (isset (self.pcflags,PC_PK_RELAXED))))) continue;
  if ((u.master != mast) and (u != mast) and (u != self))
       hm := attack_spell(i, self, medi, u, 0, effect);
  }
  quit;
}
dilend

dilbegin sonic_breath(medi : unitptr, tgt : unitptr,
               arg : string,
       hm : integer, effect : string);
var
  u : unitptr;
  i : integer;
mast:unitptr;
code
{
     i := SPL_SONIC_BREATH;

  mast := self.master;
  if (not(self.master))
    mast := self;

  foreach(UNIT_ST_PC|UNIT_ST_NPC, u)
  {
  if (u.minv>=200) continue;
  if(u.level <= 20) continue;
  if (((u.type==UNIT_ST_PC) and
  (self.type==UNIT_ST_PC)) and
  ((not (isset(u.pcflags,PC_PK_RELAXED))) or
  (not (isset (self.pcflags,PC_PK_RELAXED))))) continue;
  if ((u.master != mast) and (u != mast) and (u != self))
       hm := attack_spell(i, self, medi, u, 0, effect);
  }
  quit;
}
dilend


dilbegin meteor_shower(medi : unitptr, tgt : unitptr, arg : string,
        hm : integer, effect : string);
var
  u    : unitptr;
  mast : unitptr;
code
{

  mast := self.master;
  if (not(self.master))
    mast := self;

  foreach(UNIT_ST_PC|UNIT_ST_NPC, u)
  {
  if (u.minv>=200) continue;
  if (((u.type==UNIT_ST_PC) and
  (self.type==UNIT_ST_PC)) and
  ((not (isset(u.pcflags,PC_PK_RELAXED))) or
  (not (isset (self.pcflags,PC_PK_RELAXED))))) continue;


  if ((u.master != mast) and (u != mast) and (u != self))
       hm := attack_spell(SPL_METEOR_SHOWER, self, medi, u, 0, effect);
  }
  quit;
}
dilend

dilbegin sun_beam(medi : unitptr, tgt : unitptr,
                arg : string, hm : integer, effect : string);
var
  u : unitptr;

code
{
  hm := 0;
  u := self.outside;

  while (u)
  {
     if (isset(u.flags, UNIT_FL_NO_WEATHER | UNIT_FL_INDOORS))
     {
        act("There is no access to the forces of nature from here.",
            A_ALWAYS, self, null, null, TO_CHAR);
        quit;
     }
     u := u.outside;
  }

  if (weather != SKY_CLOUDLESS)
  {
     act("The skies are not clear.",
         A_ALWAYS, self, null, null, TO_CHAR);
     quit;
  }

  if ((mudhour < 5) or (mudhour >= 21))
  {
     act("The sun has not rised yet.",
         A_ALWAYS, self, null, null, TO_CHAR);
     quit;
  }

  /* Most powerful at noon */
  if (mudhour < 12)
    hm := 18*(mudhour - 12);
  else
    hm := -15*(mudhour - 12);

  if (RACE_IS_UNDEAD(tgt.race))
    hm := hm + 100;

  hm := attack_spell(SPL_SUN_BEAM, self, medi, tgt, hm, effect);
  quit;
}
dilend


dilbegin solar_flare(medi : unitptr, tgt : unitptr,
                arg : string,
                hm : integer, effect : string);
var
  u : unitptr;

code
{
  hm := 0;
  u := self.outside;

  while (u)
  {
     if (isset(u.flags, UNIT_FL_NO_WEATHER | UNIT_FL_INDOORS))
     {
        act("There is no access to the forces of nature from here.",
            A_ALWAYS, self, null, null, TO_CHAR);
        quit;
     }
     u := u.outside;
  }

  if (weather != SKY_CLOUDLESS)
  {
     act("The skies are not clear.",
         A_ALWAYS, self, null, null, TO_CHAR);
     quit;
  }

  if ((mudhour < 5) or (mudhour >= 21))
  {
     act("The sun has not rised yet.",
         A_ALWAYS, self, null, null, TO_CHAR);
     quit;
  }

  /* Most powerful at noon */
  if (mudhour < 12)
    hm := 18*(mudhour - 12);
  else
    hm := -15*(mudhour - 12);

  if (RACE_IS_UNDEAD(tgt.race))
    hm := hm + 100;

  hm := hm*3;
  hm := attack_spell(SPL_SOLAR_FLARE, self, medi, tgt, hm, effect);
  quit;
}
dilend


dilbegin mlight(medi:unitptr, tgt : unitptr, arg : string,
 hm : integer, effect : string);
external
  integer skill_duration  (i : integer);

code
{
  if (isaff(tgt, ID_MAGIC_LIGHT))
    return;

  if (hm < 0)
    quit;

  hm := skill_duration (hm);

  /* 1 light source */
  addaff(tgt, ID_MAGIC_LIGHT, hm, WAIT_SEC*30,
  1, 0, 0,
  TIF_CHANGE_LIGHT_ADD, TIF_NONE, TIF_CHANGE_LIGHT_SUB,
  APF_LIGHT_DARK);
  quit;
}
dilend

dilbegin cont_light(medi:unitptr, tgt : unitptr, arg : string,
     hm : integer, effect : string);
external
  integer skill_duration (i : integer);

code
{
  if (isaff(tgt, ID_MAGIC_LIGHT))
    return;

  if (hm < 0)
    quit;

  hm := skill_duration (hm);

  /* 2 light sources */
  addaff(tgt, ID_MAGIC_LIGHT, 50, 0, /* Permanent */
  2, 0, 0,
  TIF_CHANGE_LIGHT_ADD, TIF_NONE, TIF_CHANGE_LIGHT_SUB,
  APF_LIGHT_DARK);
  quit;
}
dilend

dilbegin darkness(medi:unitptr, tgt : unitptr, arg : string,
   hm : integer, effect : string);
external
  integer skill_duration (i : integer);

code
{
  if (isaff(tgt, ID_MAGIC_DARK))
    return;

  if (hm < 0)
    quit;

  hm := skill_duration (hm);

  /* 1 light source */
  addaff(tgt, ID_MAGIC_DARK, hm, WAIT_SEC*30,
  -1, 0, 0,
  TIF_CHANGE_LIGHT_SUB, TIF_NONE, TIF_CHANGE_LIGHT_ADD,
  APF_LIGHT_DARK);
  quit;
}
dilend

dilbegin cont_darkness(medi:unitptr, tgt : unitptr, arg : string,
        hm : integer, effect : string);
external
  integer skill_duration (i : integer);

code
{
  if (isaff(tgt, ID_MAGIC_DARK))
    return;

  if (hm < 0)
    quit;

  hm := skill_duration (hm);

  /* 2 light sources */
  addaff(tgt, ID_MAGIC_DARK, 50, 0,
  -2, 0, 0,
  TIF_CHANGE_LIGHT_SUB, TIF_NONE, TIF_CHANGE_LIGHT_ADD,
  APF_LIGHT_DARK);
  quit;
}
dilend

dilbegin det_align(medi:unitptr, tgt : unitptr, arg : string,
    hm : integer, effect : string);
external
  integer skill_duration (i : integer);
code
{
  if (hm < 0)
  {
     act("Nothing happens.", A_ALWAYS, self, null, null, TO_CHAR);
     quit;
  }

  hm := skill_duration (hm);

  addaff(tgt, ID_DETECT_ALIGN, hm, WAIT_SEC*30,
  CHAR_DETECT_ALIGN, 0, 0,
  TIF_EYES_TINGLE, TIF_NONE, TIF_EYES_TINGLE,
  APF_MOD_CHAR_FLAGS);
  quit;
}
dilend


dilbegin det_invis(medi:unitptr, tgt : unitptr, arg : string,
    hm : integer, effect : string);
external
  integer skill_duration (i : integer);
code
{
  if (hm < 0)
  {
     act("Nothing happens.", A_ALWAYS, self, null, null, TO_CHAR);
     quit;
  }

  hm := skill_duration (hm);

  addaff(tgt, ID_DETECT_INVISIBLE, hm, WAIT_SEC*30,
  CHAR_DETECT_INVISIBLE, 0, 0,
  TIF_EYES_TINGLE, TIF_NONE, TIF_EYES_TINGLE,
  APF_MOD_CHAR_FLAGS);
  quit;
}
dilend


dilbegin det_magic(medi:unitptr, tgt : unitptr, arg : string,
    hm : integer, effect : string);
external
  integer skill_duration (i : integer);
code
{
  if (hm < 0)
  {
     act("Nothing happens.", A_ALWAYS, self, null, null, TO_CHAR);
     quit;
  }

  hm := skill_duration (hm);

  addaff(tgt, ID_DETECT_MAGIC, hm, WAIT_SEC*30,
  CHAR_DETECT_MAGIC, 0, 0,
  TIF_EYES_TINGLE, TIF_NONE, TIF_EYES_TINGLE,
  APF_MOD_CHAR_FLAGS);
  quit;
}
dilend


dilbegin det_poison(medi:unitptr, tgt : unitptr, arg : string,
     hm : integer, effect : string);
external
  integer skill_duration (i : integer);
code
{
  if (hm < 0)
  {
     act("Nothing happens.", A_ALWAYS, self, null, null, TO_CHAR);
     quit;
  }

  hm := skill_duration (hm);

  addaff(tgt, ID_DETECT_POISON, hm, WAIT_SEC*30,
  CHAR_DETECT_POISON, 0, 0,
  TIF_EYES_TINGLE, TIF_NONE, TIF_EYES_TINGLE,
  APF_MOD_CHAR_FLAGS);
  quit;
}
dilend


dilbegin det_undead(medi:unitptr, tgt : unitptr, arg : string,
     hm : integer, effect : string);
external
  integer skill_duration (i : integer);
code
{
  if (hm < 0)
  {
     act("Nothing happens.", A_ALWAYS, self, null, null, TO_CHAR);
     quit;
  }

  hm := skill_duration (hm);

  addaff(tgt, ID_DETECT_UNDEAD, hm, WAIT_SEC*30,
  CHAR_DETECT_UNDEAD, 0, 0,
  TIF_EYES_TINGLE, TIF_NONE, TIF_EYES_TINGLE,
  APF_MOD_CHAR_FLAGS);
  quit;
}
dilend


dilbegin det_curse(medi:unitptr, tgt : unitptr, arg : string,
    hm : integer, effect : string);
external
  integer skill_duration (i : integer);
code
{
  if (hm < 0)
  {
     act("Nothing happens.", A_ALWAYS, self, null, null, TO_CHAR);
     quit;
  }

  hm := skill_duration (hm);

  addaff(tgt, ID_DETECT_CURSE, hm, WAIT_SEC*30,
  CHAR_DETECT_CURSE, 0, 0,
  TIF_EYES_TINGLE, TIF_NONE, TIF_EYES_TINGLE,
  APF_MOD_CHAR_FLAGS);
  quit;
}
dilend


dilbegin sense_life(medi:unitptr, tgt : unitptr, arg : string,
     hm : integer, effect : string);
external
  integer skill_duration (i : integer);
code
{
  if (hm < 0)
  {
     act("Nothing happens.", A_ALWAYS, self, null, null, TO_CHAR);
     quit;
  }

  hm := skill_duration (hm);

  addaff(tgt, ID_DETECT_LIFE, hm, WAIT_SEC*30,
  CHAR_DETECT_LIFE, 0, 0,
  TIF_EYES_TINGLE, TIF_NONE, TIF_EYES_TINGLE,
  APF_MOD_CHAR_FLAGS);
  quit;
}
dilend


dilbegin cure_light(medi:unitptr, tgt : unitptr, arg : string,
     hm : integer, effect : string);
external
  add_hitpoints(u : unitptr, i : integer);
  integer hit_limit(i : integer);

var
 heal : integer;

code
{
  /*
     Spell Cure Light Wounds
     This spell cures minor wounds, or partly heals major wounds
     of the target character.
     */

  if ((not RACE_IS_HUMANOID(tgt.race)) and (not RACE_IS_MAMMAL(tgt.race)))
    hm := -1;

  if (hm < 0)
  {
     act("Nothing happens.", A_ALWAYS, self, null, null, TO_CHAR);
     quit;
  }

  heal := hit_limit(1 + hm);
  heal := heal / 8;

  add_hitpoints(tgt, heal);

  if (effect == "")
  {
     if (self != tgt)
        act("$3n looks better.", A_SOMEONE, self, null, tgt, TO_CHAR);
     act("You feel better.", A_SOMEONE, self, null, tgt, TO_VICT);
  }
  else
    effect(medi, tgt, heal);

  quit;
}
dilend


dilbegin cure_serious(medi:unitptr, tgt : unitptr, arg : string,
       hm : integer, effect : string);
external
  add_hitpoints(u : unitptr, i : integer);
  integer hit_limit(i : integer);

var
 heal : integer;

code
{
  /*
     Spell Cure Light Wounds
     This spell cures minor wounds, or partly heals major wounds
     of the target character.
     */

  if ((not RACE_IS_HUMANOID(tgt.race)) and (not RACE_IS_MAMMAL(tgt.race)))
    hm := -1;

  if (hm < 0)
  {
     act("Nothing happens.", A_ALWAYS, self, null, null, TO_CHAR);
     quit;
  }

  heal := hit_limit(1 + hm);
  heal := heal / 4;

  add_hitpoints(tgt, heal);

  if (self != tgt)
     act("$3n looks better.", A_SOMEONE, self, null, tgt, TO_CHAR);
  act("You feel better.", A_SOMEONE, self, null, tgt, TO_VICT);
  quit;
}
dilend


dilbegin heal(medi:unitptr, tgt : unitptr, arg : string,
      hm : integer, effect : string);
external
  add_hitpoints(u : unitptr, i : integer);
  integer hit_limit(i : integer);

var
 heal : integer;

code
{
  /*
     Spell Cure Light Wounds
     This spell cures minor wounds, or partly heals major wounds
     of the target character.
     */

  if ((not RACE_IS_HUMANOID(tgt.race)) and (not RACE_IS_MAMMAL(tgt.race)))
    hm := -1;

  if (hm < 0)
  {
     act("Nothing happens.", A_ALWAYS, self, null, null, TO_CHAR);
     quit;
  }

  heal := hit_limit(1 + hm);
  heal := heal / 2;

  add_hitpoints(tgt, heal);

  if (self != tgt)
     act("$3n looks better.", A_SOMEONE, self, null, tgt, TO_CHAR);
  act("You feel better.", A_SOMEONE, self, null, tgt, TO_VICT);
  quit;
}
dilend


dilbegin bless(medi:unitptr, tgt : unitptr, arg : string,
       hm : integer, effect : string);
code
{
  /*
     Spell Bless:
     This spell raises the gods good attention to a character.
     With divine intervention, the characters DIV, MAG, DEX and STR
     is raised temporarily.
     */

  if ((not RACE_IS_HUMANOID(tgt.race)) and (not RACE_IS_MAMMAL(tgt.race)))
    hm := -1;

  if ((hm < 0) or isaff(tgt, ID_BLESS))
  {
     act("Nothing happens.", A_ALWAYS, self, null, null, TO_CHAR);
     quit;
  }

  hm := 1 + hm / 10;
  if (hm > 10) hm := 10;

  addaff(tgt, ID_BLESS, 10, WAIT_SEC*30,
  ABIL_DIV, hm, 0, TIF_BLESS_ON, TIF_BLESS_TICK, TIF_BLESS_OFF,
  APF_ABILITY);

  addaff(tgt, ID_BLESS, 10, WAIT_SEC*30,
  ABIL_DEX, hm, 0, TIF_NONE, TIF_NONE, TIF_NONE,
  APF_ABILITY);

  addaff(tgt, ID_BLESS, 10, WAIT_SEC*30,
  ABIL_STR, hm, 0, TIF_NONE, TIF_NONE, TIF_NONE,
  APF_ABILITY);

  addaff(tgt, ID_BLESS, 10, WAIT_SEC*30,
  ABIL_BRA, hm, 0, TIF_NONE, TIF_NONE, TIF_NONE,
  APF_ABILITY);

  /* act("$1n lay hands on $3n and chants softly.",
     A_SOMEONE, sa->caster, 0, sa->target, TO_NOTVICT);
     act("You lay hands on $3n and chant softly.",
     A_SOMEONE, sa->caster, 0, sa->target, TO_CHAR);
     act("$1n lay hands on you and chant softly.",
     A_SOMEONE, sa->caster, 0, sa->target, TO_VICT); */

  quit;
}
dilend


dilbegin curse(medi:unitptr, tgt : unitptr, arg : string,
       hm : integer, effect : string);

external
  provoked_attack (victim : unitptr, ch : unitptr);
  integer skill_duration (hm : integer);

code
{
  /* Spell Curse:
     This spell raises the gods bad attention to a character.
     With divine intervention, the characters DIV, MAG, DEX and STR
     is lowered temporarily. The target will especialy experience
     dificulty casting spells. */

  provoked_attack (tgt, self);

  if (isaff(tgt, ID_CURSE) or (hm < 0))
  {
     act("Nothing happens.", A_ALWAYS, self, null, null, TO_CHAR);
     quit;
  }

  hm := skill_duration (hm);

  if (tgt.type & (UNIT_ST_PC | UNIT_ST_NPC))
  {
     addaff(tgt, ID_CURSE, hm, WAIT_SEC*30,
     ABIL_STR, -3, 0, TIF_CURSE_ON, TIF_NONE, TIF_CURSE_OFF,
     APF_ABILITY);

     addaff(tgt, ID_CURSE, hm, WAIT_SEC*30,
     ABIL_DEX, -3, 0, TIF_NONE, TIF_NONE, TIF_NONE,
     APF_ABILITY);

     addaff(tgt, ID_CURSE, hm, WAIT_SEC*30,
     ABIL_BRA, -3, 0, TIF_NONE, TIF_NONE, TIF_NONE,
     APF_ABILITY);

     addaff(tgt, ID_CURSE, hm, WAIT_SEC*30,
     ABIL_CHA, -3, 0, TIF_NONE, TIF_NONE, TIF_NONE,
     APF_ABILITY);

     addaff(tgt, ID_CURSE, hm, WAIT_SEC*30,
     ABIL_CON, -3, 0, TIF_NONE, TIF_NONE, TIF_NONE,
     APF_ABILITY);

     /* act("$1n lay hands on $3n and chant in a strange tounge.",
 A_SOMEONE, sa->caster, 0, sa->target, TO_NOTVICT);
 act("You lay hands on $3n and chant in a strange tounge.",
 A_SOMEONE, sa->caster, 0, sa->target, TO_CHAR);
 act("$1n lay hands on you and chant in a strange tounge.",
 A_SOMEONE, sa->caster, 0, sa->target, TO_VICT); */

  }
  else if (tgt.type == UNIT_ST_OBJ)
  {
     addaff(tgt, ID_CURSE, hm, WAIT_SEC*30,
     OBJ_NO_UNEQUIP, 0, 0, TIF_CURSE_ON, TIF_NONE, TIF_CURSE_OFF,
     APF_MOD_OBJ_FLAGS);

     /* act("$1n lay hands on $3n and chant in a strange tounge.",
 A_SOMEONE, sa->caster, 0, sa->target, TO_ROOM);
 act("You lay hands on $3n and chant in a strange tounge.",
 A_SOMEONE, sa->caster, 0, sa->target, TO_CHAR); */
  }
  else
    log("Curse spell error.");

  quit;
}
dilend

dilbegin raise_div(medi:unitptr, tgt : unitptr, arg : string,
           hm : integer, effect : string);
code
{

if ((isaff(tgt,ID_SPL_RAISE_DIV)) or
(hm<0))
  {
 if (tgt!=self)
   act ("The magic disapates as it is cast on $2n",
 A_ALWAYS,self,tgt,null,TO_CHAR);
 else
   act ("The magic disapates as it is cast on you.",
 A_ALWAYS,self,tgt,null,TO_CHAR);
     if (effect != "")
        effect(tgt, medi, -1);
        quit;
        }

     hm := hm/10+1;
     if (hm>10)
hm := 10;

addaff(tgt, ID_SPL_RAISE_DIV, 20, WAIT_SEC*30,
       ABIL_DIV, hm, 0, TIF_DIV_INC, TIF_NONE, TIF_DIV_DEC,
       APF_ABILITY);
  if (effect != "")
     effect(tgt, medi, hm);


  quit;
}
dilend

dilbegin raise_mag(medi:unitptr, tgt : unitptr, arg : string,
           hm : integer, effect : string);
code
{

if ((isaff(tgt,ID_SPL_RAISE_MAG)) or
(hm<0))
  {
 if (tgt!=self)
   act ("The magic disapates as it is cast on $2n",
 A_ALWAYS,self,tgt,null,TO_CHAR);
 else
   act ("The magic disapates as it is cast on you.",
 A_ALWAYS,self,tgt,null,TO_CHAR);
     if (effect != "")
        effect(tgt, medi, -1);
        quit;
        }

     hm := hm/10+1;
     if (hm>10)
hm := 10;

addaff(tgt, ID_SPL_RAISE_MAG, 20, WAIT_SEC*30,
       ABIL_MAG, hm, 0, TIF_MAG_INC, TIF_NONE, TIF_MAG_DEC,
       APF_ABILITY);
  if (effect != "")
     effect(tgt, medi, hm);


  quit;
}
dilend

dilbegin raise_str(medi:unitptr, tgt : unitptr, arg : string,
           hm : integer, effect : string);
code
{

if ((isaff(tgt,ID_SPL_RAISE_STR)) or
(hm<0))
  {
 if (tgt!=self)
   act ("The magic disapates as it is cast on $2n",
 A_ALWAYS,self,tgt,null,TO_CHAR);
 else
   act ("The magic disapates as it is cast on you.",
 A_ALWAYS,self,tgt,null,TO_CHAR);
     if (effect != "")
        effect(tgt, medi, -1);
        quit;
        }

     hm := hm/10+1;
     if (hm>10)
hm := 10;

addaff(tgt, ID_SPL_RAISE_STR, 20, WAIT_SEC*30,
       ABIL_STR, hm, 0, TIF_STR_INC, TIF_NONE, TIF_STR_DEC,
       APF_ABILITY);
  if (effect != "")
     effect(tgt, medi, hm);


  quit;
}
dilend

dilbegin raise_dex(medi:unitptr, tgt : unitptr, arg : string,
           hm : integer, effect : string);
code
{

if ((isaff(tgt,ID_SPL_RAISE_DEX)) or
(hm<0))
  {
 if (tgt!=self)
   act ("The magic disapates as it is cast on $2n",
 A_ALWAYS,self,tgt,null,TO_CHAR);
 else
   act ("The magic disapates as it is cast on you.",
 A_ALWAYS,self,tgt,null,TO_CHAR);
     if (effect != "")
        effect(tgt, medi, -1);
        quit;
        }

     hm := hm/10+1;
     if (hm>10)
hm := 10;

addaff(tgt, ID_SPL_RAISE_DEX, 20, WAIT_SEC*30,
       ABIL_DEX, hm, 0, TIF_DEX_INC, TIF_NONE, TIF_DEX_DEC,
       APF_ABILITY);
  if (effect != "")
     effect(tgt, medi, hm);


  quit;
}
dilend

dilbegin raise_con(medi:unitptr, tgt : unitptr, arg : string,
           hm : integer, effect : string);
code
{

if ((isaff(tgt,ID_SPL_RAISE_CON)) or
(hm<0))
  {
 if (tgt!=self)
   act ("The magic disapates as it is cast on $2n",
 A_ALWAYS,self,tgt,null,TO_CHAR);
 else
   act ("The magic disapates as it is cast on you.",
 A_ALWAYS,self,tgt,null,TO_CHAR);
     if (effect != "")
        effect(tgt, medi, -1);
        quit;
        }

     hm := hm/10+1;
     if (hm>10)
hm := 10;

addaff(tgt, ID_SPL_RAISE_CON, 20, WAIT_SEC*30,
       ABIL_CON, hm, 0, TIF_CON_INC, TIF_NONE, TIF_CON_DEC,
       APF_ABILITY);
  if (effect != "")
     effect(tgt, medi, hm);


  quit;
}
dilend
dilbegin raise_cha(medi:unitptr, tgt : unitptr, arg : string,
           hm : integer, effect : string);
code
{

if ((isaff(tgt,ID_SPL_RAISE_CHA)) or
(hm<0))
  {
 if (tgt!=self)
   act ("The magic disapates as it is cast on $2n",
 A_ALWAYS,self,tgt,null,TO_CHAR);
 else
   act ("The magic disapates as it is cast on you.",
 A_ALWAYS,self,tgt,null,TO_CHAR);
     if (effect != "")
        effect(tgt, medi, -1);
        quit;
        }

     hm := hm/10+1;
     if (hm>10)
hm := 10;

addaff(tgt, ID_SPL_RAISE_CHA, 20, WAIT_SEC*30,
       ABIL_CHA, hm, 0, TIF_CHA_INC, TIF_NONE, TIF_CHA_DEC,
       APF_ABILITY);
  if (effect != "")
     effect(tgt, medi, hm);


  quit;
}
dilend

dilbegin raise_bra(medi:unitptr, tgt : unitptr, arg : string,
           hm : integer, effect : string);
code
{

if ((isaff(tgt,ID_SPL_RAISE_BRA)) or
(hm<0))
  {
 if (tgt!=self)
   act ("The magic disapates as it is cast on $2n",
 A_ALWAYS,self,tgt,null,TO_CHAR);
 else
   act ("The magic disapates as it is cast on you.",
 A_ALWAYS,self,tgt,null,TO_CHAR);
     if (effect != "")
        effect(tgt, medi, -1);
        quit;
        }

     hm := hm/10+1;
     if (hm>10)
hm := 10;

addaff(tgt, ID_SPL_RAISE_BRA, 20, WAIT_SEC*30,
       ABIL_BRA, hm, 0, TIF_BRA_INC, TIF_NONE, TIF_BRA_DEC,
       APF_ABILITY);
  if (effect != "")
     effect(tgt, medi, hm);


  quit;
}
dilend


dilbegin raise_divine(medi:unitptr, tgt : unitptr, arg : string,
           hm : integer, effect : string);
code
{

if ((isaff(tgt,ID_SPL_RAISE_DIVINE)) or
(hm<0))
  {
 if (tgt!=self)
   act ("The magic disapates as it is cast on $2n",
 A_ALWAYS,self,tgt,null,TO_CHAR);
 else
   act ("The magic disapates as it is cast on you.",
 A_ALWAYS,self,tgt,null,TO_CHAR);
     if (effect != "")
        effect(tgt, medi, -1);
        quit;
        }

     hm := hm/10+1;
     if (hm>10)
hm := 10;

addaff(tgt, ID_SPL_RAISE_DIVINE, 20, WAIT_SEC*30,
       SPL_DIVINE, hm, 0, TIF_PROTECT_INC, TIF_NONE, TIF_PROTECT_DEC,
       APF_SPELL_ADJ);
  if (effect != "")
     effect(tgt, medi, hm);


  quit;
}
dilend

dilbegin raise_heat(medi:unitptr, tgt : unitptr, arg : string,
           hm : integer, effect : string);
code
{

if ((isaff(tgt,ID_SPL_RAISE_HEAT)) or
(hm<0))
  {
 if (tgt!=self)
   act ("The magic disapates as it is cast on $2n",
 A_ALWAYS,self,tgt,null,TO_CHAR);
 else
   act ("The magic disapates as it is cast on you.",
 A_ALWAYS,self,tgt,null,TO_CHAR);
     if (effect != "")
        effect(tgt, medi, -1);
        quit;
        }

     hm := hm/10+1;
     if (hm>10)
hm := 10;

addaff(tgt, ID_SPL_RAISE_HEAT, 20, WAIT_SEC*30,
       SPL_HEAT, hm, 0, TIF_PROTECT_INC, TIF_NONE, TIF_PROTECT_DEC,
       APF_SPELL_ADJ);
  if (effect != "")
     effect(tgt, medi, hm);


  quit;
}
dilend

dilbegin raise_summoning(medi:unitptr, tgt : unitptr, arg : string,
           hm : integer, effect : string);
code
{

if ((isaff(tgt,ID_SPL_RAISE_SUMMONING)) or
(hm<0))
  {
 if (tgt!=self)
   act ("The magic disapates as it is cast on $2n",
 A_ALWAYS,self,tgt,null,TO_CHAR);
 else
   act ("The magic disapates as it is cast on you.",
 A_ALWAYS,self,tgt,null,TO_CHAR);
     if (effect != "")
        effect(tgt, medi, -1);
        quit;
        }

     hm := hm/10+1;
     if (hm>10)
hm := 10;

addaff(tgt, ID_SPL_RAISE_SUMMONING, 20, WAIT_SEC*30,
       SPL_SUMMONING, hm, 0, TIF_PROTECT_INC, TIF_NONE, TIF_PROTECT_DEC,
       APF_SPELL_ADJ);
  if (effect != "")
     effect(tgt, medi, hm);


  quit;
}
dilend

dilbegin raise_cold(medi:unitptr, tgt : unitptr, arg : string,
           hm : integer, effect : string);
code
{

if ((isaff(tgt,ID_SPL_RAISE_COLD)) or
(hm<0))
  {
 if (tgt!=self)
   act ("The magic disapates as it is cast on $2n",
 A_ALWAYS,self,tgt,null,TO_CHAR);
 else
   act ("The magic disapates as it is cast on you.",
 A_ALWAYS,self,tgt,null,TO_CHAR);
     if (effect != "")
        effect(tgt, medi, -1);
        quit;
        }

     hm := hm/10+1;
     if (hm>10)
hm := 10;

addaff(tgt, ID_SPL_RAISE_COLD, 20, WAIT_SEC*30,
       SPL_COLD, hm, 0, TIF_PROTECT_INC, TIF_NONE, TIF_PROTECT_DEC,
       APF_SPELL_ADJ);
  if (effect != "")
     effect(tgt, medi, hm);


  quit;
}
dilend

dilbegin raise_elect(medi:unitptr, tgt : unitptr, arg : string,
           hm : integer, effect : string);
code
{

if ((isaff(tgt,ID_SPL_RAISE_CELL)) or
(hm<0))
  {
 if (tgt!=self)
   act ("The magic disapates as it is cast on $2n",
 A_ALWAYS,self,tgt,null,TO_CHAR);
 else
   act ("The magic disapates as it is cast on you.",
 A_ALWAYS,self,tgt,null,TO_CHAR);
     if (effect != "")
        effect(tgt, medi, -1);
        quit;
        }

     hm := hm/10+1;
     if (hm>10)
hm := 10;

addaff(tgt, ID_SPL_RAISE_CELL, 20, WAIT_SEC*30,
       SPL_CELL, hm, 0, TIF_PROTECT_INC, TIF_NONE, TIF_PROTECT_DEC,
       APF_SPELL_ADJ);
  if (effect != "")
     effect(tgt, medi, hm);


  quit;
}
dilend

dilbegin raise_poison(medi:unitptr, tgt : unitptr, arg : string,
           hm : integer, effect : string);
code
{

if ((isaff(tgt,ID_SPL_RAISE_INTERNAL)) or
(hm<0))
  {
 if (tgt!=self)
   act ("The magic disapates as it is cast on $2n",
 A_ALWAYS,self,tgt,null,TO_CHAR);
 else
   act ("The magic disapates as it is cast on you.",
 A_ALWAYS,self,tgt,null,TO_CHAR);
     if (effect != "")
        effect(tgt, medi, -1);
        quit;
        }

     hm := hm/10+1;
     if (hm>10)
hm := 10;

addaff(tgt, ID_SPL_RAISE_INTERNAL, 20, WAIT_SEC*30,
       SPL_INTERNAL, hm, 0, TIF_PROTECT_INC, TIF_NONE, TIF_PROTECT_DEC,
       APF_SPELL_ADJ);
  if (effect != "")
     effect(tgt, medi, hm);


  quit;
}
dilend

dilbegin raise_acid(medi:unitptr, tgt : unitptr, arg : string,
           hm : integer, effect : string);
code
{

if ((isaff(tgt,ID_SPL_RAISE_EXTERNAL)) or
(hm<0))
  {
 if (tgt!=self)
   act ("The magic disapates as it is cast on $2n",
 A_ALWAYS,self,tgt,null,TO_CHAR);
 else
   act ("The magic disapates as it is cast on you.",
 A_ALWAYS,self,tgt,null,TO_CHAR);
     if (effect != "")
        effect(tgt, medi, -1);
        quit;
        }

     hm := hm/10+1;
     if (hm>10)
hm := 10;

addaff(tgt, ID_SPL_RAISE_EXTERNAL, 20, WAIT_SEC*30,
       SPL_EXTERNAL, hm, 0, TIF_PROTECT_INC, TIF_NONE, TIF_PROTECT_DEC,
       APF_SPELL_ADJ);
  if (effect != "")
     effect(tgt, medi, hm);


  quit;
}
dilend

dilbegin mind_shield(medi:unitptr, tgt : unitptr, arg : string,
           hm : integer, effect : string);
code
{

if ((isaff(tgt,ID_SPL_RAISE_MIND)) or
(hm<0))
  {
 if (tgt!=self)
   act ("The magic disapates as it is cast on $2n",
 A_ALWAYS,self,tgt,null,TO_CHAR);
 else
   act ("The magic disapates as it is cast on you.",
 A_ALWAYS,self,tgt,null,TO_CHAR);
     if (effect != "")
        effect(tgt, medi, -1);
        quit;
        }

     hm := hm/10+1;
     if (hm>10)
hm := 10;

addaff(tgt, ID_SPL_RAISE_MIND, 20, WAIT_SEC*30,
       SPL_MIND, hm, 0, TIF_PROTECT_INC, TIF_NONE, TIF_PROTECT_DEC,
       APF_SPELL_ADJ);
  if (effect != "")
     effect(tgt, medi, hm);


  quit;
}
dilend


dilbegin locate_object(medi:unitptr, tgt : unitptr, arg : string,
               hm : integer, effect : string);
external
  unitptr unit_char (u : unitptr);

var
  u : unitptr;
code
{
  if (hm >=0)
  {
     act("$2n at $3t", A_SOMEONE, self, tgt, tgt.outside.title, TO_CHAR);
  }
  else
  {
     act("You feel confused.", A_ALWAYS, self, null, null, TO_CHAR);

     if (hm < -50)
     {
        u := unit_char (tgt);
        act("You realize that $2n attempted to locate your $3n.",
            A_ALWAYS, u, self, tgt, TO_CHAR);
     }
  }
  quit;
}
dilend



dilbegin locate_char(medi:unitptr, targ : unitptr, arg : string,
             hm : integer, effect : string);
code
{
  if ( (hm > 0) and RACE_IS_HUMANOID(targ.race) )
  {
     act("$2n at $3t", A_SOMEONE, self, targ, targ.outside.title, TO_CHAR);
  }
  else
  {
     act("You feel confused.", A_ALWAYS, self, null, null, TO_CHAR);

     if (hm < -25)
     {
        act("You realize that $2n attempted to locate you.",
            A_ALWAYS, targ, self, null, TO_CHAR);
     }
  }
  quit;
}
dilend



dilbegin blind(medi:unitptr, tgt : unitptr, arg : string,
       hm : integer, effect : string);

external
  provoked_attack (victim : unitptr, ch : unitptr);
  integer skill_duration (hm : integer);

code
{

  provoked_attack (tgt, self);

  if (hm >= 0)
  {
     hm := skill_duration (hm);

     addaff(tgt, ID_BLIND_CHAR, hm, WAIT_SEC*30,
     CHAR_BLIND, 0, 0, TIF_BLIND_ON, TIF_NONE, TIF_BLIND_OFF,
     APF_MOD_CHAR_FLAGS);
  }
  quit;
}
dilend


dilbegin create_food(medi:unitptr, tgt : unitptr, arg : string,
      hm : integer, effect : string);
var
  food : unitptr;
code
{
  if (hm < 0)
  {
     act("Nothing happens.", A_ALWAYS, self, null, null, TO_CHAR);
  }
  else
  {
     food := load("magic_food@spells");
     act("You create $2n.", A_SOMEONE, self, food, null, TO_CHAR);
     act("$1n creates $2n.", A_SOMEONE, self, food, null, TO_ROOM);
  }
  quit;
}
dilend

dilbegin create_water(medi:unitptr, tgt : unitptr, arg : string,
       hm : integer, effect : string);
var
  water : unitptr;
code
{
  if (hm < 0)
  {
     act("Nothing happens.", A_ALWAYS, self, null, null, TO_CHAR);
  }
  else
  {
     water := load("magic_water@spells");
     act("You create $2n.", A_SOMEONE, self, water, null, TO_CHAR);
     act("$1n creates $2n.", A_SOMEONE, self, water, null, TO_ROOM);
  }
  quit;
}
dilend

dilbegin life_protection(medi:unitptr, tgt : unitptr, arg : string,
   hm : integer, effect : string);
external
integer skill_duration (hm : integer);
code
{
  if (hm < 0)
  {
     act("Nothing happens.", A_ALWAYS, self, null, null, TO_CHAR);
     quit;
  }

  hm := skill_duration (hm);

  addaff(tgt, ID_LIFE_PROTECTION, hm, WAIT_SEC*60*5,
  0, 0, 0, TIF_NONE, TIF_NONE, TIF_NONE,
  APF_NONE);

  act("$1n gestures warding signs in front of $3n.",
      A_HIDEINV, self, null, tgt, TO_NOTVICT);
  act("You protect the life force of $3n.",
      A_SOMEONE, self, null, tgt, TO_CHAR);
  act("$1n gestures in front of you and you feel your life force being "+
      "protected.",
      A_SOMEONE, self, null, tgt, TO_VICT);
  quit;
}
dilend

dilbegin energy_drain(medi:unitptr, tgt : unitptr, arg : string,
       hm : integer, effect : string);

external
  integer skill_duration (hm : integer);
  provoked_attack (victim : unitptr, ch : unitptr);

code
{
  provoked_attack (tgt, self);

  if (hm < 0)
  {
     act("You fail.", A_ALWAYS, self, null, null, TO_CHAR);
     quit;
  }

  if (isaff(tgt, ID_LIFE_PROTECTION))
  {
     act("As you touch $3n your drainage is prevented by a life "+
  "protection spell.",
  A_SOMEONE, self, null, tgt, TO_CHAR);
     act("$1n touches $3n and chant in a strange tounge with no result.",
  A_SOMEONE, self, null, tgt, TO_NOTVICT);
     act("$1n tries to drain your energy but your life force is protected.",
  A_SOMEONE, self, null, tgt, TO_VICT);
     subaff(tgt, ID_LIFE_PROTECTION);
     quit;
  }

  hm := skill_duration (hm);
  addaff(tgt, ID_ENERGY_DRAIN, hm, WAIT_SEC*30,
  ABIL_STR, -5, 0, TIF_NONE, TIF_NONE, TIF_NONE,
  APF_ABILITY);

  addaff(tgt, ID_ENERGY_DRAIN, hm, WAIT_SEC*30,
  ABIL_CON, -5, 0, TIF_NONE, TIF_NONE, TIF_NONE,
  APF_ABILITY);

  experience(-50, tgt); /* Loose XP! */

  act("$1n lay hands on $3n and chant in a strange tounge.",
      A_SOMEONE, self, null, tgt, TO_NOTVICT);
  act("You lay hands on $3n and chant in a strange tounge.",
      A_SOMEONE, self, null, tgt, TO_CHAR);
  act("$1n lay hands on you and drain your energy.",
      A_SOMEONE, self, null, tgt, TO_VICT);
  quit;
}
dilend

dilbegin word_of_recall(medi:unitptr, tgt : unitptr, arg : string,
  hm : integer, effect : string);
var s : string;
code
{
  if ((hm < 0) or dilfind("base_recall@spells", tgt))
  {
     act("Nothing happens.", A_ALWAYS, self, null, null, TO_CHAR);
     quit;
  }

  s := self.hometown;
  if ((s == null) or (s == ""))
    s := "temple@udgaard";

  dilcopy("base_recall@spells("+s+","+itoa(hm)+",0)", self);
  quit;
}
dilend

dilbegin drowse(medi:unitptr, tgt : unitptr, arg : string,
 hm : integer, effect : string);
external
provoked_attack (victim : unitptr, ch : unitptr);
var
  spd : integer;
code
{
  provoked_attack (tgt, self);

  if ((hm < 0) or (tgt.speed >= 20))
  {
     act("Nothing happens.", A_ALWAYS, self, null, null, TO_CHAR);
     quit;
  }

  spd := tgt.speed + 8;
  if (spd > 20)
    spd := 20;

  if (isaff(tgt, ID_SPEED))
    subaff(tgt, ID_SPEED);

  addaff(tgt, ID_SPEED, 1 + hm / 25, WAIT_SEC*15,
  spd, 0, 0, TIF_SPEED_WORSE, TIF_NONE, TIF_SPEED_BETTER,
  APF_SPEED);
  quit;
}
dilend


dilbegin slow(medi:unitptr, tgt : unitptr, arg : string,
      hm : integer, effect : string);
external
provoked_attack (victim : unitptr, ch : unitptr);
var
  spd : integer;
code
{
  provoked_attack (tgt, self);

  if ((hm < 0) or (tgt.speed >= 16))
  {
     act("Nothing happens.", A_ALWAYS, self, null, null, TO_CHAR);
     if (effect != "")
        effect(tgt, medi, -1);
     quit;
  }

  spd := tgt.speed + 4;
  if (spd > 16)
    spd := 16;

  if (isaff(tgt, ID_SPEED))
    subaff(tgt, ID_SPEED);

  addaff(tgt, ID_SPEED, 1 + hm / 25, WAIT_SEC*15,
  spd, 0, 0, TIF_SPEED_WORSE, TIF_NONE, TIF_SPEED_BETTER,
  APF_SPEED);
  if (effect != "")
     effect(tgt, medi, hm);
  quit;
}
dilend


dilbegin haste(medi:unitptr, tgt : unitptr, arg : string,
       hm : integer, effect : string);
var
  spd : integer;
code
{
  if ((hm < 0) or (tgt.speed <= 6))
  {
     act("Nothing happens.", A_ALWAYS, self, null, null, TO_CHAR);
     if (effect != "")
        effect(tgt, medi, -1);
     quit;
  }

  spd := tgt.speed - 6;
  if (spd < 6)
    spd := 6;

  if (isaff(tgt, ID_SPEED))
    subaff(tgt, ID_SPEED);

  addaff(tgt, ID_SPEED, 1 + hm / 25, WAIT_SEC*15,
  spd, 0, 0, TIF_SPEED_BETTER, TIF_NONE, TIF_SPEED_WORSE,
  APF_SPEED);

  if (effect != "")
     effect(tgt, medi, hm);

  quit;
}
dilend


dilbegin quicken(medi:unitptr, tgt : unitptr, arg : string,
  hm : integer, effect : string);
var
  spd : integer;
code
{
  if ((hm < 0) or (tgt.speed <= 9))
  {
     act("Nothing happens.", A_ALWAYS, self, null, null, TO_CHAR);
     quit;
  }

  spd := tgt.speed - 3;
  if (spd < 9)
    spd := 9;

  if (isaff(tgt, ID_SPEED))
    subaff(tgt, ID_SPEED);

  addaff(tgt, ID_SPEED, 1 + hm / 25, WAIT_SEC*15,
  spd, 0, 0, TIF_SPEED_BETTER, TIF_NONE, TIF_SPEED_WORSE,
  APF_SPEED);
  quit;
}
dilend


/* Improves the speed of a character by 3. Is not accumulative with other  */
/* speed spells such as haste.                                             */

dilbegin stun(medi : unitptr, tgt : unitptr, arg : string,
      hm : integer, effect : string);
external
provoked_attack (victim : unitptr, ch : unitptr);

code
{
  provoked_attack (tgt, self);

  if (hm < 0)
  {
     act("Nothing happens.", A_ALWAYS, self, null, null, TO_CHAR);
     quit;
  }

  change_speed(tgt, PULSE_VIOLENCE);  /* Slow him by one combat round */

  act("You stun $3n.", A_ALWAYS, self, null, tgt, TO_CHAR);

  act("$1n casts a spell upon you which makes you stunned.",
      A_ALWAYS, self, null, tgt, TO_VICT);

  act("$1n casts a powerful spell which stuns $3n.",
      A_ALWAYS, self, null, tgt, TO_NOTVICT);
  quit;
}
dilend



/* Humans & Animals - really hard (see hm) */
dilbegin hold(medi : unitptr, tgt : unitptr, arg : string,
      hm : integer, effect : string);

external
provoked_attack (victim : unitptr, ch : unitptr);
code
{
unset (self.charflags, CHAR_PEACEFUL);
provoked_attack(tgt, self);
set (self.charflags, CHAR_PEACEFUL);

  if ((hm < 35) or ((not RACE_IS_HUMANOID(tgt.race)) and
                   (not RACE_IS_MAMMAL(tgt.race))))
  {
     act("Nothing happens.", A_ALWAYS, self, null, null, TO_CHAR);
     quit;
  }

  change_speed(tgt, 5*PULSE_VIOLENCE);  /* Slow by 5 rounds */
  sendto ("1closetimer1", tgt);
  dilcopy ("block_wimpy@spells("+itoa(5*PULSE_VIOLENCE)+")", tgt);

  act("You successfully hold $3n.", A_ALWAYS, self, null, tgt, TO_CHAR);

  act("$1n engulfs you in magic leaving you unable to fight.",
      A_ALWAYS, self, null, tgt, TO_VICT);

  act("$1n casts a powerful spell which holds $3n.",
      A_ALWAYS, self, null, tgt, TO_NOTVICT);
  quit;

}
dilend


dilbegin hold_monster(medi : unitptr, tgt : unitptr,
        arg : string,
        hm : integer, effect : string);

external
provoked_attack(victim : unitptr, ch : unitptr);

var mod: integer;
   dump: integer;

code
{
if(isset(self.charflags, CHAR_PEACEFUL))
{
unset (self.charflags, CHAR_PEACEFUL); // So that provoked_attack
provoked_attack(tgt, self);            // doesn't fail
set (self.charflags, CHAR_PEACEFUL);
}

if (RACE_IS_HUMANOID(tgt.race))
        hm := hm - 25;

if (((hm >= 25) and (hm < 35)) or (RACE_IS_UNDEAD(tgt.race)))
        {
        act("Nothing happens.", A_ALWAYS, self, null, null, TO_CHAR);
        act ("$1n attempts to hold you but fails.",A_ALWAYS, self, null, tgt,TO_VICT);
        act ("$1n attempts to hold $3n but fails.",A_ALWAYS,self, null, tgt,TO_NOTVICT);
        quit;
        }

if (hm < 25)
        {
        change_speed(self, 3*PULSE_VIOLENCE);  /*slow caster by 3 rounds*/
        sendto ("1closetimer1", self); /* remove old wimpy block */
        dilcopy ("block_wimpy@spells("+itoa(3*PULSE_VIOLENCE)+")", self);

        act("Your spell misfires and you manage to hold yourself",
                A_ALWAYS,self,null, tgt, TO_CHAR);
        act("$1n attempts to hold you but manages to hold $1mself instead",
                A_ALWAYS, self, null, tgt, TO_VICT);
        act("$1n attemps to hold $3n ,but the spell misfires ,and $1n holds $1mself",
                A_ALWAYS, self, null, tgt, TO_NOTVICT);
        quit;
        }

if ((hm >=35) and (hm <45))
  {
        change_speed(self,3*PULSE_VIOLENCE);  /*slow caster 3 rounds */
        sendto ("1closetimer1", self); /* remove old wimpy block */
        dilcopy ("block_wimpy@spells("+itoa(3*PULSE_VIOLENCE)+")", self);

        change_speed(tgt, 3*PULSE_VIOLENCE);  /*slow target 3 rounds */
        sendto ("1closetimer1", tgt);
        dilcopy ("block_wimpy@spells("+itoa(3*PULSE_VIOLENCE)+")", tgt);

        act("Your spell misfires and you end up holding both of you",
                A_ALWAYS, self,null,tgt,TO_CHAR);
        act("$1n attempts to hold you but manages to hold you both instead",
                A_ALWAYS,self,null,tgt,TO_VICT);
        act("$1n attempts to hold $3n but misfires",
        A_ALWAYS,self,null,tgt,TO_NOTVICT);
        quit;
        }

if (hm < 60) mod := rnd(2,3)*PULSE_VIOLENCE;  /* Slow by up to 3 rounds */
else if (hm < 85) mod := rnd(2,4)*PULSE_VIOLENCE;  /* Slow by up to4 rounds */
else if (hm >= 85) mod := rnd(2,5)*PULSE_VIOLENCE;  /* Slow by up to 5 rounds */
else mod := 3*PULSE_VIOLENCE; /* Unprobable */

change_speed(tgt, mod);
sendto ("1closetimer1", tgt); /* remove old wimpy block */
dilcopy ("block_wimpy@spells("+itoa(mod)+")", tgt);

   act("You successfully hold $3n.", A_ALWAYS, self, null, tgt,
TO_CHAR);

   act("$1n engulfs you in magic leaving you unable to fight.",
       A_ALWAYS, self, null, tgt, TO_VICT);

   act("$1n casts a powerful spell which holds $3n.",
       A_ALWAYS, self, null, tgt, TO_NOTVICT);
   quit;
}
dilend


dilbegin recall aware block_wimpy(dur: integer);

var wimp: integer;

code
{

if (isset(self.charflags, CHAR_WIMPY))
   {
   wimp := TRUE;
   unset (self.charflags, CHAR_WIMPY);
   }

dilcopy ("hold_timer@spells("+itoa(dur)+")", self);

interrupt (SFB_CMD, (command("change") and ("wimpy" in argument)
          and (self == activator)), int_block);

:start:
wait (SFB_MSG, (self == activator) and (argument == "1stopwimpyblock1"));

if (wimp == TRUE)
   set (self.charflags, CHAR_WIMPY);

quit;

:int_block:
block;

goto start;

}

dilend

dilbegin recall hold_timer(dur: integer);

/* Necessary so that block_wimpy's interrupt does not tamper with timer */

code
{

interrupt (SFB_MSG, (argument == "1closetimer1"), ending );

heartbeat:= dur;
wait (SFB_TICK, TRUE);

:ending:
sendto ("1stopwimpyblock1", self);

quit;

}

dilend


dilbegin hold_undead(medi : unitptr, tgt : unitptr,
        arg : string,
      hm : integer, effect : string);

external
provoked_attack (victim : unitptr, ch : unitptr);
code
{
unset (self.charflags, CHAR_PEACEFUL);
provoked_attack(tgt, self);
set (self.charflags, CHAR_PEACEFUL);

  if ((hm < 35) or (not RACE_IS_UNDEAD(tgt.race)))
  {
     act("Nothing happens.", A_ALWAYS, self, null, null, TO_CHAR);
     quit;
  }

  change_speed(tgt, 5*PULSE_VIOLENCE);  /* Slow by 5 rounds */
  sendto ("1closetimer1", tgt);
  dilcopy ("block_wimpy@spells("+itoa(5*PULSE_VIOLENCE)+")", tgt);

  act("You successfully hold $3n.", A_ALWAYS, self, null, tgt, TO_CHAR);

  act("$1n engulfs you in magic leaving you unable to fight.",
      A_ALWAYS, self, null, tgt, TO_VICT);

  act("$1n casts a powerful spell which holds $3n.",
      A_ALWAYS, self, null, tgt, TO_NOTVICT);
  quit;
}
dilend




dilbegin leather_skin(medi : unitptr, tgt : unitptr,
     arg : string,
       hm : integer, effect : string);

external
provoked_attack (victim : unitptr, ch : unitptr);
code
{
  if ((hm < 0) or isaff(tgt, ID_NATURAL_ARMOUR))
  {
     act("Nothing happens.", A_ALWAYS, self, null, null, TO_CHAR);
     quit;
  }

  addaff(tgt, ID_NATURAL_ARMOUR, 1 + hm / 40, WAIT_SEC*75,
  ARM_LEATHER, 0, 0, TIF_ARMOUR_ON, TIF_NONE, TIF_ARMOUR_OFF,
  APF_NATURAL_ARMOUR);
  quit;
}
dilend


dilbegin bark_skin(medi : unitptr, tgt : unitptr,
     arg : string,
    hm : integer, effect : string);

code
{
  if ((hm < 0) or isaff(tgt, ID_NATURAL_ARMOUR))
  {
     act("Nothing happens.", A_ALWAYS, self, null, null, TO_CHAR);
     quit;
  }

  addaff(tgt, ID_NATURAL_ARMOUR, 1 + hm / 40, WAIT_SEC*60,
  ARM_HLEATHER, 0, 0, TIF_ARMOUR_ON, TIF_NONE, TIF_ARMOUR_OFF,
  APF_NATURAL_ARMOUR);
  quit;
}
dilend


dilbegin bone_skin(medi : unitptr, tgt : unitptr,
     arg : string,
    hm : integer, effect : string);

code
{
  if ((hm < 0) or isaff(tgt, ID_NATURAL_ARMOUR))
  {
     act("Nothing happens.", A_ALWAYS, self, null, null, TO_CHAR);
     quit;
  }

  addaff(tgt, ID_NATURAL_ARMOUR, 1 + hm / 40, WAIT_SEC*45,
  ARM_CHAIN, 0, 0, TIF_ARMOUR_ON, TIF_NONE, TIF_ARMOUR_OFF,
  APF_NATURAL_ARMOUR);
  quit;
}
dilend


dilbegin stone_skin(medi : unitptr, tgt : unitptr,
     arg : string,
     hm : integer, effect : string);

code
{
  if ((hm < 0) or isaff(tgt, ID_NATURAL_ARMOUR))
  {
     act("Nothing happens.", A_ALWAYS, self, null, null, TO_CHAR);
     quit;
  }

  addaff(tgt, ID_NATURAL_ARMOUR, 1 + hm / 40, WAIT_SEC*30,
  ARM_PLATE, 0, 0, TIF_ARMOUR_ON, TIF_NONE, TIF_ARMOUR_OFF,
  APF_NATURAL_ARMOUR);
  quit;
}
dilend



dilbegin prot_good(medi : unitptr, tgt : unitptr,
           arg : string,
    hm : integer, effect : string);

external
integer skill_duration (hm : integer);

code
{
  if ((hm < 0) or isaff(tgt, ID_PROT_GOOD))
  {
     act("Nothing happens.", A_ALWAYS, self, null, null, TO_CHAR);
     quit;
  }

  hm := skill_duration (hm);
  addaff(tgt, ID_PROT_GOOD, hm, WAIT_SEC*30,
  0, 0, 0, TIF_PROT_GOOD_ON, TIF_NONE, TIF_PROT_GOOD_OFF,
  APF_NONE);
  quit;
}
dilend



dilbegin prot_evil(medi : unitptr, tgt : unitptr,
           arg : string,
    hm : integer, effect : string);

external
integer skill_duration (hm : integer);

code
{
  if ((hm < 0) or isaff(tgt, ID_PROT_EVIL))
  {
     act("Nothing happens.", A_ALWAYS, self, null, null, TO_CHAR);
     quit;
  }

  hm := skill_duration (hm);
  addaff(tgt, ID_PROT_EVIL, hm, WAIT_SEC*30,
  0, 0, 0, TIF_PROT_EVIL_ON, TIF_NONE, TIF_PROT_EVIL_OFF,
  APF_NONE);
  quit;
}
dilend



dilbegin call_lightning(medi : unitptr, tgt : unitptr,
                arg : string,
  hm : integer, effect : string);
var
  u : unitptr;

code
{
  hm := 0;
  u := self.outside;

  while (u)
  {
     if (isset(u.flags, UNIT_FL_NO_WEATHER | UNIT_FL_INDOORS))
     {
 act("There is no access to the forces of nature from here.",
     A_ALWAYS, self, null, null, TO_CHAR);
 quit;
     }
     u := u.outside;
  }

  if (weather < SKY_RAINING)
  {
     act("There is no sign of a thunder storm yet.",
  A_ALWAYS, self, null, null, TO_CHAR);
     quit;
  }

  if (weather != SKY_LIGHTNING)
    hm := -50;

  hm := attack_spell(SPL_CALL_LIGHTNING, self, medi, tgt, hm, effect);
  quit;
}
dilend


dilbegin sun_ray(medi : unitptr, tgt : unitptr,
  arg : string,
  hm : integer, effect : string);
var
  u : unitptr;

code
{
  hm := 0;
  u := self.outside;

  while (u)
  {
     if (isset(u.flags, UNIT_FL_NO_WEATHER | UNIT_FL_INDOORS))
     {
 act("There is no access to the forces of nature from here.",
     A_ALWAYS, self, null, null, TO_CHAR);
 quit;
     }
     u := u.outside;
  }

  if (weather != SKY_CLOUDLESS)
  {
     act("The skies are not clear.",
  A_ALWAYS, self, null, null, TO_CHAR);
     quit;
  }

  if ((mudhour < 5) or (mudhour >= 21))
  {
     act("The sun has not rised yet.",
  A_ALWAYS, self, null, null, TO_CHAR);
     quit;
  }

  /* Most powerful at noon */
  if (mudhour < 12)
    hm := 18*(mudhour - 12);
  else
    hm := -15*(mudhour - 12);

  if (RACE_IS_UNDEAD(tgt.race))
    hm := hm + 100;

  hm := attack_spell(SPL_SUN_RAY, self, medi, tgt, hm, effect);
  quit;
}
dilend



dilbegin sleep_wait();
code
{
heartbeat:=PULSE_SEC*120;
wait (SFB_TICK, TRUE);
exec ("wake",self);
exec ("stand",self);
quit;
}
dilend


dilbegin string spc_parse (s:string);
var
slist:stringlist;
temp:string;
code
{
slist:=getwords(s);
temp:=slist.[0];
if ((temp=="cd") or
(temp=="cde") or
(temp=="cdef") or
(temp=="cdefe") or
(temp=="cdefec") or
(temp=="cdefect"))
return ("cdefect");
if ((temp=="sl") or
(temp=="sle") or
(temp=="slee") or
(temp=="sleep"))
return ("sleep");
if ((temp=="cle") or
(temp=="clea") or
(temp=="clear"))
return ("clear");

return (temp);
}
dilend

dilbegin string lst_parse(s : string);
var
i: integer;
bad: stringlist;
badstr: string;
code
{

bad:= {"quit","clear","cdefect","typo","bug","idea","password","sleep"}; /* insert any other blocks here */
/* NOTE...Sleep is not blocked, but picked up in the command code, function
subs as a parser :P */
i := 0;

while(i < length(bad))
{
if(s == left(bad.[i],length(s)))
{
badstr := bad.[i];
break;
}

i := i+1;
}

if(badstr) return(badstr);
else
return("aok");
}
dilend

dilbegin spl_command(medi : unitptr, tgt : unitptr, arg : string,
       hm : integer, effect : string);
external
provoked_attack (victim : unitptr, ch : unitptr);
string lst_parse(s : string);
var
tmp:string;
code
{
arg:=getword(arg);

tmp:= lst_parse(arg);

if((tmp != "aok") and (tmp != "sleep"))
{
if(tgt==self)
 act("Why not use the command '$2t'?", A_ALWAYS, self, tmp, null, TO_CHAR);
else
 act("Thats not nice! Why not ask them to '$2t'?",
 A_ALWAYS, self, tmp, null, TO_CHAR);
quit;
}

if (hm < 0)
 {
  act("You unsuccessfully tried to command $3n to '$2t'",
      A_SOMEONE, self, arg, tgt,TO_CHAR);
  act("$1n unsuccessfully tried to command $3n to '$2t'",
      A_SOMEONE, self, arg, tgt,TO_NOTVICT);
  act("$1n unsuccessfully tried to command you to '$2t'",
      A_SOMEONE, self, arg, tgt, TO_VICT);
  provoked_attack (tgt, self);
  quit;
  }

act ("You command $3n to '$2t'",
      A_SOMEONE, self, arg, tgt, TO_CHAR);
act ("$1n  commands you to '$2t'",
      A_SOMEONE, self, arg, tgt, TO_VICT);
act ("$1n  commands $3n to '$2t'",
      A_SOMEONE, self, arg, tgt, TO_NOTVICT);
      if ((tmp=="sleep") and
      (tgt.type==UNIT_ST_NPC))
      dilcopy ("sleep_wait@spells",tgt);
      unsecure (tgt);
if (tmp!="sleep")
{
exec (arg,tgt);
}
else
{
if ((tgt.position==POSITION_STANDING) or
 (tgt.position==POSITION_SITTING) or
 (tgt.position==POSITION_RESTING))
 {
 sendtext("You go to sleep.&n", tgt);
 act("$1n lies down and falls asleep.", A_HIDEINV, tgt, null, null, TO_REST);
 tgt.position:=POSITION_SLEEPING;
 position_update(tgt);
 quit;
 }
if (self.position==POSITION_SLEEPING)
 {
 sendtext("You are already sound asleep.&n", tgt);
 quit;
 }
if (tgt.position==POSITION_FIGHTING)
 {
 sendtext("Sleep while fighting? are you MAD?&n", tgt);
 quit;
 }
}
quit;
}
dilend

dilbegin sleep(medi : unitptr, tgt : unitptr, arg : string,
       hm : integer, effect : string);
external
provoked_attack (victim : unitptr, ch : unitptr);
code
{
  provoked_attack (tgt, self);


  if (not RACE_IS_HUMANOID(tgt.race))
    goto failure;

  if (hm >= 0)
  {
     dilcopy("spl_sleep@spells("+itoa(hm)+")", tgt);
     quit;
  }

  :failure:
  act("$1n unsuccessfully tried to make you sleep.",
      A_SOMEONE, self, null, tgt, TO_VICT);

  quit;
}
dilend



dilbegin dust_devil(medi : unitptr, tgt : unitptr, arg : string,
                   hm : integer, effect : string);
var
 u : unitptr;

code
{
  if (hm < 0)
  {
     act("Dust swirl around in the air.",
         A_SOMEONE, self, null, null, TO_ALL);
     quit;
  }

  u := load("dust_devil@spells");
  link(u, self.outside);

  act("$2n is summoned before you.",
      A_HIDEINV, self, u, null, TO_CHAR);

  act("$2n is summoned before $1n",
      A_HIDEINV, self, u, null, TO_ROOM);

  dilcopy("magic_summoned@spells("+itoa(hm)+")", u);
  dilcopy("master_servant@spells()", u);
  if (isset(self.pcflags,PC_PK_RELAXED))
  dilcopy ("catchit@spells(1)",u);
  else
  dilcopy ("catchit@spells(0)",u);


  exec("follow "+self.name, u);

  quit;
}
dilend



/* Can be cast on self while asleep! */
dilbegin awaken(medi : unitptr, tgt : unitptr,
               arg : string,
 hm : integer, effect : string);
code
{
  if (hm < 0)
  {
     act("Nothing happens.",
         A_ALWAYS, self, null, null, TO_CHAR);
     quit;
  }

  sendto("spl_awaken "+itoa(hm), tgt);
  quit;
}
dilend



dilbegin summer_rain(medi : unitptr, tgt : unitptr,
                    arg : string,
      hm : integer, effect : string);
var
  u : unitptr;

code
{
  if (hm < 0)
  {
     act("Nothing happens.",
         A_ALWAYS, self, null, null, TO_CHAR);
     quit;
  }

  u := self.outside;
  while (u)
  {
     if (isset(u.flags, UNIT_FL_NO_WEATHER | UNIT_FL_INDOORS))
     {
 act("There is no possibility of rain here.",
     A_ALWAYS, self, null, null, TO_CHAR);
 quit;
     }
     u := u.outside;
  }

  foreach (UNIT_ST_PC|UNIT_ST_NPC, u)
  {
     if (u.hp < u.max_hp)
     {
        act("Warm raindrops fall upon you, cleaning your wounds.",
            A_ALWAYS, u, null, null, TO_CHAR);
        u.hp := u.hp + 6;
        if (u.hp > u.max_hp)
          u.hp := u.max_hp;
        position_update(u);
     }
     else
       act("Warm raindrops fall upon you.",
           A_ALWAYS, u, null, null, TO_CHAR);
  }
  quit;
}
dilend



/* Can be cast on self while mortally wounded to get 0 hitpoints! */
dilbegin aid(medi : unitptr, tgt : unitptr, arg : string,
     hm : integer, effect : string);
var
  i : integer;

code
{
  if ((hm < 0) or (tgt.hp >= 0))
  {
     act("Nothing happens.", A_ALWAYS, self, null, null, TO_CHAR);
     quit;
  }

  tgt.hp := hm / 20;
  position_update(tgt);

  if (tgt != self)
  {
    act("You heal $3s bleeding wounds.",
        A_SOMEONE, self, null, tgt, TO_CHAR);

    act("Your bleeding wounds are closed by $1n.",
        A_SOMEONE, self, null, tgt, TO_VICT);

    act("$1n heals the bleeding wounds on $3n.",
        A_SOMEONE, self, null, tgt, TO_NOTVICT);
  }
  else
  {
    act("Your mortal wounds are healed.",
        A_SOMEONE, self, null, null, TO_CHAR);

    act("The bleeding wounds on $1n are magically healed.",
        A_SOMEONE, self, null, null, TO_ROOM);
  }
  quit;
}
dilend


/* Called from both 'self leaving' and 'leaving' */
/* Advanced for of flee. */
dilbegin leaving(medi : unitptr, tgt : unitptr, arg : string,
  hm : integer, effect : string);
var
  u : unitptr;
  i : integer;
  d : string;

code
{
  if (hm < 0)
  {
     act("Nothing happens.", A_SOMEONE, self, null, null, TO_CHAR);
     quit;
  }

  /* Find the room that the tgt is inside */

  u := self.outside;
  while (u.type != UNIT_ST_ROOM)
    u := u.outside;

  arg := getword(arg);

  if (arg in "north") {
    i := DIR_NORTH;
    d := "north"; }
  else if ((arg in "east") and (arg != "s")) {
    i := DIR_EAST;
    d := "east"; }
  else if ((arg in "south") and (arg != "u")) {
    i := DIR_SOUTH;
    d := "south"; }
  else if (arg in "west") {
    i := DIR_WEST;
    d := "west"; }
  else if (arg in "up") {
    i := DIR_UP;
    d := "up"; }
  else if (arg in "down") {
    i := DIR_DOWN;
    d := "down"; }
  else if ((arg in "northeast") or (arg == "ne")) {
    i := DIR_NORTHEAST;
    d := "northeast"; }
  else if ((arg in "northwest") or (arg == "nw")) {
    i := DIR_NORTHWEST;
    d := "northwest"; }
  else if ((arg in "southeast") or (arg == "se")) {
    i := DIR_SOUTHEAST;
    d := "southeast"; }
  else if ((arg in "southwest") or (arg == "sw")) {
    i := DIR_SOUTHWEST;
    d := "southwest"; }
  else
  {
     act("You must specify a direction to leave in.",
  A_SOMEONE, self, null, null, TO_CHAR);
     quit;
  }

  if ((not u.exit_to[i]) or (u.exit_info[i] & EX_CLOSED) or
      (u.exit_to[i].movement == SECT_WATER_SAIL))
  {
     act("No such direction.",
  A_SOMEONE, self, null, null, TO_CHAR);
     quit;
  }

if (self.type==UNIT_ST_PC)
if (not(paycheck(self,u.exit_to[i]))){
     act("You don't have access to that location, type 'help donation'.",
          A_ALWAYS, self, null, null, TO_CHAR);
     quit;
    }

if ("$no_leaving_clan" in self.outside.extra)
{
act ("Magical Clan powers stop you from succeeding in that spell.",
A_ALWAYS, self, null,null,TO_CHAR);
act ("Magical Clan powers stop $1n from casting the Leaving spell.",
A_ALWAYS, self, null,null,TO_REST);
quit;
}

  act("$1n vanishes.",
      A_HIDEINV, self, null, null, TO_ROOM);
  act("You are teleported "+d+".",
      A_SOMEONE, self, null, null, TO_CHAR);

  link(self, u.exit_to[i]);

  act("$1n appears from thin air.",
      A_HIDEINV, self, null, null, TO_ROOM);

  exec("look", self);

  quit;
}
dilend


dilbegin raise_dead(medi : unitptr, tgt : unitptr, arg : string,
     hm : integer, effect : string);
var
  u : unitptr;
code
{
  if ((hm < 0) or (not isaff(tgt, ID_VALHALLA)))
    goto nothing;

  foreach (UNIT_ST_OBJ, u)
  {
     if (isaff(u, ID_CORPSE) and ((" "+tgt.name+" ") in u.outside_descr))
     {
 act("A vortex appears above you draging your soul out of "+
     "Valhalla and back into your mutilated body. The pain is "+
            "overwhelming, everything becomes black...",
     A_ALWAYS, tgt, null, null, TO_CHAR);
 act("A vortex appears above $1n sucking $1s soul out of Valhalla.",
     A_ALWAYS, tgt, null, null, TO_ROOM);

        subaff(tgt, ID_VALHALLA);

 link(tgt, self.outside);

 while (u.inside)
   link(u.inside, tgt);

 destroy(u);

 act("$3n touches the corpse of $1n which moves and becomes alive!",
     A_ALWAYS, tgt, null, self, TO_NOTVICT);

 act("You restore life into the corpse of $1n.",
     A_ALWAYS, tgt, null, self, TO_VICT);

 tgt.hp        := 0;
 tgt.mana      := 0;
 tgt.endurance := 0;
 tgt.position  := POSITION_STUNNED;
 quit;
     }
  }

  act("You do not have $3n's corpse.",
      A_ALWAYS, self, null, tgt, TO_CHAR);
  quit;

  :nothing:
  act("Nothing happens.", A_SOMEONE, self, null, null, TO_CHAR);
  quit;
}
dilend

dilbegin resurrect(medi : unitptr, tgt : unitptr, arg : string,
    hm : integer, effect : string);
var
  u : unitptr;
code
{
  if ((hm < 0) or (not isaff(tgt, ID_VALHALLA)))
    goto nothing;

  foreach (UNIT_ST_OBJ, u)
  {
     if (isaff(u, ID_CORPSE) and ((" "+tgt.name+" ") in u.outside_descr))
     {
 act("A vortex appears above you draging your soul out of "+
     "Valhalla and back into your mutilated body.",
     A_ALWAYS, tgt, null, null, TO_CHAR);
 act("A vortex appears above $1n sucking $1s soul out of Valhalla.",
     A_ALWAYS, tgt, null, null, TO_ROOM);

        subaff(tgt, ID_VALHALLA);

 link(tgt, self.outside);

 while (u.inside)
   link(u.inside, tgt);

 destroy(u);

 act("$3n touches the corpse of $1n which moves and becomes alive!",
     A_ALWAYS, tgt, null, self, TO_NOTVICT);

 act("You restore life into the corpse of $1n.",
     A_ALWAYS, tgt, null, self, TO_VICT);
 quit;
     }
  }

  act("You do not have $3n's corpse.",
      A_ALWAYS, self, null, tgt, TO_CHAR);
  quit;

  :nothing:
  act("Nothing happens.", A_SOMEONE, self, null, null, TO_CHAR);
  quit;
}
dilend


dilbegin magic_candle(medi:unitptr, tgt : unitptr, arg : string,
      hm : integer, effect : string);
var
  orb : unitptr;
code
{
  if (hm < 0)
  {
     act("Nothing happens.", A_ALWAYS, self, null, null, TO_CHAR);
  }
  else
  {
     orb := load("candle@spells");
     act("You create $2n.", A_SOMEONE, self, orb, null, TO_CHAR);
     act("$1n creates $2n.", A_SOMEONE, self, orb, null, TO_ROOM);
  }
  quit;
}
dilend

dilbegin sun_globe(medi:unitptr, tgt : unitptr, arg : string,
      hm : integer, effect : string);
/* by Whistler */
var
  orb : unitptr;
code
{
  if (hm < 0)
  {
     act("Nothing happens.", A_ALWAYS, self, null, null, TO_CHAR);
  }
  else
  {
     orb := load("light_orb@spells");
     act("You create $2n.", A_SOMEONE, self, orb, null, TO_CHAR);
     act("$1n creates $2n.", A_SOMEONE, self, orb, null, TO_ROOM);
  }
  quit;
}
dilend

dilbegin recall zombie_summoned(pwr : integer);
var
 d : integer;
 u:unitptr;
 parse : stringlist;

code
{
  interrupt(SFB_DEAD, activator == self, vanish);
interrupt (SFB_MSG,TRUE,gotmsg);
  heartbeat := PULSE_SEC * 100;
  d := pwr / 15 + 2;

:start:
wait(SFB_TICK , TRUE);
if (d>0)
{
d := d - 1;
goto start;
}

goto vanish;

:gotmsg:
parse:= getwords(argument);
if (parse.[0] == "spl_dispel")
if (atoi(parse.[1]) <= pwr)
 goto start;

:vanish:
u:=load ("dust_bones@spells");
secure (u,lostu);
u.minv:=200;
link (u,self.outside);

while (self.inside!=null) link (self.inside,u);

  act ("$1n crumbles to dust.",
      A_SOMEONE, self, null, null, TO_ROOM);

u.minv:=0;
:lostu:
  destroy(self);
 quit;
}
dilend

dilbegin animate(medi : unitptr, tgt : unitptr, arg : string,
       hm : integer, effect : string);
var
  u : unitptr;
 chk : integer;
code
{
  if (hm < 0)
  {
  act ("$1n quivers a bit and then lies still.",
  A_ALWAYS,tgt,null,null,TO_ALL);
     quit;
  }

  if (tgt.nameidx+"@"+tgt.zoneidx!="corpse@basis")
 {
 act ("You try to bring life to $2n but nothing happens",
 A_ALWAYS,self,tgt,null,TO_CHAR);
 act ("$1n tries to bring life to $2n but nothing happens",
 A_SOMEONE,self,tgt,null,TO_REST);
 quit;
 }
 chk := (tgt.value[4]);

 if ( ((chk > RACE_OTHER_MAMMAL) and (chk <= RACE_OTHER_INSECT)) or
      ((chk > RACE_OTHER_CREATURE) and (chk <= RACE_OTHER_UNDEAD)) or
      (chk == RACE_SCORPION) or (chk == RACE_CAVE_WIGHT) or
      (chk == RACE_STONE_RENDER) or (chk == RACE_VAMPIRE) or
      (chk == RACE_AUTOMATON) or (chk == RACE_SLIME) or
      (chk == RACE_LESSER_DEMON) or (chk == RACE_GREATER_DEMON) or
      (chk == RACE_LESSER_DEVIL) or (chk == RACE_GREATER_DEVIL) or
      (chk == RACE_SHADOW_DEVIL) or (chk == RACE_ARCH_DEVIL) or
      (chk == RACE_MEDUSA) or (chk == RACE_GARGOYLE) or
      (chk == RACE_GOLEM) or (chk == RACE_YOGOLOTH) or
      (chk == RACE_MIST_DWELLER) or (chk == RACE_ELEMENTAL_AIR) or
      (chk == RACE_ELEMENTAL_FIRE) or (chk == RACE_ELEMENTAL_EARTH) or
      (chk == RACE_ELEMENTAL_FROST) or (chk == RACE_ELEMENTAL_WATER) or
      (chk == RACE_ELEMENTAL_LIGHT) )
 {
  act("The corpse glows briefly then suddenly crumbles into dust...",
  A_SOMEONE, self, null,null, TO_REST);
  act("The corpse glows briefly then suddenly crumbles into dust..." +
         "something was amiss with the subject." , A_SOMEONE, self, null,
         null, TO_CHAR);

  u:=load ("dust_bones@spells");
  link (u,self.outside);
  while (tgt.inside!=null)
    link (tgt.inside, u);
unsecure (tgt);
  destroy(tgt);
  quit;
 }

  u:= load("zombie@spells");
 secure (u,lostu);
   dilcopy("undead_obey@spells("+itoa(hm)+")",u);
   dilcopy ("zombie_summoned@spells("+itoa(hm)+")",u);
   dilcopy("undead_exec@spells",u);
  if (isset(self.pcflags,PC_PK_RELAXED))
  dilcopy ("catchit@spells(1)",u);
  else
  dilcopy ("catchit@spells(0)",u);
   addextra(u.extra,{"$undead control"},self.name);

while (tgt.inside!=null)
link (tgt.inside,u);

  link(u, self.outside);
  unsecure(u);
       act ("You animate $2n into a zombie.",
A_ALWAYS, self,tgt,null, TO_CHAR);
act ("$1n animates $2n into a zombie.",
A_SOMEONE, self,tgt,null,TO_ROOM);
unsecure (tgt);
destroy (tgt);
  exec("follow "+self.name, u);
  :lostu:
  quit;
}
dilend

/* Base code conversions - Mesmer - May 1999 */

dilbegin unitptr random_npc();
external
   integer may_tele_away@function(u : unitptr);

var
mob: unitptr;
tele: integer;

code
{

 mob := findrndunit(self,FIND_UNIT_WORLD,UNIT_ST_NPC);

 tele := may_tele_away@function(mob);

 if(tele == TRUE)
    return(mob);

 while(tele == FALSE)
 {
  mob := findrndunit(self,FIND_UNIT_WORLD,UNIT_ST_NPC);
  tele := may_tele_away@function(mob);
 }


 return(mob);

}
dilend


/*
  U being the pointer to the castor, N being the number of mobiles to
  summon against him/her
*/

dilbegin summon_npc(u : unitptr,n : integer);
external
   unitptr random_npc();
   provoked_attack@function(victim : unitptr, ch : unitptr);
   unitptr unit_room@function(u : unitptr);

var
mob: unitptr;
room: unitptr;
roomstr: string;

code
{

 while(n > 0)
  {

   mob := random_npc();

   if(mob != null)
    {
      if(mob.position == POSITION_FIGHTING)
         stop_fighting(mob,null);

    act("$1n disappears into a rift!",
         A_SOMEONE, mob, null, null, TO_ROOM);

    room := unit_room@function(mob);

/* can't copy a unitptr field to a target since the + relationship
  only accepts strings. So lets capture the symbolic room and use it */

   roomstr := room.nameidx+"@"+room.zoneidx;

    dilcopy("capture_room@spells("+roomstr+")", mob);

    link(mob,u.outside);

    act("$1n appears through a rift!",
        A_SOMEONE, mob, null, null, TO_ROOM);

    /* provoked_attack@function(mob,u); */

   exec("kill "+u.name, mob);
   /* temp. hack until provoked_attack(set_fighting) is faster */
   }

    n := n - 1;
  }

 return;

}
dilend

dilbegin capture_room(room : string);
var
tick: integer;
dest: unitptr;
code
{

  tick := 0;

  heartbeat := PULSE_SEC * 2;

  :start:

  wait(SFB_TICK, TRUE);

  if(self.position == POSITION_FIGHTING)
   {

    while(self.position==POSITION_FIGHTING) pause;

    if(self.position < POSITION_FIGHTING) quit;
    /* Hence the mob is incapped, or _worse_ */

    goto relink;

   }

/*
   And just in case the tick goes off before the set_fighting(dunno)
   we try it once more.
*/

  tick := tick + 1;
  if(tick > 1) goto relink;

 :relink:
 heartbeat := PULSE_SEC * rnd(1,4);
 /*
    let them sit in the room for a few seconds, instant relinking looks
    cheesy
 */
 pause;

 dest := findsymbolic(room);
/*
Not going to check for a null pointer because if the mob _was_ in
that room it should NEVER return null
*/

 act("$1n disappears into a rift!",
      A_SOMEONE, self, null, null, TO_ROOM);
 link(self,dest);
 act("$1n appears through a rift!",
     A_SOMEONE, self, null, null, TO_ROOM);
 quit;
}

dilend

dilbegin integer same_room(u1 : unitptr,u2 : unitptr);
external
      unitptr unit_room@function(u : unitptr);

var
room1: unitptr;
room2: unitptr;

code
{

 room1 := unit_room@function(u1);
 room2 := unit_room@function(u2);

if(room1 == room2) return(TRUE);
else
  return(FALSE);

}
dilend


dilbegin rift_failure(targ : unitptr);
external
    summon_npc(u : unitptr,n : integer);

var
i: integer; /* cast_spell integer */
chance: integer; /* rift types chance */
u: unitptr; /* room unitptr */

code
{

 act("You cause a great disturbance in the powers of magic.",
     A_ALWAYS, self, null, null, TO_CHAR);
 act("$1n causes a great disturbance in the powers of magic.",
     A_SOMEONE, self, null, null, TO_REST);

 if(self.level >= IMMORTAL_LEVEL)
 {
   act("In the last second you successfully close the rift!",
      A_ALWAYS, self, null, null, TO_CHAR);
   act("$1n battles the rift for a split second, and closes it again!",
      A_SOMEONE, self, null, null, TO_REST);
   return;
 }

 self.mana := 0;

 chance := rnd(0,100);

 if(chance <= 35)
  {
     if(not(targ) or (chance == 0) or (chance == 1))
      {
       i := cast_spell(SPL_RANDOM_TELEPORT, self, self, self, "");
      }
     else
       {
        i := cast_spell(SPL_CONTROL_TELEPORT, self, self, targ, "");
       }
    }
       else if (chance <= 60)
        {
         u := findsymbolic("void@basis");
         i := cast_spell(SPL_CONTROL_TELEPORT, self, self, u, "");
        }

       else if (chance <= 80)
        {
         summon_npc(self,2);
        }

       else if (chance <= 85)
        {
         summon_npc(self,3);
        }

       else if (chance <= 90)
        {
         summon_npc(self,4);
        }

       else if (chance <= 95)
        {
         summon_npc(self,5);
        }

        else
        {
         summon_npc(self,6);
        }

       return;

}
dilend


dilbegin spl_random_tele(medi : unitptr, tgt : unitptr, arg : string,
                 hm : integer, effect : string);
external
     rift_failure(targ : unitptr);
     integer may_tele_away@function(u : unitptr);

var
plce: unitptr;
i: integer;
walk: integer;
tt: integer;

code
{

 if(hm < 0)
    return;

 plce := findrndunit(self,FIND_UNIT_WORLD,UNIT_ST_ROOM);
  if(rnd(1,RIFT_RISK) <= 5)
  {
   rift_failure(plce);
   return;
  }

  i := may_tele_away@function(self);
 tt := may_tele_away@function(plce);

   if((i == FALSE) or (tt == FALSE))
    {
     act("It seems that you can't teleport there.",
          A_ALWAYS, self, null, null, TO_CHAR);
     return;
    }

/*
   Can we tele away? YES
*/

/*
   walk := pathto(self,plce);

   if(walk == DIR_IMPOSSIBLE)
   {
    act("The magic disperses.",
       A_ALWAYS, self, null, null, TO_CHAR);
    return;
   }
*/

/*
  Can we walk there, hence being linked to the world. YES

  Ok in the base code this line is used within a #if and since
  I only have the part with the #if I cannot tell if the varible is
  defined so I coded this support anyways. Comment out if you want to
  be able to random tele to trans-continental zones
*/

   act("$1n disappears in a puff of green smoke.",
        A_ALWAYS, self, null, null, TO_REST);
   link(self,plce);
   act("$1n appears in a puff of green smoke.",
        A_SOMEONE, self, null, null, TO_REST);
   act("You feel confused.",
        A_ALWAYS, self, null, null, TO_CHAR);

   exec("look", self);

  quit;

}
dilend

dilbegin spl_transport(medi : unitptr, tgt : unitptr, arg : string,
                 hm : integer, effect : string);
external
     rift_failure(targ : unitptr);
     integer may_tele_away@function(u : unitptr);
     integer skillresist@function(aa : integer, ad : integer, sa : integer,
                                  sd : integer);
     unitptr unit_room@function(u : unitptr);
var
teletgt: integer;
teleme: integer;
plce: unitptr;
walk: integer;

code
{

 if(tgt == null) quit;

/*

 ok someone explain this to me..transport to a person/mobile worked just
 fine. But transport to an object inside a person/mobile and the dil would
 return to itself for some messed up reason. I mean it could be a number of
 things such as a missed return somewhere, but I treat mobiles and objects
 the same in the code so why does it return to a null state and try to run
 again?? Who knows, but it works now.

*/

   if(rnd(1,RIFT_RISK) <= 5)
   {
    rift_failure(tgt);
    quit;
   }

  if(hm < 0)
    {
     act("You can't seem to clearly locate the target.",
         A_ALWAYS, self, null, null, TO_CHAR);
     quit;
    }

  plce := unit_room@function(tgt);


  teleme := may_tele_away@function(self); /* Can I tele away?      */
  teletgt := may_tele_away@function(plce);/* Can we tele there?    */

 if((teleme == FALSE) or (teletgt == FALSE))
    {
     act("It seems that you can't teleport there.",
          A_ALWAYS, self, null, null, TO_CHAR);
     quit;
    }

if (self.type==UNIT_ST_PC)
if (not(paycheck(self,plce))){
     act("You don't have access to that location, type 'help donation'.",
          A_ALWAYS, self, null, null, TO_CHAR);
     quit;
    }

  walk := pathto(self,plce);

  if(walk == DIR_IMPOSSIBLE)
  {
    act("The magic disperses.",
        A_ALWAYS, self, null, null, TO_CHAR);
    quit;
   }

   act("$1n disappears in a puff of green smoke.",
        A_SOMEONE, self, null, null, TO_REST);

   link(self,plce);

   act("$1n appears in a puff of green smoke.",
        A_SOMEONE, self, null, null, TO_REST);
   exec("look", self);

  quit;
}
dilend


dilbegin spl_cont_tele(medi : unitptr, tgt : unitptr, arg : string,
                 hm : integer, effect : string);
external
     rift_failure(targ : unitptr);
     integer may_tele_away@function(u : unitptr);
     unitptr unit_room@function(u : unitptr);

var
teleme: integer;
teletgt: integer;
room: unitptr;

code
{

 if(tgt == null) quit;

 room := unit_room@function(tgt);

 teleme := may_tele_away@function(self);
 teletgt := may_tele_away@function(room);

if((teleme == FALSE) or (teletgt == FALSE))
{
   act("It seems that you can't teleport there.",
         A_ALWAYS, self, null, null, TO_CHAR);
   quit;
 }

if (self.type==UNIT_ST_PC)
if (not(paycheck(self,room))){
     act("You don't have access to that location, type 'help donation'.",
          A_ALWAYS, self, null, null, TO_CHAR);
     quit;
    }

if(hm < 0)
{

  act("You can't seem to clearly locate the target.",
         A_ALWAYS, self, null, null, TO_CHAR);
  quit;
}

if(rnd(1,RIFT_RISK) <= 5)
{
 rift_failure(tgt);
 quit;
}

act("$1n disappears in a puff of green smoke.",
     A_SOMEONE, self, null, null, TO_REST);

link(self,room);

act("$1n appears in a puff of green smoke.",
    A_SOMEONE, self, null, null, TO_REST);

exec("look", self);

quit;

}
dilend


dilbegin spl_undead_door(medi : unitptr, tgt : unitptr, arg : string,
                 hm : integer, effect : string);
external
     rift_failure(targ : unitptr);
     integer may_tele_away@function(u : unitptr);
     unitptr unit_room@function(u : unitptr);

var
room_me: unitptr;
room_tgt: unitptr;
teleme: integer;
teletgt: integer;

code
{

 if(tgt == null) quit;

 if(not(RACE_IS_UNDEAD(tgt.race)))
  {
   act("You fail.",
        A_ALWAYS, self, null, null, TO_CHAR);
    quit;
   }

  teleme := may_tele_away@function(self);
  teletgt := may_tele_away@function(tgt);

 if((teleme == FALSE) or (teletgt == FALSE))
  {
   act("It seems that you can't switch with this undead.",
        A_ALWAYS, self, null, null, TO_CHAR);
   quit;
  }

if (self.type==UNIT_ST_PC)
if (not(paycheck(self,tgt))){
     act("You don't have access to the location that the undead is in, type 'help donation'.",
          A_ALWAYS, self, null, null, TO_CHAR);
     quit;
    }

 if(hm < 0)
  {
   act("You can't seem to clearly locate the target.",
       A_ALWAYS, self, null, null, TO_CHAR);
   quit;
  }

 if(rnd(1,RIFT_RISK) <= 5)
  {
    rift_failure(tgt);
    quit;
   }

 room_me := unit_room@function(self);
 room_tgt := unit_room@function(tgt);

 act("$1n is replaced with $3n!",
     A_SOMEONE, self, null, tgt, TO_REST);

 act("$1n is replaced with $3n!",
     A_SOMEONE, tgt, null, self, TO_REST);

 link(self,room_tgt);
 link(tgt,room_me);

 exec("look", self);
 exec("look", tgt);

quit;

}
dilend


dilbegin spl_minor_gate(medi : unitptr, tgt : unitptr, arg : string,
                 hm : integer, effect : string);
external
     rift_failure(targ : unitptr);
     integer may_tele_away@function(u : unitptr);
     unitptr unit_room@function(u : unitptr);
     integer same_room(u1 : unitptr,u2 : unitptr);
     provoked_attack@function(victim : unitptr, ch : unitptr);

var
teleme: integer;
teletgt: integer;
room_me: unitptr;
room_tgt: unitptr;
check: integer;
pay:unitptr;

code
{

 if(tgt == null) quit;

 if(tgt.level > self.level) quit;

 room_me := unit_room@function(self);
 room_tgt := unit_room@function(tgt);

 check := same_room(room_me,room_tgt);

 if(check == TRUE)
   {
    act("The magic fizzles as there is nowhere for the creature to "+
        "arrive.", A_ALWAYS, self, null, null, TO_CHAR);
     quit;
   }

  teleme := may_tele_away@function(self);
  teletgt := may_tele_away@function(tgt);

 if((teleme == FALSE) or (teletgt == FALSE))
   {
    act("Powers beyond your control prevent the summoning.",
         A_ALWAYS, self, null, null, TO_CHAR);
    quit;
   }

pay:=self.outside;
while (pay.type!=UNIT_ST_ROOM){
pay:=pay.next;
}

if (tgt.type==UNIT_ST_PC)
if (not (paycheck(tgt,pay))){
     act("$3n doesn't have access to your location have $3m type, 'help donation'.",
          A_ALWAYS, self, null, tgt, TO_CHAR);
     quit;
    }

 if(hm < 0)
  {
   act("$3n tried to summon you.",
       A_SOMEONE, tgt, null, self, TO_CHAR);
   quit;
  }

 if((tgt.position == POSITION_FIGHTING) and (rnd(0, 100) < 30))
 {
   act("There is a disturbance in the powers, you fail.",
        A_ALWAYS, self, null, null, TO_CHAR);
   act("The air is loaded with energy for a short moment.",
        A_SOMEONE, tgt, null, null, TO_CHAR);
   quit;
  }

 if(rnd(1, RIFT_RISK) <= 5)
   {
    rift_failure(tgt);
    quit;
   }

 if((self.type == UNIT_ST_PC) and (tgt.type == UNIT_ST_PC))
  {
    log(tgt.name+" was summoned by "+self.name+" to "+room_me.nameidx+
        "@"+room_me.zoneidx+".");
  }


  if(tgt.position == POSITION_FIGHTING)
   stop_fighting(tgt,null);

  act("You are summoned!",
        A_SOMEONE, tgt, null, null, TO_CHAR);
  act("$1n disappears in a puff of smoke!",
        A_SOMEONE, tgt, null, null, TO_REST);

  link(tgt,room_me);

  exec("look", tgt);

  act("$1n appears in a puff of smoke!",
        A_SOMEONE, tgt, null, null, TO_REST);

  provoked_attack@function(tgt, self);
  change_speed(self,PULSE_VIOLENCE*2);
 quit;
}
dilend

dilbegin spl_gate(medi : unitptr, tgt : unitptr, arg : string,
                 hm : integer, effect : string);
external
     rift_failure(targ : unitptr);
     integer may_tele_away@function(u : unitptr);
     unitptr unit_room@function(u : unitptr);
     integer same_room(u1 : unitptr,u2 : unitptr);
     provoked_attack@function(victim : unitptr, ch : unitptr);

var
teleme: integer;
teletgt: integer;
room_me: unitptr;
room_tgt: unitptr;
check: integer;
num: integer;
pay:unitptr;
code
{

 if(hm < 0)
  {
    act("$3n tried to summon you.",
        A_SOMEONE, tgt, null, self,TO_CHAR);
    quit;
   }

  room_me := unit_room@function(self);
  room_tgt := unit_room@function(tgt);

  check := same_room(room_me,room_tgt);

  if(check == TRUE)
   {

    act("The magic fizzles as there is nowhere for the creature to "+
        "arrive.", A_ALWAYS, self, null, null, TO_CHAR);
    quit;
    }

   teleme := may_tele_away@function(self);
   teletgt := may_tele_away@function(tgt);

   if((teleme == FALSE) or (teletgt == FALSE))
   {
    act("Powers beyond your control prevent the summoning.",
         A_ALWAYS, self, null, null, TO_CHAR);
    quit;
   }

pay:=self.outside;
while (pay.type!=UNIT_ST_ROOM){
pay:=pay.next;
}

if (tgt.type==UNIT_ST_PC)
if (not (paycheck(tgt,pay))){
     act("$3n doesn't have access to your location have $3m type, 'help donation'.",
          A_ALWAYS, self, null, tgt, TO_CHAR);
     quit;
    }

   if((tgt.position == POSITION_FIGHTING) and (rnd(0, 100) < 30))
   {
    act("There is a disturbance in the powers, you fail.",
       A_ALWAYS, self, null, null, TO_CHAR);
    act("The air is loaded with energy for a short moment.",
       A_SOMEONE, tgt, null, null, TO_CHAR);
    quit;
   }


  num := tgt.level - self.level;

 if(num < 0) num := 0;

   if(rnd(1,RIFT_RISK - num) <= 5)
    {
     rift_failure(tgt);
     quit;
    }

  if(tgt.fighting)
stop_fighting(tgt,null);


   if((self.type == UNIT_ST_PC) and (tgt.type == UNIT_ST_PC))
    {
       log(tgt.name+" was summoned by "+self.name+" to "+room_me.nameidx+
            "@"+room_me.zoneidx+".");
    }

     act("You are summoned!",
           A_ALWAYS,tgt, null, null, TO_CHAR);
     act("$1n disappears in a flash of light!",
           A_SOMEONE, tgt, null, null, TO_REST);

     link(tgt,room_me);
     exec("look",tgt);
     act("$1n appears in a flash of light!",
           A_HIDEINV, tgt, null, null, TO_REST);

     provoked_attack@function(tgt, self);
     change_speed(self,PULSE_VIOLENCE*2);

     quit;

}
dilend

dilbegin spl_fireball_1(medi : unitptr, tgt : unitptr, arg : string,
                     hm : integer, effect : string);
code
{

 hm := attack_spell(SPL_FIREBALL_1, self, medi, tgt, 0, effect);
 quit;
}
dilend

dilbegin spl_fireball_2(medi : unitptr, tgt : unitptr, arg : string,
                     hm : integer, effect : string);
code
{

 hm := attack_spell(SPL_FIREBALL_2, self, medi, tgt, 0, effect);
 quit;
}
dilend


dilbegin spl_fireball_3(medi : unitptr, tgt : unitptr, arg : string,
                     hm : integer, effect : string);
code
{

 hm := attack_spell(SPL_FIREBALL_3, self, medi, tgt, 0, effect);
 quit;
}
dilend

dilbegin spl_frostball_1(medi : unitptr, tgt : unitptr, arg : string,
                     hm : integer, effect : string);
code
{
 hm := attack_spell(SPL_FROSTBALL_1, self, medi, tgt, 0, effect);
 quit;
}
dilend

dilbegin spl_frostball_2(medi : unitptr, tgt : unitptr, arg : string,
                     hm : integer, effect : string);
code
{
 hm := attack_spell(SPL_FROSTBALL_2, self, medi, tgt, 0, effect);
 quit;
}
dilend

dilbegin spl_frostball_3(medi : unitptr, tgt : unitptr, arg : string,
                     hm : integer, effect : string);
code
{
 hm := attack_spell(SPL_FROSTBALL_3, self, medi, tgt, 0, effect);
 quit;
}
dilend

dilbegin spl_lightning_1(medi : unitptr, tgt : unitptr, arg : string,
                     hm : integer, effect : string);
code
{

 hm := attack_spell(SPL_LIGHTNING_1, self, medi, tgt, 0, effect);
 quit;
}
dilend

dilbegin spl_lightning_2(medi : unitptr, tgt : unitptr, arg : string,
                     hm : integer, effect : string);
code
{

 hm := attack_spell(SPL_LIGHTNING_2, self, medi, tgt, 0, effect);
 quit;
}
dilend

dilbegin spl_lightning_3(medi : unitptr, tgt : unitptr, arg : string,
                     hm : integer, effect : string);
code
{

 hm := attack_spell(SPL_LIGHTNING_3, self, medi, tgt, 0, effect);
 quit;
}
dilend

dilbegin spl_acidball_1(medi : unitptr, tgt : unitptr, arg : string,
                     hm : integer, effect : string);
code
{

 hm := attack_spell(SPL_ACIDBALL_1, self, medi, tgt, 0, effect);
 quit;
}
dilend


dilbegin spl_acidball_2(medi : unitptr, tgt : unitptr, arg : string,
                     hm : integer, effect : string);
code
{

 hm := attack_spell(SPL_ACIDBALL_2, self, medi, tgt, 0, effect);
 quit;
}
dilend

dilbegin spl_acidball_3(medi : unitptr, tgt : unitptr, arg : string,
                     hm : integer, effect : string);
code
{

 hm := attack_spell(SPL_ACIDBALL_3, self, medi, tgt, 0, effect);
 quit;
}
dilend

dilbegin spl_colour_1(medi : unitptr, tgt : unitptr, arg : string,
                     hm : integer, effect : string);
code
{

 hm := attack_spell(SPL_COLOURSPRAY_1, self, medi, tgt, 0, effect);
 quit;
}
dilend

dilbegin spl_colour_2(medi : unitptr, tgt : unitptr, arg : string,
                     hm : integer, effect : string);
code
{

 hm := attack_spell(SPL_COLOURSPRAY_2, self, medi, tgt, 0, effect);
 quit;
}
dilend

dilbegin spl_colour_3(medi : unitptr, tgt : unitptr, arg : string,
                     hm : integer, effect : string);
code
{

 hm := attack_spell(SPL_COLOURSPRAY_3, self, medi, tgt, 0, effect);
 quit;
}
dilend

dilbegin spl_stink_1(medi : unitptr, tgt : unitptr, arg : string,
                     hm : integer, effect : string);
code
{

 hm := attack_spell(SPL_STINKING_CLOUD_1, self, medi, tgt, 0, effect);
 quit;
}
dilend

dilbegin spl_stink_2(medi : unitptr, tgt : unitptr, arg : string,
                     hm : integer, effect : string);
code
{

 hm := attack_spell(SPL_STINKING_CLOUD_2, self, medi, tgt, 0, effect);
 quit;
}
dilend

dilbegin spl_stink_3(medi : unitptr, tgt : unitptr, arg : string,
                     hm : integer, effect : string);
code
{

 hm := attack_spell(SPL_STINKING_CLOUD_3, self, medi, tgt, 0, effect);
 quit;
}
dilend

dilbegin spl_cause_1(medi : unitptr, tgt : unitptr, arg : string,
                     hm : integer, effect : string);
code
{

if(tgt == null) quit; /* Due to some strange occurances */

if((not RACE_IS_HUMANOID(tgt.race)) and (not RACE_IS_MAMMAL(tgt.race)))
  {
  act("You fail.",A_ALWAYS, self, null, null, TO_CHAR);
  quit;
  }

 hm := attack_spell(SPL_CAUSE_WOUNDS_1, self, medi, tgt, 0, effect);
 quit;
}
dilend

dilbegin spl_cause_2(medi : unitptr, tgt : unitptr, arg : string,
                     hm : integer, effect : string);
code
{
if(tgt == null) quit;

if((not RACE_IS_HUMANOID(tgt.race)) and (not RACE_IS_MAMMAL(tgt.race)))
  {
  act("You fail.",A_ALWAYS, self, null, null, TO_CHAR);
  quit;
  }

 hm := attack_spell(SPL_CAUSE_WOUNDS_2, self, medi, tgt, 0, effect);
 quit;
}
dilend

dilbegin spl_cause_3(medi : unitptr, tgt : unitptr, arg : string,
                     hm : integer, effect : string);
code
{
 if(tgt == null) quit;

 if((not RACE_IS_HUMANOID(tgt.race)) and (not RACE_IS_MAMMAL(tgt.race)))
  {
  act("You fail.",A_ALWAYS, self, null, null, TO_CHAR);
  quit;
  }

 hm := attack_spell(SPL_CAUSE_WOUNDS_3, self, medi, tgt, 0, effect);
 quit;
}
dilend

/* Whistler gets credit on this concept */

dilbegin string unit_inside(unit : unitptr);
var
u: unitptr;
pc_list: stringlist;
npc_list: stringlist;
obj_list: stringlist;
n_npc: stringlist;
n_obj: stringlist;
tmp: string;
i: integer;
tmp_i: integer;
str: string;

code
{

if(unit.type == UNIT_ST_ROOM) quit;

u := unit.inside;

tmp := "";
str := "";

if(u == null)
   return("&[obj_title]Nothing!&[default]");


while( u != null )
{
  if((u == self) or (isset (u.flags, UNIT_FL_BURIED)))
   {
    u := u.next;
    continue;
   }

/* a PC inside an object, well, for xray should be rare, but possible */

if(u.type == UNIT_ST_PC)
   {
     if(visible(self,u))
      {
        if(u.level >= IMMORTAL_LEVEL)
         addstring(pc_list,"&[immort_descr]"+u.name+"&[default]&n");
           else
             addstring(pc_list,"&[pc_descr]"+u.name+"&[default]&n");
       }
  }

else if(u.type == UNIT_ST_NPC)
      {
       if(visible(self,u))
        {
         tmp := "&[npc_descr]"+u.title+"&[default]&n";
         tmp_i := tmp in npc_list;

         if(tmp_i > 0)
          {
           i := atoi(n_npc.[tmp_i - 1]) + 1;
           n_npc.[tmp_i - 1] := itoa(i);
          }
         else
          {
           addstring(npc_list,tmp);
           addstring(n_npc,"1");
          }
       }
 }

 else if(u.type == UNIT_ST_OBJ)
       {
        if(visible(self,u))
         {
          tmp := "&[obj_title]"+u.title+"&[default]&n";
          tmp_i := tmp in obj_list;

          if(tmp_i > 0)
          {
           i := atoi(n_obj.[tmp_i - 1]) + 1;
           n_obj.[tmp_i - 1] := itoa(i);
          }
          else
           {
            addstring(obj_list,tmp);
            addstring(n_obj,"1");
           }
         }
  }
tmp := "";
u := u.next;
}

tmp_i:= length(obj_list);
i:= 0;

while( i < tmp_i)
  {
   if(atoi(n_obj.[i]) > 1)
     str := str+"[x"+n_obj.[i]+"] "+obj_list.[i];
      else
        str := str+obj_list.[i];

    i := i + 1;
   }

tmp_i:= length(npc_list);
i:= 0;

while(i < tmp_i)
   {
     if(atoi(n_npc.[i]) > 1)
      str := str+"[x"+n_npc.[i]+"] "+npc_list.[i];
       else
         str := str+npc_list.[i];

      i := i + 1;
     }

tmp_i:= length(pc_list);
i:= 0;

while(i < tmp_i)
{
  str := str+pc_list.[i];
  i := i + 1;
}

return(str);
}

dilend



dilbegin spl_xray_vision(medi : unitptr, tgt : unitptr, arg : string,
                     hm : integer, effect : string);
external
   string unit_inside(unit : unitptr);

var
ins: string;

code
{

 if(hm < 0) quit;

 if(tgt == self) quit;
 /* this could be done in the spells.def, but I like seeing people
    continuously trying to cast it upon themselves. @grin@ */

 ins := unit_inside(tgt);

 act("$3n contains :",
       A_HIDEINV, self, null, tgt, TO_CHAR);
 pagestring(ins,self);
 quit;

}

dilend


/* This to whistler also */
dilbegin string get_pos (u:unitptr);
var
       p:stringlist;
       i:integer;
code
{
i:=u.position;
p:={
" is lying here, dead ... creepy.",
" is lying here, mortally wounded.",
" is lying here, incapacitated.",
" is lying here, stunned.",
" is sleeping here.",
" is resting here.",
" is sitting here.",
" is here, fighting ",
" is standing here."};

if (i!=7) return (p.[i]);

if (u.fighting==null)
       return (p.[i]+"someone who has already left.");
if (u.fighting==self)
       return (p.[i]+"YOU!");
else if(u.fighting)
 return(p.[i]+u.fighting.name+".");

return (p.[i]);
}
dilend


dilbegin string room_inside(room : unitptr);
external
  string display_exits(u : unitptr);
  string get_pos(u : unitptr);

var
u: unitptr;
pc_list: stringlist;
npc_list: stringlist;
obj_list: stringlist;
n_npc: stringlist;
n_obj: stringlist;
tmp: string;
i: integer;
tmp_i: integer;
str: string;
r_title: string;
r_descr: string;
pos: string;
exits: string;

code
{

if(room.type != UNIT_ST_ROOM) quit;

if(self.level >= IMMORTAL_LEVEL)
  r_title := "&[room_title]"+room.title+" ["+room.nameidx+
             "@"+room.zoneidx+"]&[default]&n";
    else
     r_title := "&[room_title]"+room.title+"&[default]&n";

r_descr := "&[room_descr]"+room.inside_descr+"&[default]&n";

sendtext(r_title,self);

if(not(isset(self.pcflags,PC_BRIEF)))
  sendtext(r_descr,self);

if(isset(self.pcflags,PC_EXITS))
  {
  exits := display_exits(room);
  sendtext(exits,self);
  }

tmp := "";

u := room.inside;

while( u != null )
{

if ((u==self) or (isset (u.flags, UNIT_FL_BURIED)))
   {
     u:=u.next;
     continue;
   }

if(u.type == UNIT_ST_PC)
 {
  if(visible(self,u))
   {
    pos := get_pos(u);

    if(u.level >= IMMORTAL_LEVEL)
     addstring(pc_list,"&[immort_descr]"+u.name+" "+u.title+
                       pos+"&[default]&n");
      else
       addstring(pc_list,"&[pc_descr]"+u.name+" "+u.title+
                       pos+"&[default]&n");
    }
  else if((isset(self.flags,ID_DETECT_LIFE)) and (u.level    addstring(pc_list,"You sense a hidden life form in the room.&n");
  /* This may cause a problem */
 }

else if(u.type == UNIT_ST_NPC)
 {
  if(visible(self,u))
   {

    if(u.position != POSITION_STANDING)
    {
    pos := get_pos(u);
    tmp := "&[npc_descr]"+u.title+pos+"&[default]&n";
    }
     else
       tmp := "&[npc_descr]"+u.outside_descr+"&[default]&n";

    tmp_i := tmp in npc_list;

    if(tmp_i > 0)
    {
     i := atoi(n_npc.[tmp_i - 1]) + 1;
     n_npc.[tmp_i-1]:=itoa(i);
    }
    else
     {
      addstring(npc_list,tmp);
      addstring(n_npc,"1");
     }
   }
  else if((isset(self.flags,ID_DETECT_LIFE)) and
           (self.level    {
    addstring(npc_list,"You sense a hidden life form in the room.&n");
    addstring(n_npc,"1");
   }
 }

else if(u.type == UNIT_ST_OBJ)
  {
    if (visible(self,u))
     {
      tmp := "&[obj_title]"+u.outside_descr+"&[default]&n";
      tmp_i := tmp in obj_list;

      if(tmp_i > 0)
      {
       i := atoi(n_obj.[tmp_i - 1]) + 1;
       n_obj.[tmp_i-1] := itoa(i);
      }
      else
        {
         addstring(obj_list,tmp);
         addstring(n_obj,"1");
        }
     }
  }

tmp:= "";
u:= u.next;
}

str:= "";

tmp_i:= length(obj_list);
i:= 0;

while(i < tmp_i)
 {
  if (atoi(n_obj.[i])>1)
     str:=str+"&[obj_title][x"+n_obj.[i]+"] "+obj_list.[i];
  else
     str:=str+obj_list.[i];

  i := i+1;
  }

tmp_i:= length(npc_list);
i:= 0;

while(i < tmp_i)
 {
   if(atoi(n_npc.[i]) > 1)
    str:=str+"&[npc_descr][x"+n_npc.[i]+"] "+npc_list.[i];
     else
      str:=str+npc_list.[i];

   i := i + 1;
 }

tmp_i:= length(pc_list);
i:= 0;

while(i < tmp_i)
 {
  str:=str+pc_list.[i];
  i := i + 1;
  }

return(str);
}
dilend


dilbegin string display_exits(u : unitptr);
var
dir: string;
cmma: string;

code
{

dir:= "";
if((u.exit_to[NORTH] != null) and
   (not(isset (u.exit_info[NORTH],EX_HIDDEN))))
      dir := "north";
if((u.exit_to[EAST] != null) and
    (not(isset (u.exit_info[EAST], EX_HIDDEN))))
      dir := dir+", east";
if((u.exit_to[SOUTH] != null) and
    (not(isset (u.exit_info[SOUTH], EX_HIDDEN))))
      dir := dir+", south";
if((u.exit_to[WEST] != null) and
    (not(isset (u.exit_info[WEST], EX_HIDDEN))))
      dir := dir+", west";
if((u.exit_to[UP] != null) and
    (not(isset (u.exit_info[UP], EX_HIDDEN))))
      dir := dir+", up";
if((u.exit_to[DOWN] != null) and
    (not(isset (u.exit_info[DOWN], EX_HIDDEN))))
      dir := dir+", down";
if((u.exit_to[NORTHEAST] != null) and
    (not(isset (u.exit_info[NORTHEAST], EX_HIDDEN))))
      dir := dir+", northeast";
if((u.exit_to[NORTHWEST] != null) and
    (not(isset (u.exit_info[NORTHWEST], EX_HIDDEN))))
      dir := dir+", northwest";
if((u.exit_to[SOUTHEAST] != null) and
    (not(isset (u.exit_info[SOUTHEAST], EX_HIDDEN))))
      dir := dir+", southeast";
if((u.exit_to[SOUTHWEST] != null) and
    (not(isset (u.exit_info[SOUTHWEST], EX_HIDDEN))))
      dir := dir+", southwest";

if(dir == "") dir := "none";

cmma := getword(dir);

if(cmma != ",") dir := cmma+" "+dir;

dir:= "&[exit]Exits: "+dir+"&[default]&n";

return(dir);

}
dilend

dilbegin spl_wiz_eye(medi : unitptr, tgt : unitptr, arg : string,
                     hm : integer, effect : string);
external
  string room_inside(room : unitptr);
  string unit_inside(unit : unitptr);

var
out: unitptr;
see: string;

code
{

  if(hm < 0) quit;

  out := tgt.outside;

  if(out.type == UNIT_ST_ROOM)
  {
   sendtext("An image forms in your mind:&n", self);
   see := room_inside(out);
   goto show_it;
  }

/* inside a bag? */
 if(out.type == UNIT_ST_OBJ)
 {

  sendtext("An image forms in your mind of &cc"+out.title+"&[default]"+
           " and you see:&n", self);
  see := unit_inside(out);
  goto show_it;
 }

 if(out.type == UNIT_ST_PC)
 {

  sendtext("An image forms in your mind and you see &cc"+
            out.name+"'s &[default]inventory:&n", self);
  see := unit_inside(out);
  goto show_it;
  }

 if(out.type == UNIT_ST_NPC)
 {

  sendtext("An image forms in your mind and you see &cc"+
           out.title+"'s &[default]inventory:&n", self);
  see := unit_inside(out);
  goto show_it;
 }

 else
   log("This is impossible, but something has no type "+out.name+".");

 :show_it:

 pagestring(see, self);
 quit;
}
dilend

dilbegin spl_invis(medi : unitptr, tgt : unitptr, arg : string,
                     hm : integer, effect : string);
external
    integer skill_duration(hm : integer);

code
{

if(hm < 0) quit;

if(effect == "")
{
act("$1n fades away",
     A_HIDEINV, tgt, null, null, TO_REST);
act("You become invisible.",
     A_HIDEINV, tgt, null, null, TO_CHAR);
}
else
effect(tgt,medi,hm);

hm := skill_duration(hm);

addaff(tgt, ID_INVISIBILITY, hm, WAIT_SEC*30, UNIT_FL_INVISIBLE,
            0, 0, TIF_INVISIBILITY_ON, TIF_NONE, TIF_INVISIBILITY_OFF,
            APF_MOD_UNIT_FLAGS);

quit;
}
dilend

dilbegin spl_fear(medi : unitptr, tgt : unitptr, arg : string,
                     hm : integer, effect : string);
external
    integer skill_duration(hm : integer);
    provoked_attack@function(victim : unitptr, ch : unitptr);
code
{

 if((not RACE_IS_HUMANOID(tgt.race)) and (not RACE_IS_MAMMAL(tgt.race)))
        quit;

 provoked_attack@function(tgt,self);

 if(hm < 0) quit;

 hm := skill_duration(hm);

 addaff(tgt, ID_FEAR, hm, WAIT_SEC * 30, 0, 0, 0,
             TIF_FEAR_CHECK, TIF_FEAR_CHECK, TIF_NONE,
             APF_NONE);

if(effect != "")
 effect(tgt,medi,hm);

 quit;
}
dilend

dilbegin spl_confusion(medi : unitptr, tgt : unitptr, arg : string,
                     hm : integer, effect : string);
external
    integer skill_duration(hm : integer);
    provoked_attack@function(victim : unitptr, ch : unitptr);
code
{

if(hm < 0)
{
 provoked_attack@function(tgt,self);
 quit;
}

hm := skill_duration(hm);

addaff(tgt, ID_CONFUSION, hm, WAIT_SEC * 15, 0, 0, 0,
            TIF_CONFUSION_ON, TIF_CONFUSION_TICK,
            TIF_CONFUSION_OFF, APF_NONE);

if(effect != "")
 effect(tgt,medi,hm);

quit;
}
dilend

dilbegin spl_rem_curse(medi : unitptr, tgt : unitptr, arg : string,
                     hm : integer, effect : string);
var
u: unitptr;

code
{


 if(hm < 0)
 {
  act("You fail.", A_ALWAYS, self, null, null, TO_CHAR);
  quit;
 }

 if(isaff(tgt, ID_CURSE)) subaff(tgt,ID_CURSE);

 u := tgt.inside;

while( u != null )
{
 if(isaff(u, ID_CURSE)) subaff(u,ID_CURSE);
 u := u.next;
}


 quit;

}
dilend


dilbegin spl_dispel_evil(medi : unitptr, tgt : unitptr, arg : string,
                     hm : integer, effect : string);

code
{

 if(not(IS_EVIL(tgt.alignment)))
 {
  act("You fail.", A_ALWAYS, self, null, null, TO_CHAR);
  quit;
 }

 if(isaff(tgt,ID_PROT_GOOD))
  {
   subaff(tgt,ID_PROT_GOOD);
   quit;
  }

 hm := attack_spell(SPL_DISPEL_EVIL, self, medi, tgt, 0, effect);

quit;

}
dilend

dilbegin spl_dispel_good(medi : unitptr, tgt : unitptr, arg : string,
                     hm : integer, effect : string);

code
{

 if((IS_GOOD(self.alignment)) and (not(IS_GOOD(tgt.alignment))))
  {
   act("You fail.", A_ALWAYS, self, null, null, TO_CHAR);
   quit;
  }

 if(isaff(tgt,ID_PROT_EVIL))
  {
   subaff(tgt,ID_PROT_EVIL);
   quit;
  }

 hm := attack_spell(SPL_DISPEL_GOOD, self, medi, tgt, 0, effect);

quit;
}
dilend

dilbegin spl_repel_1(medi : unitptr, tgt : unitptr, arg : string,
                     hm : integer, effect : string);
external
    integer skill_duration(hm : integer);

code
{

 if((not RACE_IS_UNDEAD(tgt.race)) or (hm < 0)) quit;

 hm := skill_duration(hm);

 addaff(tgt, ID_FEAR, hm, WAIT_SEC * 30, 0, 0, 0,
        TIF_FEAR_CHECK, TIF_FEAR_CHECK, TIF_NONE,
        APF_NONE);

if(effect != "")
 effect(tgt,medi,hm);

 quit;
}
dilend

dilbegin spl_repel_2(medi : unitptr, tgt : unitptr, arg : string,
                     hm : integer, effect : string);
external
    integer skill_duration(hm : integer);
    integer skillresist(aa : integer, ad : integer,
                        sa : integer, sd : integer);
    provoked_attack@function(victim : unitptr, ch : unitptr);
var
u: unitptr;

code
{

 foreach(UNIT_ST_PC|UNIT_ST_NPC, u)
 {

  if((not(visible(self,u))) or (u.level >= IMMORTAL_LEVEL) or
     (u == self)) continue;

  if(RACE_IS_UNDEAD(u.race))
  {
   hm := skillresist(self.abilities[ABIL_BRA],
                     u.abilities[ABIL_BRA],
                     self.spells[SPL_REPEL_UNDEAD_2],
                     u.spells[SPL_DIVINE]);

    if(hm > 0)
     {

       hm := skill_duration(hm);

      addaff(u, ID_FEAR, hm, WAIT_SEC * 30, 0, 0, 0,
                TIF_FEAR_CHECK, TIF_FEAR_CHECK, TIF_NONE,
                APF_NONE);

       if(effect != "")
         effect(tgt,medi,hm);
      }
     else
      provoked_attack@function(u,self);
  }
 }
quit;
}
dilend

dilbegin spl_cure_blind(medi : unitptr, tgt : unitptr, arg : string,
                     hm : integer, effect : string);
code
{


if(hm < -30) quit;

if(isaff(tgt,ID_BLIND_CHAR))
  subaff(tgt,ID_BLIND_CHAR);

quit;
}
dilend

dilbegin spl_sanctuary(medi : unitptr, tgt : unitptr, arg : string,
                     hm : integer, effect : string);
external
   integer skill_duration(hm : integer);
code
{

  if((isaff(tgt,ID_SANCTUARY)) or (hm < 0)) quit;

  hm := skill_duration(hm);

  addaff(tgt, ID_SANCTUARY, hm, WAIT_SEC * 30, 0, 0, 0,
              TIF_SANCTUARY_ON, TIF_SANCTUARY_TICK,
              TIF_SANCTUARY_OFF, APF_NONE);

if(effect != "")
 effect(tgt,medi,hm);

  quit;
}
dilend


dilbegin spl_sustain(medi : unitptr, tgt : unitptr, arg : string,
                     hm : integer, effect : string);
external
   integer skill_duration(hm : integer);

code
{

 if((isaff(tgt, ID_SUSTAIN)) or (hm < 0)) quit;

 hm := skill_duration(hm);

 addaff(tgt, ID_SUSTAIN, hm, WAIT_SEC * 30, tgt.drunk,
             tgt.full, tgt.thirst, TIF_SUSTAIN_ON,
             TIF_SUSTAIN_TICK, TIF_SUSTAIN_OFF, APF_NONE);

if(effect != "")
 effect(tgt,medi,hm);

 quit;

}
dilend


dilbegin spl_unlock(medi : unitptr, tgt : unitptr, arg : string,
                     hm : integer, effect : string);
external
    dir_locks(dir : integer, st : string, todo : integer);
    integer rev_dir@function(i : integer);

var
wrd: string;
dir: integer;
obj: unitptr; /* since we can lock backpacks and such */
room: unitptr;
i: integer;
str: string;
rev: integer;

code
{

if((arg == "") or (hm < 0)) goto failed;

str := arg; /*preserve the complete argument for later use*/

wrd := getword(arg);

dir := -1;

if(wrd in "north") dir := NORTH;
else if(wrd in "south") dir := SOUTH;
else if(wrd in "east") dir := EAST;
else if(wrd in "west") dir := WEST;
else if(wrd in "up") dir := UP;
else if(wrd in "down") dir := DOWN;
else if(wrd in "northeast") dir := NORTHEAST;
else if(wrd in "northwest") dir := NORTHWEST;
else if(wrd in "southeast") dir := SOUTHEAST;
else if(wrd in "southwest") dir := SOUTHWEST;

if(dir != -1)
{
 dir_locks(dir,arg,1);
 quit;
}

room := self.outside;

i := NORTH;

while(i <= MAX_EXIT)
{

 if(str in room.exit_names[i]) break;

 i := i + 1;
}


/* there is no such lock in our self.outside, maybe it's an object? */
// Removed the EX_HIDDEN check til search is fixed - Storm
if((i > MAX_EXIT) /* or isset(room.exit_info[i], EX_HIDDEN)*/ )
  goto obj_check;

if((not(isset(room.exit_info[i], EX_OPEN_CLOSE))) or
   (not(isset(room.exit_info[i], EX_CLOSED))) or
   (not(isset(room.exit_info[i], EX_LOCKED))))
  goto failed;

  unset(room.exit_info[i], EX_LOCKED);
  act("*click*", A_ALWAYS, room.inside, null, null, TO_ALL);

  rev := rev_dir@function(i);

 if(isset(room.exit_to[i].exit_info[rev], EX_LOCKED))
  {
   unset(room.exit_to[i].exit_info[rev], EX_LOCKED);
   act("*click*",
        A_ALWAYS, room.exit_to[i].inside, null, null, TO_ALL);
  }

quit;

:obj_check:

obj := findunit(self,str,FIND_UNIT_HERE,null);

if(obj == null) goto failed;

if((not(isset(obj.openflags, EX_OPEN_CLOSE))) or
   (not(isset(obj.openflags, EX_CLOSED))) or
   (not(isset(obj.openflags, EX_LOCKED))))
  goto failed;

unset(obj.openflags, EX_LOCKED);
act("*click*",
    A_SOMEONE, self, null, null, TO_ALL);

/* there is no recursive abilties inside a closable object */

quit;


:failed:
act("The spell failed.",
    A_ALWAYS, self, null, null, TO_CHAR);
quit;

}
dilend

/* Ok this is for stuff like cast lock/unlock south door */
/* I did this just so I didn't have to duplicate it for both
  lock and unlock since they both check for pretty much the
  same things */

                /*  DIRECTION     ARGUMENT    0=LOCK/1=UNLOCK */
dilbegin dir_locks(dir : integer, st : string, todo : integer);
external
  string dirstring@function(dr:integer);
  integer rev_dir@function(i : integer);
var
room: unitptr;
plce: string;
rev: integer;

code
{

if(st == "")
{
 plce := dirstring@function(dir);
 act("What is the name of the exit to the "+plce+"?",
       A_ALWAYS, self, null, null, TO_CHAR);
 goto failed;
}

room := self.outside;

if(not(room.exit_to[dir])) goto failed;

/* Is there an exit there ? */
if(not(st in room.exit_names[dir]) or isset(room.exit_info[dir],EX_HIDDEN))
{
 act("You see no such exit in that direction.",
      A_ALWAYS, self, null, null, TO_CHAR);
 goto failed;
}

if((not(isset(room.exit_info[dir],EX_OPEN_CLOSE))) or
   (not(isset(room.exit_info[dir],EX_CLOSED))))
     goto failed;

if((todo == 0) and (isset(room.exit_info[dir], EX_LOCKED)))
     goto failed;

if((todo == 1) and (not(isset(room.exit_info[dir], EX_LOCKED))))
    goto failed;

/* Ok everything checks out, lets set the right flags and get outta here */

/* LOCK */
if(todo == 0)
{

 set(room.exit_info[dir], EX_LOCKED);
 act("*cluck*", A_ALWAYS, room.inside, null, null, TO_ALL);

 rev := rev_dir@function(dir);

/* Is the recursive door already locked? Better yet can it be? */
 if((not(isset(room.exit_to[dir].exit_info[rev], EX_LOCKED))) and
    (isset(room.exit_to[dir].exit_info[rev], EX_OPEN_CLOSE)))
  {
   set(room.exit_to[dir].exit_info[rev], EX_LOCKED);
   act("*cluck*",
   A_ALWAYS,room.exit_to[dir].inside, null, null, TO_ALL);
  }
 quit;
}
else /* UNLOCK */
 {
  unset(room.exit_info[dir], EX_LOCKED);
  act("*click*", A_ALWAYS, room.inside, null, null, TO_ALL);

  rev := rev_dir@function(dir);

 if((isset(room.exit_to[dir].exit_info[rev], EX_LOCKED)) and
    (isset(room.exit_to[dir].exit_info[rev], EX_OPEN_CLOSE)))
  {
   unset(room.exit_to[dir].exit_info[rev], EX_LOCKED);
   act("*click*",
     A_ALWAYS, room.exit_to[dir].inside, null, null, TO_ALL);
  }
 quit;
}

:failed:
act("The spell failed.",
    A_ALWAYS, self, null, null, TO_CHAR);
quit;

}

dilend

/* pretty much the same code as unlock, just switched around */
dilbegin spl_lock(medi : unitptr, tgt : unitptr, arg : string,
                     hm : integer, effect : string);
external
    dir_locks(dir : integer, st : string, todo : integer);
    integer rev_dir@function(i : integer);

var
room: unitptr;
obj: unitptr;
wrd: string;
str: string;
dir: integer;
rev: integer;
i: integer;

code
{

 if((arg == "") or (hm < 0)) goto failed;

str := arg;

wrd := getword(arg);

dir := -1;

if(wrd in "north") dir := NORTH;
else if(wrd in "south") dir := SOUTH;
else if(wrd in "east") dir := EAST;
else if(wrd in "west") dir := WEST;
else if(wrd in "up") dir := UP;
else if(wrd in "down") dir := DOWN;
else if(wrd in "northeast") dir := NORTHEAST;
else if(wrd in "northwest") dir := NORTHWEST;
else if(wrd in "southeast") dir := SOUTHEAST;
else if(wrd in "southwest") dir := SOUTHWEST;

if(dir != -1)
{
 dir_locks(dir,arg,0);
 quit;
}


room := self.outside;

i := NORTH;

while(i <= MAX_EXIT)
{

 if(str in room.exit_names[i]) break;

 i := i + 1;
}

if(i > MAX_EXIT) goto obj_check;

if((not(isset(room.exit_info[i], EX_OPEN_CLOSE))) or
   (not(isset(room.exit_info[i], EX_CLOSED))) or
   (isset(room.exit_info[i], EX_LOCKED)))
  goto failed;

  set(room.exit_info[i], EX_LOCKED);
  act("*cluck*", A_ALWAYS, room.inside, null, null, TO_ALL);

  rev := rev_dir@function(i);

 if(not(isset(room.exit_to[i].exit_info[rev], EX_LOCKED)))
  {
   set(room.exit_to[i].exit_info[rev], EX_LOCKED);
   act("*cluck*",
        A_ALWAYS, room.exit_to[i].inside, null, null, TO_ALL);
  }

quit;

:obj_check:

obj := findunit(self,str,FIND_UNIT_HERE,null);

if(obj == null) goto failed;

if((not(isset(obj.openflags, EX_OPEN_CLOSE))) or
   (not(isset(obj.openflags, EX_CLOSED))) or
   (isset(obj.openflags, EX_LOCKED)))
  goto failed;

set(obj.openflags, EX_LOCKED);
act("*cluck*",
    A_SOMEONE, self, null, null, TO_ALL);

/* there is no recursive abilties inside a closable object */

quit;


:failed:
act("The spell failed.",
    A_ALWAYS, self, null, null, TO_CHAR);
quit;

}
dilend

dilbegin spl_identify_2(medi : unitptr, tgt : unitptr, arg : string,
                     hm : integer, effect : string);
var
ex: extraptr;
str: string;
code
{

if(hm < 0) quit;

str := "";

ex := "$identify" in tgt.extra;

if(ex != null)
 str := str+ex.descr;

ex := "$improved identify" in tgt.extra;

if(ex != null)
 str := str+ex.descr;

if(str == "")
{
 act("There is nothing exceptional to learn about this item.",
      A_ALWAYS, self, null, null, TO_CHAR);
 quit;
}
else
  pagestring(str,self);

quit;

}
dilend

%rooms

                                  spell_room
title "The Spell Room"
descr
"Token room."
movement SECT_INSIDE
flags {UNIT_FL_NO_WEATHER}
ALWAYS_LIGHT
end

%objects

shield_leaf
names {"leaf shield", "shield", "leaf"}
title "a leaf shield"
descr "A gigantic leaf has been left here."
extra {}
"Simply an enormous leaf, its purpose is to serve as a shield for
embattled adventurers. While the nature of the shield may lead one to
consider the quality to be lacking, appearances are often deceiving."
SHIELD_DEF(SHIELD_LARGE, -25, -25)
dilcopy blowaway@function(600, "$1n shrinks back into a normal leaf.");
weight 2
end

stat_obj2
names {"secondary statue object","statue object","object2","object"}
title "secondary statue object"
descr "The secondary statue object is here."
type ITEM_OTHER
extra {}
"This object loads the primary statue object which in turn loads any
player statues left over after a crash/reboot.  This bugger loads and
destroys itself real fast, so if you're seeing it now, something's
probably amiss."
minv 200
dilbegin aware obj2();
var
  prim : unitptr;
  f    : integer;

code
{
heartbeat:=PULSE_SEC*4;
 prim := restore("statue_object1", null);
 if(prim == null)
  {
   prim := load("stat_obj1@spells");
  }
link(prim, self.outside);
  f := dilfind("obj1@spells", prim);
  if(f == FALSE) dilcopy("obj1@spells()", prim);
f:= dilfind("obj1a@spells", prim);
if(f == FALSE) dilcopy("obj1a@spells()", prim);
destroy(self);
}
dilend
end

stat_obj1
names {"primary statue object","statue object","object1","object"}
title "primary statue object"
descr "The primary statue object is here."
CONTAINER_DEF(2500)
extra {}
"This object loads any player statues left over after a crash/reboot.  Admins
may reset this object's memory by using the command 'ERASE'."
minv 200
end

stat_corpse
names {"statue","stat_corpse"}
title "a base statue"
descr "A base statue is here."
CONTAINER_DEF(1000)
manipulate {MANIPULATE_ENTER}
extra {}
"It is a remarkably life-like statue..."
dilbegin stat_blow();
var
r   : integer;
t   : integer;
obj : unitptr;

code
{
 t := 0;
 heartbeat := PULSE_SEC * 5;
 wait (SFB_TICK, TRUE); // Wait for petrify to be done with statue

 if (self.value[2] == 1) // Player
   heartbeat := PULSE_SEC*SECS_PER_REAL_HOUR*8; // 8 real hours
 else // Mob
   heartbeat := PULSE_SEC*SECS_PER_REAL_HOUR + PULSE_SEC*rnd(-30,30);

:loop:
  wait (SFB_TICK, TRUE); // Exact wait
  t := t + 1;
  if(t < 3) goto loop;

  act("$1n shatters into millions of pieces!",
      A_SOMEONE, self, null, null, TO_ROOM);

if (self.value[2] == 1)
{
 obj := findsymbolic("stat_obj1@spells");
 if(obj == null)
  {
   log("Statue object not present at time of blowaway expiration.");
   quit;
  }
 substring(obj.names, self.names.[2]);
 store(obj, "statue_object1", TRUE);

 r := delunit(self.names.[2]+".spells");
  if(not(r)) log(self.names.[2]+".spells file FAILED to delete after blowaway.");
  if(r) log(self.names.[2]+".spells file DELETED, blowaway expired.");
}
  destroy(self);
}
dilend
dilcopy stat_report2@spells();
end

bram_bush
names {"brambles", "bush"}
title "a large brambles bush"
descr "A large bush of brambles has grown here."
extra {}
"It is quite large and intimidating. The thorns are proportionate to the
size of the bush and appear to be able to inflict quite a bit of damage
to passers-by."
weight 10
end

ice_thorn
names {"dagger of ice","ice dagger","ice thorn","dagger","thorn","ice"}
title "a dagger of ice"
descr "An icicle shaped remarkably like a dagger lies here, melting."
manipulate {MANIPULATE_TAKE, MANIPULATE_HOLD, MANIPULATE_WIELD}
WEAPON_DEF(WPN_DAGGER, -25, -25)
weight 2
cost 1 IRON_PIECE
extra {}
"A large thorn made of clear glistening ice, this magical creation can be
wielded at its wide end and used as a dagger.  Unfortunately, the magic which
created it is somewhat unstable and the weapon will melt in only a short
time."
dilbegin aware recall melting();
var
 melt : integer;

code
{
heartbeat := PULSE_SEC * 60;
melt := 21;

:start:
wait(SFB_TICK, TRUE);
melt := melt - 1;
 if(melt == 14)
 {
  act("Your ice dagger begins to melt.",
      A_ALWAYS, self.outside, null, null, TO_CHAR);
  act("$1n's ice dagger begins to melt.",
      A_SOMEONE, self.outside, null, null, TO_REST);
  self.value[1] := self.value[1] - 2;
  self.value[2] := self.value[2] - 2;
 }
 if(melt == 7)
 {
  act("Your ice dagger drips steadily; it will not hold its form for long.",
      A_ALWAYS, self.outside, null, null, TO_CHAR);
  act("$1n's ice dagger drips steadily as it melts.",
      A_SOMEONE, self.outside, null, null, TO_REST);
  self.value[1] := self.value[1] - 4;
  self.value[2] := self.value[2] - 4;
 }
 if(melt <= 0)
 {
  act("Your ice dagger melts away completely.",
      A_ALWAYS, self.outside, null, null, TO_CHAR);
  act("$1n's ice dagger melts away completely.",
      A_SOMEONE, self.outside, null, null, TO_REST);
  destroy(self);
  quit;
 }
goto start;
}
dilend
end

m_puddle
names {"mud puddle", "puddle"}
title "&cya mud puddle&[default]"
descr "&cyA large puddle of slippery mud is on the ground here.&[default]"
extra {}
"It is of significant size while remaining quite shallow over its area.
The consistency of the mud is somewhere between slime and water, yielding
a quality of slickness akin to ice."
weight 10
end

portal
names {"Portal"}
title "the Portal"
descr
"An eliptical portal shines like a mirror here."

extra {}
"It is like a film of water about six feet in height, hovering gently about
half a foot off the ground. Perhaps you should enter it? It shimmers and
shines, radiating a light of its own."

type ITEM_OTHER

end /* portal */

gate
names {"Gate","hole","window","rectangle"}
title "the Travel Gate"
descr
"A shining upright rectangle of light hangs just off the ground here."

extra {}
"Wafer thin, it stands just over six feet in height, and though it doesn't
shed light on anything around it, it shines brilliantly, a perfect rectangle.
It's large enough to step through, and casting a GAZE at it reveals a lot."

type ITEM_OTHER

end /* gate */

fungus
names {"glowing fungus", "chunk", "glowing chunk", "fungus"}
title "a glowing chunk of fungus"
descr "A chunk of fungus is glowing here."
extra {}
"The chunk of fungus glows oddly, shimmering much like the moon on a crisp
winter's eve."
bright 4
weight 1
manipulate {MANIPULATE_TAKE,MANIPULATE_HOLD}
dilcopy blowaway@function(300, "A glowing chunk of fungus dissolves into a
puddle of slime and slowly seeps into the ground.");
end

dust_bones
names {"pile of dust","dust","pile"}
title "a pile of dust"
descr "A pile of dust and bones lies here."
MATERIAL_EARTH("Ordinary dust")

manipulate {MANIPULATE_TAKE,MANIPULATE_ENTER}
extra{}
"It looks like the remains of a zombie."
weight 50
CONTAINER_DEF(10)
dilcopy blowaway@function (600,"A sudden wind scatters a pile of dust and
bones.");
end


                           magic_water

names {"barrel", "water"}
title "a barrel"
descr "A barrel has been left here."
manipulate {MANIPULATE_TAKE}
LIQ_DEF("clear", 6,24,24,10,1,0,0)
cost 2 IRON_PIECE
end

candle
names {"magic candle","candle"}
title "a bright magic candle"
descr "A magic candle has been discarded here."
bright 3
manipulate {MANIPULATE_HOLD, MANIPULATE_TAKE}
dilbegin candle ();
code
{
 heartbeat := PULSE_SEC*180;
 pause;
 act("Your magic candle slowly begins to dim.",
     A_SOMEONE, self.outside, null, null, TO_CHAR);
 pause;
 act("The magic candle dims to a faint glow.",
      A_SOMEONE, self.outside, null, null, TO_CHAR);
 pause;
 act("The magic candle flickers into an oblivion.",
      A_SOMEONE, self.outside, null, null, TO_CHAR);
 destroy(self);
}
dilend
end

                           light_orb
names {"yellow light globe","light globe", "globe", "light"}
title "a bright yellow globe of light"
descr "A yellow glowing globe of light has been discarded here."
bright 3
manipulate {MANIPULATE_HOLD, MANIPULATE_TAKE}
end


                            magic_food

names {"salted beef", "beef"}
title "a piece of salted beef"
descr "A piece of salted beef has been left here."
manipulate {MANIPULATE_TAKE}
FOOD_DEF(24, 0)
weight 1
cost 2 IRON_PIECE
end



%mobiles

lightn_elm
names {"lightning elemental", "elemental"}
title "a lightning elemental"
descr "a large, humanoid lightning bolt stands here."
extra {}
"The creature is made of pure electricity, and sparkles and crackles
menacingly."
race RACE_ELEMENTAL_LIGHT
level 50
sex SEX_NEUTRAL
exp 0
height 200
weight 300
alignment -350
NATURAL_DEF(WPN_FIST, ARM_CHAIN)
MSET_ABILITY(18,16,5,14,17,5,20,5)
MSET_WEAPON(5,5,5,5,29,5)
MSET_SPELL(3,0,0,1,1,5,6,6,16,5,3)
dilcopy obey_animal@function();
dilcopy combat_mag@function("jolt", "", 0, 2);
dilcopy sum_check@spells();
end



   earth_elm

names {"earth elemental", "elemental"}
title "an earth elemental"
descr "a large, humanoid column of rock stands here."
extra {}
"The large beast is made of solid rock, with huge diamonds for eyes."

M_ELEMENTAL_FIRE
exp 0
level 13
race RACE_ELEMENTAL_EARTH
special SFUN_COMBAT_MAGIC "cast acid drop"
dilcopy obey_animal@function();
dilcopy sum_check@spells();
end


   air_elm

names {"air elemental", "elemental"}
title "an air elemental"
descr "a large, swirling mist in humanoid form floats here."
extra {}
"This being is nearly translucent, and floats in the air quietly."

M_ELEMENTAL_FIRE
exp 0
race RACE_ELEMENTAL_AIR
level 17

special SFUN_COMBAT_MAGIC "cast electrical shock"
dilcopy obey_animal@function();
dilcopy sum_check@spells();
end

   water_elm

names {"water elemental", "elemental"}
title "a water elemental"
descr "a large column of water stands here."
extra {}
"This column of water seems to be alive!"

M_ELEMENTAL_FIRE
exp 0
race RACE_ELEMENTAL_WATER
level 23

special SFUN_COMBAT_MAGIC "cast snowball"
dilcopy obey_animal@function();
dilcopy sum_check@spells();
end


   fire_elm

names {"fire elemental", "elemental"}
title "a fire elemental"
descr "a large column of flame stands here."
extra {}
"Movement from the flames suggest intelligence is present."

M_ELEMENTAL_FIRE
exp 0
level 28

dilcopy obey_animal@function();
dilcopy sum_check@spells();
end


   demon

names {"demon"}
title "a demon"
descr "a large demon stands here."
extra {}
"This large beast looks very upset at being pulled from its plane of
existance."

M_DEMON_AVG(SEX_MALE)
exp 0
level 35

dilcopy obey_animal@function();
dilcopy sum_check@spells();
end


   devil

names {"devil"}
title "a devil"
descr "a large devil stands here."
extra {}
"This large creature stands with a malevolent grin on his face."

M_DEMON_AVG(SEX_MALE)
level 45
exp 0
race RACE_LESSER_DEVIL
dilcopy sum_check@spells();
dilcopy obey_animal@function();
end


                          dust_devil

names {"dust devil", "dust", "devil"}
title "a dust devil"
descr "A small tornado of swirling dust is spinning around."
extra {}
"Watch out, you might get the dust in your eyes!"

M_DUST_DEVIL
exp 0

dilcopy obey_animal@function();
end

                          zombie

names {"zombie"}
title "the zombie"
descr "A mindless zombie is roaming around here."
extra {} "Disgusting!"
M_ZOMBIE_AVG
level 4
exp 0
end



%end