pdirt/data/
pdirt/data/HELP/
pdirt/data/HELP/0/
pdirt/data/HELP/F/
pdirt/data/HELP/G/
pdirt/data/HELP/H/
pdirt/data/HELP/J/
pdirt/data/HELP/K/
pdirt/data/HELP/O/
pdirt/data/HELP/Q/
pdirt/data/HELP/R/
pdirt/data/HELP/U/
pdirt/data/HELP/V/
pdirt/data/HELP/Y/
pdirt/data/HELP/Z/
pdirt/data/MESSAGES/
pdirt/data/POWERINFO/
pdirt/data/WIZ_ZONES/
pdirt/drv/
pdirt/drv/bin/
pdirt/drv/compiler/converter/
pdirt/drv/compiler/libs/
pdirt/drv/compiler/scripts/
pdirt/drv/include/AberChat/
pdirt/drv/include/InterMud/
pdirt/drv/include/machine/
pdirt/drv/src/InterMud/
pdirt/drv/src/Players/
pdirt/drv/utils/UAFPort/
pdirt/drv/utils/dnsresolv/
pdirt/drv/utils/gdbm/
#define FIGHT_C

#include "kernel.h"
#include <stdlib.h>
#include "config.h"
#include "verbs.h"
#include "mobile.h"
#include "lflags.h"
#include "sflags.h"
#include "pflags.h"
#include "mflags.h"
#include "oflags.h"
#include "cflags.h"
#include "sendsys.h"
#include "fight.h"
#include "bprintf.h"
#include "commands.h"
#include "hate.h"
#include "objsys.h"
#include "log.h"
#include "parse.h"
#include "move.h"
#include "rooms.h"
#include "clone.h"
#include "mud.h"
#include "quest.h"
#include "special.h"
#include "tables.h"
#include "zones.h"
#include "corpse.h"

struct _spell
{
  int verb;
  char mob_chance;		/* If caster is a mobile, chance to cast the spell */
  char mob_cast_mflag;		/* mflag to see if mobile can cast this spell */
  short mob_dam;		/* If caster is mobile, damage is mob_dam */
  
  short chance;			/* Chance to succeed */
  short hp_loss;		/* The hit points that this spell costst */
  short like_mflag;		/* mflag to see if victim likes the spell. */
  short fear_mflag;		/* mflag to see if factor 6 should be used */
  short maxlev;			/* If caster is above this level, treat him as this */
  short obj3first;		/* First index in spell_enhance[] for factor 3 object */
  short obj3next;		/* first index beyond list */
  char *like_it;		/* Text to tell caster if victim likes the spell */
  char *to_room;		/* Msg to all in room, including victim, excl caster */
  char *to_victim;		/* Msg to victim */
  char *to_others;		/* Msg to others in room */
};

Boolean cast_spell (int caster, int victim, int spell_type);

struct _spell spell_table[] =
{
  {VERB_FIREBALL, 15, MFL_CFIREBALL, 10, 5,
     2, MFL_NFIREBALL, MFL_NFROST, -1,
     0, 2,
     "&+w%s enjoys the heat and gets STRONGER!&*\n",
     "\001A\033[31m\003\001p%s\003 casts a &+wfireball&*.\001A\033[0m\003\n",
     "&+wYou are struck!&*\n",
     "&+w\001p%s\003 is struck!&*\n"},
  {VERB_FROST, 25, MFL_CFROST, 10, 5,
     2, MFL_NFROST, MFL_NFIREBALL, -1,
     2, 3,
     "&+w%s likes the cold and gets STRONGER!&*\n",
     "\001A\033[31m\003\001p%s\003 fires an &+wicy&* ray!\001A\033[0m\003\n",
     "&+wYou are chilled to the bone!&*\n",
     "&+w\001p%s\003 is struck!&*\n"},
  {VERB_MISSILE, 20, MFL_CMISSILE, 10, 7,
     3, MFL_NMISSILE, -1, LVL_SIX,
     3, 4,
     "&+w%s likes your magic missile and gets STRONGER!&*\n",
     "Bolts of &+wfire&* leap from the fingers of \001p%s\003\n",
     "&+wYou are struck!&*\n",
     "&+w\001p%s\003 is struck!&*\n"},
  {VERB_SHOCK, 15, MFL_CSHOCK, 8, 5,
     2, MFL_NSHOCK, -1, -1,
     4, 5,
     "&+w%s likes the shock and gets STRONGER!&*\n",
     "&+wSparks&* fly from the fingers of \001p%s\003!\n",
     "&+w\001A\033[1;36m\003\001p%s\003 touches you, giving you a "
       "strong electric shock!&*\001A\033[0m\003\n",
       "&+w\001p%s\003 is struck!&*\n"},
  {-1}
};


/* Calculate damage done by a player 'pl' carrying item 'it'.
 * If no item, return damage of player. If it is not a weapon, return -1
 * else return damage of player + damage of weapon.
 * dambyitem: DAMage BY ITEM. 
 */
int dambyitem (int pl, int it)
{
  if (it == -1)
    return pdam (pl);
  return !otstbit (it, OFL_WEAPON) ? -1 : odamage (it) + pdam (pl);
}

/*
 * Command function block to handle wielding of weapons.
 */
A_COMMAND(wieldcom)
{ int a;
  
  if ((a = ob1) == -1)
    {
      bprintf ("What's that?\n");
      return;
    }
  else if (psitting(mynum)==2)
   { 
      bprintf("You move around in your sleeping bag.\n");
      return;
   }
  else if (!iscarrby (a, mynum))
    {
      bprintf ("You're not carrying the %s!\n", item1);
      set_weapon (mynum, -1);
      return;
    }
  else if (!otstbit (a, OFL_WEAPON))
    {
      bprintf ("It's not a weapon.\n");
      set_weapon (mynum, -1);
      return;
    }
    if (obj_fun(onum(a)) != NULL)
    {   param_s.plx = mynum;
        param_s.ob = a;
        param_s.loc = ploc(mynum);
        param_s.ret = 1;
        obj_fun(onum(a))(E_ONWIELD);
        if (param_s.ret != 1)
          return;
    }
    
  set_weapon (mynum, a);
  
  send_msg (ploc (mynum), 0, pvis (mynum), LVL_MAX, real_mynum, NOBODY,
	    "%s wields the %s.\n", pname (mynum), oname (a));
  
  bprintf ("You are now wielding the %s.\n", oname (a));
}



/*
 *  The killing and hitting command
 */
PRIVATE void wreckdoor (void);

A_COMMAND(killcom)
{
  
  if (pfighting (mynum) >= 0)
    {
      bprintf ("You're already fighting!\n");
      return;
    }
  if (psitting(mynum) == 2)
  {  bprintf("You kick the butt of the mighty demon... in your dreams..\n");
     return;
  }
  if (psitting(mynum) == 3)
  {  bprintf("Starting a fight now, will cause a great imbalance in your trance.\n");
     return;
  }
  if (pl1 == -1 && ob1 == -1)
    {
      bprintf ("Kill who?\n");
      return;
    }
  if (EQ (item1, "door"))
    {
      if (!ptstflg (mynum, PFL_WRECK))
	{
	  bprintf ("What are you trying to do?  Wreck the door?\n");
	}
      else
	wreckdoor ();
      return;
    }
  if (ob1 != -1)
    {
      breakitem (ob1);
      return;
    }
  if (pl1 == -1)
    {
      bprintf ("You can't do that.\n");
      return;
    }
  if (pl1 == mynum)
    {
      bprintf ("Come on, it will look better tomorrow...\n");
      return;
    }
  if (ploc (pl1) != ploc (mynum))
    {
      bprintf ("They aren't here.\n");
      return;
    }
  if (testpeace (mynum))
    {
      bprintf ("Sorry, it's too peaceful for violence.\n");
      return;
    }
  if (ptstflg (pl1, PFL_NOHASSLE))
    {
      bprintf ("Something interferes with your attack.\n");
      return;
    }

  if (mob_fun(pl1) != NULL)   /* Special events E_ONKILL */
  {   param_s.plx = mynum;
      param_s.pl  = pl1;
      param_s.ret = 1;
      param_s.loc = ploc(mynum);
      param_s.ob = -1;
      mob_fun(pl1)(E_ONKILL);
      if (param_s.ret != 1)
        return;
  }

  if (pl1 < max_players && plev (mynum) < LVL_APPREN && plev (pl1) < LVL_APPREN)
  {   send_msg (DEST_ALL, MODE_QUIET | MODE_BRACKET, LVL_APPREN, LVL_MAX,
		NOBODY, NOBODY, "%s%s attacked %s",
               (the_world->w_tournament) ? "Tournament: " : "", pname (mynum), pname (pl1));
  }
  if (pl1 < max_players && plev(mynum) < LVL_APPREN && plev(pl1) < LVL_APPREN && (!the_world->w_tournament))
  {
      send_msg(DEST_ALL, MODE_QUIET|MODE_BRACKET, LVL_APPREN, LVL_MAX,
	       NOBODY, NOBODY, "Peace declared by Game Driver");
      the_world->w_peace = 1;
#ifdef LOG_PK
      mudlog("PK: %s attacked %s", pname(mynum), pname(pl1));
#endif
      sendf(ploc(mynum),"The Game Driver says 'I cannot allow you to attack eachother'\n");
      bprintf("The Game Driver tells you 'Try to behave yourself.'\n");
      setpstr(mynum, pstr(mynum) /2);
      setpfighting(mynum, -1);
      setpfighting(pl1, -1);
      if (pstr(mynum) ==0)
      {  send_msg(DEST_ALL,MODE_BRACKET|MODE_QUIET,LVL_APPREN,LVL_MAX,mynum,NOBODY,
                  "The Game Driver has removed %s from the game, for %s PK attempts",
                  pname(mynum),his_or_her(mynum));
#ifdef LOG_PK
         mudlog("PK: %s has been kicked off.",pname(mynum));
#endif
         crapup("You die by your own hand.",CRAP_SAVE|CRAP_RETURN);
      }
      the_world->w_peace = 0;
      send_msg(DEST_ALL, MODE_QUIET|MODE_BRACKET, LVL_APPREN, LVL_MAX,
	       NOBODY, NOBODY, "War declared by Game Driver");
      return;
  }
  setpfighting (mynum, pl1);
  
  hit_player (mynum, pl1, (ob2 == -1) ? pwpn (mynum) : ob2);
  
  return;
}


void breakitem (int x)
{ 
  if (x == -1)
  {  bprintf("What's that?\n");
     return;
  }
  
  if (obj_fun(x) != NULL)
  {  param_s.plx = mynum;
     param_s.loc = ploc(mynum);
     param_s.ob  = x;
     param_s.ret = 1;
     obj_fun(x)(E_ONKILL);
     if (param_s.ret != 1)
       return;
  }
  bprintf("You can't break that!\n");
}

PRIVATE void wreckdoor (void)
{ int a;
  char ms[80];
  
  if ((a = fobna ("door")) == -1)
    bprintf ("Sorry, no doors here.\n");
  else if (state (a) == 0)
    bprintf ("It's already open.\n");
  else
    {
      setobjstate (a, 0);
      bprintf ("The door flies open!\n");
      sprintf (ms, "%s hits the door...  It flies open!\n", pname (mynum));
      sillycom (ms);
      sprintf (ms,
	       "\001dYou hear the distinctive crunch of %s meeting a door.\n\003",
	       pname (mynum));
      broad (ms);
    }
}



Boolean testpeace (int player)
{
  return (the_world->w_peace || ltstflg (ploc (player), LFL_PEACEFUL));
}


A_COMMAND(fleecom)
{ int pf,oldloc,newloc;

  if (pstr(mynum) < 0)
       return;
       
  if ((pf = pfighting(mynum)) < 0)
  {   dogocom ();
  } 
  else if (carries_obj_type (mynum, RuneSword_Obj) > -1)
  {
      bprintf ("The sword won't let you!\n");
  } 
  else
  {  set_hate(pfighting(mynum),mynum);
     setpfighting(mynum,-1);
     oldloc = ploc(mynum);
     dogocom();
     if(oldloc == ploc(mynum)) /* we never moved... */
     {  setpfighting(mynum, pf);
        return;
     }
     newloc=ploc(mynum);
     setploc(mynum,oldloc);
     send_msg (ploc (mynum), 0, pvis (mynum), LVL_MAX, mynum, NOBODY,
		"%s drops things as %s make a frantic attempt to escape.\n",
		pname (mynum), psex (mynum) ? "she" : "he");
 
     bprintf("Avoiding a big hit you crawl towards one of the exits.\n");

     send_msg(DEST_ALL,MODE_BRACKET|MODE_NOBATTLE,Max(pvis(mynum),LVL_APPREN),
	      LVL_MAX,mynum,NOBODY,"%s fled from %s &+w(%d/%d)",
	      pname(mynum),pname(pf),pstr(mynum),maxstrength(mynum));

     drop_some_objects (mynum);
     setpscore (mynum, pscore (mynum) - pscore (mynum) / 33);	/* lose 3% */
     calibme ();
     setpfighting (mynum, -1);
     if (cur_player->i_follow >= 0)
     {    bprintf ("You stopped following %s.\n", pname (cur_player->i_follow));
	  cur_player->i_follow = -1;
     }
     setploc(mynum,newloc);
  }
}

int mob_cast_spell (int caster)
{ struct _spell *s;
  
  /* caster is a mobile, see if we let him cast a spell... */
  
  for (s = spell_table; s->verb >= 0; s++)
    {
      if (mtstflg (caster, s->mob_cast_mflag) == 0)
	continue;
      if (randperc () < s->mob_chance)
	return s->verb;
    }
  return -1;
}



void hit_player (int attacker, int victim, int weapon)
{ int x, cth, i, d, w;
  int num_attacks = 1;

  if (weapon >=0 && weapon < numobs)
  {  if (otstbit(weapon,OFL_DOUBLEHIT))
	num_attacks++;
  }
  else if (mtstflg(attacker,MFL_DOUBLEHIT))
     num_attacks = 2;
  else if (mtstflg(attacker,MFL_FOURHIT))
     num_attacks = 4;

 do {
  if ((x = attacker) >= max_players)
    x = victim;
  
  if (attacker >= numchars || victim >= numchars || attacker < 0 ||
      victim < 0 || testpeace (victim) || ploc (attacker) != ploc (victim)
      || !is_in_game (attacker) || !is_in_game (victim))
    return;
  
  /* if the attacker is played by a human: */
  
  if (attacker < max_players || ststflg (attacker, SFL_OCCUPIED) != 0)
  {
#if 0
      /* if the attacker is a mortal: */
      if (plev (attacker) < LVL_APPREN || ststflg (attacker, SFL_OCCUPIED) != 0)
      {
#endif
	  /* if the victim is a mobile: */
	  if (victim >= max_players)
	  {
	      if ((mtstflg (victim, MFL_BLIND) || ststflg(victim,SFL_BLIND)) &&
                   !ststflg (attacker, SFL_BLIND))
	      {
		  sendf (attacker, "%s scratches your eyes out! You are blind!\n",
			 pname (victim));
		  ssetflg (attacker, SFL_BLIND);
	      }
	      if (mob_fun(victim) != NULL)
	      {   param_s.plx = attacker;
	          param_s.pl  = victim;
	          param_s.ob  = weapon;
	          param_s.loc = ploc(attacker);
	          param_s.ret = 1;
	          param_s.misc = -1;
	          mob_fun(victim)(E_WHILEFIGHT);
	          if (param_s.ret != 1)
	            return;
	      }
	  }			/* end if victim is a mobile */
#if 0
      }			/* end, the attacker is a mortal */
#endif      
      if (testpeace (attacker))
	return;
      if ((w = weapon) < 0)
	w = pwpn (attacker);
      if (w >= 0 && !iscarrby (w, attacker))
      {
	  sendf (attacker,
		 "You belatedly realize you don't have the %s,\nand are forced "
		 "to use your hands instead.\n", oname (w));
	  w = -1;
      }
      set_weapon (attacker, w);
      if (w >= 0 && (onum(w) == RuneSword_Obj) && 
	  carries_obj_type(victim, Tower_Staff_Obj) > -1)
      {
	  sendf (attacker,
		 "The Runesword flashes back from its target, growling in "
		 "anger!\n");
	  return;
      }
      
      if (weapon >= 0 && dambyitem (attacker, weapon) < 0)
      {
	  sendf (attacker, "You can't attack %s with a %s!\n",
		 pname (victim), oname (weapon));
	  set_weapon (attacker, -1);
	  return;
      }
      
      if (psitting (attacker)==1 || psitting(attacker)==2 || 
          psitting (attacker)==3 )
	{
	  standcom (attacker);
	}
      
      /* end, attacker is played by a human */
      
    }
    else if (weapon < 0 && !carrobjfrom(victim,sp_shields) &&
	   (x = mob_cast_spell (attacker)) >= 0)
    {
      if (cast_spell (attacker, victim, x))
	return;
    }				/* end, the attacker was a mobile */
  
  
  x = randperc ();
  cth = 57 - parmor (victim);
  if (carries_obj_type (attacker, HorseShoe_Obj) > -1)
    cth += 5;
  
  for (i = 0; i < pnumobs (victim); i++)
  {
      if (iswornby (pobj_nr (i, victim), victim) &&
	  otstbit (pobj_nr (i, victim), OFL_ARMOR))
      {
	  cth -= oarmor (pobj_nr (i, victim));
      }
  }
  
  if(cth<10) cth = 10;
  /* Add 1/2 damage of wielded weapon for mobiles..full for players.. */
  if ((w = weapon) < 0)
    w = pwpn (attacker);
  if (w >= 0 && iscarrby (w, attacker) && iswielded (w) &&
      otstbit (w, OFL_WEAPON))
  { 
      d = odamage (w);
      if (attacker >= max_players)
	d /= 2;
  }
  else
  {
      d = 0;
  }
  
  d += pdam (attacker);

  d = (x < cth) ? MY_RANDOM () % (d + 1) : -1;	/* damage done */
 
  /* Drunken players do not hit very well. */
  if (ststflg(attacker,SFL_DRUNK))   
  {  d = d - (d / 3);
     
     if (d < 0)
       d = 0;
  }
 
  combatmessage (victim, attacker, weapon, d);
  wound_player(attacker, victim, d, -1);
  should_hate(victim,attacker,d);
  num_attacks--;
  } while (num_attacks > 0);
}





/* High level procedure to cast a spell.
 * spell_type = verb of spell.
 */
A_COMMAND(spellcom)
/*void spellcom (int spell_verb)*/
{ int victim = brkword () < 0 ? pfighting (mynum) : fpbn (wordbuf);

  if (ltstflg(ploc(mynum),LFL_JAIL) && (plev(mynum) < LVL_DEMI) )
  {  bprintf("You can't cast from here.\n");
     return;
  }

  if (psitting(mynum) >= 2)
  {  bprintf("You can't cast a spell while resting.\n");
     return;
  }

  if (!is_in_game (victim))
  {  if (pstr(mynum) > 3)
     {  bprintf ("You cast your spell, but there's no one to receive it!\n"); 
        setpstr(mynum,pstr(mynum) - 3);
     }
     else
     {  bprintf("You loose your last piece of strength to cast the spell.\n"
                "Soon your sight starts to blurr, and you faint.\n");
        crapup("You have kicked the bucket.",CRAP_SAVE|CRAP_RETURN);    
        return;
     }
  }
  else if (victim < max_players && !the_world->w_tournament)
    bprintf("You fumble the magic.\n");
  else if (victim >= max_players && victim < numchars)
  {  if (!can_manipulate(mynum,victim))
     {   bprintf("You can't focus your spell.\n");
     }
     else
       cast_spell (mynum, victim, verbnumber);
  }
  else
    cast_spell (mynum, victim, verbnumber);
}


/* Procedure to cast a spell
 * caster   = player index of the spell caster (may be a mobile).
 * victim   = player index of the victim.
 * spell_type = key in spell_table.
 *
 * Return true if the spell succeeded.
 */
Boolean cast_spell (int caster, int victim, int spell_type)
{ struct _spell *spell;
  int clev;
  int i;
  int ob = 0;
  int f;
  
  if ((caster < max_players) && (victim < max_players) && (plev(mynum) < LVL_SENIOR) && !the_world->w_tournament) {
    bprintf("A shield of the Gods can not be surpassed by your wimpy magical spells.\n");
    return 0;
  }
  
  /* Failure to cast the spell? */
  if (plev (caster) < LVL_APPREN && ploc (caster) != ploc (victim))
    {
      sendf (caster, "%s is not here.\n", pname (victim));
      return False;
    }
  /* Find spell */
  for (spell = spell_table; spell->verb != spell_type; spell++)
    {
      if (spell->verb < 0)
	return False;		/* No such spell */
    }

  if (mob_fun(victim) != NULL)
  {   param_s.plx = caster;
      param_s.pl  = victim;
      param_s.loc = ploc(caster);
      param_s.ob  = -1;
      param_s.ret = 1;
      param_s.misc = -1;
      mob_fun(victim)(E_ONKILL);
      if (param_s.ret != 1)
        return False;
  }
  
  if (plev (caster) < LVL_APPREN)
    {
      
      if (pstr (caster) < 10)
	{
	  sendf (caster, "You are too weak to cast magic.\n");
	  return False;
	}
     
      setpstr (caster, pstr (caster) - spell->hp_loss);
      
      if (testpeace (caster))
	{
	  sendf (caster, "No, that's violent!\n");
	  return False;
	}
      else if (ltstflg (ploc (victim), LFL_NO_MAGIC))
	{
	  sendf (caster, "Something about this location has drained your mana.\n");
	  return False;
	}
      
      i = (caster >= max_players) ? 90 + spell->chance : spell->chance;
      
      i += has_magic_object(caster);

      if (caster < max_players && randperc () > i * plev (caster))
	{
	  sendf (caster, "You fumble the magic.\n");
	  return False;
	}
      
      if (ptstflg (victim, PFL_NOHASSLE) != 0)
	{
	  sendf (caster, "The magic flashes harmlessly past.\n");
	  return False;
	}
      else if (carrobjfrom(victim,sp_shields))
	{
	  sendf (caster, "The spell is absorbed by %s shield!\n", his_or_her (victim));
	  send_msg (ploc (caster), 0, pvis (caster), LVL_MAX, caster, victim,
		    "%s casts a spell on %s. It is absorbed by %s shield!\n",
		    pname (caster), pname (victim), his_or_her (victim));
	  
	  sendf (victim, "%s casts a spell on you. It is absorbed by your shield!\n",
		 see_name (victim, caster));
	  return False;
	}
    }
  
  if (caster == victim)
    {
      sendf (victim, "You're supposed to be killing others, not yourself.\n");
      return False;
    }
  if (!do_okay (caster, victim, PFL_NOHASSLE))
    {
      sendf (caster, "The magic flashes harmlessly past %s.\n", pname (victim));
      return False;
    }
  clev = plev (caster);
  if (spell->maxlev >= 0 && clev > spell->maxlev)
    clev = spell->maxlev;
  
  f = 0;
  if (victim >= max_players)
    {
      /* victim likes the spell? */
      if (spell->like_mflag >= 0 && mtstflg (victim, spell->like_mflag))
	{
	  sendf (caster, spell->like_it, pname (victim));
	  if (pstr (victim) < pstr_reset (victim))
	    setpstr (victim, pstr (victim) + 5);
	  f = -1;
	}
      else if (spell->fear_mflag >= 0 && mtstflg (victim, spell->fear_mflag))
	{
	  /* victim fears the spell, give factor 6 */
	  f = 6;
	}
    }
  if (f == 0)
    {
      /* Find if player is carrying any magical object for this spell */
      for (i = spell->obj3first; i < spell->obj3next; i++)
	{
	  if (iscarrby (ob = spell_enhance[i], caster))
	    break;
	  ob = -1;
	}
      f = (ob >= 0 ? 3 : 2);
    }
  i = (caster >= max_players ? spell->mob_dam : f > 0 ? f * clev : 0);
  
  send_msg (ploc (victim), MODE_NOBATTLE, LVL_MIN, LVL_MAX, caster, NOBODY,
	    spell->to_room, pname (caster));
  if (ststflg(victim, SFL_NOBATTLE)) {
    sendf (victim, spell->to_room, pname (caster));}
  sendf (victim, spell->to_victim, pname (caster));
  send_msg (ploc (victim), MODE_NOBATTLE, LVL_MIN, LVL_MAX, victim, NOBODY,
            spell->to_others, pname (victim));
  wound_player (caster, victim, i, spell_type);
  return True;
}

/*
 * procedure to wound a player.
 * attacker = player index of the attacker.
 * victim   = player index of the victim.
 * damage   = damage caused by the attacker on the victim.
 * hit_type >= 0  verb that caused the magical hit.
 *          <  0  non-magical hit.
 *
 * Return true if victim died.
 */
Boolean wound_player (int attacker, int victim, int damage, int hit_type)
{ int x, q, i;

  if (victim < 0 || victim >= numchars || attacker < 0 ||
      attacker >= numchars)
  {
      return False;
  }
  
  pfighting (victim) = attacker;
  
  if (damage <= 0)
    return False;

  if ((i = p_ohanyflag(victim,OFL_REFLECTMAGIC)) >=0  && hit_type >= 0)
  {  sendf(attacker,"The spell reflects off the %s carried by %s.\n",oname(i),pname(victim));
     i = victim;
     victim = attacker;
     attacker = i;
  } 
  
  if (victim >= max_players)
  {  setpstr (victim, pstr (victim) - damage);
  }
  else if (plev (victim) < LVL_APPREN)
  {  setpstr (victim, pstr (victim) - damage);
     if (attacker >= max_players)
     {  if (mtstflg (attacker, MFL_DSCORE) != 0)
        {  sendf (victim, "You feel weaker as %s's icy touch drains your "
		     "very life force!\n", pname (attacker));
	   setpscore (victim, pscore (victim) - 100 * damage);
	   if ((int)pscore (victim) <= 0)
	   {  setpstr (victim, -1);
	   }
	}
        if (mtstflg(attacker,MFL_DSTRENGTH))
        {   sendf(victim,"\001p%s\003 sucks the strength right out of you.\n",pname(attacker));
            setpstr(victim,pstr(victim) - 3);
        }
     }
  }
  
  if (pstr (victim) >= 0)
  {  if (attacker < max_players &&
        (plev (victim) > LVL_FOUR || victim >= max_players))
     {  setpscore (attacker, pscore (attacker) + damage * 2);
     }
     return False;
  }
  
  
  /* Victim has died */
  
  pfighting (victim) = -1;
  
  if (hit_type >= 0 && hit_type != VERB_ZAP)
  { sendf (attacker, "&+wYour last spell did the trick.&*\n");
  }
  setpstr (victim, -1);
  setpfighting (victim, -1);

  sendf (ploc (victim), "%s has died.\n", pname (victim));
  send_msg (DEST_ALL, MODE_BRACKET | MODE_QUIET | MODE_NOSLAIN, LVL_APPREN, LVL_MAX, NOBODY, NOBODY,
	    "%s has been slain by %s", pname (victim), pname (attacker));
 
  if (the_world->w_tournament)
  {  send_msg (DEST_ALL, MODE_BRACKET, LVL_MIN, LVL_APPREN, NOBODY, NOBODY,
		"%s has died", pname (victim));
  }
  
  if (victim >= max_players)
  {  /* Kill mobile */
     if (attacker < max_players)
     {  setpscore (attacker, pscore (attacker) + 10 * pdam (victim));
     }
     if ((q = find_pretender (victim)) >= 0)
     {  sendf (victim, "*** You have died. ***\n");
        unalias (q);
        unpolymorph (q);
     }

     up_pkilled(victim);

     if (attacker < max_players)
	setpscore (victim, attacker);	/* remember who killed the mobile */
     else
	setpscore (victim, -1);	/* Mobile killing mobile */

      /* Special events ON_KILLED (some quests etc) */
      if (mob_fun(victim) != NULL)
      {  param_s.plx = attacker;
         param_s.pl  = victim;
         param_s.ret = 1;
         param_s.ob = -1;
         param_s.misc = -1;
         param_s.loc = ploc(victim);
         mob_fun(victim)(E_ONKILLED);
         if (param_s.ret != 1)
            return True;
      }

#ifndef LEAVE_CORPSES
      dumpstuff (victim, ploc (victim));
      destroy_mobile(victim);
#else
      if (mtstflg(victim,MFL_NOCORPSE))
      {   dumpstuff(victim,ploc(victim));
          destroy_mobile(victim);
          return True;
      }
      add_corpse_for(victim,attacker);
#endif

      if (ptemporary (victim))
	destruct_mobile (victim, NULL);
  }
  else if (plev (victim) >= LVL_APPREN)
    return False;		/* Wizards don't die */
  else
  {
      /* Kill mortal */
#ifdef LOG_SLAIN/*
      mudlog ("DEATH: %s SLAIN %sby %s", pname (victim),
	      (hit_type < 0 ? "" : "magically "),
	      pname (attacker));*/
#endif
      dumpstuff (victim, ploc (victim));

      if (attacker < max_players &&
	  (the_world->w_tournament || plev (victim) > LVL_FOUR))
      {   x = plev (victim);
	  setpscore (attacker, pscore (attacker) + x * x * x * 10);
      }

#ifdef setpspellpts
      setpspellpts(victim, 0);
#endif

    setpstr (victim, 40);
    setpscore (victim, pscore (victim) - (pscore(victim) * 35) / 100);  /* 35*/

    x = real_mynum;
    setup_globals (victim);

    /* Count of number of deaths */
    if (victim < max_players && !the_world->w_tournament)
    {   up_pdied(victim);
    }    

    if (attacker < max_players && the_world->w_tournament)
    {   up_pkilled(attacker);
    }
       
    /* Tell the world what a wus the player was */
    send_msg (DEST_ALL, 0, pvis (victim), LVL_MAX, victim, NOBODY,
	      "%s &*shouts &+w'Huh huh what a wus, %s couldn't even kill me!'&*\n",
	      pname (attacker), pname (victim));

    calibme ();
    setpfighting(mynum,-1);
    crapup ("\t\tOh dear... you seem to be slightly dead.",
	    CRAP_SAVE | CRAP_RETURN);
    setup_globals (x);

  }
  return True;
}



void combatmessage (int victim, int attacker, int wpn, int ddn)
{ static char *form = "\001p%s\003";
  
  char vic_name[64];
  char att_name[64];
  char weap[64];
  char his[20];
  char hard[64];
  
  if (victim < 0 || attacker < 0 || victim >= numchars ||
      attacker >= numchars)
    return;
  sprintf (vic_name, form, pname (victim));
  sprintf (att_name, form, pname (attacker));
  
  strcpy (his, his_or_her (attacker));
  
  if (wpn >= 0)
    {
      strcpy (weap, oname (wpn));
    }
  else
    {
      strcpy (weap, "bare hands");
    }
  
  if (ddn < 0)
    {				/* Miss */
      sendf (attacker, "You completely missed %s.\n", vic_name);
      sendf (victim, "%s completely missed you.\n", att_name);
      send_msg (ploc (victim), MODE_NOBATTLE, LVL_MIN, LVL_MAX, victim, attacker,
		"%s completely missed %s.\n", att_name, vic_name);
    }
  else if (ddn < 4)
    {
      sendf (attacker, "You hit %s very lightly.\n", vic_name);
      sendf (victim, "%s hit you very lightly.\n", att_name);
      send_msg (ploc (victim), MODE_NOBATTLE, LVL_MIN, LVL_MAX, victim, attacker,
		"%s hit %s very lightly.\n", att_name, vic_name);
    }
  else if (ddn < 7)
    {
      sendf (attacker, "You hit %s lightly.\n", vic_name);
      sendf (victim, "%s hits you lightly.\n", att_name);
      send_msg (ploc (victim), MODE_NOBATTLE, LVL_MIN, LVL_MAX, victim, attacker,
		"%s hit %s lightly.\n", att_name, vic_name);
    }
  else if (ddn < 13)
    {
      sendf (attacker, "You hit %s with your %s.\n", vic_name,weap);
      sendf (victim, "%s hit you with %s %s.\n", att_name,his,weap);
      send_msg (ploc (victim), MODE_NOBATTLE, LVL_MIN, LVL_MAX, victim, attacker,
		"%s hit %s with %s %s.\n", att_name, vic_name, his, weap);
    }
  else
    {
      if (ddn < 17)
	strcpy (hard, " hard");
      else if (ddn < 21)
	strcpy (hard, " very hard");
      else
      {   sendf(attacker,"You completely mutilate %s with your %s.\n",vic_name,weap);
          sendf(victim,"%s completely mutilates you with %s %s.\n",att_name,his,weap);
          send_msg(ploc(victim),MODE_NOBATTLE,LVL_MIN,LVL_MAX,victim,attacker,
                  "%s completely mutilates %s with %s %s.\n",att_name,vic_name,his,
                  weap);
          return;
      }
/*	strcpy (hard, " extremely hard");*/
      sendf (attacker, "You hit %s%s with your %s.\n", vic_name, hard, weap);
      sendf (victim, "%s hit you%s with %s %s.\n", att_name, hard, his, weap);
      send_msg (ploc (victim), MODE_NOBATTLE, LVL_MIN, LVL_MAX, victim, attacker,
		"%s hit %s%s with %s %s.\n",
		att_name, vic_name, hard, his, weap);
    }
}

void setpfighting (int x, int y)
{ int ct, loc = ploc (x);
  
  pfighting (x) = y;
  
  if (y == -1)
    {
      if (exists (loc))
	{
	  for (ct = 0; ct < lnumchars (loc); ct++)
	    {
	      
	      if (pfighting (lmob_nr (ct, loc)) == x)
		{
		  pfighting (lmob_nr (ct, loc)) = -1;
		}
	    }
	}
    }
  else
    {
      pfighting (y) = x;
    }
}

void chkfight (int mon)
{ int plx;
  
  if (mon < max_players || mon >= numchars || 
      (pagg (mon) == 0 && (no_hate(mon))) ||
      ststflg (mon, SFL_OCCUPIED) || EMPTY (pname (mon)) ||
      pstr (mon) < 0 || testpeace (mon) || pfighting (mon) >= 0)	/* Already? */
    return;
  
  /* See if we can hit someone.... */
  for (plx = lfirst_mob (ploc (mon)); plx != SET_END; plx = lnext_mob (ploc (mon)))
  {
      if (plx < max_players && is_in_game (plx) && players[plx].linkdead == False 
	  && !ptstflg (plx, PFL_NOHASSLE) && pvis (plx) == 0)
      {
	  if (mtstflg (mon, MFL_CROSS) &&
	      carries_obj_type (plx, Church_Cross) > -1) 
	    continue;

	  /* moved hate code up to make it more hatelike */
          if (hates_you(mon,plx) && randperc() < (pagg(mon) + 20))
          {  send_hate_msg(mon,plx);
          } 
          else if ( randperc () >= pagg (mon) || 
                   (!hates_you(mon,plx) && pagg(mon) <= 0)
                  )
	  {  continue;
          }
	  else 
	  if (mtstflg (mon, MFL_NOHEAT) && p_ohany (plx, (1 << OFL_LIT)))
	  {
	      sendf (plx,
		     "%s seems disturbed by naked flame, and keeps its distance.\n",
		     pname (mon));
	      continue;
	  }
	  
          /* Drain Level command. */
          if (mtstflg(mon,MFL_DLEVEL) && randperc() < 5 && plev(plx) < LVL_APPREN)
          {  sendf(plx,"The sheer presence of %s drains your life strength!\n",pname(mon));
             setplev(plx,plev(plx) -1);
             continue;
          }
	  hit_player (mon, plx, pwpn (mon));	/* Start the fight */
	} 
    }
}