Appendix E. The Skills Zone


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

notes
"This is the skills zone. Don't 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 integer skillresist(aa : integer, ad : integer,
			     sa : integer, sd : integer);
code
{
   return (openroll(100, 5) + aa + sa - ad - sd - 50);
}
dilend


dilbegin string sizestring(cm : integer);
var
   ftn : integer;
   fts : string;
   inn : integer;
   ins : string;
code
{
   /* One inch equals 2,54 cm. There are 12 inches (30.48 cm) to a foot */
   ftn := cm / 30;
   inn := (10*(cm % 30))/25;
   if (ftn == 1)
     fts := "one foot";
   else if (ftn > 1)
     fts := itoa(ftn)+" feet";
   else
     fts := "";

   if (inn == 1)
     ins := "one inch";
   else if (inn > 1)
     ins := itoa(inn)+" inches";
   else
     ins := "";

   if (fts != "")
   {
      if (ins != "")
        fts := fts + " and ";
   }
   else
   {
      if (inn >lt; 1)
	ins := "less than an inch";
   }

   return (fts + ins);
}
dilend
dilbegin string weightstring(p : integer);
var
   s : string;
code
{
   if (p == 1)
     s := "one pound";
   else if (p > 1)
     s := itoa(p)+" pounds";
   else
     s := "less than a pound";

   return (s);
}
dilend


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

   if (not (ch.type >amp; (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 >lt;= 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 skill_duration(hm : integer);
code
{
   if (hm >lt; 20)
     return (2);
   else if (hm > 150)
     return (15);
   else
     return (hm / 10);
}
dilend

#define  SKIN_SKIN   "skin"
#define  SKIN_HIDE   "hide"
#define SKIN_FUR  "fur"
#define  SKIN_SCALE  "scales"
#define  SKIN_FEATHER   "feathers"
#define SKIN_QUILL  "quills"
#define SKIN_TREE  "bark"
#define  SKIN_SHELL  "shell"
#define  SKIN_NONE  "NONE"

dilbegin disarm(arg : string);
/* by Drevar */
external
   integer skillresist (aa : integer, ad : integer,
                             sa : integer, sd : integer);
   provoked_attack (victim : unitptr, ch : unitptr);

var
   tweapon  : unitptr;
   mweapon  : unitptr;
   skilla : integer;
   skilld : integer;
   hm     : integer;
   targ   : unitptr;

code
{

  if ((self.type == UNIT_ST_PC) and (self.skills[SKI_DISARM] >lt;= 0))
  {
     act("You must practice first.", A_ALWAYS, self, null, null, TO_CHAR);
     quit;
  }

   if (arg == "")
   {
     if (self.fighting)
     {
       targ := self.fighting;
       goto disarm;
     }
     else
     {
       act("Who do you wish to disarm?", A_SOMEONE, self, null, null,
           TO_CHAR);
       quit;
     }
   }
   targ := findunit(self, arg, FIND_UNIT_SURRO, null);

   if ((targ == null) or not visible(self, targ))
     {
       act("They are not here!", A_SOMEONE, self, null, targ, TO_CHAR);
       quit;
     }

if (targ==self)
  {
      act("Why not use the remove command.", A_SOMEONE, self,
          null, null, TO_CHAR);
      quit;
    }


  if ( (targ.type != UNIT_ST_PC) and (targ.type != UNIT_ST_NPC) )
    {
      act("No need to disarm that, it can't attack you.", A_SOMEONE, self,
          null, null, TO_CHAR);
      quit;
    }

   if (targ.position >lt;= POSITION_INCAP)
     {
       act("Why bother?  $3e can't hurt you now!", A_SOMEONE, self, null,
           targ, TO_CHAR);
       quit;
     }

   if ((targ.type==UNIT_ST_PC) and
   (self.type==UNIT_ST_PC))
  {
if (not(isset (self.pcflags, PC_PK_RELAXED)))
  {
  act ("You are not allowed to do this unless you sign the book of blood.",
  A_ALWAYS,self,null,null,TO_CHAR);
  quit;
  }

if (not(isset (targ.pcflags, PC_PK_RELAXED)))
  {
  act ("You are not allowed to do this unless $2e signs the book of blood.",
  A_ALWAYS,self,targ,null,TO_CHAR);
  quit;
  }
  }

   :disarm:
   mweapon := self.inside;
   while (mweapon)
     {
       if ( (mweapon.objecttype == ITEM_WEAPON) and
            (mweapon.equip == WEAR_WIELD) )
         {
           break;
         }
       mweapon := mweapon.next;
     }

   if (mweapon == null)
     {
       act("Better get yourself a weapon first!", A_SOMEONE, self, null, null,
           TO_CHAR);
       quit;
     }

   tweapon := targ.inside;
   while (tweapon)
     {
       if ( (tweapon.objecttype == ITEM_WEAPON) and
            (tweapon.equip == WEAR_WIELD) )
         {
           break;
         }
       tweapon := tweapon.next;
     }

   if (tweapon == null)
     {
       act("$3n has no weapon!", A_SOMEONE, self, null, targ, TO_CHAR);
       quit;
     }

   provoked_attack (targ, self);

   if (self.type == UNIT_ST_PC)
     skilla := self.skills[SKI_DISARM];
   else
     skilla := (self.abilities[ABIL_DEX] / 2) + (self.abilities[ABIL_STR] /2);

   if (targ.type == UNIT_ST_PC)
     skilld := targ.skills[SKI_DISARM];
   else
     skilld := (targ.abilities[ABIL_DEX] / 2) + (targ.abilities[ABIL_STR] /2);

   if (self.fighting)
     hm := skillresist (
              (self.abilities[ABIL_DEX] / 4) + (self.abilities[ABIL_STR] /4),
              (targ.abilities[ABIL_DEX] / 2) + (targ.abilities[ABIL_STR] /2),
              (skilla / 2), skilld);
   else
     hm := skillresist (
              (self.abilities[ABIL_DEX] / 2) + (self.abilities[ABIL_STR] /2),
              (targ.abilities[ABIL_DEX] / 2) + (targ.abilities[ABIL_STR] /2),
               skilla, skilld);


   if (self.endurance >lt; 3)
     act("You are too exhausted to attempt that.", A_ALWAYS, self, null,
         null, TO_CHAR);
   else self.endurance := self.endurance - 3;

   if (hm >lt;= -25)
     {
        act("As you attempt to disarm $3n, your $2N slips through your " +
            "hands!", A_SOMEONE, self, mweapon, targ, TO_CHAR);
        act("$1n tries a fancy move, but you counter and cause $1m to drop
"  +
            "$1s $2N!.", A_SOMEONE, self, mweapon, targ, TO_VICT);
        act("$3n counters $1n's disarm attempt, $1n lost $1s own weapon " +
            "instead!",A_SOMEONE, self, mweapon, targ, TO_NOTVICT);
        link(mweapon, self.outside);
        if (self.type == UNIT_ST_NPC)
          dilcopy("rearm@skills("+mweapon.name+")", self);
        quit;
     }
   if (hm >lt;= 0)
     {
       act("You attempt to disarm $3n, but fail.", A_SOMEONE, self, null,
targ,
           TO_CHAR);
       act("$1n makes a feeble attempt to relieve you of your $2N.",
           A_SOMEONE, self, tweapon, targ, TO_VICT);
       act("$1n fails $1s attempt at disarming $3n.", A_SOMEONE, self, null,
           targ, TO_NOTVICT);
       quit;
     }
   act("Your quick move pulls $3n's $2N from $3s hands!", A_SOMEONE, self,
       tweapon, targ, TO_CHAR);
   act("$1n strips your $2N from you hands!", A_SOMEONE, self, tweapon,
       targ, TO_VICT);
   act("$1n deftly strips $3n's $2N from $3s hands!", A_SOMEONE, self,
       tweapon, targ, TO_NOTVICT);
   link(tweapon, targ.outside);
   if (targ.type == UNIT_ST_NPC)
    dilcopy("rearm@skills("+tweapon.name+")", targ);
   quit;

}
dilend

dilbegin rearm(t : string);
var
i : integer;
tweap : unitptr;
code
{
  interrupt(SFB_DEAD, activator == self, stop);
  heartbeat := PULSE_VIOLENCE;

  :retry:

  wait(SFB_COM, self.position == POSITION_FIGHTING);

  heartbeat := PULSE_VIOLENCE;
  i := rnd(1, 100);
  if (i >= 40)
  {
    change_speed(self, PULSE_VIOLENCE);
    act("$1n ducks quickly and tries to recover $1s weapon.", A_SOMEONE,
        self, null, null, TO_ROOM);
    i := rnd(1, 200);
    if (i >lt;= self.abilities[ABIL_DEX])
    {
      tweap := findunit(self, t, FIND_UNIT_SURRO, null);
          if ( (tweap!=null) and
          (tweap.type == UNIT_ST_OBJ) and
               (tweap.objecttype == ITEM_WEAPON) and
               (not isset(tweap.flags, UNIT_FL_BURIED)) )
      {
        link(tweap, self);
        act("$1n manages to retrieve $1s "+tweap.name+"", A_SOMEONE, self,
            null, null, TO_ROOM);
        exec("wield "+tweap.name+"", self);
        goto stop;
      }
      else
      {
        tweap := self.outside.inside;
        while (tweap)
        {
          if ( (tweap.type == UNIT_ST_OBJ) and
               (tweap.objecttype == ITEM_WEAPON) and
               (not isset(tweap.flags, UNIT_FL_BURIED)) )
          {
            link(tweap, self);
            act("$1n manages to retrieve a "+tweap.name+"", A_SOMEONE, self,
                null, null, TO_ROOM);
            exec("wield "+tweap.name+"", self);
            act("$1n scowls at $1s "+tweap.name+"", A_SOMEONE, self, null,
                null, TO_ROOM);
            i := 1;
            break;
          }
          else
          {
            tweap := tweap.next;
            i := 0;
          }
        }
      if (i == 0)
        act("$1n resigns to using $1s natural weapons.", A_SOMEONE, self,
            null, null, TO_ROOM);

      goto stop;
      }
    }
    else
    {
      act("$1n fumbles and fails to retrieve $1s weapon.", A_SOMEONE, self,
          null, null, TO_ROOM);
      goto retry;
    }
  }
  else
    goto retry;

  :stop:
  quit;
}
dilend

dilbegin pickpocket(arg : string);
/* by Drevar */
external
   integer skillresist (aa : integer, ad : integer,
                             sa : integer, sd : integer);
   provoked_attack (victim : unitptr, ch : unitptr);
var
skilla   :  integer;
skilld   :  integer;
hm       :  integer;
vict     :  unitptr;
object   :  unitptr;
willtake :  integer;
plat     :  integer;
gold     :  integer;
silv     :  integer;
copp     :  integer;
iron     :  integer;

code
{
  if ((self.type == UNIT_ST_PC) and (self.skills[SKI_PICK_POCKETS] >lt;= 0))
  {
     act("You must practice first.", A_ALWAYS, self, null, null, TO_CHAR);
     quit;
  }

  object := self.inside;
  hm := 0;
  while ((object) and (hm != 2))
    {
      if ( (object.equip == WEAR_WIELD) and
           (isset(object.objectflags, OBJ_TWO_HANDS)) )
        {
          hm := 2;
          continue;
        }

      if ( (object.equip == WEAR_HOLD) or (object.equip == WEAR_WIELD) or
         (object.equip == WEAR_SHIELD) )
        {
          hm := hm + 1;
        }

      object := object.next;
    }

  if (hm == 2)
    {
       act("You must have at least one hand free to attempt that!", A_SOMEONE,
           self, null, null, TO_CHAR);
       quit;
    }


  vict := findunit(self, arg, FIND_UNIT_SURRO, null);

  if ((vict == null) or not visible(self, vict))
    {
      act("No such person to pickpocket.",  A_SOMEONE, self, null, null,
          TO_CHAR);
      quit;
    }

   if ((vict.type==UNIT_ST_PC) and
   (self.type==UNIT_ST_PC))
  {
if (not(isset (self.pcflags, PC_PK_RELAXED)))
  {
  act ("You are not allowed to do this unless you sign the book of blood.",
  A_ALWAYS,self,null,null,TO_CHAR);
  quit;
  }

if (not(isset (vict.pcflags, PC_PK_RELAXED)))
  {
  act ("You are not allowed to do this unless $2e signs the book of blood.",
  A_ALWAYS,self,vict,null,TO_CHAR);
  quit;
  }
  }


   if (self.type == UNIT_ST_PC)
     skilla := self.skills[SKI_PICK_POCKETS];
   else
     skilla := self.abilities[ABIL_DEX];

   if (vict.type == UNIT_ST_PC)
     skilld := vict.skills[SKI_PICK_POCKETS];
   else
     skilld := vict.abilities[ABIL_DEX];

   hm := skillresist (self.abilities[ABIL_DEX],
                     vict.abilities[ABIL_DEX],
		     skilla, skilld);

  if (hm >lt;= -5)
    {
      act("You are caught!", A_SOMEONE, self, null, vict, TO_CHAR);

      if (isaff(self, ID_INVISIBILITY))
        subaff(self, ID_INVISIBILITY);

      act("You catch $1n with $1s hand in your purse!", A_SOMEONE, self, null,
          vict, TO_VICT);
      act("You see $1n trying to pilfer money from $3n...$3e doesn't " +
          "seem amused!", A_SOMEONE, self, null, vict, TO_NOTVICT);
      provoked_attack (vict, self);
      logcrime(self, vict, CRIME_STEALING);
      quit;
    }


  if (hm >lt;= 0)
    {
      act("You fail to get any money from $3n, but at least no one was
watching!",
        A_SOMEONE, self, null, vict, TO_CHAR);
      quit;
    }

  if (hm >lt;= 5)
    {
      act("You pilfer a handful of coins just as $3e turns toward you..." +
          "You have been caught!", A_SOMEONE, self, null, vict, TO_CHAR);
      if (isaff(self, ID_INVISIBILITY))
        subaff(self, ID_INVISIBILITY);

      act("Arrgh!  $1n just stole some of your hard earned money!",
           A_SOMEONE, self, null, vict, TO_VICT);
      act("You see $1n swipe a handful of coins from $3n...$3e doesn't " +
          "seem amused!", A_SOMEONE, self, null, vict, TO_NOTVICT);
      willtake := (self.skills[SKI_PICK_POCKETS] / 2);
      willtake := (rnd((willtake / 4), willtake));
      plat := (((purse(vict, PLATINUM_PIECE)*willtake) / 100) * 40960);
      gold := (((purse(vict, GOLD_PIECE)*willtake) / 100) * 5120);
      silv := (((purse(vict, SILVER_PIECE)*willtake) / 100) * 640);
      copp := (((purse(vict, COPPER_PIECE)*willtake) / 100) * 80);
      iron := (((purse(vict, IRON_PIECE)*willtake) / 100) * 10);

      if (iron)
        iron := (transfermoney(vict, self, iron));
      if (copp)
        copp := (transfermoney(vict, self, copp));
      if (silv)
        silv := (transfermoney(vict, self, silv));
      if (gold)
        gold := (transfermoney(vict, self, gold));
      if (plat)
        plat := (transfermoney(vict, self, plat));

      provoked_attack (vict, self);
      logcrime(self, vict, CRIME_STEALING);
      quit;
    }

  willtake := (self.skills[SKI_PICK_POCKETS] / 2);
  willtake := (rnd((willtake / 4), willtake));

  plat := (((purse(vict, PLATINUM_PIECE)*willtake) / 100) * 40960);
  gold := (((purse(vict, GOLD_PIECE)*willtake) / 100) * 5120);
  silv := (((purse(vict, SILVER_PIECE)*willtake) / 100) * 640);
  copp := (((purse(vict, COPPER_PIECE)*willtake) / 100) * 80);
  iron := (((purse(vict, IRON_PIECE)*willtake) / 100) * 10);

  if (iron)
    iron := (transfermoney(vict, self, iron));
  if (copp)
    copp := (transfermoney(vict, self, copp));
  if (silv)
    silv := (transfermoney(vict, self, silv));
  if (gold)
    gold := (transfermoney(vict, self, gold));
  if (plat)
    plat := (transfermoney(vict, self, plat));


  act("You stealthily pilfer a handful of coins from $3n's purse and " +
      "quickly deposit them in your own.",A_SOMEONE, self, null, vict,
      TO_CHAR);
  quit;

}
dilend

dilbegin peek(arg : string);

external
   integer skillresist (aa : integer, ad : integer,
                             sa : integer, sd : integer);

var
   skilla : integer;
   skilld : integer;
   hm     : integer;
   targ   : unitptr;
   object  : unitptr;
code
{
  if ((self.type == UNIT_ST_PC) and (self.skills[SKI_PEEK] >lt;= 0))
  {
    act("You must practice first.", A_ALWAYS, self, null, null, TO_CHAR);
    quit;
  }

  if (arg == "")
  {
    act("Who's inventory do you wish to peek at?", A_SOMEONE, self, null,
         null, TO_CHAR);
    quit;
  }

  targ := findunit(self, arg, FIND_UNIT_SURRO, null);

  if ((targ == null) or not visible(self, targ))
  {
    act("That person is not here!", A_SOMEONE, self, null, null, TO_CHAR);
    quit;
  }

  if (targ.type >amp;(UNIT_ST_ROOM | UNIT_ST_OBJ))
  {
    act("You don't have to peek, just look in it!", A_SOMEONE, self, null,
    null, TO_CHAR);
    quit;
  }

  if (targ == self)
  {
    act("Why don't you just use the inventory command?", A_SOMEONE, self,
         null, null, TO_CHAR);
    quit;
  }

  if (targ.position >lt;=  POSITION_SLEEPING)
  {
    act("They won't mind if you take a little peek at the moment.",
        A_SOMEONE, self, null, null, TO_CHAR);
    goto success;
  }

  if (self.type == UNIT_ST_PC)
    skilla := self.skills[SKI_PEEK];
  else
    skilla := self.abilities[ABIL_BRA];

  if (targ.type == UNIT_ST_PC)
    skilld := targ.skills[SKI_PEEK];
  else
    skilld := targ.abilities[ABIL_BRA];

  hm := skillresist (self.abilities[ABIL_BRA],
                     targ.abilities[ABIL_BRA],
		     skilla, skilld);

  if (hm >lt; -25)
  {
    act("You clumsily attempt to see what goodies $3n has, $3e " +
         "doesn't seem to be amused.", A_SOMEONE, self, null, targ, TO_CHAR);
      if (isaff(self, ID_INVISIBILITY))
        {
          subaff(self, ID_INVISIBILITY);
        }
    act("You catch $1n blatantly peeking at your possessions!",
         A_SOMEONE, self, null, targ, TO_VICT);
    quit;
  }

  if (hm >lt;= 0)
  {
    act("You can't quite make out what $3e has, but at least you were " +
    "discrete.", A_SOMEONE, self, null, targ, TO_CHAR);
    quit;
  }

  act("You manage to peek at $3s belongings.", A_SOMEONE, self, null, targ,
      TO_CHAR);

  :success:
  act("You see $3e has: ", A_SOMEONE, self, null, targ, TO_CHAR);

  hm := FALSE;

  object := targ.inside;

  while (object)
  {
     if (visible(self, object))
     {
        if (object.equip == 0)
        {
           /* Perhaps do check for each item */
           act(object.title, A_SOMEONE, self, null, targ, TO_CHAR);
           hm := TRUE;
        }
     }
     object := object.next;
  }

  if (hm == FALSE)
    act("Absolutely nothing!", A_SOMEONE, self, null, targ, TO_CHAR);

  quit;
}
dilend

dilbegin steal(arg : string);

external
  integer skillresist (aa : integer, ad : integer,
                            sa : integer, sd : integer);
  provoked_attack (victim : unitptr, ch : unitptr);
var
skilla  :  integer;
skilld  :  integer;
hm      :  integer;
vict    :  unitptr;
object  :  unitptr;
targ    :  unitptr;
hands   :  integer;
t       :  string;
temp    : string;
ti:integer;
code
{
  if ((self.type == UNIT_ST_PC) and (self.skills[SKI_STEAL] >lt;= 0))
  {
     act("You must practice first.", A_ALWAYS, self, null, null, TO_CHAR);
     quit;
  }

  object := self.inside;
  while ((object) and (hands != 2))
    {
      if ( ((object.equip == WEAR_WIELD) or (object.equip == WEAR_HOLD))
and
           (isset(object.objectflags, OBJ_TWO_HANDS)) )
        {
          hands := 2;
          continue;
        }

      if ( (object.equip == WEAR_HOLD) or (object.equip == WEAR_WIELD) or
         (object.equip == WEAR_SHIELD) )
        {
          hands := hands + 1;
        }
      object := object.next;
    }

  if (hands == 2)
    {
       act("You must have at least one hand free to attempt that!",
A_SOMEONE,
           self, null, null, TO_CHAR);
       quit;
    }

  if (not (" from " in arg))
    {
      act("Steal what from who?", A_SOMEONE, self, null, null,  TO_CHAR);
      quit;
    }

  /* needed for multi word names */
  t := getword(arg);
  temp := getword(arg);
  while (temp != "from")
  {
    t := (t + " " + temp);
    temp := getword(arg);
  }

  vict := findunit(self, arg, FIND_UNIT_SURRO, null);
  if ((vict == null) or not visible(self, vict))
    {
      act("No such person to steal from.",  A_SOMEONE, self, null,  null,
          TO_CHAR);
      quit;
    }


  if ( (vict.type != UNIT_ST_PC) and (vict.type != UNIT_ST_NPC) )
    {
      act("Why bother? Just get the darn thing!", A_SOMEONE, self, null,
null,
          TO_CHAR);
      quit;
    }

   if ((vict.type==UNIT_ST_PC) and
   (self.type==UNIT_ST_PC))
  {
if (not(isset (self.pcflags, PC_PK_RELAXED)))
  {
  act ("You are not allowed to do this unless you sign the book of blood.",
  A_ALWAYS,self,null,null,TO_CHAR);
  quit;
  }

if (not(isset (vict.pcflags, PC_PK_RELAXED)))
  {
  act ("You are not allowed to do this unless $2e signs the book of
blood.",
  A_ALWAYS,self,vict,null,TO_CHAR);
  quit;
  }
  }



  targ := findunit(vict, t, FIND_UNIT_IN_ME, null);

  if ((targ == null) or not visible(self,targ))
    {
      act("You can't find that on $3n.", A_SOMEONE, self, targ, vict,
TO_CHAR);
      quit;
    }

  if (targ.objecttype == ITEM_MONEY)
    {
      act("That would take a different type of finesse, try pilfering " +
          "instead.", A_SOMEONE, self, null, vict, TO_CHAR);
      quit;
    }

  if ( (targ.equip != 0) )  /* 0 = not equipped, value not in values.h */
    {
      act("You can only steal non-equipped items!", A_SOMEONE, self, null,
           vict, TO_CHAR);
      quit;
    }

   if (targ.zoneidx == "treasure")
   {
     act("A chill runs down your spine...someone or something is watching.",
         A_ALWAYS, self, null, null, TO_CHAR);
     act("You change your mind about stealing that.", A_ALWAYS, self,
         null, null, TO_CHAR);
     quit;
   }

ti:=can_carry (self,targ,1);
if (ti==1)
	{
	act ("You can't carry another thing.",
		A_ALWAYS,self,null,null,TO_CHAR);
		quit;
		}
   if (self.type == UNIT_ST_PC)
     skilla := self.skills[SKI_STEAL];
   else
     skilla := self.abilities[ABIL_DEX];

   if (targ.type == UNIT_ST_PC)
     skilld := vict.skills[SKI_STEAL];
   else
     skilld := vict.abilities[ABIL_DEX];

   hm := skillresist (self.abilities[ABIL_DEX],
                     vict.abilities[ABIL_DEX],
		     skilla, skilld);



   if (hm >lt;= -5)
    {
      act("You are caught!", A_SOMEONE, self, targ, vict, TO_CHAR);
      if (isaff(self, ID_INVISIBILITY))
        {
          subaff(self, ID_INVISIBILITY);
        }
      act("You catch $1n trying to steal your $2n!", A_SOMEONE, self, targ,
          vict, TO_VICT);
      act("You see $1n trying to steal something from $3n...$3e doesn't " +
          "seem amused!", A_SOMEONE, self, targ, vict, TO_NOTVICT);

      provoked_attack (vict, self);
      logcrime(self, vict, CRIME_STEALING);
      quit;
    }

  if (hm >lt;= 0)
    {
      act("You fail to steal $3n's $2n, but at least no one was watching!",
        A_SOMEONE, self, targ, vict, TO_CHAR);
      quit;
    }
  if (hm >lt; 5)
    {
      act("You steal $2n from $3n just as $3e turns toward you..You have "
+
          "been caught!", A_SOMEONE, self, targ, vict, TO_CHAR);
      if (isaff(self, ID_INVISIBILITY))
        {
          subaff(self, ID_INVISIBILITY);
        }
      act("Arrgh!  $1n just stole your $2n!", A_SOMEONE, self, targ, vict,
          TO_VICT);
      act("You see $1n steal something from $3n...$3e doesn't seem
amused!",
          A_SOMEONE, self, targ, vict, TO_NOTVICT);
      link(targ, self);
      provoked_attack (vict, self);
      logcrime(self, vict, CRIME_STEALING);
      quit;
    }

  act("You stealthily steal $3n's $2n and quickly tuck it out of " +
      "sight!", A_SOMEONE, self, targ, vict, TO_CHAR);
  link(targ, self);
  quit;


}
dilend

dilbegin filch(arg : string);

external
   integer skillresist (aa : integer, ad : integer,
                             sa : integer, sd : integer);
   provoked_attack (victim : unitptr, ch : unitptr);

var
   skilla  : integer;
   skilld  : integer;
   hm      : integer;
   targ    : unitptr;
   vict    : unitptr;
   from    : string;
   object  : unitptr;
   hands   : integer;
   t       : string;
   temp    : string;
	 ti:integer;
code
{
  if ((self.type == UNIT_ST_PC) and (self.skills[SKI_FILCH] >lt;= 0))
  {
     act("You must practice first.", A_ALWAYS, self, null, null, TO_CHAR);
     quit;
  }

  hands := (0);
  object := self.inside;
  while ((object) and (hands != 2))
    {
      if ( ((object.equip == WEAR_WIELD) or (object.equip == WEAR_HOLD))
and
           (isset(object.objectflags, OBJ_TWO_HANDS)) )
        {
          hands := 2;
          continue;
        }

      if ( (object.equip == WEAR_HOLD) or (object.equip == WEAR_WIELD) or
           (object.equip == WEAR_SHIELD) )
        {
          hands := hands + 1;
        }
      object := object.next;
    }

  if (hands == 2)
    {
       act("You must have at least one hand free to attempt that!",
A_SOMEONE,
           self, null, null, TO_CHAR);
       quit;
    }

  if (not (" from " in arg))
    {
      act("Filch what from who?", A_SOMEONE, self, null, null,  TO_CHAR);
      quit;
    }

  /* needed for multi word names */
  t := getword(arg);
  temp := getword(arg);
  while (temp != "from")
  {
    t := (t + " " + temp);
    temp := getword(arg);
  }

  vict := findunit(self, arg, FIND_UNIT_SURRO, null);
  if ((vict == null) or not visible(self, vict))
    {
      act("No such person to filch from.",  A_SOMEONE, self, null,  null,
          TO_CHAR);
      quit;
    }
  if ( (not(vict.type >amp; (UNIT_ST_PC | UNIT_ST_NPC)) ))
    {
      act("Why bother? Just get the darn thing!", A_SOMEONE, self, null,
null,
          TO_CHAR);
      quit;
    }


   if ((vict.type==UNIT_ST_PC) and
   (self.type==UNIT_ST_PC))
  {
if (not(isset (self.pcflags, PC_PK_RELAXED)))
  {
  act ("You are not allowed to do this unless you sign the book of blood.",
  A_ALWAYS,self,null,null,TO_CHAR);
  quit;
  }

if (not(isset (vict.pcflags, PC_PK_RELAXED)))
  {
  act ("You are not allowed to do this unless $2e signs the book of
blood.",
  A_ALWAYS,self,vict,null,TO_CHAR);
  quit;
  }
  }


  targ := findunit(vict, t, FIND_UNIT_EQUIP, null);
  if ((targ == null) or not visible(self, targ))
    {
      act("You can't find that on $3n.", A_SOMEONE, self, targ, vict,
TO_CHAR);
      quit;
    }

  if ( (targ.equip != WEAR_FINGER_R) and (targ.equip != WEAR_FINGER_L) and
       (targ.equip != WEAR_NECK_1) and (targ.equip != WEAR_NECK_2) and
       (targ.equip != WEAR_WAIST) and (targ.equip != WEAR_WRIST_R) and
       (targ.equip != WEAR_BACK) and (targ.equip != WEAR_EAR_L) and
       (targ.equip != WEAR_EAR_R) and (targ.equip != WEAR_ANKLE_L) and
       (targ.equip != WEAR_ANKLE_R) and (targ.equip != WEAR_WRIST_L) )
    {
      act("That would be much to difficult to filch away from $3n!",
          A_SOMEONE, self, null, vict, TO_CHAR);
      quit;
    }

   if (targ.zoneidx == "treasure")
   {
     act("A chill runs down your spine...someone or something is watching.",
         A_ALWAYS, self, null, null, TO_CHAR);
     act("You change your mind about filching that.", A_ALWAYS, self,
         null, null, TO_CHAR);
     quit;
   }
ti:=can_carry (self,targ,1);
if (ti==1)
	{
	act ("You can't carry another thing.",
		A_ALWAYS,self,null,null,TO_CHAR);
		quit;
		}

   if (self.type == UNIT_ST_PC)
     skilla := self.skills[SKI_FILCH];
   else
     skilla := self.abilities[ABIL_DEX];

   if (vict.type == UNIT_ST_PC)
     skilld := vict.skills[SKI_FILCH];
   else
     skilld := vict.abilities[ABIL_DEX];

   hm := skillresist (self.abilities[ABIL_DEX],
                     vict.abilities[ABIL_DEX],
		     skilla, skilld);




  if (hm >lt;= -5)
    {
      act("You are caught!", A_SOMEONE, self, targ, vict, TO_CHAR);
      if (isaff(self, ID_INVISIBILITY))
        {
          subaff(self, ID_INVISIBILITY);
        }
      act("You catch $1n trying to filch your $2n!", A_SOMEONE, self, targ,
          vict, TO_VICT);
      act("You see $1n trying to filch something from $3n...$3e doesn't " +
          "seem amused!", A_SOMEONE, self, targ, vict, TO_NOTVICT);
      provoked_attack (vict, self);
      logcrime(self, vict, CRIME_STEALING);
      quit;
    }


  if (hm >lt;= 0)
    {
      act("You fail to filch $3n's $2n, but at least no one was watching!",
        A_SOMEONE, self, targ, vict, TO_CHAR);
      quit;
    }

  if (hm >lt;= 5)
    {
      act("You filch $2n from $3n just as $3e turns toward you..You have "
+
          "been caught!", A_SOMEONE, self, targ, vict, TO_CHAR);
      if (isaff(self, ID_INVISIBILITY))
        {
          subaff(self, ID_INVISIBILITY);
        }
      act("Arrgh!  $1n just stole your $2n!", A_SOMEONE, self, targ, vict,
          TO_VICT);
      act("You see $1n filch something from $3n...$3e doesn't seem
amused!",
          A_SOMEONE, self, targ, vict, TO_NOTVICT);
      link(targ, self);
      provoked_attack (vict, self);
      logcrime(self, vict, CRIME_STEALING);
      quit;
    }

  act("You stealthily filch $3n's $2n and quickly tuck it out of " +
      "sight!", A_SOMEONE, self, targ, vict, TO_CHAR);
  link(targ, self);
  quit;


}
dilend

dilbegin diagnose(arg : string);
external
   string sizestring (cm : integer);
   string weightstring (cm : integer);
   integer skillresist (aa : integer, ad : integer,
			     sa : integer, sd : integer);

var
   percent : integer;
   hm      : integer;
   s1      : string;
   s2      : string;
   vict    : unitptr;
   skilla  : integer;
code
{
   if ((self.type == UNIT_ST_PC) and
       (self.skills[SKI_DIAGNOSTICS] == 0))
   {
      act("You must practice first.",
	  A_ALWAYS, self, null, null, TO_CHAR);
      quit;
   }

   if (arg == "")
   {
      vict := self.fighting;
      if (vict == null)
      {
	 act("Diagnose who?",
             A_ALWAYS, self, null, null, TO_CHAR);
	 quit;
      }
   }
   else
   {
      vict := findunit(self, arg, FIND_UNIT_SURRO, null);
      if ((vict == null) or not visible(self, vict))
      {
	 act("Nobody here by that name.",
	     A_ALWAYS, self, null, vict, TO_CHAR);
	 quit;
      }
   }

   if (not (vict.type >amp; (UNIT_ST_PC | UNIT_ST_NPC)))
   {
      act("It seems to be dead?",
	  A_ALWAYS, self, null, null, TO_CHAR);
      return;
   }

   if (vict.max_hp > 0)
     percent := (100 * vict.hp) / vict.max_hp;
   else
     percent := -1; /* How could MAX_HIT be >lt; 1?? */

   if (self.type == UNIT_ST_PC)
     skilla := self.skills[SKI_DIAGNOSTICS];
   else
     skilla := self.abilities[ABIL_BRA];

   hm := skillresist (self.abilities[ABIL_BRA], 20,
				skilla, 50);

   if (hm > 0)
     hm := 0;

   percent := percent + ((percent * (-hm))/100);

   if (percent >= 100)
     act("$3n is in an excellent condition.",
	 A_ALWAYS, self, null, vict, TO_CHAR);
   else if (percent >= 90)
     act("$3n has a few scratches.",
	 A_ALWAYS, self, null, vict, TO_CHAR);
   else if (percent >= 75)
     act("$3n has some small wounds and bruises.",
         A_ALWAYS, self, null, vict, TO_CHAR);
   else if (percent >= 50)
     act("$3n has quite a few wounds.",
         A_ALWAYS, self, null, vict, TO_CHAR);
   else if (percent >= 30)
     act("$3n has some big nasty wounds and scratches.",
         A_ALWAYS, self, null, vict, TO_CHAR);
   else if (percent >= 15)
     act("$3n looks pretty hurt.",
         A_ALWAYS, self, null, vict, TO_CHAR);
   else if (percent >= 0)
     act("$3n is in an awful condition.",
	 A_ALWAYS, self, null, vict, TO_CHAR);
   else
     act("$3n is bleeding awfully from big wounds.",
	 A_ALWAYS, self, null, vict, TO_CHAR);

   if (self.fighting == null)
   {
      s1 := weightstring (vict.baseweight);
      s2 := sizestring (vict.height);
      act("$3e weighs "+s1+" and is "+s2+" tall.",
	  A_SOMEONE, self, null, vict, TO_CHAR);
   }

   quit;
}
dilend

dilbegin resize(arg:string);
external
   res_clothes@skills (tgt:unitptr,tgt_pc:unitptr);
   res_lth@skills (tgt:unitptr,tgt_pc:unitptr);
   res_metal@skills (tgt:unitptr,tgt_pc:unitptr);
var
   item : unitptr;
   tgt_pc : unitptr;
code
{
   if (arg == "")
   {
      act("What do you wish to resize?", A_SOMEONE, self, null, null,TO_CHAR);
      quit;
   }

   item := findunit(self, arg, FIND_UNIT_INVEN, null);

   if ((item == null) or not visible(self, item))
   {
      act("No such thing by that name!", A_SOMEONE, self, null, null,
TO_CHAR);
      quit;
   }

   tgt_pc := findunit(self,arg,FIND_UNIT_SURRO,null);

   if ((tgt_pc==null) or not visible(self, tgt_pc))
     tgt_pc := self;

   if (not (item.type>amp;UNIT_ST_OBJ))
   {
      act("You can't resize that!", A_SOMEONE, self, null, null,
	  TO_CHAR);
      quit;
   }

   if (item.objecttype == ITEM_ARMOR)
   {
      if ((item.value[0]>lt;ARM_CLOTHES)or
          (item.value[0]>ARM_PLATE))
      {
         act ("The armor seems to be broken.",
	      A_ALWAYS,self,null, null,TO_CHAR);
         quit;
      }
      on item.value[0] goto clothes,leather,leather,metal,metal;
   }
   else if (item.objecttype == ITEM_SHIELD)
     goto metal;
   else if (item.objecttype == ITEM_WEAPON)
     goto metal;
   else if (item.objecttype == ITEM_WORN)
     goto clothes;
   else
   {
      if ((item.manipulate >amp; (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 ("There is no way the $3N can be resized.",
	      A_SOMEONE, self, null, item, TO_CHAR);
         quit;
      }
      goto metal; /* What else can one do? */
   }
   quit;

   :clothes:
   res_clothes(item,tgt_pc);
   quit;
   :leather:
   res_lth (item,tgt_pc);
   quit;
   :metal:
   res_metal(item,tgt_pc);
   quit;
}
dilend


dilbegin res_clothes(tgt:unitptr,tgt_pc:unitptr);
external
   integer skillresist (aa : integer, ad : integer,
			     sa : integer, sd : integer);
   unitptr unit_room (u:unitptr);
var
  hm:integer;
  amount:integer;
  size:string;
  diff:integer;
  skilla : integer;
  rm:unitptr;
  skilld : integer;
  hold_eq:unitptr;
  wield_eq:unitptr;

code
{
   if ((self.type == UNIT_ST_PC) and (self.skills[SKI_RESIZE_CLOTHES] >lt;= 0))
   {
      act("You have no knowledge in tailoring, you must practice first.",
	  A_ALWAYS, self, null, null, TO_CHAR);
      quit;
   }

/*
   rm := unit_room(self);
   if ("$clothes room" in rm.extra)
     goto workshop;

   hold_eq := equipment (self ,WEAR_HOLD);
   wield_eq := equipment (self,WEAR_WIELD);
   if ((not("$refit clothes" in hold_eq.extra)) and
       (not("$refit clothes" in wield_eq.extra)))
   {
      act ("You need to hold or use a proper tailoring tool to work on $2n.",
	   A_ALWAYS,self,tgt,null,TO_CHAR);
      quit;
   }
*/
   :workshop:
   if ("$resized" in tgt.extra)
   {
      act("You see that the $2N has already been resized, you are unable "+
          "to do more yourself.",
	   A_ALWAYS,self,tgt,null,TO_CHAR);
      quit;
   }

   if (self.type == UNIT_ST_PC)
     skilla := self.skills[SKI_RESIZE_CLOTHES];
   else
     skilla := self.abilities[ABIL_DEX];

   skilld := 2*tgt.value[1] + 6*tgt.value[2];

   hm := skillresist (self.abilities[ABIL_DEX],
		     tgt.spells[SPL_CREATION],
		     skilla, skilld);

   if (hm>lt;=-100)
     goto major_fail;
   if (hm>lt;-50)
     goto fail;
   if (hm >lt; 0)
   {
      act("Nothing happens.", A_ALWAYS, self, null, null, TO_CHAR);
      quit;
   }

   amount := (100*tgt_pc.height) / tgt.height;
   if (amount > 100)
     diff := amount - 100;
   else
     diff := 100 - amount;
   if (self.endurance>lt;diff) goto fail_endurance;

   if (tgt_pc.height>tgt.height)
    size:="enlarges"
   else
    size:="shrinks";

   tgt.max_hp := tgt.max_hp-diff;
   tgt.hp := tgt.hp-diff;
   tgt.height := tgt_pc.height;

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

   self.endurance := self.endurance - diff;

   if (tgt_pc==self)
   {
      act("You skillfully work on $2n till it $3t enough to fit.",
	  A_ALWAYS, self, tgt, size, TO_CHAR);
      act("$1n skillfully works on $2n till it $3t enough to fit $1m",
	  A_SOMEONE, self, tgt, size, TO_REST);
   }
   else
   {
      act("You skillfully work on $2n till it $3t enough to fit "+
	  tgt_pc.name+".", A_SOMEONE, self, tgt, size, TO_CHAR);
      act("$1n skillfully works on "+tgt.title+
	  " till it $3t enough to fit $2n",
	  A_SOMEONE, self, tgt_pc, size, TO_REST);
   }
   quit;

   :fail:
   tgt.hp := tgt.hp-diff;
   if (tgt.hp>lt;1) goto major_fail;
   act("You try to $3t $2n but you make a mistake and damage it instead",
       A_ALWAYS, self, tgt, size, TO_CHAR);
   act ("$1n tries to $3t but $1e makes a mistake and damages it instead.",
	A_SOMEONE, self, tgt, size, TO_REST);
   quit;

   :major_fail:
   act("You try to $3t $2n but the job is to much for you and you destroy
it.",
       A_ALWAYS, self, tgt, size, TO_CHAR);
   act ("$1n tries to $3t but the job is to much for $1m and he destroys it.",
	A_SOMEONE, self, tgt, size, TO_REST);
  addextra (tgt.extra,tgt.names,"Well whatever this was it looks like
someone really screwed up resizing this.");
  tgt.title:=tgt.title+"Broken";
   tgt.objecttype := ITEM_TRASH;

   quit;

   :fail_endurance:
   act("You begin to work on $2n but realize you are much to tired to finish.",
       A_ALWAYS, self, tgt,null, TO_CHAR);
   act("$1n Begins working on $2n but realizes $1e is to tired and slumps "+
       "back exhausted.",
       A_SOMEONE, self, tgt, size, TO_REST);
   quit;
}
dilend

dilbegin res_lth(tgt:unitptr,tgt_pc:unitptr);
external
   integer skillresist (aa : integer, ad : integer,
			     sa : integer, sd : integer);
   unitptr unit_room (u:unitptr);
var
  hm:integer;
  amount:integer;
  size:string;
  diff:integer;
  rm:unitptr;
  skilla : integer;
  skilld : integer;
  hold_eq:unitptr;
  wield_eq:unitptr;

code
{
   if ((self.type == UNIT_ST_PC) and (self.skills[SKI_RESIZE_LEATHER] >lt;= 0))
   {
      act("You have no knowledge in leather, you must practice first.",
	  A_ALWAYS, self, null, null, TO_CHAR);
      quit;
   }

/*
   rm := unit_room(self);
   if ("$leather room" in rm.extra) goto workshop;

   hold_eq := equipment (self ,WEAR_HOLD);
   wield_eq := equipment (self,WEAR_WIELD);

   if ((not("$refit leather" in hold_eq.extra)) and
       (not("$refit leather" in wield_eq.extra)))
   {
      act ("You need to use a proper leather tool to work on $2n.",
	   A_ALWAYS,self,tgt,null,TO_CHAR);
      quit;
   }
*/
   :workshop:
   if ("$resized" in tgt.extra)
   {
      act("You see that the $2N have already been resized, you are unable "+
          "to do more yourself.",
	   A_ALWAYS,self,tgt,null,TO_CHAR);
      quit;
   }

   if (self.type == UNIT_ST_PC)
     skilla  :=  self.skills[SKI_RESIZE_LEATHER];
   else
     skilla  :=  self.abilities[ABIL_STR];

   skilld := 2*tgt.value[1] + 6*tgt.value[2];

   hm := skillresist (self.abilities[ABIL_DEX],
		     tgt.spells[SPL_CREATION],
		     skilla, skilld);

   if (hm>lt;=-100)goto major_fail;

   if (hm>lt;-50) goto fail;

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

   amount := (100*tgt_pc.height) / tgt.height;
   if (amount > 100)
     diff := amount - 100;
   else
     diff := 100 - amount;
   if (self.endurance>lt;diff) goto fail_endurance;

   if (tgt_pc.height>tgt.height)
     size := "enlarges"
   else
     size := "shrinks";


   tgt.max_hp := tgt.max_hp-diff;
   tgt.hp := tgt.hp-diff;
   tgt.height := tgt_pc.height;

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

   self.endurance := self.endurance - diff;

   if (tgt_pc==self)
   {
      act("You skillfully work on $2n till it $3t enough to fit.",
	  A_ALWAYS, self, tgt, size, TO_CHAR);
      act("$1n skillfully works on $2n till it $3t enough to fit $1m",
	  A_SOMEONE, self, tgt, size, TO_REST);
   }
   else
   {
      act("You skillfully work on $2n till it $3t enough to fit
"+tgt_pc.name+".",
	  A_SOMEONE, self, tgt, size, TO_CHAR);
      act("$1n skillfully works on "+tgt.title+" till it $3t enough to fit
$2n",
	  A_SOMEONE, self, tgt_pc, size, TO_REST);
   }

   quit;
   :fail:
   tgt.hp := tgt.hp-diff;
   if (tgt.hp>lt;1) goto major_fail;
   act("You try to $3t $2n but you make a mistake and damage it instead",
       A_ALWAYS, self, tgt, size, TO_CHAR);
   act ("$1n tries to $3t but $1e makes a mistake and damages it instead.",
	A_SOMEONE, self, tgt, size, TO_REST);
   quit;

   :major_fail:

   act("You try to $3t $2n but the job is to much for you and you destroy
it.",
       A_ALWAYS, self, tgt, size, TO_CHAR);
   act ("$1n tries to $3t but the job is to much for $1m and he destroys it.",
	A_SOMEONE, self, tgt, size, TO_REST);
  addextra (tgt.extra,tgt.names,"Well whatever this was it looks like
someone really screwed up resizing this.");
  tgt.title:=tgt.title+"Broken";
   tgt.objecttype := ITEM_TRASH;

   quit;

   :fail_endurance:
   act("You begin to work on $2n but realize you are much to tired to finish.",
       A_ALWAYS, self, tgt,null, TO_CHAR);
   act ("$1n Begins working on $2n but realizes $1e is to tired and slumps
back exhausted.",
	A_SOMEONE, self, tgt, size, TO_REST);
   quit;

}
dilend

dilbegin res_metal(tgt:unitptr,tgt_pc:unitptr);
external
   integer skillresist (aa : integer, ad : integer,
			     sa : integer, sd : integer);
   unitptr unit_room (u:unitptr);

var
  hm:integer;
  amount:integer;
  size:string;
  diff:integer;
  rm:unitptr;
  skilla : integer;
  skilld : integer;
  hold_eq:unitptr;
  wield_eq:unitptr;

code
{
   if ((self.type == UNIT_ST_PC) and (self.skills[SKI_RESIZE_METAL] >lt;= 0))
   {
      act("You have no knowledge in smithing, you must practice first.",
          A_ALWAYS, self, null, null, TO_CHAR);
      quit;
   }

/*
   rm := unit_room(self);
   if ("$metal room" in rm.extra) goto workshop;

   hold_eq := equipment (self ,WEAR_HOLD);
   wield_eq := equipment (self,WEAR_WIELD);

   if ((not("$refit metal" in hold_eq.extra)) and
       (not("$refit metal" in wield_eq.extra)))
   {
      act ("You need to use a proper smithing tool to work on $2n.",
	   A_ALWAYS,self,tgt,null,TO_CHAR);
      quit;
   }
*/
   :workshop:
   if ("$resized" in tgt.extra)
   {
      act("You see that the $2N have already been resized, you are unable "+
          "to do more yourself.",
	   A_ALWAYS,self,tgt,null,TO_CHAR);
      quit;
   }

   if (self.type == UNIT_ST_PC)
     skilla  :=  self.skills[SKI_RESIZE_METAL];
   else
     skilla := self.abilities[ABIL_STR];

   skilld := 2*tgt.value[1] + 6*tgt.value[2];

   hm := skillresist (self.abilities[ABIL_STR],
		     tgt.spells[SPL_CREATION],
		     skilla, skilld);

   if (hm>lt;=-100)goto major_fail;
   if (hm>lt;-50) goto fail;
   if (hm >lt; 0)
   {
      act("Nothing happens.", A_ALWAYS, self, null, null, TO_CHAR);
      quit;
   }

   amount := (100*tgt_pc.height) / tgt.height;
   if (amount > 100)
     diff := amount - 100;
   else
     diff := 100 - amount;
   if (self.endurance>lt;diff) goto fail_endurance;

   if (tgt_pc.height>tgt.height)
    size:="enlarges"
   else
     size := "shrinks";

   self.endurance := self.endurance - diff;

   tgt.max_hp := tgt.max_hp-diff;
   tgt.hp := tgt.hp-diff;
   tgt.height := tgt_pc.height;

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

   if (tgt_pc==self)
   {
      act("You skillfully work on $2n till it $3t enough to fit.",
	  A_ALWAYS, self, tgt, size, TO_CHAR);
      act("$1n skillfully works on $2n till it $3t enough to fit $1m",
	  A_SOMEONE, self, tgt, size, TO_REST);
   }
   else
   {
      act("You skillfully work on $2n till it $3t enough to fit "+
	  tgt_pc.name+".", A_SOMEONE, self, tgt, size, TO_CHAR);
      act("$1n skillfully works on "+tgt.title+
	  " till it $3t enough to fit $2n",
	  A_SOMEONE, self, tgt_pc, size, TO_REST);
   }

   quit;
   :fail:
   tgt.hp := tgt.hp-diff;
   if (tgt.hp>lt;1) goto major_fail;
   act("You try to $3t $2n but you make a mistake and damage it instead",
       A_ALWAYS, self, tgt, size, TO_CHAR);
   act ("$1n tries to $3t but $1e makes a mistake and damages it instead.",
	A_SOMEONE, self, tgt, size, TO_REST);
   quit;

   :major_fail:

   act("You try to $3t $2n but the job is to much for you and you destroy
it.",
       A_ALWAYS, self, tgt, size, TO_CHAR);
   act ("$1n tries to $3t but the job is to much for $1m and he destroys it.",
	A_SOMEONE, self, tgt, size, TO_REST);
  addextra (tgt.extra,tgt.names,"Well whatever this was it looks like
someone really screwed up resizing this.");
  tgt.title:=tgt.title+"Broken";
   tgt.objecttype := ITEM_TRASH;

   quit;

   :fail_endurance:
   act("You begin to work on $2n but realize you are much to tired to finish.",
       A_ALWAYS, self, tgt,null, TO_CHAR);
   act ("$1n Begins working on $2n but realizes $1e is to tired and slumps
back exhausted.",
	A_SOMEONE, self, tgt, size, TO_REST);
   quit;

}
dilend

/* The climb skill as a special routine to be connected to ROOMS

  Ticks  : None
  Used on: ROOMS
  Syntax : climb(destination:string, difficulty:integer,
	         damage : integer, direction : integer);
  Example: dilcopy climb ("deck@ship", 17, 20, "up");

     This special dil is used for the climb skill and should be set
     on stationary objects (stationary mast, robe, tree, wall, etc).
     The >lt;difficulty> is the skill-amount required to climb. A skill of 100
     would be a 50% chance for the expert thief / climber.
     The >lt;damage> is how much damage is given if you fail to climb the
     object. When you fail, you "fall" to the >lt;destination>, so you can
     make gravity work correctly.
     The destination can be the same room in which you started.
     The >lt;direction> is the direction in which a climb is required
     (most usually it is up, which is macro UP == 5).
*/

dilbegin climb(destination:string, difficulty:integer,
               damage:integer, direction:integer);
external
   integer skillresist (aa : integer, ad : integer,
                             sa : integer, sd : integer);
var
   dest : unitptr;
   skilla : integer;
   hm : integer;
   doorname : string;
code
{
   if (not self.exit_to[direction])
   {
      log("No such exit in climb dil.");
      quit;
   }

   if (not findroom(destination))
   {
      log("No such room in climb dil.");
      quit;
   }

   doorname := self.exit_names[direction].[0];
   /* One could check for an empty name here... */

   :loop:
   wait(SFB_CMD, command("climb") or command(direction));

   if (self.type == UNIT_ST_PC)
   {
      skilla := self.skills[SKI_CLIMB];
      if (skilla >lt; 1)
	skilla := -25;
   }
   else
     skilla := self.abilities[ABIL_DEX];

   hm := skillresist (skilla, 0,
		     activator.abilities[ABIL_DEX], 0);

   if (hm >= difficulty)
   {
      act("You easily climb the $2t.",
	  A_ALWAYS, activator, doorname, null, TO_CHAR);
      act("$1n easily climbs the $2t.",
	  A_HIDEINV, activator, doorname, null, TO_ROOM);
      goto loop;
   }

   dest := findroom(destination);

   if (dest != activator.outside)
   {
      act("You fall and hit yourself!",
	  A_ALWAYS, activator, doorname, null, TO_CHAR);

      act("$1n failed to climb the $2t and takes a nasty fall...",
	  A_SOMEONE, activator, doorname, null, TO_ROOM);

      link(activator, dest);

      act("$1n failed to climb the $2t and lands at your feet...",
	  A_SOMEONE, activator, doorname, null, TO_ROOM);
   }
   else
   {
      act("You fail to climb the $2t!",
	  A_ALWAYS, activator, doorname, null, TO_CHAR);

      act("$1n failed to climb the $2t!",
	  A_SOMEONE, activator, doorname, null, TO_ROOM);
   }

   if (activator.level >lt; IMMORTAL_LEVEL)
   {
      activator.hp := activator.hp - damage;
      position_update(activator);
   }
   block;
   goto loop;
}
dilend



dilbegin do_rescue(arg: string);

external base_rescue(targ: unitptr); /* Needed for SFUN_RESCUE */

var targ: unitptr;

code
{

if (arg == "")
    {
    sendtext("Rescue who?>amp;n", self);
    quit;
    }

targ :=findunit(self, arg, FIND_UNIT_SURRO, null);

if ((not targ) or not(targ.type >amp; UNIT_ST_PC|UNIT_ST_NPC))
    {
    sendtext("Who do you want to rescue?>amp;n", self);
    quit;
    }

base_rescue(targ);

quit;
}

dilend


dilbegin base_rescue(targ: unitptr); /* May be copied on mobs easily */

external integer skillresist (aa : integer, ad : integer,
                              sa : integer, sd : integer);

var tmp: unitptr;
    hm : integer;
    ska: integer;
    skb: integer;

code
{

if (not visible(self, targ))
    {
    sendtext("Who do you want to rescue?>amp;n", self);
    return;
    }

if (targ == self)
    {
    sendtext("What about fleeing instead?>amp;n", self);
    return;
    }

if (targ == self.fighting)
    {
    sendtext("How can you rescue someone you are trying to kill?>amp;n", self);
    return;
    }

foreach (UNIT_ST_PC|UNIT_ST_NPC, tmp)
    {
    if (tmp.fighting == targ)
        break;
    }

if ((tmp == null) or (tmp.fighting != targ))
    {
    act("Nobody is fighting $3m?", A_SOMEONE, self, null, targ, TO_CHAR);
    return;
    }

if ((self.type == UNIT_ST_PC) and (self.skills[SKI_RESCUE] >lt;= 0))
    {
    sendtext("You'd better practice first.>amp;n", self);
    return;
    }

if (self.type == UNIT_ST_PC)
    ska := self.skills[SKI_RESCUE];

else
    ska := (self.abilities[ABIL_DEX] + self.abilities[ABIL_BRA]) / 2;

if (tmp.type == UNIT_ST_PC)
    skb := tmp.skills[SKI_RESCUE];

else
    skb := (tmp.abilities[ABIL_DEX] + tmp.abilities[ABIL_BRA]) / 2;

hm := skillresist(self.abilities[ABIL_DEX], tmp.abilities[ABIL_DEX], ska, skb);

if ((tmp.type == UNIT_ST_PC) and (self.skills[SKI_LEADERSHIP])
   and (targ.master == self))
   hm := hm + self.skills[SKI_LEADERSHIP] / 4;

if (hm >lt; 0)
    {
    sendtext("You bulge in from the left...>amp;n"+
        "...and continue out to the right.>amp;n", self);

    act("$1n bulges in from the left...>amp;n"+
        "...and continues out to the right.",
        A_SOMEONE, self, null, targ, TO_VICT);

    act("$1n makes a feeble attempt to rescue $3n.",
        A_SOMEONE, self, null, targ, TO_NOTVICT);
    return;
    }

sendtext("Banzai! To the rescue...>amp;n", self);

act("You are rescued by $1n, you are confused!",
    A_SOMEONE, self, null, targ, TO_VICT);

act("$1n heroically rescues $3n.", A_SOMEONE, self, null, targ, TO_NOTVICT);

if (targ.fighting == tmp)
    stop_fighting (targ, tmp);

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

if (isset(tmp.charflags, CHAR_SELF_DEFENCE))
    set(self.charflags, CHAR_SELF_DEFENCE);

set_fighting(self, tmp);
set_fighting(tmp, self);

/*
Can I set that?

   if (CHAR_COMBAT(tmp_ch))
     CHAR_COMBAT(tmp_ch)->setMelee(ch);
*/

return;
}

dilend


dilbegin kick(arg : string);

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

var
   bonus : integer;
   targ  : unitptr;

code
{
   if ((self.type == UNIT_ST_PC) and (self.weapons[WPN_KICK] >lt;= 0))
   {
      act("You must practice first.", A_ALWAYS, self, null, null, TO_CHAR);
      quit;
   }

   if (arg == "")
   {
      if (self.fighting)
      {
	 targ := self.fighting;
	 goto kick;
      }

      act("Kick who?", A_SOMEONE, self, null, null, TO_CHAR);
      quit;
   }

   targ := findunit(self, arg, FIND_UNIT_SURRO, null);

   if ((targ == null) or not visible(self, targ))
   {
      act("That person is not here!", A_SOMEONE, self, null, null, TO_CHAR);
      quit;
   }

   if (not (targ.type >amp; (UNIT_ST_PC | UNIT_ST_NPC)))
   {
      act("You can't kick that, silly!", A_SOMEONE, self, null, null,
	  TO_CHAR);
      quit;
   }

   if (targ == self)
   {
      act("You kick yourself.", A_HIDEINV, self, null, null,
	  TO_CHAR);
      act("$1n kicks $1mself.", A_HIDEINV, self, null, null,
	  TO_ROOM);
      quit;
   }

   if ((targ.type==UNIT_ST_PC) and
   (self.type==UNIT_ST_PC))
  {
if (not(isset (self.pcflags, PC_PK_RELAXED)))
  {
  act ("You are not allowed to do this unless you sign the book of blood.",
  A_ALWAYS,self,null,null,TO_CHAR);
  quit;
  }

if (not(isset (targ.pcflags, PC_PK_RELAXED)))
  {
  act ("You are not allowed to do this unless $2e signs the book of blood.",
  A_ALWAYS,self,targ,null,TO_CHAR);
  quit;
  }
  }


   :kick:
   /* Penalty for wielding a weapon while kicking! */
   if (equipment(self, WEAR_WIELD))
     bonus := -25;
   else
     bonus := +25;
   if (self.endurance >lt; 2)
     act("You are too exhausted to attempt that.", A_ALWAYS, self, null,
         null, TO_CHAR);
   else self.endurance := self.endurance - 2;
   provoked_attack (targ, self);
   bonus := meleeattack(self, targ, (bonus+self.level), WPN_KICK);
   quit;
}
dilend

dilbegin tripwt ();
code
{
heartbeat:=PULSE_VIOLENCE*3;
wait (SFB_TICK,TRUE);
quit;
}
dilend

dilbegin trip(arg : string);

external
   integer skillresist (aa : integer, ad : integer,
                             sa : integer, sd : integer);
   provoked_attack (victim : unitptr, ch : unitptr);

var
   skilla : integer;
   skilld : integer;
   hm     : integer;
   targ   : unitptr;

code
{
   if ((self.type == UNIT_ST_PC) and (self.skills[SKI_TRIP] >lt;= 0))
   {
      act("You must practice first.", A_ALWAYS, self, null, null, TO_CHAR);
      quit;
   }

   if (arg == "")
   {
      if (self.fighting)
      {
	 targ := self.fighting;
	 goto trip;
      }
      else
      {
	 act("Who do you wish to trip?", A_SOMEONE, self, null, null,
	     TO_CHAR);
	 quit;
      }
   }

   targ := findunit(self, arg, FIND_UNIT_SURRO, null);

   if ((targ == null) or not visible(self, targ))
   {
      act("That person is not here!", A_SOMEONE, self, null, null, TO_CHAR);
      quit;
   }

   if (not (targ.type >amp; (UNIT_ST_PC | UNIT_ST_NPC)))
   {
      act("You can't trip that, silly!", A_SOMEONE, self, null, null,
	  TO_CHAR);
      quit;
   }

   if (targ == self)
   {
      act("You trip over your own feet.", A_HIDEINV, self, null, null,
	  TO_CHAR);
      act("$1n trips over $1s own feet.", A_SOMEONE, self, null, null,
	  TO_ROOM);
      quit;
   }


   if ((targ.type==UNIT_ST_PC) and
   (self.type==UNIT_ST_PC))
  {
if (not(isset (self.pcflags, PC_PK_RELAXED)))
  {
  act ("You are not allowed to do this unless you sign the book of blood.",
  A_ALWAYS,self,null,null,TO_CHAR);
  quit;
  }

if (not(isset (targ.pcflags, PC_PK_RELAXED)))
  {
  act ("You are not allowed to do this unless $2e signs the book of blood.",
  A_ALWAYS,self,targ,null,TO_CHAR);
  quit;
  }
  }

   if (not (RACE_IS_MAMMAL(targ.race) or RACE_IS_HUMANOID(targ.race)))
   {
      act("There doesn't seem to be a way to effectively trip $3n.",
          A_SOMEONE, self, null, targ, TO_CHAR);
      quit;
   }

   if ( ((targ.weight - self.weight) > 350) )
   {
      act("You quickly find that $3e is much to heavy to trip...ouch.",
          A_SOMEONE, self, null, targ, TO_CHAR);
      quit;
   }

   if (targ.position >lt;= POSITION_STUNNED)
   {
      act("$3e is already down!", A_SOMEONE, self, null, targ, TO_CHAR);
      quit;
   }

   :trip:
   provoked_attack (targ, self);

if (dilfind ("tripwt@skills",targ))
	{
	act ("$3n anticipates $1n's trip and leaps harmlessly over.",
		A_ALWAYS, self,null,targ,TO_NOTVICT);
	act ("You try to trip again but $3n anticipates your trip and leaps harmlessly over.",
		A_ALWAYS, self,null,targ,TO_CHAR);
		act ("You notice $3n trying to trip you again and you leap harmlessly over $3s leg.",
			A_ALWAYS, targ,null,self,TO_CHAR);
			quit;
			}

   if (self.type == UNIT_ST_PC)
     skilla := self.skills[SKI_TRIP];
   else
     skilla := self.abilities[ABIL_DEX];

   if (targ.type == UNIT_ST_PC)
     skilld := targ.skills[SKI_TRIP];
   else
     skilld := targ.abilities[ABIL_DEX];

   hm := skillresist (self.abilities[ABIL_DEX],
		     targ.abilities[ABIL_DEX],
		     skilla, skilld);
   if (self.endurance >lt; 10)
     act("You are too exhausted to attempt that.", A_ALWAYS, self, null,
         null, TO_CHAR);
   else self.endurance := self.endurance - 10;
   if (hm >lt; -25)
   {
      change_speed(self, PULSE_VIOLENCE);
      act("You fumble your trip attempt and stumble!.", A_ALWAYS, self,
	  null, targ, TO_CHAR);
      act("$1n ducks clumsily and attempts to sweep your feet!.",
	  A_ALWAYS, self, null, targ, TO_VICT);
      act("$1n attempts to trip $3n but fails miserably.", A_SOMEONE, self,
	  null, targ, TO_NOTVICT);
      quit;
   }

   if (hm >lt; 0)
   {
      change_speed(self, PULSE_VIOLENCE / 2);
      act("You fumble your trip attempt on $3n!.", A_ALWAYS, self, null, targ,
	  TO_CHAR);
      act("$1n ducks and attempts to sweep your feet!.", A_ALWAYS, self,
	  null, targ, TO_VICT);
      act("$1n attempts to trip $3n but fails.", A_SOMEONE, self, null, targ,
	  TO_NOTVICT);
      quit;
   }

dilcopy ("tripwt@skills",targ);
   change_speed(targ, PULSE_VIOLENCE);
   act("You make a quick move and trip $3n.", A_ALWAYS, self, null, targ,
       TO_CHAR);
   act("$1n ducks quickly and sweeps your feet from under you.",
       A_ALWAYS, self, null, targ, TO_VICT);
   act("$1n makes a quick maneuver and trips $3n.", A_SOMEONE, self, null,
       targ, TO_NOTVICT);
   quit;
}
dilend


dilbegin string race_skin (race_def:integer);
code
{
if (race_def==RACE_HUMAN)  {
  return (SKIN_SKIN);}
else if (race_def==RACE_ELF)  {
  return (SKIN_SKIN);}
else if (race_def==RACE_DWARF)  {
return (SKIN_HIDE);}
else if (race_def==RACE_HALFLING)  {
  return (SKIN_SKIN);}
else if (race_def==RACE_GNOME)  {
  return (SKIN_SKIN);}
else if (race_def==RACE_HALF_ORC)  {
  return (SKIN_SKIN);}
else if (race_def==RACE_HALF_OGRE)  {
  return (SKIN_SKIN);}
else if (race_def==RACE_HALF_ELF)  {
  return (SKIN_SKIN);}
else if (race_def==RACE_BROWNIE)  {
  return (SKIN_SKIN);}
else if (race_def==RACE_GROLL)  {
  return (SKIN_SKIN);}
else if (race_def==RACE_DARK_ELF)  {
  return (SKIN_SKIN);}
else if (race_def==RACE_SKAVEN)  {
  return (SKIN_SKIN);}
else if (race_def==RACE_GNOLL)  {
  return (SKIN_SKIN);}
else if (race_def==RACE_GOBLIN)  {
  return (SKIN_SKIN);}
else if (race_def==RACE_HOBGOBLIN)  {
return (SKIN_HIDE);}
else if (race_def==RACE_KOBOLD)  {
return (SKIN_HIDE);}
else if (race_def==RACE_NIXIE)  {
  return (SKIN_SKIN);}
else if (race_def==RACE_NYMPH)  {
  return (SKIN_SKIN);}
else if (race_def==RACE_OGRE)  {
return (SKIN_HIDE);}
else if (race_def==RACE_ORC)  {
return (SKIN_HIDE);}
else if (race_def==RACE_SATYR)  {
  return (SKIN_SKIN);}
else if (race_def==RACE_FAUN)  {
  return (SKIN_SKIN);}
else if (race_def==RACE_SPRITE)  {
  return (SKIN_SKIN);}
else if (race_def==RACE_DRYAD)  {
return (SKIN_SKIN);}
else if (race_def==RACE_LEPRECHAUN)  {
return (SKIN_SKIN);}
else if (race_def==RACE_PIXIE)  {
return (SKIN_SKIN);}
else if (race_def==RACE_SYLPH)  {
return (SKIN_SKIN);}
else if (race_def==RACE_HERMIT)  {
return (SKIN_SKIN);}
else if (race_def==RACE_SHARGUGH)  {
return (SKIN_SKIN);}
else if (race_def==RACE_GIANT)  {
return (SKIN_SKIN);}
else if (race_def==RACE_WARDEN)  {
return (SKIN_SKIN);}
else if (race_def==RACE_TROLL)  {
return (SKIN_SKIN);}
else if (race_def==RACE_NORSE_GOD)  {
return (SKIN_SKIN);}
else if (race_def==RACE_MERMAID)  {
return (SKIN_SKIN);}
else if (race_def==RACE_SIREN)  {
return (SKIN_SKIN);}
else if (race_def==RACE_NAIAD)  {
return (SKIN_SKIN);}
else if (race_def==RACE_MERMAN)  {
return (SKIN_SKIN);}
else if (race_def==RACE_MINOTAUR)  {
return (SKIN_SKIN);}
else if (race_def==RACE_YETI)  {
return (SKIN_SKIN);}
else if (race_def==RACE_OTHER_HUMANOID)  {
return (SKIN_SKIN);}
else if (race_def==RACE_BEAR)  {
return (SKIN_FUR);}
else if (race_def==RACE_DOG)  {
return (SKIN_FUR);}
else if (race_def==RACE_WOLF)  {
return (SKIN_FUR);}
else if (race_def==RACE_FOX)  {
return (SKIN_FUR);}
else if (race_def==RACE_CAT)  {
return (SKIN_FUR);}
else if (race_def==RACE_RABBIT)  {
return (SKIN_FUR);}
else if (race_def==RACE_DEER)  {
return (SKIN_HIDE);}
else if (race_def==RACE_COW)  {
return (SKIN_HIDE);}
else if (race_def==RACE_HARE)  {
return (SKIN_FUR);}
else if (race_def==RACE_GOAT)  {
return (SKIN_FUR);}
else if (race_def==RACE_EAGLE)  {
return (SKIN_FEATHER);}
else if (race_def==RACE_PIG)  {
return (SKIN_HIDE);}
else if (race_def==RACE_DUCK)  {
return (SKIN_FEATHER);}
else if (race_def==RACE_BIRD)  {
return (SKIN_FEATHER);}
else if (race_def==RACE_RAT)  {
return (SKIN_FUR);}
else if (race_def==RACE_HORSE)  {
return (SKIN_FUR);}
else if (race_def==RACE_BADGER)  {
return (SKIN_HIDE);}
else if (race_def==RACE_SKUNK)  {
return (SKIN_FUR);}
else if (race_def==RACE_BOAR)  {
return (SKIN_FUR);}
else if (race_def==RACE_MOUSE)  {
return (SKIN_HIDE);}
else if (race_def==RACE_MONKEY)  {
return (SKIN_HIDE);}
else if (race_def==RACE_PORCUPINE)  {
  return (SKIN_QUILL);}
else if (race_def==RACE_ELEPHANT)  {
return (SKIN_SKIN);}
else if (race_def==RACE_CAMEL)  {
return (SKIN_HIDE);}
else if (race_def==RACE_FERRET)  {
return (SKIN_HIDE);}
else if (race_def==RACE_VULTURE)  {
return (SKIN_FEATHER);}
else if (race_def==RACE_SQUIRREL)  {
return (SKIN_FUR);}
else if (race_def==RACE_OWL)  {
return (SKIN_FEATHER);}
else if (race_def==RACE_LEMURE)  {
return (SKIN_HIDE);}
else if (race_def==RACE_ELK)  {
return (SKIN_FUR);}
else if (race_def==RACE_LION)  {
return (SKIN_SKIN);}
else if (race_def==RACE_TIGER)  {
return (SKIN_SKIN);}
else if (race_def==RACE_LEOPARD)  {
return (SKIN_SKIN);}
else if (race_def==RACE_OTHER_MAMMAL)  {
return (SKIN_HIDE);}
else if (race_def==RACE_TREE)  {
  return (SKIN_TREE);}
else if (race_def==RACE_VINE)  {
return (SKIN_NONE);}
else if (race_def==RACE_FLOWER)  {
return (SKIN_NONE);}
else if (race_def==RACE_SEAWEED)  {
return (SKIN_NONE);}
else if (race_def==RACE_CACTUS)  {
return (SKIN_NONE);}
else if (race_def==RACE_OTHER_PLANT)  {
return (SKIN_NONE);}
else if (race_def==RACE_MAGGOT)  {
return (SKIN_NONE);}
else if (race_def==RACE_BEETLE)  {
return (SKIN_NONE);}
else if (race_def==RACE_SPIDER)  {
return (SKIN_NONE);}
else if (race_def==RACE_COCKROACH)  {
return (SKIN_NONE);}
else if (race_def==RACE_BUTTERFLY)  {
return (SKIN_NONE);}
else if (race_def==RACE_ANT)  {
return (SKIN_NONE);}
else if (race_def==RACE_WORM)  {
return (SKIN_NONE);}
else if (race_def==RACE_LEECH)  {
return (SKIN_NONE);}
else if (race_def==RACE_DRAGONFLY)  {
return (SKIN_NONE);}
else if (race_def==RACE_MOSQUITO)  {
return (SKIN_NONE);}
else if (race_def==RACE_OTHER_INSECT)  {
return (SKIN_NONE);}
else if (race_def==RACE_LIZARD)  {
return (SKIN_SKIN);}
else if (race_def==RACE_SNAKE)  {
return (SKIN_SKIN);}
else if (race_def==RACE_FROG)  {
return (SKIN_NONE);}
else if (race_def==RACE_ALLIGATOR)  {
return (SKIN_SKIN);}
else if (race_def==RACE_DINOSAUR)  {
return (SKIN_HIDE);}
else if (race_def==RACE_CHAMELEON)  {
return (SKIN_NONE);}
else if (race_def==RACE_SCORPION)  {
return (SKIN_NONE);}
else if (race_def==RACE_TURTLE)  {
return (SKIN_SHELL);}
else if (race_def==RACE_BAT)  {
return (SKIN_NONE);}
else if (race_def==RACE_TOAD)  {
return (SKIN_NONE);}
else if (race_def==RACE_OTHER_REPTILE)  {
return (SKIN_SCALE);}
else if (race_def==RACE_CAVE_WIGHT)  {
return (SKIN_NONE);}
else if (race_def==RACE_UR_VILE)  {
return (SKIN_SKIN);}
else if (race_def==RACE_STONE_RENDER)  {
return (SKIN_NONE);}
else if (race_def==RACE_VAMPIRE)  {
return (SKIN_SKIN);}
else if (race_def==RACE_SLIME)  {
return (SKIN_NONE);}
else if (race_def==RACE_WYRM)  {
return (SKIN_SKIN);}
else if (race_def==RACE_AUTOMATON)  {
return (SKIN_HIDE);}
else if (race_def==RACE_UNICORN)  {
return (SKIN_FUR);}
else if (race_def==RACE_DRAGON_MIN)  {
return (SKIN_SCALE);}
else if (race_def==RACE_DRAGON_BLACK)  {
return (SKIN_SCALE);}
else if (race_def==RACE_DRAGON_BLUE)  {
return (SKIN_SCALE);}
else if (race_def==RACE_DRAGON_GREEN)  {
return (SKIN_SCALE);}
else if (race_def==RACE_DRAGON_RED)  {
return (SKIN_SCALE);}
else if (race_def==RACE_DRAGON_WHITE)  {
return (SKIN_SCALE);}
else if (race_def==RACE_DRAGON_SILVER)  {
return (SKIN_SCALE);}
else if (race_def==RACE_DRAGON_TURTLE)  {
return (SKIN_SCALE);}
else if (race_def==RACE_DRAGON_LAVA)  {
return (SKIN_SCALE);}
else if (race_def==RACE_DRAGON_SHADOW)  {
return (SKIN_SCALE);}
else if (race_def==RACE_DRAGON_LIZARD)  {
return (SKIN_SCALE);}
else if (race_def==RACE_LESSER_DEMON)  {
return (SKIN_SKIN);}
else if (race_def==RACE_GREATER_DEMON)  {
return (SKIN_SKIN);}
else if (race_def==RACE_SERVANT_DEMON)  {
return (SKIN_SKIN);}
else if (race_def==RACE_PRINCE_DEMON)  {
return (SKIN_SKIN);}
else if (race_def==RACE_LESSER_DEVIL)  {
return (SKIN_SKIN);}
else if (race_def==RACE_GREATER_DEVIL)  {
return (SKIN_SKIN);}
else if (race_def==RACE_SHADOW_DEVIL)  {
return (SKIN_SKIN);}
else if (race_def==RACE_ARCH_DEVIL)  {
return (SKIN_SKIN);}
else if (race_def==RACE_MEDUSA)  {
return (SKIN_SKIN);}
else if (race_def==RACE_WINGED_HORSE)  {
return (SKIN_HIDE);}
else if (race_def==RACE_GARGOYLE)  {
return (SKIN_NONE);}
else if (race_def==RACE_GOLEM)  {
return (SKIN_NONE);}
else if (race_def==RACE_YOGOLOTH)  {
return (SKIN_HIDE);}
else if (race_def==RACE_MIST_DWELLER)  {
return (SKIN_NONE);}
else if (race_def==RACE_WEREWOLF)  {
return (SKIN_FUR);}
else if (race_def==RACE_WERERAT)  {
return (SKIN_FUR);}
else if (race_def==RACE_ELEMENTAL_AIR)  {
return (SKIN_NONE);}
else if (race_def==RACE_ELEMENTAL_EARTH)  {
return (SKIN_NONE);}
else if (race_def==RACE_ELEMENTAL_FIRE)  {
return (SKIN_NONE);}
else if (race_def==RACE_ELEMENTAL_FROST)  {
return (SKIN_NONE);}
else if (race_def==RACE_ELEMENTAL_WATER)  {
return (SKIN_NONE);}
else if (race_def==RACE_ELEMENTAL_LIGHT)  {
return (SKIN_NONE);}
else if (race_def==RACE_DEVOURER)  {
return (SKIN_SKIN);}
else if (race_def==RACE_DANALEK)  {
return (SKIN_SKIN);}
else if (race_def==RACE_FAMILIAR)  {
return (SKIN_NONE);}
else if (race_def==RACE_OTHER_CREATURE)  {
return (SKIN_HIDE);}
else if (race_def==RACE_ZOMBIE)  {
return (SKIN_NONE);}
else if (race_def==RACE_LICH)  {
return (SKIN_NONE);}
else if (race_def==RACE_GHOUL)  {
return (SKIN_NONE);}
else if (race_def==RACE_SKELETON)  {
return (SKIN_NONE);}
else if (race_def==RACE_GHOST)  {
return (SKIN_NONE);}
else if (race_def==RACE_SPIRIT)  {
return (SKIN_NONE);}
else if (race_def==RACE_MUMMIE)  {
return (SKIN_NONE);}
else if (race_def==RACE_BANSHEE)  {
return (SKIN_SKIN);}
else if (race_def==RACE_NAGA_SOUL)  {
return (SKIN_SKIN);}
else if (race_def==RACE_OTHER_UNDEAD)  {
return (SKIN_SKIN);}
else if (race_def==RACE_CRAB)  {
return (SKIN_SHELL);}
else if (race_def==RACE_SAND_SPIDER)  {
return (SKIN_NONE);}
else if (race_def==RACE_RIVER_LEECH)  {
return (SKIN_NONE);}
else if (race_def==RACE_SAND_CRAWLER)  {
return (SKIN_SHELL);}
else if (race_def==RACE_SEA_HORSE)  {
return (SKIN_NONE);}
else if (race_def==RACE_SHARK)  {
return (SKIN_SCALE);}
else if (race_def==RACE_LAMPREY)  {
return (SKIN_HIDE);}
else if (race_def==RACE_MANTA_RAY)  {
return (SKIN_NONE);}
else if (race_def==RACE_CLIFF_HUGGER)  {
return (SKIN_HIDE);}
else if (race_def==RACE_ALGAE_MAN)  {
return (SKIN_NONE);}
else if (race_def==RACE_WHELK)  {
return (SKIN_SKIN);}
else if (race_def==RACE_OYSTER)  {
return (SKIN_SHELL);}
else if (race_def==RACE_KRAKEN)  {
return (SKIN_HIDE);}
else if (race_def==RACE_CAVE_FISHER)  {
return (SKIN_SHELL);}
else if (race_def==RACE_OCTOPUS)  {
return (SKIN_NONE);}
else if (race_def==RACE_WHALE)  {
return (SKIN_SKIN);}
else if (race_def==RACE_DOLPHIN)  {
return (SKIN_SKIN);}
else if (race_def==RACE_EEL)  {
return (SKIN_SKIN);}
else if (race_def==RACE_FISH)  {
return (SKIN_SCALE);}
else if (race_def==RACE_OTHER_MARINE)  {
return (SKIN_SCALE);}
return (SKIN_NONE);
}
dilend

dilbegin integer race_cost (race_def:integer);
var
  cst:integer;
code
{
if (race_def==RACE_HUMAN)  {
cst:=550;}
else if (race_def==RACE_ELF)  {
cst:=555;}
else if (race_def==RACE_DWARF)  {
cst:=550;}
else if (race_def==RACE_HALFLING)  {
cst:=580;}
else if (race_def==RACE_GNOME)  {
cst:=560;}
else if (race_def==RACE_HALF_ORC)  {
cst:=560;}
else if (race_def==RACE_HALF_OGRE)  {
cst:=550;}
else if (race_def==RACE_HALF_ELF)  {
cst:=550;}
else if (race_def==RACE_BROWNIE)  {
cst:=550;}
else if (race_def==RACE_GROLL)  {
cst:=530;}
else if (race_def==RACE_DARK_ELF)  {
cst:=560;}
else if (race_def==RACE_SKAVEN)  {
cst:=591;}
else if (race_def==RACE_GNOLL)  {
cst:=572;}
else if (race_def==RACE_GOBLIN)  {
cst:=543;}
else if (race_def==RACE_HOBGOBLIN)  {
cst:=526;}
else if (race_def==RACE_KOBOLD)  {
cst:=533;}
else if (race_def==RACE_NIXIE)  {
cst:=575;}
else if (race_def==RACE_NYMPH)  {
cst:=584;}
else if (race_def==RACE_OGRE)  {
cst:=523;}
else if (race_def==RACE_ORC)  {
cst:=527;}
else if (race_def==RACE_SATYR)  {
cst:=567;}
else if (race_def==RACE_FAUN)  {
cst:=554;}
else if (race_def==RACE_SPRITE)  {
cst:=566;}
else if (race_def==RACE_DRYAD)  {
cst:=579;}
else if (race_def==RACE_LEPRECHAUN)  {
cst:=589;}
else if (race_def==RACE_PIXIE)  {
cst:=545;}
else if (race_def==RACE_SYLPH)  {
cst:=550;}
else if (race_def==RACE_HERMIT)  {
cst:=550;}
else if (race_def==RACE_SHARGUGH)  {
cst:=550;}
else if (race_def==RACE_GIANT)  {
cst:=550;}
else if (race_def==RACE_WARDEN)  {
cst:=550;}
else if (race_def==RACE_TROLL)  {
cst:=550;}
else if (race_def==RACE_NORSE_GOD)  {
cst:=635;}
else if (race_def==RACE_MERMAID)  {
cst:=550;}
else if (race_def==RACE_SIREN)  {
cst:=550;}
else if (race_def==RACE_NAIAD)  {
cst:=550;}
else if (race_def==RACE_MERMAN)  {
cst:=550;}
else if (race_def==RACE_MINOTAUR)  {
cst:=550;}
else if (race_def==RACE_YETI)  {
cst:=550;}
else if (race_def==RACE_OTHER_HUMANOID)  {
cst:=550;}
else if (race_def==RACE_BEAR)  {
cst:=235;}
else if (race_def==RACE_DOG)  {
cst:=75;}
else if (race_def==RACE_WOLF)  {
cst:=150;}
else if (race_def==RACE_FOX)  {
cst:=150;}
else if (race_def==RACE_CAT)  {
cst:=75;}
else if (race_def==RACE_RABBIT)  {
cst:=100;}
else if (race_def==RACE_DEER)  {
cst:=150;}
else if (race_def==RACE_COW)  {
cst:=150;}
else if (race_def==RACE_HARE)  {
cst:=75;}
else if (race_def==RACE_GOAT)  {
cst:=150;}
else if (race_def==RACE_EAGLE)  {
cst:=250;}
else if (race_def==RACE_PIG)  {
cst:=100;}
else if (race_def==RACE_DUCK)  {
cst:=75;}
else if (race_def==RACE_BIRD)  {
cst:=75;}
else if (race_def==RACE_RAT)  {
cst:=50;}
else if (race_def==RACE_HORSE)  {
cst:=250;}
else if (race_def==RACE_BADGER)  {
cst:=200;}
else if (race_def==RACE_SKUNK)  {
cst:=150;}
else if (race_def==RACE_BOAR)  {
cst:=150;}
else if (race_def==RACE_MOUSE)  {
cst:=50;}
else if (race_def==RACE_MONKEY)  {
cst:=150;}
else if (race_def==RACE_PORCUPINE)  {
cst:=25;}
else if (race_def==RACE_ELEPHANT)  {
cst:=200;}
else if (race_def==RACE_CAMEL)  {
cst:=200;}
else if (race_def==RACE_FERRET)  {
cst:=90;}
else if (race_def==RACE_VULTURE)  {
cst:=175;}
else if (race_def==RACE_SQUIRREL)  {
cst:=100;}
else if (race_def==RACE_OWL)  {
cst:=100;}
else if (race_def==RACE_LEMURE)  {
cst:=255;}
else if (race_def==RACE_ELK)  {
cst:=200;}
else if (race_def==RACE_LION)  {
cst:=225;}
else if (race_def==RACE_TIGER)  {
cst:=250;}
else if (race_def==RACE_LEOPARD)  {
cst:=275;}
else if (race_def==RACE_OTHER_MAMMAL)  {
cst:=150;}
else if (race_def==RACE_TREE)  {
cst:=10;}
else if (race_def==RACE_VINE)  {
cst:=0;}
else if (race_def==RACE_FLOWER)  {
cst:=0;}
else if (race_def==RACE_SEAWEED)  {
cst:=0;}
else if (race_def==RACE_CACTUS)  {
cst:=0;}
else if (race_def==RACE_OTHER_PLANT)  {
cst:=0;}
else if (race_def==RACE_MAGGOT)  {
cst:=0;}
else if (race_def==RACE_BEETLE)  {
cst:=0;}
else if (race_def==RACE_SPIDER)  {
cst:=0;}
else if (race_def==RACE_COCKROACH)  {
cst:=0;}
else if (race_def==RACE_BUTTERFLY)  {
cst:=0;}
else if (race_def==RACE_ANT)  {
cst:=0;}
else if (race_def==RACE_WORM)  {
cst:=0;}
else if (race_def==RACE_LEECH)  {
cst:=0;}
else if (race_def==RACE_DRAGONFLY)  {
cst:=0;}
else if (race_def==RACE_MOSQUITO)  {
cst:=0;}
else if (race_def==RACE_OTHER_INSECT)  {
cst:=0;}
else if (race_def==RACE_LIZARD)  {
cst:=120;}
else if (race_def==RACE_SNAKE)  {
cst:=250;}
else if (race_def==RACE_FROG)  {
cst:=0;}
else if (race_def==RACE_ALLIGATOR)  {
cst:=200;}
else if (race_def==RACE_DINOSAUR)  {
cst:=1280;}
else if (race_def==RACE_CHAMELEON)  {
cst:=0;}
else if (race_def==RACE_SCORPION)  {
cst:=0;}
else if (race_def==RACE_TURTLE)  {
cst:=75;}
else if (race_def==RACE_BAT)  {
cst:=0;}
else if (race_def==RACE_TOAD)  {
cst:=0;}
else if (race_def==RACE_OTHER_REPTILE)  {
cst:=75;}
else if (race_def==RACE_CAVE_WIGHT)  {
cst:=0;}
else if (race_def==RACE_UR_VILE)  {
cst:=200;}
else if (race_def==RACE_STONE_RENDER)  {
cst:=0;}
else if (race_def==RACE_VAMPIRE)  {
cst:=440;}
else if (race_def==RACE_SLIME)  {
cst:=0;}
else if (race_def==RACE_WYRM)  {
cst:=635;}
else if (race_def==RACE_AUTOMATON)  {
cst:=120;}
else if (race_def==RACE_UNICORN)  {
cst:=635;}
else if (race_def==RACE_DRAGON_MIN)  {
cst:=5115;}
else if (race_def==RACE_DRAGON_BLACK)  {
cst:=7115;}
else if (race_def==RACE_DRAGON_BLUE)  {
cst:=8115;}
else if (race_def==RACE_DRAGON_GREEN)  {
cst:=8500;}
else if (race_def==RACE_DRAGON_RED)  {
cst:=8700;}
else if (race_def==RACE_DRAGON_WHITE)  {
cst:=8800;}
else if (race_def==RACE_DRAGON_SILVER)  {
cst:=8900;}
else if (race_def==RACE_DRAGON_TURTLE)  {
cst:=1235;}
else if (race_def==RACE_DRAGON_LAVA)  {
cst:=1535;}
else if (race_def==RACE_DRAGON_SHADOW)  {
cst:=1935;}
else if (race_def==RACE_DRAGON_LIZARD)  {
cst:=1435;}
else if (race_def==RACE_LESSER_DEMON)  {
cst:=5115;}
else if (race_def==RACE_GREATER_DEMON)  {
cst:=5515;}
else if (race_def==RACE_SERVANT_DEMON)  {
cst:=5915;}
else if (race_def==RACE_PRINCE_DEMON)  {
cst:=6115;}
else if (race_def==RACE_LESSER_DEVIL)  {
cst:=4115;}
else if (race_def==RACE_GREATER_DEVIL)  {
cst:=5110;}
else if (race_def==RACE_SHADOW_DEVIL)  {
cst:=2110;}
else if (race_def==RACE_ARCH_DEVIL)  {
cst:=3115;}
else if (race_def==RACE_MEDUSA)  {
cst:=635;}
else if (race_def==RACE_WINGED_HORSE)  {
cst:=635;}
else if (race_def==RACE_GARGOYLE)  {
cst:=0;}
else if (race_def==RACE_GOLEM)  {
cst:=0;}
else if (race_def==RACE_YOGOLOTH)  {
cst:=0;}
else if (race_def==RACE_MIST_DWELLER)  {
cst:=0;}
else if (race_def==RACE_WEREWOLF)  {
cst:=0;}
else if (race_def==RACE_WERERAT)  {
cst:=0;}
else if (race_def==RACE_ELEMENTAL_AIR)  {
cst:=0;}
else if (race_def==RACE_ELEMENTAL_EARTH)  {
cst:=0;}
else if (race_def==RACE_ELEMENTAL_FIRE)  {
cst:=0;}
else if (race_def==RACE_ELEMENTAL_FROST)  {
cst:=0;}
else if (race_def==RACE_ELEMENTAL_WATER)  {
cst:=0;}
else if (race_def==RACE_ELEMENTAL_LIGHT)  {
cst:=0;}
else if (race_def==RACE_DEVOURER)  {
cst:=635;}
else if (race_def==RACE_DANALEK)  {
cst:=635;}
else if (race_def==RACE_FAMILIAR)  {
cst:=0;}
else if (race_def==RACE_OTHER_CREATURE)  {
cst:=550;}
else if (race_def==RACE_ZOMBIE)  {
cst:=0;}
else if (race_def==RACE_LICH)  {
cst:=0;}
else if (race_def==RACE_GHOUL)  {
cst:=0;}
else if (race_def==RACE_SKELETON)  {
cst:=0;}
else if (race_def==RACE_GHOST)  {
cst:=0;}
else if (race_def==RACE_SPIRIT)  {
cst:=0;}
else if (race_def==RACE_MUMMIE)  {
cst:=0;}
else if (race_def==RACE_BANSHEE)  {
cst:=450;}
else if (race_def==RACE_NAGA_SOUL)  {
cst:=205;}
else if (race_def==RACE_OTHER_UNDEAD)  {
cst:=200;}
else if (race_def==RACE_CRAB)  {
cst:=75;}
else if (race_def==RACE_SAND_SPIDER)  {
cst:=0;}
else if (race_def==RACE_RIVER_LEECH)  {
cst:=0;}
else if (race_def==RACE_SAND_CRAWLER)  {
cst:=250;}
else if (race_def==RACE_SEA_HORSE)  {
cst:=0;}
else if (race_def==RACE_SHARK)  {
cst:=100;}
else if (race_def==RACE_LAMPREY)  {
cst:=120;}
else if (race_def==RACE_MANTA_RAY)  {
cst:=0;}
else if (race_def==RACE_CLIFF_HUGGER)  {
cst:=120;}
else if (race_def==RACE_ALGAE_MAN)  {
cst:=0;}
else if (race_def==RACE_WHELK)  {
cst:=0;}
else if (race_def==RACE_OYSTER)  {
cst:=0;}
else if (race_def==RACE_KRAKEN)  {
cst:=75;}
else if (race_def==RACE_CAVE_FISHER)  {
cst:=30;}
else if (race_def==RACE_OCTOPUS)  {
cst:=0;}
else if (race_def==RACE_WHALE)  {
cst:=500;}
else if (race_def==RACE_DOLPHIN)  {
cst:=450;}
else if (race_def==RACE_EEL)  {
cst:=55;}
else if (race_def==RACE_FISH)  {
cst:=50;}
else if (race_def==RACE_OTHER_MARINE)  {
cst:=50;}

return (cst);
}
dilend

dilbegin skin(arg : string);
external
   integer skillresist (aa : integer, ad : integer,
                             sa : integer, sd : integer);
  string race_skin (race_def:integer);
  integer race_cost  (race_def:integer);
var
  temp:string;
hm      : integer;
targ    : unitptr;
wpn:unitptr;
skin    : unitptr;
cst:integer;
skin_name:string;
wt      : integer;
corpse_name:string;
beheaded:integer;
code
{
beheaded:=0;
   if ((self.type == UNIT_ST_PC) and (self.skills[SKI_SKIN] >lt;= 0))
   {
      act("You must practice first.", A_ALWAYS, self, null, null, TO_CHAR);
      quit;
   }


if (self.position==POSITION_FIGHTING)
  {
  act ("You can't skin something in combat!",
  A_ALWAYS,self,null,null,TO_CHAR);
  quit;
  }
if (arg=="") {
  act ("Skin what?",
  A_ALWAYS,self,null,null,TO_CHAR);
  quit;
  }


if (self.endurance>lt;20)
  {
  act ("You are too tired to skin a mouse.",
  A_ALWAYS,self,null,null,TO_CHAR);
  quit;
  }
targ:=findunit(self,arg,FIND_UNIT_SURRO,null);
if ((targ==null) or not visible(self, targ))
    {
    act ("There is nothing like that to skin here.",
        A_ALWAYS,self,null,null,TO_CHAR);
    quit;
    }

if ((targ.nameidx+"@"+targ.zoneidx)!="corpse@basis")
{
act ("You can't skin that!",
A_ALWAYS,self,null,null,TO_CHAR);
quit;
}

if ("$skinned" in targ.extra)
  {
  act ("Sorry that has already been skinned.",
  A_ALWAYS,self,null,null,TO_CHAR);
  quit;
  }
skin_name:=race_skin(targ.value[4]);
if (skin_name=="NONE"){
  act ("That $2N can not be skinned.",
  A_ALWAYS,self,targ,null,TO_CHAR);
  quit;
  }


    secure (targ,losttarg);
wpn:=equipment (self,WEAR_WIELD);
if (wpn==null)goto no_wpn;
if ((wpn.objecttype != ITEM_WEAPON) or
  (wpn.value[0] != WPN_DAGGER))
  {
  wpn:=equipment (self,WEAR_HOLD);
  if (wpn==null) goto no_wpn;
  if ((wpn.objecttype != ITEM_WEAPON) or
    (wpn.value[0] != WPN_DAGGER))
    {
    :no_wpn:
    act("You must hold or wield a small blade to skin a carcass.",
      A_SOMEONE, self, null, null, TO_CHAR);
    quit;
    }
 }

  hm := skillresist ( ((self.abilities[ABIL_BRA] +
                             self.abilities[ABIL_DEX]) / 2), 25,
                            self.skills[SKI_SKIN], 25);

  if (self.level >lt; 10) hm:=hm+5;
  self.endurance:=self.endurance - 20;

corpse_name:=targ.outside_descr;
temp:=getword (corpse_name);
temp:=getword (corpse_name);
if (temp=="beheaded")  beheaded:=1;
temp:=getword (corpse_name);
if (hm >lt;= 0)
    {
      act("You shred the "+skin_name+" of $3n into a thousand bloody pieces.",
          A_SOMEONE, self, null, targ, TO_CHAR);
      act("$1n shreds the "+skin_name+"  of $3n into a thousand bloody pieces...what a " +
          "mess!", A_SOMEONE, self, null, targ, TO_ROOM);
          addextra (targ.extra, {"$skinned"},itoa(targ.value[4]));
          if (beheaded==0){
          targ.title:="a poorly skinned corpse";
          targ.outside_descr:="a poorly skinned corpse of "+corpse_name;
          }
        else
        {
          targ.title:="a poorly skinned, beheaded corpse";
          targ.outside_descr:="a poorly skinned, beheaded corpse of "+corpse_name;
          }
      quit;
    }

  if (hm >lt;= -10)
    {
      act("You skin $3n and leave a corpse and a small, useless scrap of "+skin_name+".",
          A_SOMEONE, self, null, targ, TO_CHAR);
      act("$1n skins $3n and leaves a corpse and a small, useless looking"+
      "scrap of "+skin_name+".",
      A_SOMEONE,self,null,targ,TO_REST);
          addextra (targ.extra, {"$skinned"},itoa(targ.value[4]));
      skin := load("base_skin@skills");
      link(skin, self.outside);
      secure(skin, lostskin);
      skin.names:={"useless scrap",
      "scrap"};
      addstring (skin.names,"useless scrap of "+corpse_name+" "+skin_name);
      addstring (skin.names,corpse_name);
      addstring (skin.names,skin_name);

  skin.title:="a useless looking scrap of "+skin_name;
  if (beheaded==0){
  skin.outside_descr := "A small useless scrap of "+skin_name+" from "+corpse_name;
          targ.outside_descr:="a skinned corpse of "+corpse_name;
  }
else
  {
  skin.outside_descr := "A small useless scrap of "+skin_name+"is laying here.";
          targ.outside_descr:="a skinned beheaded corpse is laying here rotting..";
          }

  skin.cost:=10;
          targ.title:="a skinned corpse";

      quit;
    }

cst:=race_cost(targ.value[4]);
  if (hm > -10)
    {
      act("You skin $3n and leave a corpse and some "+skin_name+".",
          A_SOMEONE, self, null, targ, TO_CHAR);
      act("$1n skins $3n and leaves a corpse and some "+skin_name+".",
      A_SOMEONE,self,null,targ,TO_REST);
      skin := load("base_skin@skills");
      link(skin, self.outside);
      secure(skin, lostskin);
          addextra (targ.extra, {"$skinned"},itoa(targ.value[4]));
      skin.names:={"large pile",
      "pile"};
      addstring (skin.names,"large pile of "+corpse_name+" "+skin_name);
      addstring (skin.names,corpse_name);
      addstring (skin.names,skin_name);

  skin.title:= "a large pile of "+skin_name;
  if (beheaded==0){
  skin.outside_descr := "A large pile of "+skin_name+" from "+corpse_name;
          targ.outside_descr:="a skinned corpse of "+corpse_name;
          }
        else
          {
  skin.outside_descr := "A large pile of "+skin_name+" is laying here.";
          targ.outside_descr:="a skinned, beheaded corpse is laying here rotting.";
          }

  skin.cost:=cst;
  cst:=targ.weight/10;
  if (cst>50) cst:=50;
setweight (skin,cst);
          targ.title:="a skinned corpse";

      quit;
    }

:losttarg:
:lostskin:
  unsecure (targ);
 unsecure(skin);
 quit;

}
dilend
dilbegin throw (arg : string); /* The throw skill */

external
   integer skillresist@skills(aa : integer, ad : integer, sa : integer,
                             sd : integer);

var
   wielded      : unitptr;  /* Have I got anything in my hands. */
   held         : unitptr;  /* And what about that other handy... */
   thing        : unitptr;  /* Well I guess this is our missile. */
   targ         : unitptr;  /* Hello wabbit. */

   cost_of      : integer;  /* Endurance cost. */
   bonus        : integer;  /* For meleedamage. */
   sharpness    : integer;  /* Approximate sharpness of non-weapons. */
   miss         : integer;  /* If we miss or not. This is for what to
                               do with the missile after the business
                               of attacking is over with. */
   mdam         : integer;  /* Damage the missile takes from the fight */
   hm           : integer;  /* For skillresist */
   dead_jim     : integer;  /* did we kill it? huh huh? */

   tstr         : string;   /* Temporary string for processing argument. */
   tstr2        : string;   /* For corpses */
   thing_name   : string;   /* In case we ever forget what we're throwing. */

code
{
   heartbeat := 2;
   miss := 0; /* We hit until we're told differently. */
   bonus := -20;

   if (self.position >lt; POSITION_STANDING)
   {
      act("You need to be standing to do that.",
          A_ALWAYS, self, null, null, TO_CHAR);
      quit;
   }

   thing := findunit(self, arg, FIND_UNIT_IN_ME, null);

   if ((thing == null) or not visible(self, targ))
   {
      act("You can't find that in your inventory or your equipment!",
          A_ALWAYS, self, null, null, TO_CHAR);
      quit;
   }

   thing_name := thing.name;

   if (thing.objecttype != ITEM_WEAPON)
   {
      act("Why bother throwing that?! Throw a weapon instead!",
          A_ALWAYS, self, null, null, TO_CHAR);
      quit;
   }

   tstr := getword(arg);

   if (tstr == "at")
      tstr := arg;

   else if (tstr == "")
   {
      act("What do you want to throw that at?",
          A_ALWAYS, self, null, null, TO_CHAR);
      quit;
   }

   else
      tstr := tstr + " " + arg;

   targ := findunit(self, tstr, FIND_UNIT_SURRO, null);

   if ((targ == null) or (not(visible(self, targ))))
   {
      act("You don't see that person here!",
          A_ALWAYS, self, null, null, TO_CHAR);
      quit;
   }

   if (not(targ.type >amp; (UNIT_ST_PC | UNIT_ST_NPC)))
   {
      act("Yeah, take your frustration out on that poor inanimate " +
          "object! Hit it, yeah!",
          A_ALWAYS, self, null, null, TO_CHAR);
      quit;
   }

   if ((targ.type==UNIT_ST_PC) and (self.type==UNIT_ST_PC))
   {
      if (not(isset (self.pcflags, PC_PK_RELAXED)))
      {
         act("You are not allowed to do that unless you sign " +
             "the book of blood.",
             A_ALWAYS, self, null, null, TO_CHAR);
         quit;
      }

      if (not(isset (targ.pcflags, PC_PK_RELAXED)))
      {
         act("You are not allowed to do that unless $2e signs " +
             "the book of blood.",
             A_ALWAYS, self, targ, null, TO_CHAR);
         quit;
      }
   }

   wielded := equipment(self, WEAR_WIELD);
   held    := equipment(self, WEAR_HOLD);

/* This doesn't seem to work, but later in the dil something takes care
of the case in which you're wielding a weapon.. */

   if ((wielded != null) and (held != null) and ((thing != wielded) and
                                                 (thing != held)))
   {
      act("Your hands are full! How do you expect to throw something " +
          "if you don't have a free hand (or aren't throwing what's in " +
          "your hand) ?!",
          A_ALWAYS, self, null, null, TO_CHAR);
      quit;
   }

   cost_of := (rnd(20,30) * thing.weight) / 25;

   if (self.endurance >lt; cost_of)
   {
      act("You simply don't have the energy to throw that!",
          A_ALWAYS, self, null, null, TO_CHAR);
      quit;
   }

   /* DISABLED..Since we can only use meleedamage with Weapons, it's time to
      distinguish item types so we know which way to go. */

/*
   if (thing.objecttype == ITEM_WEAPON) goto is_weapon;
   else goto is_other;
*/


:is_weapon:

/* In a previous version, all targets were assumed having skills,
which caused the mobs to be easier to throw things at.. */

   if (targ.type == UNIT_ST_PC)
      hm := skillresist@skills((self.abilities[ABIL_DEX] +
                               self.abilities[ABIL_STR]) /2,
                               (targ.abilities[ABIL_DEX]*2)/3,
                               self.skills[SKI_THROW],
                               targ.skills[SKI_THROW] - 25);

   else
      hm := skillresist@skills((self.abilities[ABIL_DEX] +
                               self.abilities[ABIL_STR]) /2,
                               (targ.abilities[ABIL_DEX]*2)/3,
                               self.skills[SKI_THROW],
                               targ.abilities[ABIL_DEX] - 25);

   if (hm >lt; 0) goto miss;

   bonus := bonus + (self.weapons[thing.value[0]] /10);

   tstr := "";
   tstr2 := "";
   tstr := targ.name;
   if (targ.type == UNIT_ST_NPC) tstr2 := targ.title;

   dead_jim := targ.hp;

   if ((thing == held) and (wielded != null))
   {
      unequip(wielded);
      unequip(thing);
      addequip(thing, WEAR_WIELD);
      act("You throw your " + thing.name + " at $3n!",
          A_ALWAYS, self, null, targ, TO_CHAR);
      act("$1n throws $1s " + thing.name + " at you!",
          A_SOMEONE, self, null, targ, TO_VICT);
      act("$1n throw $1s " + thing.name + " at $3n!",
          A_SOMEONE, self, null, targ, TO_NOTVICT);
      bonus := meleedamage(self, targ, bonus, 0);
      unequip(thing);
      addequip(wielded, WEAR_WIELD);
   goto dispose_thing;
   }

   else if (thing == wielded)
   {
      act("You throw your " + thing.name + " at $3n!",
          A_ALWAYS, self, null, targ, TO_CHAR);
      act("$1n throws $1s " + thing.name + " at you!",
          A_SOMEONE, self, null, targ, TO_VICT);
      act("$1n throw $1s " + thing.name + " at $3n!",
          A_SOMEONE, self, null, targ, TO_NOTVICT);
      bonus := meleedamage(self, targ, bonus, 0);
      unequip(thing);
      goto dispose_thing;
   }

   else if ((wielded != null) and (thing != wielded))
   {
      unequip(wielded);
      addequip(thing, WEAR_WIELD);
      act("You throw your " + thing.name + " at $3n!",
          A_ALWAYS, self, null, targ, TO_CHAR);
      act("$1n throws $1s " + thing.name + " at you!",
          A_SOMEONE, self, null, targ, TO_VICT);
      act("$1n throw $1s " + thing.name + " at $3n!",
          A_SOMEONE, self, null, targ, TO_NOTVICT);
      bonus := meleedamage(self, targ, bonus, 0);
      unequip(thing);
      addequip(wielded, WEAR_WIELD);
      goto dispose_thing;
   }

   else
   {
      addequip(thing, WEAR_WIELD);
      act("You throw your " + thing.name + " at $3n!",
          A_ALWAYS, self, null, targ, TO_CHAR);
      act("$1n throws $1s " + thing.name + " at you!",
          A_SOMEONE, self, null, targ, TO_VICT);
      act("$1n throw $1s " + thing.name + " at $3n!",
          A_SOMEONE, self, null, targ, TO_NOTVICT);
      bonus := meleedamage(self, targ, bonus, 0);
      unequip(thing);
      goto dispose_thing;
   }

:miss:
bonus := 0;
   miss := 1;
   if (targ.position > POSITION_SLEEPING)
   {
      act("You throw your " + thing.name + " at $3n!",
          A_ALWAYS, self, null, targ, TO_CHAR);
      act("$1n throws $1s " + thing.name + " at you!",
          A_ALWAYS, self, null, targ, TO_VICT);
      act("$1n throws $1s " + thing.name + " at $3n!",
          A_SOMEONE, self, null, targ, TO_NOTVICT);

      act("$3n dodges your throw!",
          A_ALWAYS, self, null, targ, TO_CHAR);
      act("You skillfully dodge out of the path of $1n's " + thing.name +
          "!",
          A_ALWAYS, self, null, targ, TO_VICT);
      act("$1n misses as $3n skillfully dodges out of the way of $1s " +
          thing.name + ".",
          A_ALWAYS, self, null, targ, TO_NOTVICT);

      goto dispose_thing;
   }
   else
   {
      act("You throw your " + thing.name + " at $3n but miss $3m completely!",
          A_ALWAYS, self, null, targ, TO_CHAR);
      act("$1n throws $1s " + thing.name + " at $3n but misses completely!",
          A_SOMEONE, self, null, targ, TO_NOTVICT);
      goto dispose_thing;
   }


:dispose_thing:
dead_jim := dead_jim - bonus;

   if (bonus == -1)
   {
      link(thing, self.outside);
      quit;
   }
   else
   {
      mdam := rnd(0, 40 - (thing.value[1] + thing.value[2]));
      thing.hp := thing.hp - mdam;
      position_update(thing);

/*      if ((bonus > 30) and (dead_jim > -10)) link(thing, targ)
      else if ((bonus > 30) and (dead_jim == -10)) link(thing, self.outside);
      else if ((bonus >30) and (dead_jim >lt; -10))
      {
         pause;
         thing := findunit(self, thing_name, FIND_UNIT_IN_ME, null);
         if (tstr2 == "")
         {
            tstr := "corpse of " + tstr;
            targ := findunit(self, tstr, FIND_UNIT_SURRO, null);
            if (targ == null) link(thing, self.outside);
            else link(thing, targ);
         }
         else if (tstr2 != "")
         {
            targ := findunit(self, "corpse", FIND_UNIT_SURRO, null);
            if (targ == null) link(thing, self.outside);
            else if (tstr2 in targ.outside_descr) link(thing, targ);
            else link(thing, self.outside);
         }
         else link(thing, self.outside);

      } */
      if ((bonus > 30) and (dead_jim >= -10))
        link (thing, targ);

      else if ((bonus > 30) and (dead_jim >lt; -10))
        {
        targ := findunit(self, "corpse", FIND_UNIT_SURRO, null);

        if ((tstr2 != "") and (tstr2 in targ.outside_descr))
            link(thing, targ);
        else if ((tstr2 == "") and (tstr in targ.outside_descr))
            link (thing, targ);

        else link(thing, self.outside);
        }

      else
        link(thing, self.outside);
   }

   quit;
}
dilend /* throw */

dilbegin shoot(arg : string);

external
   integer skillresist@skills(aa : integer, ad : integer, sa : integer,
                             sd : integer);

var
   targ     : unitptr;   /* El victim */
   missile  : unitptr;   /* The actual arrow/sling/etc to shoot */
   quiver   : unitptr;   /* The quiver, pouch, etc */
   weapon   : unitptr;   /* Ranged Weapon */
   in_hand  : unitptr;   /* Am I holding anything */
   tempu    : unitptr;   /* Old room */
   wep_type : integer;   /* The Ranged Weapon Type - Bow, Crossbow, Sling */
   slay_bon : integer;   /* Slaying bonus if weapon or missiles match
                            targ.race - not cumulative */
   result   : integer;   /* Integer for cast_spell */
   spl_type : integer;   /* The bow's spells */
   bonus    : integer;   /* For meleeattack */
   mdam     : integer;   /* Missile's damage taken */
   hm       : integer;
   temp     : integer;   /* did we kill it? */

   act_list : stringlist; /* list of strings */
   magic_ar : string;    /* Magic arrow attack type */
   temp_str : string;     /* Temporary string*/

   tstr         : string;   /* Temporary string for processing argument. */
   tstr2        : string;   /* For corpses */
   thing_name   : string;   /* In case we ever forget what we're throwing. */

code
{
   heartbeat:=2;
/*   if (self.fighting != null)
   {
      act("You're too busy to do that!",
          A_ALWAYS, self, null, null, TO_CHAR);
      quit;
   }
*/

   weapon:=equipment(self, WEAR_HOLD);
   in_hand:=equipment(self, WEAR_WIELD);

   if (weapon==null)
   {
      act("You aren't holding anything to shoot with!",
          A_ALWAYS, self, null, null, TO_CHAR);
      quit;
   }

   if (in_hand != null)
   {
      act("You need two hands to shoot accurately.",
          A_ALWAYS, self, null, null, TO_CHAR);
      quit;
   }
/*
   if (self.skills[SKI_SHOOT] >lt;= 0)
   {
      act("You need to practice your shooting first.",
          A_ALWAYS, self, null, null, TO_CHAR);
      quit;
   }
*/

   if (weapon.objecttype != ITEM_FIREWEAPON)
   {
      act("How do you propose to shoot something with that!?",
          A_ALWAYS, self, null, null, TO_CHAR);
      quit;
   }

   if (arg == "")
   {
      act("Shoot? Yes! Fine! Shoot we must, but WHAT??",
          A_ALWAYS, self, null, null, TO_CHAR);
      quit;
   }

   temp_str := arg;

   wep_type := weapon.value[4];
   if ((wep_type != WPN_BOW) and (wep_type != WPN_CROSSBOW) and
       (wep_type != WPN_SLING))
   {
      act("Invalid Ranged Weapon - Please report this to a god.",
          A_ALWAYS, self, null, null, TO_CHAR);
      log(self.name + " has encountered an invalid ranged weapon " +
          "- this is a big error so someone tell Eirinn quick.");
      quit;
   }

   if (wep_type == WPN_BOW)
      act_list := {"Bow", "arrow", "quiver", "42", "draw back",
                   "draws back", "shoot", "shoots"};
   else if (wep_type == WPN_CROSSBOW)
      act_list := {"Crossbow", "bolt", "quiver", "43", "knock",
                   "knocks", "shoot", "shoots"};
   else
      act_list := {"Sling", "stone", "pouch", "44", "spin",
                   "spins", "let fly", "lets fly"};

   if (self.weapons[wep_type] >lt;= 0)
   {
      act("You are not skilled enough with a " + act_list.[0] + ". You " +
          "should practice.",
          A_ALWAYS, self, null, null, TO_CHAR);
      quit;
   }

   if (weapon.value[0] > 0) goto get_targ; /* This is magical - no arrows */

   quiver := findunit(self, act_list.[2], FIND_UNIT_EQUIP, null);

   if (quiver.objecttype != ITEM_CONTAINER) goto search_inv;

   missile := findunit(quiver, act_list.[1], 0, quiver.inside);

   if ((missile == null) or not visible(self, missile)) goto search_inv;

   if (missile.value[0] != atoi(act_list.[3]))
   {
      act("You have no proper " + act_list.[1] + "s!",
          A_ALWAYS, self, null, null, TO_CHAR);
      quit;
   }

   goto get_targ;


:search_inv:
   missile := findunit(self, act_list.[1], 0, self.inside);

   if (missile == null)
   {
      act("You can't find any " + act_list.[1] + "s to shoot.",
          A_ALWAYS, self, null, null, TO_CHAR);
      quit;
   }

   if (missile.value[0] != atoi(act_list.[3]))
   {
      act("You have no proper " + act_list.[1] + "s!",
          A_ALWAYS, self, null, null, TO_CHAR);
      quit;
   }


:get_targ:

   targ := findunit(self, arg, FIND_UNIT_SURRO, null);

   if ((targ==null) or (not(visible(self, targ))))
   {
      act("You don't see that here.",
          A_ALWAYS, self, null, null, TO_CHAR);
      quit;
   }

   if (not (targ.type >amp; UNIT_ST_NPC|UNIT_ST_PC))
   {
      act("Why waste a good " + act_list.[1] + " on an inanimate object " +
          "like that?",
          A_ALWAYS, self, null, null, TO_CHAR);
      quit;
   }

   if (targ==self)
   {
      act("You carefully aim at your foot, then think better of it.",
          A_ALWAYS, self, null, null, TO_CHAR);
      act("$1n almost shoots $1mself in the foot! What an idiot.",
          A_HIDEINV, self, null, null, TO_REST);
      quit;
   }

   if ((targ.type==UNIT_ST_PC) and (self.type==UNIT_ST_PC))
   {
      if (not(isset (self.pcflags, PC_PK_RELAXED)))
      {
         act("You are not allowed to do that unless you sign " +
             "the book of blood.",
             A_ALWAYS, self, null, null, TO_CHAR);
         quit;
      }

      if (not(isset (targ.pcflags, PC_PK_RELAXED)))
      {
         act("You are not allowed to do that unless $2e signs " +
             "the book of blood.",
             A_ALWAYS, self, targ, null, TO_CHAR);
         quit;
      }
   }


:slay_proc:

   if (weapon.value[0] > 0) goto spell_proc;

/* Slaying missiles/bows etc. Effects not cumulative */

   slay_bon := 0;

   hm := skillresist@skills(self.abilities[ABIL_DEX],
                           (targ.abilities[ABIL_DEX]-20),
                           self.weapons[wep_type],
                           (targ.abilities[ABIL_BRA]-10));
   if (hm >lt;= -10)
   {
      act("Your " + act_list.[1] + " misses $3n as $3e dodges out " +
          "of the way.",
          A_ALWAYS, self, null, targ, TO_CHAR);
      act("$1n's " + act_list.[1] + " misses $3n " +
          "as $3e dodges out of the way.",
          A_SOMEONE, self, null, targ, TO_NOTVICT);
      act("$1n's " + act_list.[1] + " misses you " +
          "as you dodge out of the way.",
          A_SOMEONE, self, null, targ, TO_VICT);
      bonus := -1;
      goto finish_off;
   }

   link(missile, self);
   addequip(missile, WEAR_WIELD);
   act("You " + act_list.[4] + " your " + weapon.name + " and " +
       act_list.[6] + " at $3n!",
       A_ALWAYS, self, null, targ, TO_CHAR);
   act("$1n " + act_list.[5] + " $1s " + weapon.name + " and " +
       act_list.[7] + " at $3n!",
       A_ALWAYS, self, null, targ, TO_NOTVICT);
   act("$1n " + act_list.[5] + " $1s " + weapon.name + " and " +
       act_list.[7] + " at you!",
       A_ALWAYS, self, null, targ, TO_VICT);

   if (missile.value[3] == targ.race)
   {
      slay_bon := 15;
/*
      act(">amp;c+wYour $2n glows!>amp;cw",
          A_ALWAYS, self, missile, null, TO_CHAR);
      act(">amp;c+w$1n's $2n glows!>amp;cw",
          A_ALWAYS, self, missile, null, TO_REST);
*/
   }

   if ((weapon.value[3] == targ.race) and (slay_bon == 0))
   {
      slay_bon := 30;
      act(">amp;c+wYour $2n glows!>amp;cw",
          A_ALWAYS, self, weapon, null, TO_CHAR);
      act(">amp;c+w$1n's $2n glows!>amp;cw",
          A_ALWAYS, self, weapon, null, TO_REST);
   }

   bonus := missile.value[1] + missile.value[2] + weapon.value[1] +
            weapon.value[2] + self.skills[weapon.value[4]] +
            slay_bon;

   goto do_damage;



:spell_proc:

/* Magic Bows, etc: Fire, Frost, Lightning, Acid.
   NOTE:  CURARE is an exception to this and does not count as a spell. */

   spl_type := 0;

   if (weapon.value[0] > 0)
   {
      if (weapon.value[0] == 1)
      {
         spl_type := SPL_FIREBALL_3;
         magic_ar := "fire";
      }
      else if (weapon.value[0] == 2)
      {
         spl_type := SPL_FROSTBALL_3;
         magic_ar := "frost";
      }
      else if (weapon.value[0] == 3)
      {
         spl_type := SPL_LIGHTNING_3;
         magic_ar := "lightning";
      }
      else if (weapon.value[0] == 4)
      {
         spl_type := SPL_ACIDBALL_3;
         magic_ar := "acid";
      }
      else
      {
         act("Invalid Ranged Weapon - Please report this to a god.",
             A_ALWAYS, self, null, null, TO_CHAR);
         log(self.name + " has encountered an invalid ranged weapon " +
             "- this is a big error so someone tell Eirinn quick.");
         quit;
      }
   }

   if (self.mana >lt; 20)
   {
      act("You have not the magical essence left to succeed.",
          A_ALWAYS, self, null, null, TO_CHAR);
      quit;
   }

   hm := skillresist@skills(self.abilities[ABIL_DEX],
                           (targ.abilities[ABIL_DEX]-20),
                           self.weapons[wep_type],
                           (targ.abilities[ABIL_BRA]-10));

   if (hm >lt;= -10)
   {
      act("You " + act_list.[4] + " your " + weapon.name + " and " +
          act_list.[6] + " a magical " + act_list.[1] +
          " of " + magic_ar + " but you miss $3n!",
          A_ALWAYS, self, null, targ, TO_CHAR);
      act("$1n " + act_list.[5] + " $1s " + weapon.name + " and " +
          act_list.[7] + " a magical " + act_list.[1] +
          " of " + magic_ar + " at $3n but misses $3m completely!",
          A_ALWAYS, self, null, targ, TO_NOTVICT);
      act("$1n " + act_list.[5] + " $1s " + weapon.name + " and " +
          act_list.[7] + " a magical " + act_list.[1] +
          " of " + magic_ar + " at you but it misses you completely!",
          A_ALWAYS, self, null, targ, TO_VICT);
      goto spell_end;

   }

   act("You " + act_list.[4] + " your " + weapon.name + " and " +
       act_list.[6] + " a magical " + act_list.[1] +
       " of " + magic_ar + " at $3n!",
       A_ALWAYS, self, null, targ, TO_CHAR);
   act("$1n " + act_list.[5] + " $1s " + weapon.name + " and " +
       act_list.[7] + " a magical " + act_list.[1] +
       " of " + magic_ar + " at $3n!",
       A_ALWAYS, self, null, targ, TO_NOTVICT);
   act("$1n " + act_list.[5] + " $1s " + weapon.name + " and " +
       act_list.[7] + " a magical " + act_list.[1] +
       " of " + magic_ar + " at you!",
       A_ALWAYS, self, null, targ, TO_VICT);
   result := cast_spell(spl_type, self, weapon, targ, "");
:spell_end:
   self.mana := self.mana - 20;
   quit;


:do_damage:
   thing_name := missile.name;
   tstr := targ.name;
   if (targ.type == UNIT_ST_NPC) tstr2 := targ.title;

   temp := targ.hp;

   bonus := meleedamage(self, targ, bonus, 0);

   missile := equipment(self, WEAR_WIELD);
   unequip(missile);

:finish_off:

   temp := temp - bonus;
   if (bonus >lt;= 0)
   {
      link(missile, self.outside);
      quit;
   }
   else
   {
:do_dam:
      mdam := rnd(0, 40 - (missile.value[1] + missile.value[2]));
      missile.hp := missile.hp - mdam;
      position_update(missile);

      if ((bonus > 30) and (temp > -10)) link(missile, targ)
      else if ((bonus > 30) and (temp == -10)) link(missile, self.outside);
      else if ((bonus > 30) and (temp >lt; -10))
      {
         pause;
         missile := findunit(self, thing_name, FIND_UNIT_IN_ME, null);
         if (tstr2 == "")
         {
            tstr := "corpse of " + tstr;
            targ := findunit(self, tstr, FIND_UNIT_SURRO, null);
            if (targ == null) link(missile, self.outside);
            else link(missile, targ);
         }
         else if (tstr2 != "")
         {
            targ := findunit(self, "corpse", FIND_UNIT_SURRO, null);
            if (targ == null) link(missile, self.outside);
            else if (tstr2 in targ.outside_descr) link(missile, targ);
            else link(missile, self.outside);
         }
         else link(missile, self.outside);

      }
      else link(missile, self.outside);
   }

   quit;
}
dilend /* Shoot */
%rooms
                                   skill_room
title "The Skill Room"
descr
"Token room."
movement SECT_INSIDE
flags {UNIT_FL_NO_WEATHER}
ALWAYS_LIGHT
end


%objects


/* Butcher objects */

fillet_template
names {"fillet"}
title "a succulent fillet"
descr "A fillet of some marine creature has been left here."
extra {}
"A choice fillet of some fishy creature, this looks very good to eat."

weight 4

manipulate {MANIPULATE_TAKE}
FOOD_DEF(16, 0)
dilcopy blowaway@function(220, "$1n is consumed by some smelly maggots.");
end /* fillet_template */

leg_template
names {"leg"}
title "a lovely leg"
descr "The leg of some creature has been left here."
extra {}
"This leg looks very good to eat."

weight 1

manipulate {MANIPULATE_TAKE}
FOOD_DEF(10, 0)
dilcopy blowaway@function(250, "$1n is consumed by some smelly maggots.");
end /* leg_template */

arm_template
names {"arm"}
title "a lovely arm"
descr "The arm of some creature has been left here."
extra {}
"This arm would make good eating."

weight 1

manipulate {MANIPULATE_TAKE}
FOOD_DEF(10, 0)
dilcopy blowaway@function(280, "$1n is consumed by some smelly maggots.");
end /* arm_template */

scraps_template
names {"scraps"}
title "some scraps of meat"
descr "Some scraps of meat have been left on the ground here."
extra {}
"They look reasonably edible."

weight 2

manipulate {MANIPULATE_TAKE}
FOOD_DEF(3, 0)
dilcopy blowaway@function(240, "$1n are consumed by some smelly maggots.");
end /* scraps_template */

steak_template
names {"delicious steak", "steak"}
title "a delicious steak"
descr "A steak cut from some creature has been discarded here."
extra {}
"This steak looks very tasty - perhaps it would make good eating."

weight 6

manipulate {MANIPULATE_TAKE}
FOOD_DEF(20, 0)
dilcopy blowaway@function(200, "$1n is consumed by some smelly maggots.");
end /* steak_template */

base_skin /* used for skin skill*/
title "a piece of base skin"
names {"base skin"}
outside_descr "base skin is lying here"
type ITEM_SKIN
manipulate {MANIPULATE_TAKE}
weight 1
dilcopy blowaway@function  (600,"$1n decays into dust.");
end

/* campfire obj for cook */
campfire_0
names {"campfire", "fire"}
title "a campfire"
descr "A crackling campfire is here."
extra {}
"This is a small campfire with flames about a foot high. It looks like
it could go out any minute."
weight 10
dilcopy blowaway@function(300, "$1n goes out suddenly in a puff of smoke.");
end
/* end of campfire obj for cook */

/* forage food objects for forage skill */
roots
names {"roots", "root"}
title "some roots"
descr "Some roots have been pulled out of the ground here."
extra {}
"These are just some thick brown roots which a ranger has pulled out of
the ground in their search for food."
weight 3
manipulate {MANIPULATE_TAKE}
FOOD_DEF(20, 0)
dilcopy blowaway@function(240, "$1n dry up and turn to dust.");
end

tubers
names {"tubers", "tuber"}
title "some tubers"
descr "Some tubers have been pulled out of the ground here."
extra {}
"These tubers are not unlike potatoes, except that they are different
shapes and sizes and do not have eyes. A ranger must have found these
in the search for food."
weight 3
manipulate {MANIPULATE_TAKE}
FOOD_DEF(20, 0)
dilcopy blowaway@function(240, "$1n dry up and turn to dust.");
end

berries
names {"berries", "berry"}
title "some berries"
descr "Some berries are lying here waiting to be stepped on."
extra {}
"These berries are of various shapes, sizes and colours. They look
positively delicious. A ranger must have picked these in the search for
food."
weight 1
manipulate {MANIPULATE_TAKE}
FOOD_DEF(10, 0)
dilcopy blowaway@function(240, "$1n get eaten by hungry ants.");
end

grubs
names {"grubs", "grub"}
title "some grubs"
descr "Some bloated grubs lie here, squirming."
extra {}
"These grubs, small, white and almost transparent, are utterly
repulsive, but what can one do when they're hungry? A ranger found
these in the search for food."
weight 1
manipulate {MANIPULATE_TAKE}
FOOD_DEF(5, 0)
dilcopy blowaway@function(240, "$1n dry up and turn to dust.");
end

egg
names {"bird egg", "egg"}
title "a bird egg"
descr "A small bird egg is here."
extra {}
"This is a small bird egg. It obviously got lost from its nest, and
now it can serve as food for a hungry ranger."
weight 2
manipulate {MANIPULATE_TAKE}
FOOD_DEF(8, 0)
dilcopy blowaway@function(240, "$1n gets crushed underfoot.");
end

mushroom
names {"mushroom"}
title "a mushroom"
descr "A mushroom is lying here."
extra {}
"This mushroom is rather large, with pinkish spots. A ranger has found
this in the search for food."
weight 2
manipulate {MANIPULATE_TAKE}
FOOD_DEF(7, 0)
dilcopy blowaway@function(240, "$1n turns to slime and seeps away.");
end

truffle
names {"truffle"}
title "a truffle"
descr "A truffle lies here, looking like a misshapen potato."
extra {}
"This is a type of fungus that grows underground. It is considered a
rare delicacy, and obviously the ranger that found it has exquisite
taste."
weight 3
manipulate {MANIPULATE_TAKE}
FOOD_DEF(12, 0)
dilcopy blowaway@function(240, "$1n turns to slime and seeps away.");
end

fruit
names {"fruit"}
title "a fruit"
descr "A piece of fruit is lying here."
extra {}
"This is a typical piece of fruit. It looks like a cross between an
apple and a pear, but smells more like an orange. A ranger has picked
this in the search for food."
weight 3
manipulate {MANIPULATE_TAKE}
FOOD_DEF(9, 0)
dilcopy blowaway@function(240, "$1n rots away.");
end

nuts
names {"nuts", "nut"}
title "some nuts"
descr "Some nuts have been left here."
extra {}
"These are some assorted nuts. They look very nutritious. A ranger must
have found them in the search for food."
weight 1
manipulate {MANIPULATE_TAKE}
FOOD_DEF(6, 0)
dilcopy blowaway@function(240, "$1n are carried off by a hungry squirrel.");
end

d_lizard
names {"dead lizard", "lizard"}
title "a dead lizard"
descr "A dead lizard is here."
extra {}
"This is a dead lizard, killed by a ranger in the search for food. It
is green, scaly and reminds you of a goblin with psoriasis."
weight 6
manipulate {MANIPULATE_TAKE}
FOOD_DEF(15, 0)
dilcopy blowaway@function(240, "$1n is consumed by a horde of maggots.");
end

d_newt
names {"dead newt", "newt"}
title "a dead newt"
descr "A dead newt is here."
extra {}
"This is a small, slimy, dead red newt. This dead red newt is also
a food source for hungry rangers."
weight 2
manipulate {MANIPULATE_TAKE}
FOOD_DEF(7, 0)
dilcopy blowaway@function(240, "$1n is consumed by a horde of maggots.");
end

algae
names {"algae"}
title "some algae"
descr "Some algae has been left in a pool here."
extra {}
"This algae is basically greenish-brown slime. It looks like something
orcs would have regurgitated, but it also serves as a meal for a ranger
in search of food."
weight 2
manipulate {MANIPULATE_TAKE}
FOOD_DEF(11, 0)
dilcopy blowaway@function(240, "$1n dries up and blows away.");
end

kelp
names {"kelp", "seaweed"}
title "some kelp"
descr "Some kelp lies here in a heap."
extra {}
"Some blackish, briny kelp. Rich in nutrients, richer in sea water. This
is a meal for a hungry ranger."
weight 3
manipulate {MANIPULATE_TAKE}
FOOD_DEF(14, 0)
dilcopy blowaway@function(240, "$1n dries up and blows away.");
end

d_fish
names {"dead fish", "fish"}
title "a dead fish"
descr "A dead fish lies here, doing nothing."
extra {}
"This dead fish is about a foot long, bright silver and looks almost
yummy. Caught by a ranger in search of food, this fish will yield a
lot of filet."
weight 12
manipulate {MANIPULATE_TAKE}
FOOD_DEF(25, 0)
dilcopy blowaway@function(240, "$1n is consumed by a horde of maggots.");
end

d_frog
names {"dead frog", "frog"}
title "a dead frog"
descr "A dead frog is here."
extra {}
"This is a dead bullfrog. It is a fine example of the species, and it
will also serve as a fine example of natural cuisine for a ranger."
weight 5
manipulate {MANIPULATE_TAKE}
FOOD_DEF(8, 0)
dilcopy blowaway@function(240, "$1n is consumed by a horde of maggots.");
end

d_snail
names {"dead snail", "snail"}
title "a dead snail"
descr "A dead snail lies here in a pool of its own slime."
extra {}
"Slimy, green and really disgusting, this snail is also considered food
by rangers in times of need. They don't seem to be very picky about
what they eat, do they?"
weight 1
manipulate {MANIPULATE_TAKE}
FOOD_DEF(2, 0)
dilcopy blowaway@function(240, "$1n dries up and blows away.");
end

d_slug
names {"dead slug", "slug"}
title "a dead slug"
descr "A dead slug is here, being disgusting."
extra {}
"Despite it's horrible appearance, this bright green, slimy object is
a slug, and not only that, it's food for a ranger. Maybe it's time to
finally start that diet..."
weight 2
manipulate {MANIPULATE_TAKE}
FOOD_DEF(4, 0)
dilcopy blowaway@function(240, "$1n dries up and blows away.");
end
/* end of forage objects */

/* b_spring, b_leafcup and b_icepool are for dowse skill */
b_spring
names {"spring", "springwater", "pool", "water"}
title "a pool of springwater"
descr "A small spring bubbles up at your feet."
extra {}
"This is a small spring that a Ranger has discovered. It only provides a
small amount of water, so be sparing with it."
LIQ_DEF("clear", 2,20,20,10,1,0,0)
dilcopy blowaway@function(240, "$1n dries up and disappears.");
dilcopy empty@skills();
end

b_leafcup
names {"leafcup", "cup", "water"}
title "a leafcup of water"
descr "A small leafcup of water is here."
extra {}
"This is a small cup fashioned from dead leaves that a Ranger has made.
It only provides a small amount of water, so be sparing with it."
LIQ_DEF("clear", 2,10,10,10,1,0,0)
dilcopy blowaway@function(240, "$1n dries up and disappears.");
dilcopy empty@skills();
end

b_icepool
names {"icewater", "pool", "water"}
title "a pool of icewater"
descr "A small pool of icewater is about to freeze solid here."
extra {}
"This is a small pool of icewater that a Ranger has melted. It only
provides a small amount of water, so be sparing with it."
LIQ_DEF("clear", 2,20,20,10,1,0,0)
dilcopy blowaway@function(60, "$1n freezes solid.");
end
/* end of dowse objects */

f_staff
names {"fighting staff", "full staff", "staff"}
title "a ranger's fighting staff"
descr "A hand crafted ranger staff has been discarded here."
MATERIAL_WOOD("Tree branch")
manipulate {MANIPULATE_TAKE, MANIPULATE_WIELD}
cost 100 IRON_PIECE
weight 12
extra {}
"Hand crafted by a skilled Ranger, this staff is a formidable
two-handed weapon. Wielding this staff would make any potential
opponent think twice before engaging the wielder in combat."

WEAPON_DEF(WPN_FIGHTING_STAFF, 1, 0)

extra {"$wear_s"}
"You take the staff in your hands, ready for battle."

extra {"$wear_o"}
"$1n takes $1s staff in $1s hands, ready for battle."

extra {"$rem_s"}
"You let go of the staff."

extra {"$rem_o"}
"$1n lets go of $1s staff."

end /* f_staff */

q_staff
names {"quarter staff", "staff"}
title "a ranger's quarter staff"
descr "A hand crafted ranger quarter staff has been discarded here."
MATERIAL_WOOD("Tree branch")
manipulate {MANIPULATE_TAKE, MANIPULATE_WIELD}
cost 100 IRON_PIECE
weight 8
extra {}
"Hand crafted by a skilled Ranger, this staff is a formidable
weapon. Wielding this staff would make any potential
opponent think twice before engaging the wielder in combat."

WEAPON_DEF(WPN_QUARTERSTAFF, 1, 0)

extra {"$wear_s"}
"You take the staff in your hand, ready for battle."

extra {"$wear_o"}
"$1n takes $1s staff in $1s hand, ready for battle."

extra {"$rem_s"}
"You let go of the staff."

extra {"$rem_o"}
"$1n lets go of $1s staff. The battle has ended."

end /* q_staff */

bow
names {"long bow", "bow"}
title "a ranger's long bow"
descr "A hand crafted ranger long bow has been discarded here."
MATERIAL_WOOD("Tree branch")

RANGED_DEF(0, 10, 5, 15000, WPN_BOW, 0)

cost 100 IRON_PIECE
weight 3
extra {}
"Hand crafted by a skilled Ranger, this long bow is a formidable
weapon. With a true aim, this bow would likely bring down almost
any target."

extra {"$wear_s"}
"You take the bow in your hand, ready for battle."

extra {"$wear_o"}
"$1n takes $1s bow in $1s hand, ready for battle."

extra {"$rem_s"}
"You let go of the bow."

extra {"$rem_o"}
"$1n lets go of $1s bow. The battle has ended."

end

arrow
names {"arrow"}
title "an arrow"
descr "A hand crafted arrow has been discarded here."
MATERIAL_WOOD("Tree branch")

MISSILE_DEF(WPN_BOW, 5, 1, 15000, 0)

cost 10 IRON_PIECE
weight 1
extra {}
"Hand crafted by a skilled Ranger, this arrow is deadly when shot
by a skilled bowman."

end /* arrow */

man_trap
  names{"man trap", "trap"}
  title "a man trap"
  descr "A small man trap lies nearly undetectable here."
  extra{}
  "This trap looks purposeful and nasty, hunting rabbit with it would be
  efficient to say the least but even the biggest ogre would have trouble
  wresting free of its jaws."

  TRAP_DEF(5, 5)

  extra {"$spring_self"}
  "default"
  extra {"$spring_other"}
  "default"

  flags      {UNIT_FL_NO_TELEPORT, UNIT_FL_TRANS}
  weight 4
  cost 2 COPPER_PIECE
  MATERIAL_WOOD("Wood from a tree branch")

end /* man_trap */

grass_hut
names {"grass hut", "hut", "shelter"}
title "a grass hut"
descr "A large sturdy grass hut has been erected here."

inside_descr
"The walls are made from long stems of grass woven into a thick mat. It looks
quite sturdy. The roof is flat and of the same construction as the walls. There
is a single entrance."

extra {}
"Fashioned from long grasses, this hut would accommodate at least three people.
Constructed by a ranger, it is deceptively strong, and it looks sturdy enough to
withstand all but the harshest of weather. There is a single entrance flap."

extra {"door", "flap"}
"The door to this hut is little more than a flap of grass woven into a mat."

extra {"$enter_s"}
"You crawl in through the narrow entrance to the hut. It feels nice and cosy
inside."
extra {"$enter_o"}
"$1n crawls into the hut."

extra {"$exit_s"}
"You crawl out of the hut."
extra {"$exit_o"}
"$1n crawls out of the hut."

CONTAINER_DEF(3000)
manipulate {MANIPULATE_ENTER}

weight 1000

flags {UNIT_FL_NO_MOB, UNIT_FL_SACRED, UNIT_FL_NO_TELEPORT}

open {EX_OPEN_CLOSE, EX_INSIDE_OPEN, EX_CLOSED}

end /* grass hut */

wooden_shack
names {"wooden shack", "shack", "shelter"}
title "a wooden shack"
descr "A sturdy wooden shack has been erected here."

inside_descr
"The walls have been constructed from tree branches bound together with a
makeshift rope of thin branches, rather like wattle. The roof is a flat mat of
branches covered in leaves and bound with the same thin young branches. There is
a single entrance."

extra {}
"Fashioned from the wood of the surrounding trees, this shack, though a
temporary abode, would accommodate at least three people, looks sturdy enough
to withstand all but the harshest of weather. There is a single door set
in one side. It looks to have been built by a ranger."

extra {"door"}
"The door has been made from a few wooden slats bound together with sapling
wood - not a very elaborate affair."

extra {"$enter_s"}
"You duck and enter through the narrow doorway of the shack."
extra {"$enter_o"}
"$1n enters the wooden shack."

extra {"$exit_s"}
"You duck and exit the hut."
extra {"$exit_o"}
"$1n emerges from the wooden hut."

CONTAINER_DEF(3000)
manipulate {MANIPULATE_ENTER}

weight 1000

flags {UNIT_FL_NO_MOB, UNIT_FL_SACRED, UNIT_FL_NO_TELEPORT}

open {EX_OPEN_CLOSE, EX_INSIDE_OPEN, EX_CLOSED}

end /* wooden_shack */

igloo
names {"igloo", "shelter"}
title "a small igloo"
descr "A small makeshift igloo has been constructed here."

inside_descr
"The crudely cut blocks of ice which make up the walls of this igloo provide a
greater amount of insulation than their appearance would betray. They form a
dome which apexs in a smooth curve for a roof, making the shape of the igloo
like a half-sphere. There is a single entrance."

extra {}
"This igloo looks to have been thrown together with speed - the blocks making up
the structure are crudely cut, but the igloo looks sturdy enough to last a day
or two. It looks to have been built by a ranger."

extra {"door"}
"The door is made from ice blocks piled on top of each other. It takes a bit
of time to open it."

extra {"$enter_s"}
"You enter through the low entrance to the igloo."

extra {"$enter_o"}
"$1n enters the igloo."

extra {"$exit_s"}
"You crouch down and exit the igloo."
extra {"$exit_o"}
"$1n exits the igloo through the low entrance."

CONTAINER_DEF(3000)
manipulate {MANIPULATE_ENTER}

weight 1000

flags {UNIT_FL_NO_MOB, UNIT_FL_SACRED, UNIT_FL_NO_TELEPORT}

open {EX_OPEN_CLOSE, EX_INSIDE_OPEN, EX_CLOSED}

end /* igloo */

grass
names {"grass", "pile"}
title "a pile of grass"
descr "A pile of grass has been left here."

extra {}
"It looks to be the remains of a grass hut."

end /* grass */

ice
names {"ice blocks", "ice block", "ice", "pile"}
title "a pile of ice blocks"
descr "A pile of ice blocks have been left here."

extra {}
"They look to be the remains of an igloo."

end /* ice */

wood
names {"wood sticks", "wood", "sticks"}
title "wooden sticks"
descr "A pile of wooden sticks are all that remain of a shack that was once
here."

extra {}
"They look to be the remains of an igloo."

end /* ice */

%mobiles

/* Just to test some stuff without having them cast spells - Storm */
hel
/* Godess of Hell */
names {"hel"}
title "Hel"
descr "Hel the grim reaper is here."
extra {} "Dressed in black."
romflags {CHAR_DETECT_INVISIBLE}
ATTACK_DEFENSE(+500, +500)

M_NORSE_HELA

end

%end