toc/
toc/account/a/
toc/area/backup/
toc/area/imc/
toc/caste/
toc/caste/backup/
toc/clans/
toc/classes/
toc/crash/
toc/gods/
toc/guilds/
toc/lname/s/
toc/maps/backup/
toc/player/a/
toc/src/
toc/system/backup/
toc/tableprog/
/****************************************************************************
 * [S]imulated [M]edieval [A]dventure multi[U]ser [G]ame      |   \\._.//   *
 * -----------------------------------------------------------|   (0...0)   *
 * SMAUG 1.4 (C) 1994, 1995, 1996, 1998  by Derek Snider      |    ).:.(    *
 * -----------------------------------------------------------|    {o o}    *
 * SMAUG code team: Thoric, Altrag, Blodkai, Narn, Haus,      |   / ' ' \   *
 * Scryn, Rennard, Swordbearer, Gorog, Grishnakh, Nivek,      |~'~.VxvxV.~'~*
 * Tricops and Fireblade                                      |             *
 * ------------------------------------------------------------------------ *
 * Merc 2.1 Diku Mud improvments copyright (C) 1992, 1993 by Michael        *
 * Chastain, Michael Quan, and Mitchell Tse.                                *
 * Original Diku Mud copyright (C) 1990, 1991 by Sebastian Hammer,          *
 * Michael Seifert, Hans Henrik St{rfeldt, Tom Madsen, and Katja Nyboe.     *
 * ------------------------------------------------------------------------ *
 *			    Battle & death module			    *
 ****************************************************************************/

#include <sys/types.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include "mud.h"


extern char lastplayercmd[MIL];
extern CHAR_DATA *gch_prev;
extern int barena;

int blockdam;
int g_tohit;
int g_roll;
int g_lowtohit;
int g_hitohit;

/*
 * Local functions.
 */
void new_dam_message args((CHAR_DATA * ch, CHAR_DATA * victim, int dam, int dt, OBJ_DATA * obj, int spec, int limb));
void death_cry args((CHAR_DATA * ch));
void group_gain args((CHAR_DATA * ch, CHAR_DATA * victim));
int xp_compute args((CHAR_DATA * gch, CHAR_DATA * victim));
int align_compute args((CHAR_DATA * gch, CHAR_DATA * victim));
ch_ret one_hit args((CHAR_DATA * ch, CHAR_DATA * victim, int dt, int limb));
int obj_hitroll args((OBJ_DATA * obj));
void show_condition args((CHAR_DATA * ch, CHAR_DATA * victim));

/*
 * Check to see if player's attacks are (still?) suppressed
 * #ifdef TRI
 */
bool is_attack_supressed(CHAR_DATA * ch)
{
   TIMER *timer;

   if (IS_NPC(ch))
      return FALSE;

   timer = get_timerptr(ch, TIMER_ASUPRESSED);

   if (!timer)
      return FALSE;

   /* perma-supression -- bard? (can be reset at end of fight, or spell, etc) */
   if (timer->value == -1)
      return TRUE;

   /* this is for timed supressions */
   if (timer->count >= 1)
      return TRUE;

   return FALSE;
}

int get_empty_limb(CHAR_DATA *victim)
{
   int limb;
   
   if(get_eq_char(victim, WEAR_NECK) == NULL)
   {
      limb = LM_NECK;
      return limb;
   }
   if(get_eq_char(victim, WEAR_HEAD) == NULL)
   {
      limb = LM_HEAD;
      return limb;
   }         
   if(get_eq_char(victim, WEAR_BODY) == NULL)
   {
      limb = LM_BODY;
      return limb;
   }
   if(get_eq_char(victim, WEAR_ARM_R) == NULL)
   {
      limb = LM_RARM;
      return limb;
   }
   if(get_eq_char(victim, WEAR_ARM_L) == NULL)
   {
      limb = LM_LARM;
      return limb;
   }
   if(get_eq_char(victim, WEAR_LEG_R) == NULL)
   {
      limb = LM_RLEG;
      return limb;
   }
   if(get_eq_char(victim, WEAR_LEG_L) == NULL)
   {
      limb = LM_LLEG;
      return limb;
   }
   return -1;
}

int get_random_limb(CHAR_DATA *victim, int rnum)
{
   int limb = LM_BODY;
   
   if(rnum == 1)
      limb = LM_RARM;
   if(rnum == 2)
      limb = LM_LARM;
   if(rnum == 3)
      limb = LM_RLEG;
   if(rnum == 4)
      limb = LM_LLEG;
   if(rnum == 5)
      limb = LM_BODY;
   if(rnum == 6)
      limb = LM_HEAD;
   if(rnum == 7)
     limb = LM_NECK;
                
   return limb;
}

int get_weapon_limb(CHAR_DATA *victim)
{
   int limb;
   
   if (IS_NPC(victim))
      return -1;
      
   if (get_eq_char(victim, WEAR_WIELD) != NULL)
   {
      if (victim->pcdata->righthanded == 1)
         limb = LM_RARM;
      else
         limb = LM_LARM;
      return limb;
   }
   else
      return -1;
}

int get_tohit_diff(CHAR_DATA *ch, CHAR_DATA *victim, int wear, int type)
{
    OBJ_DATA *weapon;
    OBJ_DATA *armor;
    int bashmod = 0;
    int slashmod = 0;
    int stabmod = 0;
    
    weapon = get_eq_char(ch, WEAR_WIELD);
    if (!weapon)
    {
       bashmod += ch->tohitbash;
       stabmod += ch->tohitstab;
       slashmod += ch->tohitslash;
    }
    else
    {
       bashmod += weapon->value[7];
       stabmod += weapon->value[9];
       slashmod += weapon->value[8];
    }
    armor = get_eq_char(victim, wear);
    if (!armor && IS_NPC(victim))
    {
       bashmod -= victim->armor;
       stabmod -= victim->armor;
       slashmod -= victim->armor;
    }
    else if (armor)
    {
       bashmod -= armor->value[0];
       stabmod -= armor->value[2];
       slashmod -= armor->value[1];
    }
    if (bashmod > stabmod && bashmod > slashmod)
    {
       if (type == 1)
          return bashmod;
       else
          return GRIP_BASH;    
    }
    if (stabmod > bashmod && stabmod > slashmod)
    {
       if (type == 1)
          return stabmod;
       else
          return GRIP_STAB;  
    }
    if (slashmod > stabmod && slashmod > bashmod)
    {
       if (type == 1)
          return slashmod;
       else
          return GRIP_SLASH;  
    }
    if (bashmod == slashmod || bashmod == stabmod)
    {
       if (type == 1)
          return bashmod;
       else
          return GRIP_BASH;  
    }
          
    if (stabmod == slashmod)
    {
       
       if (type == 1)
          return slashmod;
       else
          return GRIP_SLASH;            
    }      
    
    if (type == 1)
       return -30;
    else
       return GRIP_BASH;
}
    
int get_best_grip(CHAR_DATA *ch, CHAR_DATA *victim)
{
   int grip = GRIP_BASH;
   int diff = -30;
   
   grip = get_tohit_diff(ch, victim, WEAR_NECK, 2);
   diff = get_tohit_diff(ch, victim, WEAR_NECK, 1);
   if (get_tohit_diff(ch, victim, WEAR_HEAD, 1) > diff)
   {
      diff = get_tohit_diff(ch, victim, WEAR_HEAD, 1);
      grip = get_tohit_diff(ch, victim, WEAR_HEAD, 2);
   }
   if (get_tohit_diff(ch, victim, WEAR_ARM_R, 1) > diff)
   {
      diff = get_tohit_diff(ch, victim, WEAR_ARM_R, 1); 
      grip = get_tohit_diff(ch, victim, WEAR_ARM_R, 2);
   }
   if (get_tohit_diff(ch, victim, WEAR_ARM_L, 1) > diff)
   {
      diff = get_tohit_diff(ch, victim, WEAR_ARM_L, 1);
      grip = get_tohit_diff(ch, victim, WEAR_ARM_L, 2);
   }
   if (get_tohit_diff(ch, victim, WEAR_LEG_R, 1) > diff)
   {
      diff = get_tohit_diff(ch, victim, WEAR_LEG_R, 1);
      grip = get_tohit_diff(ch, victim, WEAR_LEG_R, 2);
   }
   if (get_tohit_diff(ch, victim, WEAR_LEG_L, 1) > diff)
   {
      diff = get_tohit_diff(ch, victim, WEAR_LEG_L, 1);
      grip = get_tohit_diff(ch, victim, WEAR_LEG_L, 2);
   }
   if (get_tohit_diff(ch, victim, WEAR_BODY, 1) > diff)
   {
      diff = get_tohit_diff(ch, victim, WEAR_BODY, 1);
      grip = get_tohit_diff(ch, victim, WEAR_BODY, 2);
   } 
   return grip;
}       
    
int get_best_diff(CHAR_DATA *ch, CHAR_DATA *victim, int type)
{
   int diff = -30;
   int limb = LM_BODY;
   
   diff = get_tohit_diff(ch, victim, WEAR_NECK, 1);
   limb = LM_NECK;
   if (get_tohit_diff(ch, victim, WEAR_HEAD, 1) > diff)
   {
      diff = get_tohit_diff(ch, victim, WEAR_HEAD, 1);
      limb = LM_HEAD;
   }
   if (get_tohit_diff(ch, victim, WEAR_ARM_R, 1) > diff)
   {
      diff = get_tohit_diff(ch, victim, WEAR_ARM_R, 1);
      limb = LM_RARM;
   }
   if (get_tohit_diff(ch, victim, WEAR_ARM_L, 1) > diff)
   {
      diff = get_tohit_diff(ch, victim, WEAR_ARM_L, 1);
      limb = LM_LARM;
   }
   if (get_tohit_diff(ch, victim, WEAR_LEG_R, 1) > diff)
   {
      diff = get_tohit_diff(ch, victim, WEAR_LEG_R, 1);
      limb = LM_RLEG;
   }
   if (get_tohit_diff(ch, victim, WEAR_LEG_L, 1) > diff)
   {
      diff = get_tohit_diff(ch, victim, WEAR_LEG_L, 1);
      limb = LM_LLEG;
   }
   if (get_tohit_diff(ch, victim, WEAR_BODY, 1) > diff)
   {
      diff = get_tohit_diff(ch, victim, WEAR_BODY, 1);
      limb = LM_BODY;
   }
   
   if (type == 1)
      return diff;
   else
      return limb;   
}  

void do_emptycorpses(CHAR_DATA *ch, char *argument)
{
   OBJ_DATA *corpse;
   OBJ_DATA *contents;
   OBJ_DATA *next_content;
   
   for (corpse = ch->in_room->first_content; corpse; corpse = corpse->next_content)
   {
      if (IN_SAME_ROOM_OBJ(ch, corpse))
      {
         if (corpse->item_type == ITEM_CORPSE_NPC)
         {
            for (contents = corpse->first_content; contents; contents = next_content)
            {
               next_content = contents->next_content;
               obj_from_obj(contents);
               obj_to_room(contents, ch->in_room, ch);
            }
         }
      }
   }
   send_to_char("All NPC corpses in this room are now empty.\n\r", ch);
   return;
}

/* Target Limb choosing function */
int target_chooser(CHAR_DATA * ch, CHAR_DATA * victim )
{
    int mobint, mobwis, rnum, limb;
    OBJ_DATA *weapon;
    int diff;
    
    /*
    LM_RARM
    LM_LARM
    LM_RLEG
    LM_LLEG
    LM_BODY
    LM_HEAD
    LM_NECK
    */
    mobint = get_curr_int(ch);
    mobwis = get_curr_wis(ch);
    
    if ((ch->pIndexData->vnum >= OVERLAND_LOW_MOB && ch->pIndexData->vnum <= OVERLAND_HI_MOB) && ch->m1 == 1) //can just set the stats low, but incase
    {
       limb = LM_BODY;
       return limb;
    }
    if(mobint < 8) //target body
    {
       limb = LM_BODY;
       return limb;
    }
    if(mobint >= 8 && mobint <= 11) //target random part
    {
       rnum = number_range(1,7);
       limb = get_random_limb(victim, rnum);
       return limb;
    }
    if ((weapon = get_eq_char(ch, WEAR_WIELD)) != NULL)
    {      
       if (weapon->value[7] > weapon->value[8] && weapon->value[7] > weapon->value[9])
          ch->grip = GRIP_BASH;
       if (weapon->value[8] > weapon->value[7] && weapon->value[8] > weapon->value[9])
          ch->grip = GRIP_SLASH;
       if (weapon->value[9] > weapon->value[7] && weapon->value[9] > weapon->value[8])
          ch->grip = GRIP_STAB;
       if (weapon->value[7] == weapon->value[8] || weapon->value[7] == weapon->value[9])
          ch->grip = GRIP_BASH;
       if (weapon->value[8] == weapon->value[9])
          ch->grip = GRIP_SLASH;
    }
    if(mobint >= 12 && mobint <= 14) //target empty limb or random part
    {
       limb = get_empty_limb(victim);
       if (limb < 0)
       {
          rnum = number_range(1,7);
          limb = get_random_limb(victim, rnum);
       }
       return limb;
    }
    if (mobint >= 15 && mobint <= 17) //target empty slots, weapon hand, or random part
    {
        if (mobwis < 15)
        {
           limb = get_empty_limb(victim);
           if (limb < 0)
              limb = get_weapon_limb(victim);
           if (limb < 0)
           {
              rnum = number_range(1,7);
              limb = get_random_limb(victim, rnum);
           }          
           return limb;
        }
        else //target arms or legs instead of rest of target (if no weapon/empty slots)
        {          
           limb = get_empty_limb(victim);
           if (limb < 0)
           {
              if (number_range(1, 5) <= 2)
              {
                 limb = get_weapon_limb(victim);
              }
           }
           if (limb < 0)
           {
              rnum = number_range(1,4);
              limb = get_random_limb(victim, rnum);
           }    
        }
        return limb;
     }
     if (mobint >= 18 && mobint <= 21) //target limb based on equipment matchups, higher the wisdom, the better it can matchup
     {
        if (mobwis < 18)
        {
           limb = get_empty_limb(victim);
           if (limb < 0)
           {
              diff = get_best_diff(ch, victim, 1);
              if (diff >= 3)
              {
                 limb = get_best_diff(ch, victim, 2);
                 ch->grip = get_best_grip(ch, victim);
              }
           }
           if (limb < 0)
           {
              if (number_range(1, 5) >= 3)
                 limb = get_weapon_limb(victim);
           }
           if (limb < 0)
           {
              rnum = number_range(1,4);
              limb = get_random_limb(victim, rnum);
           }
           return limb;
        }
        else
        {  
           limb = get_empty_limb(victim);
           if (limb < 0)
           {
              diff = get_best_diff(ch, victim, 1);
              if (diff >= 1)
              {
                 limb = get_best_diff(ch, victim, 2);
                 ch->grip = get_best_grip(ch, victim);
              }
           }
           if (limb < 0)
              limb = get_weapon_limb(victim);
           if (limb < 0)
           {
              rnum = number_range(1,4);
              limb = get_random_limb(victim, rnum);
           }
           return limb;
        }
     }
     if (mobint > 21)  //Target best possible limb, high wisdom mobs will make BEST decision possible
     {
        if (mobwis < 22)
        {
           limb = get_empty_limb(victim);
           if (limb < 0)
           {
              diff = get_best_diff(ch, victim, 1);
              limb = get_best_diff(ch, victim, 2);
              ch->grip = get_best_grip(ch, victim);
           }
           return limb;
        }
        else
        {
           limb = get_empty_limb(victim); //empty slot?
           if (limb < 0) //Good armor target?
           {
              diff = get_best_diff(ch, victim, 1);
              if (diff >= 1)
              {
                 limb = get_best_diff(ch, victim, 2);
                 ch->grip = get_best_grip(ch, victim);
              }
           }
           if (limb < 0) //Hurt limb?
           {
              if (victim->con_larm < 400 || victim->con_rarm < 400 || victim->con_rleg < 400 || victim->con_rleg < 400) //target hurt limbs
              {
                 if (victim->con_rleg < 400 && victim->con_rleg <= victim->con_lleg && victim->con_rleg <= victim->con_rarm
                 && victim->con_rleg <= victim->con_larm)
                    return LM_RLEG;
                 
                 if (victim->con_lleg < 400 && victim->con_lleg <= victim->con_rleg && victim->con_lleg <= victim->con_rarm
                 && victim->con_lleg <= victim->con_larm)
                    return LM_LLEG;
                 
                 if (!IS_NPC(victim) && victim->pcdata->righthanded == 0) //in case of a tie target the wielding limb
                 {
                    if (victim->con_rarm < 400 && victim->con_rarm <= victim->con_larm && victim->con_rarm <= victim->con_rleg
                    && victim->con_rarm <= victim->con_lleg)
                       return LM_RARM;
                    
                    if (victim->con_larm < 400 && victim->con_larm <= victim->con_rarm && victim->con_larm <= victim->con_rleg
                    && victim->con_larm <= victim->con_lleg)
                       return LM_LARM;
                 }
                 else
                 {                 
                    if (victim->con_larm < 400 && victim->con_larm <= victim->con_rarm && victim->con_larm <= victim->con_rleg
                    && victim->con_larm <= victim->con_lleg)
                       return LM_LARM;
                    
                    if (victim->con_rarm < 400 && victim->con_rarm <= victim->con_larm && victim->con_rarm <= victim->con_rleg
                    && victim->con_rarm <= victim->con_lleg)
                       return LM_RARM;
                 }
              }
           }
           if (limb < 0) //damaged eq?
           {
              OBJ_DATA *eq;
              if (((eq = get_eq_char(victim, WEAR_NECK)) != NULL) && eq->value[3] < 300)
                 return LM_NECK;
              if (((eq = get_eq_char(victim, WEAR_HEAD)) != NULL) && eq->value[3] < 300)          
                 return LM_HEAD;
              if (!IS_NPC(victim) && victim->pcdata->righthanded == 0)
              {
                 if (((eq = get_eq_char(victim, WEAR_ARM_R)) != NULL) && eq->value[3] < 300)
                    return LM_RARM;
              }
              else
              {
                 if (((eq = get_eq_char(victim, WEAR_ARM_L)) != NULL) && eq->value[3] < 300)               
                     return LM_LARM;
              }
              if (((eq = get_eq_char(victim, WEAR_LEG_R)) != NULL) && eq->value[3] < 300)
                 return LM_RLEG;
              if (((eq = get_eq_char(victim, WEAR_LEG_L)) != NULL) && eq->value[3] < 300)
                 return LM_LLEG;
              if (((eq = get_eq_char(victim, WEAR_BODY)) != NULL) && eq->value[3] < 300)
                 return LM_BODY;
           }
           if (limb < 0) //all else fails just find the best
           {
              limb = get_best_diff(ch, victim, 2);
              ch->grip = get_best_grip(ch, victim);
              return limb;
           }
           return limb;
        }
     }
     return LM_BODY;
}

/*
 * Check to see if weapon is poisoned.
 */
bool is_wielding_poisoned(CHAR_DATA * ch)
{
   OBJ_DATA *obj;

   if ((obj = get_eq_char(ch, WEAR_WIELD)) != NULL && IS_OBJ_STAT(obj, ITEM_POISONED))
      return TRUE;

   return FALSE;
}

/*
 * hunting, hating and fearing code				-Thoric
 */
bool is_hunting(CHAR_DATA * ch, CHAR_DATA * victim)
{
   if (!ch->hunting || ch->hunting->who != victim)
      return FALSE;

   return TRUE;
}

bool is_hating(CHAR_DATA * ch, CHAR_DATA * victim)
{
   if (!ch->hating || ch->hating->who != victim)
      return FALSE;

   return TRUE;
}

bool is_fearing(CHAR_DATA * ch, CHAR_DATA * victim)
{
   if (!ch->fearing || ch->fearing->who != victim)
      return FALSE;

   return TRUE;
}

void stop_hunting(CHAR_DATA * ch)
{
   if (ch->hunting)
   {
      STRFREE(ch->hunting->name);
      DISPOSE(ch->hunting);
      ch->hunting = NULL;
   }
   return;
}

void stop_hating(CHAR_DATA * ch)
{
   if (ch->hating)
   {
      STRFREE(ch->hating->name);
      DISPOSE(ch->hating);
      ch->hating = NULL;
   }
   return;
}

void stop_fearing(CHAR_DATA * ch)
{
   if (ch->fearing)
   {
      STRFREE(ch->fearing->name);
      DISPOSE(ch->fearing);
      ch->fearing = NULL;
   }
   return;
}

void start_hunting(CHAR_DATA * ch, CHAR_DATA * victim)
{
   if (!IS_NPC(ch))
      return;
   if (ch->hunting)
      stop_hunting(ch);

   CREATE(ch->hunting, HHF_DATA, 1);
   ch->hunting->name = QUICKLINK(victim->name);
   ch->hunting->who = victim;
   return;
}

void start_hating(CHAR_DATA * ch, CHAR_DATA * victim)
{
   if (!IS_NPC(ch))
      return;
   if (ch->hating)
      stop_hating(ch);

   CREATE(ch->hating, HHF_DATA, 1);
   ch->hating->name = QUICKLINK(victim->name);
   ch->hating->who = victim;
   return;
}

void start_fearing(CHAR_DATA * ch, CHAR_DATA * victim)
{
   if (!IS_NPC(ch))
      return;
   if (ch->fearing)
      stop_fearing(ch);

   CREATE(ch->fearing, HHF_DATA, 1);
   ch->fearing->name = QUICKLINK(victim->name);
   ch->fearing->who = victim;
   return;
}

/*
 * Get the current armor class for a vampire based on time of day
 */
sh_int VAMP_AC(CHAR_DATA * ch)
{
   if (IS_VAMPIRE(ch) && IS_OUTSIDE(ch))
   {
      switch (time_info.sunlight)
      {
         case SUN_DARK:
            return -10;
         case SUN_RISE:
            return 5;
         case SUN_LIGHT:
            return 10;
         case SUN_SET:
            return 2;
         default:
            return 0;
      }
   }
   else
      return 0;
}

int max_fight(CHAR_DATA * ch)
{
   return 20;
}

bool has_artifact(CHAR_DATA * ch)
{
   OBJ_DATA *obj;

   if (xIS_SET(ch->in_room->room_flags, ROOM_TSAFE))
      return FALSE;
   for (obj = ch->last_carrying; obj; obj = obj->prev_content)
   {
      if (IS_OBJ_STAT(obj, ITEM_ARTIFACT)) //Found the artifact
         return TRUE;
   }
   return FALSE;
}

void do_stack(CHAR_DATA *ch, char *argument)
{
   char buf[MSL];
   if (check_npc(ch))
      return;   
      
    if (strlen(argument) + strlen(ch->pcdata->stackbuf) >= MSL-5)
    {
       send_to_char("You can only have roughly 4000 characters in your command stack, clear it if there is a problem.\n\n", ch);
       return;
    }
    if (argument[0] == '\0')
    {
       send_to_char("You must provide an argument.\n\r", ch);
       return;
    }
    sprintf(buf, "/%s/", argument);;
       
    strcat(ch->pcdata->stackbuf, buf);
    return;
}

void do_clearstack(CHAR_DATA *ch, char *argument)
{
   if (check_npc(ch))
      return; 
      
    strcpy(ch->pcdata->stackbuf, "");
    send_to_char("Cleared.\n\r", ch);
    return;
}
    
void parse_attack_buffer(char *fullbuf, char *cbuf)
{
   int x = 0;
   int z = 0;
   int cnt = 0;
   char buf[MSL];
   int y = 0;
   for (;;)
   {
      if (fullbuf[x] == '\0')
      {
         strcpy(fullbuf, "");
         strcpy(cbuf, "");
         return;
      }
      if (fullbuf[x] == '/')
      {
         cnt++;
         if (cnt == 2)
         {
            cbuf[z] = '\0';
            x++;
            for (;;)
            {
               if (fullbuf[x] != '\0')
                   buf[y++] = fullbuf[x++];
               else
                   break;
            }
            buf[y] = '\0';
            sprintf(fullbuf, buf);
            return;
         }
         x++;
      }
      else
      {
         cbuf[z++] = fullbuf[x++];
      }
   }
}
      

/*
 * Control the fights going on.
 * Called periodically by update_handler.
 * Many hours spent fixing bugs in here by Thoric, as noted by residual
 * debugging checks.  If you never get any of these error messages again
 * in your logs... then you can comment out some of the checks without
 * worry.
 *
 * Note:  This function also handles some non-violence updates.
 */
void violence_update(void)
{
   char buf[MSL];
   CHAR_DATA *ch;
   CHAR_DATA *lst_ch;
   CHAR_DATA *ich;
   CHAR_DATA *victim;
   CHAR_DATA *rch, *rch_next;
   TIMER *timer, *timer_next;
   ch_ret retcode;
   OBJ_DATA *shield;
   int attacktype, cnt;
   static int pulse = 0;
   int range;
   AGGRO_DATA *aggro;
   AGGRO_DATA *naggro;
   int haggro = -1;
   char abuf[100];
   char target[10];
   char commandbuf[MSL];

   lst_ch = NULL;
   pulse = (pulse + 1) % 100;

   for (ch = last_char; ch; lst_ch = ch, ch = gch_prev)
   {
      set_cur_char(ch);

      if (ch == first_char && ch->prev)
      {
         bug("ERROR: first_char->prev != NULL, fixing...", 0);
         ch->prev = NULL;
      }

      gch_prev = ch->prev;

      if (gch_prev && gch_prev->next != ch)
      {
         if (!ch->name)
         {
            bug("short-cutting");
            UNLINK(ch, first_char, last_char, next, prev);
            continue;
         }
         sprintf(buf, "FATAL: violence_update: %s->prev->next doesn't point to ch.", ch->name);
         bug(buf, 0);
         bug("Short-cutting here", 0);
         ch->prev = NULL;
         gch_prev = NULL;
         do_shout(ch, "Thoric says, 'Prepare for the worst!'");
      }

      /*
       * See if we got a pointer to someone who recently died...
       * if so, either the pointer is bad... or it's a player who
       * "died", and is back at the healer...
       * Since he/she's in the char_list, it's likely to be the later...
       * and should not already be in another fight already
       */
      if (char_died(ch))
         continue;

      /*
       * See if we got a pointer to some bad looking data...
       */
      if (!ch->in_room || !ch->name)
      {
         log_string("violence_update: bad ch record!  (Shortcutting.)");
         sprintf(buf, "ch: %d  ch->in_room: %d  ch->prev: %d  ch->next: %d", (int) ch, (int) ch->in_room, (int) ch->prev, (int) ch->next);
         log_string(buf);
         log_string(lastplayercmd);
         if (lst_ch)
            sprintf(buf, "lst_ch: %d  lst_ch->prev: %d  lst_ch->next: %d", (int) lst_ch, (int) lst_ch->prev, (int) lst_ch->next);
         else
            strcpy(buf, "lst_ch: NULL");
         log_string(buf);
         gch_prev = NULL;
         continue;
      }

      /*
       * Experience gained during battle deceases as battle drags on
       */
      if (ch->fighting)
         if ((++ch->fighting->duration % 24) == 0)
            ch->fighting->xp = ((ch->fighting->xp * 9) / 10);

      if (ch->fighting && ch->fighting->who && ch->fighting->who->name)
      {     
         int hking;
         int iking;
         
         if (IS_NPC(ch->fighting->who))
            hking = ch->fighting->who->m4;
         else
            hking = ch->fighting->who->pcdata->hometown;
            
         for (ich = ch->in_room->first_person; ich; ich = ich->next_in_room)
         {
            if (ich == ch)
               continue;
            range = ich->m5;
            if (IS_NPC(ich))
               iking = ich->m4;
            else
               iking = ich->pcdata->hometown;
                  
            if (IN_WILDERNESS(ch))
            {
               if (abs(ich->coord->x - ch->coord->x) <= range && abs(ich->coord->y - ch->coord->y) <= range && ich->map == ch->map)
               {
                  if (IS_NPC(ich) && ch->fighting && !ich->hating && !ich->hunting && !ich->fighting && ch->fighting->who != ich
                     && number_range(1, 100) <= 70 && xIS_SET(ich->act, ACT_MILITARY) && !xIS_SET(ich->miflags, KM_NOASSIST)
                     && can_see_map(ich, ch->fighting->who) && hking != iking && !is_safe(ich, ch->fighting->who))
                  {
                     start_hating(ich, ch->fighting->who);
                     start_hunting(ich, ch->fighting->who);
                     break;
                  }
               }
            }
            else
            {
               if (IS_NPC(ich) && ch->fighting && !ich->hating && !ich->hunting && !ich->fighting && ch->fighting->who != ich
                  && number_range(1, 100) <= 70 && xIS_SET(ich->act, ACT_MILITARY) && !xIS_SET(ich->miflags, KM_NOASSIST)
                  && can_see_map(ich, ch->fighting->who) && hking != iking && !is_safe(ich, ch->fighting->who))
               {
                  start_hating(ich, ch->fighting->who);
                  start_hunting(ich, ch->fighting->who);
                  break;
               }
            }
         }
      }
      for (timer = ch->first_timer; timer; timer = timer_next)
      {
         timer_next = timer->next;
         if (--timer->count <= 0)
         {
            if (timer->type == TIMER_ASUPRESSED)
            {
               if (timer->value == -1)
               {
                  timer->count = 1000;
                  continue;
               }
            }
            if (timer->type == TIMER_NUISANCE)
            {
               DISPOSE(ch->pcdata->nuisance);
            }

            if (timer->type == TIMER_DO_FUN)
            {
               int tempsub;

               tempsub = ch->substate;
               ch->substate = timer->value;
               (timer->do_fun) (ch, "");
               if (char_died(ch))
                  break;
               ch->substate = tempsub;
            }
            extract_timer(ch, timer);
         }
      }

      if (char_died(ch))
         continue;
      
      /*
      for (aggro = ch->first_aggro; aggro; aggro = aggro->next)
      {
         if (aggro->ch)
            bug("%d > %s", aggro->value, aggro->ch->name);
      }
      */
         
      for (aggro = ch->first_aggro; aggro; aggro = naggro)
      {
         naggro = aggro->next;
         if (number_range(1, 20) == 1) //10 seconds roughly
            aggro->value-=1;
         if (aggro->value <= 0)
         {
            UNLINK(aggro, ch->first_aggro, ch->last_aggro, next, prev);
            UNLINK(aggro, first_global_aggro, last_global_aggro, next_global, prev_global);
            DISPOSE(aggro);
         }
      }
         
      //Do not attack this round if there is a fight timer
      if (ch->fight_timer > 0)
      {
         ch->fight_timer--;
         if (ch->fight_timer == 0)
            ch->fight_state = 0;
         continue;
      }
      if (IS_NPC(ch) && xIS_SET(ch->act, ACT_NOATTACK))
         continue;

      /* check for exits moving players around */
      if ((retcode = pullcheck(ch, pulse)) == rCHAR_DIED || char_died(ch))
         continue;

      /* Let the battle begin! */

      if ((victim = who_fighting(ch)) == NULL || IS_AFFECTED(ch, AFF_PARALYSIS))
         continue;
         
      if (!IN_SAME_ROOM(ch, victim))
      {
         stop_fighting(ch, FALSE);
         continue;
      }
      
  if( IS_NPC(ch) )
  {
      retcode = rNONE;

      if (is_safe(victim, ch) && !has_artifact(ch) && !has_artifact(victim))
      {
         sprintf(buf, "violence_update: %s fighting %s in a SAFE room.", ch->name, victim->name);
         log_string(buf);
         stop_fighting(ch, TRUE);
      }
      else if (IS_AWAKE(ch) && in_same_room(ch, victim))
      {
         int fired = 0;
         /*
          *  Mob triggers
          */
         rprog_rfight_trigger(ch);
         if (char_died(ch))
            continue;
         mprog_hitprcnt_trigger(ch, victim);
         if (char_died(ch))
            continue;
         mprog_fight_trigger(ch, victim);
         if (char_died(ch))
            continue;
       
         /*
          * NPC special attack flags    -Thoric
          */
         if (IS_NPC(ch))
         {
            if (!xIS_EMPTY(ch->attacks))
            {
               attacktype = -1;
               if (15 >= number_percent())
               {
                  cnt = 0;
                  for (;;)
                  {
                     if (cnt++ > 100)
                     {
                        attacktype = -1;
                        break;
                     }
                     attacktype = number_range(7, MAX_ATTACK_TYPE - 1);
                     if (xIS_SET(ch->attacks, attacktype))
                     {
                        fired = 1;
                        break;
                     }
                  }
                  switch (attacktype)
                  {
                     case ATCK_BASH:
                        break;
                     case ATCK_STUN:
                        do_stun(ch, "");
                        retcode = global_retcode;
                        break;
                     case ATCK_GOUGE:
                        do_gouge(ch, "");
                        retcode = global_retcode;
                        break;
                     case ATCK_FEED:
                        break;
                     case ATCK_DRAIN:
                        break;
                     case ATCK_FIREBREATH:
                        retcode = spell_fire_breath(skill_lookup("fire breath"), ch->level, ch, victim);
                        break;
                     case ATCK_FROSTBREATH:
                        retcode = spell_frost_breath(skill_lookup("frost breath"), ch->level, ch, victim);
                        break;
                     case ATCK_ACIDBREATH:
                        retcode = spell_acid_breath(skill_lookup("acid breath"), ch->level, ch, victim);
                        break;
                     case ATCK_LIGHTNBREATH:
                        retcode = spell_lightning_breath(skill_lookup("lightning breath"), ch->level, ch, victim);
                        break;
                     case ATCK_GASBREATH:
                        retcode = spell_gas_breath(skill_lookup("gas breath"), ch->level, ch, victim);
                        break;
                     case ATCK_SPIRALBLAST:
                        break;
                     case ATCK_POISON:
                        retcode = spell_poison(gsn_poison, ch->level, ch, victim);
                        break;
                     case ATCK_NASTYPOISON:
                        /*
                           retcode = spell_nasty_poison( skill_lookup( "nasty poison" ), ch->level, ch, victim );
                         */
                        break;
                     case ATCK_GAZE:
                        /*
                           retcode = spell_gaze( skill_lookup( "gaze" ), ch->level, ch, victim );
                         */
                        break;
                     case ATCK_BLINDNESS:
                        retcode = spell_blindness(gsn_blindness, ch->level, ch, victim);
                        break;
                     case ATCK_CAUSESERIOUS:
                        retcode = spell_cause_serious(skill_lookup("cause serious"), ch->level, ch, victim);
                        break;
                     case ATCK_EARTHQUAKE:
                        retcode = spell_earthquake(skill_lookup("earthquake"), ch->level, ch, victim);
                        break;
                     case ATCK_CAUSECRITICAL:
                        retcode = spell_cause_critical(skill_lookup("cause critical"), ch->level, ch, victim);
                        break;
                     case ATCK_CURSE:
                        retcode = spell_curse(skill_lookup("curse"), ch->level, ch, victim);
                        break;
                     case ATCK_FLAMESTRIKE:;
                        break;
                     case ATCK_HARM:
                        retcode = spell_harm(skill_lookup("harm"), ch->level, ch, victim);
                        break;
                     case ATCK_FIREBALL:
                        break;
                     case ATCK_COLORSPRAY:
                        break;
                     case ATCK_WEAKEN:
                        retcode = spell_weaken(skill_lookup("weaken"), ch->level, ch, victim);
                        break;
                  }
                  ch->fight_timer = 0;
                  if (attacktype != -1 && (retcode == rCHAR_DIED || char_died(ch)))
                     continue;
               }
            }
            /*
             * NPC special defense flags    -Thoric
             */
            if (!xIS_EMPTY(ch->defenses))
            {
               attacktype = -1;
               if (15 > number_percent())
               {
                  cnt = 0;
                  for (;;)
                  {
                     if (cnt++ > 100)
                     {
                        attacktype = -1;
                        break;
                     }
                     attacktype = number_range(2, MAX_DEFENSE_TYPE - 1);
                     if (xIS_SET(ch->defenses, attacktype))
                     {
                        fired = 1;
                        break;
                     }
                  }
                  switch (attacktype)
                  {
                     case DFND_CURELIGHT:
                        act(AT_MAGIC, "$n mutters a few incantations...and looks a little better.", ch, NULL, NULL, TO_ROOM);
                        retcode = spell_smaug(skill_lookup("cure light"), ch->level, ch, ch);
                        break;
                     case DFND_CURESERIOUS:
                        act(AT_MAGIC, "$n mutters a few incantations...and looks a bit better.", ch, NULL, NULL, TO_ROOM);
                        retcode = spell_smaug(skill_lookup("cure serious"), ch->level, ch, ch);
                        break;
                     case DFND_CURECRITICAL:
                        act(AT_MAGIC, "$n mutters a few incantations...and looks healthier.", ch, NULL, NULL, TO_ROOM);
                        retcode = spell_smaug(skill_lookup("cure critical"), ch->level, ch, ch);
                        break;
                     case DFND_HEAL:
                        act(AT_MAGIC, "$n mutters a few incantations...and looks much healthier.", ch, NULL, NULL, TO_ROOM);
                        retcode = spell_smaug(skill_lookup("heal"), ch->level, ch, ch);
                        break;
                     case DFND_DISPELMAGIC:
                        act(AT_MAGIC, "$n utters an incantation...", ch, NULL, NULL, TO_ROOM);
                        retcode = spell_dispel_magic(skill_lookup("dispel magic"), ch->level, ch, victim);
                        break;
                     case DFND_DISPELEVIL:
                        break;
                     case DFND_SHOCKSHIELD:
                        if (!IS_AFFECTED(ch, AFF_SHOCKSHIELD))
                        {
                           act(AT_MAGIC, "$n utters a few incantations...", ch, NULL, NULL, TO_ROOM);
                           retcode = spell_smaug(skill_lookup("shockshield"), ch->level, ch, ch);
                        }
                        else
                           retcode = rNONE;
                        break;
                     case DFND_FIRESHIELD:
                        if (!IS_AFFECTED(ch, AFF_FIRESHIELD))
                        {
                           act(AT_MAGIC, "$n utters a few incantations...", ch, NULL, NULL, TO_ROOM);
                           retcode = spell_smaug(skill_lookup("fireshield"), ch->level, ch, ch);
                        }
                        else
                           retcode = rNONE;
                        break;
                     case DFND_ICESHIELD:
                        if (!IS_AFFECTED(ch, AFF_ICESHIELD))
                        {
                           act(AT_MAGIC, "$n utters a few incantations...", ch, NULL, NULL, TO_ROOM);
                           retcode = spell_smaug(skill_lookup("iceshield"), ch->level, ch, ch);
                        }
                        else
                           retcode = rNONE;
                        break;
                     case DFND_TRUESIGHT:
                        if (!IS_AFFECTED(ch, AFF_TRUESIGHT))
                           retcode = spell_smaug(skill_lookup("true"), ch->level, ch, ch);
                        else
                           retcode = rNONE;
                        break;
                     case DFND_SANCTUARY:
                        if (!IS_AFFECTED(ch, AFF_SANCTUARY))
                        {
                           act(AT_MAGIC, "$n utters a few incantations...", ch, NULL, NULL, TO_ROOM);
                           retcode = spell_smaug(skill_lookup("sanctuary"), ch->level, ch, ch);
                        }
                        else
                           retcode = rNONE;
                        break;
                  }
                  ch->fight_timer = 0;
                  if (attacktype != -1 && (retcode == rCHAR_DIED || char_died(ch)))
                     continue;
               }
            }
         }
         if (ch->fight_timer > 0)
            continue;
         //Still want it to fire roughly every 12 seconds per unit even if in battle, roughly comes out to about 16 or
         //so seconds with the 65 percent chance.  At 5 units that is roughly a heal every 3 seconds.
         //Mage units will fire at a much faster rate since magic is their primary way of damage and survival
         if (IS_NPC(ch) && xIS_SET(ch->act, ACT_MILITARY) && ch->m4 > 1 && ch->m4 < sysdata.max_kingdom
         &&  ch->fight_timer == 0 && ch->fighting && ch->fighting->who && number_range(1, 24) <= get_btimer(ch, -1, NULL))
         { 
            int csn;
            BUYKMOB_DATA *kmob;
            char snbuf[MSL];
     
            for (kmob = first_buykmob; kmob; kmob = kmob->next)
            {
               if (ch->pIndexData->vnum == kmob->vnum)
               {
                  if (xIS_SET(kmob->flags, KMOB_MAGE))
                  {   
                     if (xIS_SET(kmob->flags, KMOB_MAGEDAMAGE1) || xIS_SET(kmob->flags, KMOB_MAGEDAMAGE2)
                     ||  xIS_SET(kmob->flags, KMOB_MAGEDAMAGE3) || xIS_SET(kmob->flags, KMOB_MAGEDAMAGE4))
                     {
                        int num;
                        for (;;)
                        {
                           num = number_range(1, 4);                           
                           if (num == 1 && xIS_SET(kmob->flags, KMOB_MAGEDAMAGE1))
                           {
                              num = number_range(1, 10);
                              if (num == 1)
                                 csn = skill_lookup("jagged spike");
                              else if (num == 2)
                                 csn = skill_lookup("jagged stone");
                              else if (num == 3)
                                 csn = skill_lookup("fire arrow");
                              else if (num == 4)
                                 csn = skill_lookup("fire blast");
                              else if (num == 5)
                                 csn = skill_lookup("wind chill");
                              else if (num == 6)
                                 csn = skill_lookup("wind gust");
                              else if (num == 7)
                                 csn = skill_lookup("cold ball");
                              else if (num == 8)
                                 csn = skill_lookup("frozen dart");
                              else if (num == 9)
                                 csn = skill_lookup("energy blast");
                              else
                                 csn = skill_lookup("power drain");
                              if (csn <= 0)
                                 continue;
                              sprintf(snbuf, "$n waves $s hands and casts %s on $N", skill_table[csn]->name);
                              act(AT_ACTION, snbuf, ch, NULL, ch->fighting->who, TO_ROOM);
                              spell_smaug(csn, POINT_LEVEL(LEARNED(ch, csn), MASTERED(ch, csn)), ch, ch->fighting->who);
                              break;        
                           }
                           if (num == 2 && xIS_SET(kmob->flags, KMOB_MAGEDAMAGE2))
                           {
                              num = number_range(1, 10);
                              if (num == 1)
                                 csn = skill_lookup("acid blast");
                              else if (num == 2)
                                 csn = skill_lookup("acidic ball");
                              else if (num == 3)
                                 csn = skill_lookup("fire bolt");
                              else if (num == 4)
                                 csn = skill_lookup("scolding blast");
                              else if (num == 5)
                                 csn = skill_lookup("funnel");
                              else if (num == 6)
                                 csn = skill_lookup("wind spike");
                              else if (num == 7)
                                 csn = skill_lookup("frozen ball");
                              else if (num == 8)
                                 csn = skill_lookup("frozen spike");
                              else if (num == 9)
                                 csn = skill_lookup("electric blast");
                              else
                                 csn = skill_lookup("energy drain");
                              if (csn <= 0)
                                 continue;
                              sprintf(snbuf, "$n waves $s hands and casts %s on $N", skill_table[csn]->name);
                              act(AT_ACTION, snbuf, ch, NULL, ch->fighting->who, TO_ROOM);
                              spell_smaug(csn, POINT_LEVEL(LEARNED(ch, csn), MASTERED(ch, csn)), ch, ch->fighting->who);
                              break;        
                           }
                           if (num == 3 && xIS_SET(kmob->flags, KMOB_MAGEDAMAGE3))
                           {
                              num = number_range(1, 10);
                              if (num == 1)
                                 csn = skill_lookup("acidic blast");
                              else if (num == 2)
                                 csn = skill_lookup("earth clamp");
                              else if (num == 3)
                                 csn = skill_lookup("blazing burst");
                              else if (num == 4)
                                 csn = skill_lookup("fireball");
                              else if (num == 5)
                                 csn = skill_lookup("tornado");
                              else if (num == 6)
                                 csn = skill_lookup("blitzing wave");
                              else if (num == 7)
                                 csn = skill_lookup("frigid ball");
                              else if (num == 8)
                                 csn = skill_lookup("frozen blast");
                              else if (num == 9)
                                 csn = skill_lookup("deanimation");
                              else
                                 csn = skill_lookup("jolting burst");
                              if (csn <= 0)
                                 continue;
                              sprintf(snbuf, "$n waves $s hands and casts %s on $N", skill_table[csn]->name);
                              act(AT_ACTION, snbuf, ch, NULL, ch->fighting->who, TO_ROOM);
                              spell_smaug(csn, POINT_LEVEL(LEARNED(ch, csn), MASTERED(ch, csn)), ch, ch->fighting->who);
                              break;        
                           }
                           if (num == 4 && xIS_SET(kmob->flags, KMOB_MAGEDAMAGE4))
                           {
                              num = number_range(1, 10);
                              if (num == 1)
                                 csn = skill_lookup("acidic oblivion");
                              else if (num == 2)
                                 csn = skill_lookup("demolic blast");
                              else if (num == 3)
                                 csn = skill_lookup("dancing fire");
                              else if (num == 4)
                                 csn = skill_lookup("eradication");
                              else if (num == 5)
                                 csn = skill_lookup("heavenly blast");
                              else if (num == 6)
                                 csn = skill_lookup("meteor");
                              else if (num == 7)
                                 csn = skill_lookup("frigid death");
                              else if (num == 8)
                                 csn = skill_lookup("tidal wave");
                              else if (num == 9)
                                 csn = skill_lookup("molecular degeneration");
                              else
                                 csn = skill_lookup("quantum spike");
                              if (csn <= 0)
                                 continue;
                              sprintf(snbuf, "$n waves $s hands and casts %s on $N", skill_table[csn]->name);
                              act(AT_ACTION, snbuf, ch, NULL, ch->fighting->who, TO_ROOM);
                              spell_smaug(csn, POINT_LEVEL(LEARNED(ch, csn), MASTERED(ch, csn)), ch, ch->fighting->who);
                              break;        
                           }
                        }
                        break;
                     }            
                  }              
                  if (xIS_SET(kmob->flags, KMOB_CLERIC))
                  {
                     CHAR_DATA *rch;
                     int num = number_range(1, 20);  
                     if (num > 13 && (xIS_SET(kmob->flags, KMOB_HARM) || xIS_SET(kmob->flags, KMOB_CLERICDAMAGE)))
                     {
                        num = number_range(1, 2);
                        
                        if (num == 1 && xIS_SET(kmob->flags, KMOB_HARM))
                        {
                           csn = skill_lookup("harm");
                           if (csn <= 0)
                              continue;
                           act(AT_ACTION, "$n waves $s hands and casts harm on $N.", ch, NULL, ch->fighting->who, TO_ROOM);
                           spell_harm(csn, POINT_LEVEL(LEARNED(ch, csn), MASTERED(ch, csn)), ch, ch->fighting->who);
                           break;      
                        }
                        if (num == 2 && xIS_SET(kmob->flags, KMOB_CLERICDAMAGE))
                        {
                           num = number_range(1, 5);
                           if (num == 1)
                              csn = skill_lookup("gurori");
                           else if (num == 2)
                              csn = skill_lookup("furori");
                           else if (num == 3)
                              csn = skill_lookup("aurori");
                           else if (num == 4)
                              csn = skill_lookup("wurori");
                           else
                              csn = skill_lookup("eurori");
                           if (csn <= 0)
                              continue;
                           sprintf(snbuf, "$n waves $s hands and casts %s on $N", skill_table[csn]->name);
                           act(AT_ACTION, snbuf, ch, NULL, ch->fighting->who, TO_ROOM);
                           spell_smaug(csn, POINT_LEVEL(LEARNED(ch, csn), MASTERED(ch, csn)), ch, ch->fighting->who);
                           break;      
                        }
                     }                                    
                     if (num <= 13 && (xIS_SET(kmob->flags, KMOB_CURELIGHT) || xIS_SET(kmob->flags, KMOB_CURESERIOUS)
                     || xIS_SET(kmob->flags, KMOB_CURECRITICAL) || xIS_SET(kmob->flags, KMOB_HEAL) 
                     || xIS_SET(kmob->flags, KMOB_DIVINITY) || xIS_SET(kmob->flags, KMOB_POWERHEAL)))
                     {
                        for (rch = ch->in_room->first_person; rch; rch = rch->next_in_room)
                        {
                           if (in_same_room(ch, rch) && IS_NPC(rch) && rch->m4 == ch->m4 && rch->hit < rch->max_hit)
                           { 
                              for (;;)
                              {
                                 num = number_range(1, 6);
                           
                                 if (num == 1 && xIS_SET(kmob->flags, KMOB_CURELIGHT))
                                 {
                                     csn = skill_lookup("cure light");
                                    if (csn <= 0)
                                       continue;
                                     spell_smaug(csn, POINT_LEVEL(LEARNED(ch, csn), MASTERED(ch, csn)), ch, rch);
                                     act(AT_ACTION, "$n waves $s hands and casts cure light on $N.", ch, NULL, rch, TO_ROOM);
                                     break;
                                 }
                                 if (num == 2 && xIS_SET(kmob->flags, KMOB_CURESERIOUS))
                                 {
                                    csn = skill_lookup("cure serious");
                                    if (csn <= 0)
                                       continue;
                                    spell_smaug(csn, POINT_LEVEL(LEARNED(ch, csn), MASTERED(ch, csn)), ch, rch);
                                    act(AT_ACTION, "$n waves $s hands and casts cure serious on $N.", ch, NULL, rch, TO_ROOM);
                                    break;
                                 }
                                 if (num == 3 && xIS_SET(kmob->flags, KMOB_CURECRITICAL))
                                 {
                                    csn = skill_lookup("cure critical");
                                    if (csn <= 0)
                                       continue;
                                    spell_smaug(csn, POINT_LEVEL(LEARNED(ch, csn), MASTERED(ch, csn)), ch, rch);
                                    act(AT_ACTION, "$n waves $s hands and casts cure critical on $N.", ch, NULL, rch, TO_ROOM);
                                    break;
                                 }
                                 if (num == 4 && xIS_SET(kmob->flags, KMOB_HEAL))
                                 {
                                    csn = skill_lookup("heal");
                                    if (csn <= 0)
                                       continue;
                                    spell_smaug(csn, POINT_LEVEL(LEARNED(ch, csn), MASTERED(ch, csn)), ch, rch);
                                    act(AT_ACTION, "$n waves $s hands and casts heal on $N.", ch, NULL, rch, TO_ROOM);
                                    break;
                                 }
                                 if (num == 5 && xIS_SET(kmob->flags, KMOB_DIVINITY))
                                 {
                                    csn = skill_lookup("divinity");
                                    if (csn <= 0)
                                       continue;
                                    spell_smaug(csn, POINT_LEVEL(LEARNED(ch, csn), MASTERED(ch, csn)), ch, rch);
                                    act(AT_ACTION, "$n waves $s hands and casts divinity on $N.", ch, NULL, rch, TO_ROOM);
                                    break;
                                 }
                                 if (num == 6 && xIS_SET(kmob->flags, KMOB_POWERHEAL))
                                 {
                                    csn = skill_lookup("power heal");
                                    if (csn <= 0)
                                       continue;
                                    spell_smaug(csn, POINT_LEVEL(LEARNED(ch, csn), MASTERED(ch, csn)), ch, rch);
                                    act(AT_ACTION, "$n waves $s hands and casts power heal on $N.", ch, NULL, rch, TO_ROOM);
                                    break;
                                 }
                              }
                              break;
                           }
                        }
                     }                        
                  }
                  break;
               }
            }
            continue;
         }
         else
         {
            retcode = one_hit(ch, victim, TYPE_HIT, LM_BODY);
            if (fired == 1)
               ch->fight_timer += 2;
         }
      }
      else
         stop_fighting(ch, FALSE);

      if (char_died(ch))
         continue;

      if (retcode == rCHAR_DIED || (victim = who_fighting(ch)) == NULL)
         continue;
      
      //Don't want to target some bum with a giant shield all the time do we!!
      if (ch->fighting && ch->fighting->who && (shield = get_eq_char(ch->fighting->who, WEAR_SHIELD)) != NULL && IS_NPC(ch) && !xIS_SET(ch->act, ACT_MILITARY))
      {
         if (shield->value[2] >= 30) //Lower aggression rate against this target
         {
            for (aggro = ch->first_aggro; aggro; aggro = aggro->next)
            {
               if (aggro->ch && aggro->ch == ch->fighting->who)
                  break;
            }
            if (aggro)
            {
               aggro->value -= UMAX(1, (shield->value[2]- 30) / 4);
            }
         }
      }
      //stop kingdom buffering, mobs will target unequiped foes first....
      if (ch->fighting && ch->fighting->who && ch->fighting->who->name && xIS_SET(ch->act, ACT_MILITARY))
      {     
         int eqlevel;
         int fnd = 0;
         int npeace;
         int ht;
         int bpercent = 100;
         CHAR_DATA *newtarget = NULL;
         
         if (!get_eq_char(ch->fighting->who, WEAR_NECK))
            eqlevel = 1;
         else if (!get_eq_char(ch->fighting->who, WEAR_HEAD))
            eqlevel = 2;
         else if (!get_eq_char(ch->fighting->who, WEAR_ARM_R))
            eqlevel = 3;
         else if (!get_eq_char(ch->fighting->who, WEAR_ARM_L))
            eqlevel = 4;
         else if (!get_eq_char(ch->fighting->who, WEAR_LEG_R))
            eqlevel = 5;
         else if (!get_eq_char(ch->fighting->who, WEAR_LEG_L))
            eqlevel = 6; 
         else if (!get_eq_char(ch->fighting->who, WEAR_BODY))
            eqlevel = 7;
         else
            eqlevel = 8;
            
         if (eqlevel > 1)
         {            
            if (xIS_SET(ch->miflags, KM_ATTACKN))
               npeace = 1;
            else if (xIS_SET(ch->miflags, KM_ATTACKE))
               npeace = 0;
            else
               npeace = -1;
            if (IS_NPC(ch->fighting->who))
               ht = ch->fighting->who->m4;
            else
               ht = ch->fighting->who->pcdata->hometown;
         
            
            for (ich = ch->in_room->first_person; ich; ich = ich->next_in_room)
            {
               if (ich == ch)
                  continue;
                  
               if (IN_WILDERNESS(ch))
               {
                  if (ich->coord->x == ch->coord->x && ich->coord->y == ch->coord->y && ich->map == ch->map)
                  {
                     if (can_see_map(ch, ich) && !is_safe(ch, ich) && ch->m4 != ht && (npeace == -1 || kingdom_table[ch->m4]->peace[ht] <= npeace) && !IS_IMMORTAL(ich))
                     {
                        if (!get_eq_char(ich, WEAR_NECK))
                        {
                           for (aggro = ch->first_aggro; aggro; aggro = aggro->next)
                              if (aggro->ch && aggro->ch == ich)
                                 aggro->value = 10000;
                           fnd = 1;
                           break;
                        }
                        if (!get_eq_char(ich, WEAR_HEAD) && eqlevel > 2)
                        {
                           for (aggro = ch->first_aggro; aggro; aggro = aggro->next)
                              if (aggro->ch && aggro->ch == ich)
                                 aggro->value = 10000;
                           fnd = 1;
                           break;
                        }
                        if (!get_eq_char(ich, WEAR_ARM_R) && eqlevel > 3)
                        {
                           for (aggro = ch->first_aggro; aggro; aggro = aggro->next)
                              if (aggro->ch && aggro->ch == ich)
                                 aggro->value = 10000;
                           fnd = 1;
                           break;
                        }
                        if (!get_eq_char(ich, WEAR_ARM_L) && eqlevel > 4)
                        {
                           for (aggro = ch->first_aggro; aggro; aggro = aggro->next)
                              if (aggro->ch && aggro->ch == ich)
                                 aggro->value = 10000;
                           fnd = 1;
                           break;
                        }
                        if (!get_eq_char(ich, WEAR_LEG_R) && eqlevel > 5)
                        {
                           for (aggro = ch->first_aggro; aggro; aggro = aggro->next)
                              if (aggro->ch && aggro->ch == ich)
                                 aggro->value = 10000;
                           fnd = 1;
                           break;
                        }
                        if (!get_eq_char(ich, WEAR_LEG_L) && eqlevel > 6)
                        {
                           for (aggro = ch->first_aggro; aggro; aggro = aggro->next)
                              if (aggro->ch && aggro->ch == ich)
                                 aggro->value = 10000;
                           fnd = 1;
                           break;
                        }
                        if (!get_eq_char(ich, WEAR_BODY) && eqlevel > 7)
                        {
                           for (aggro = ch->first_aggro; aggro; aggro = aggro->next)
                              if (aggro->ch && aggro->ch == ich)
                                 aggro->value = 10000;
                           fnd = 1;
                           break;
                        }
                        if (eqlevel == 8)
                        {        
                           shield = get_eq_char(ich, WEAR_SHIELD);
                           if (shield && shield->value[2] >= 40) //switch targets on a decent block percent
                           {
                              if (bpercent == 100)
                              {
                                 shield = get_eq_char(ch->fighting->who, WEAR_SHIELD);
                                 if (shield)
                                    bpercent = shield->value[2];
                                 else
                                    bpercent = 0;
                              }
                              shield = get_eq_char(ich, WEAR_SHIELD);
            
                              if (!shield && ich != ch && !IS_NPC(ich) && !IS_IMMORTAL(ich))
                              {
                                 newtarget = ich;
                                 bpercent = 0;
                                 continue;
                              }
                              if (shield && shield->value[2] < bpercent && ich != ch && !IS_NPC(ich) && !IS_IMMORTAL(ich))
                              {
                                 newtarget = ich;
                                 bpercent = shield->value[2];
                              }
                           }
                        }
                     }
                  }
               }
               else
               {
                  if (can_see_map(ch, ich) && !is_safe(ch, ich) && ch->m4 != ht && (npeace == -1 || kingdom_table[ch->m4]->peace[ht] <= npeace) && !IS_IMMORTAL(ich))
                  {
                     if (!get_eq_char(ich, WEAR_NECK))
                     {
                        for (aggro = ch->first_aggro; aggro; aggro = aggro->next)
                           if (aggro->ch && aggro->ch == ich)
                              aggro->value = 10000;
                        fnd = 1;
                        break;
                     }
                     if (!get_eq_char(ich, WEAR_HEAD) && eqlevel > 2)
                     {
                        for (aggro = ch->first_aggro; aggro; aggro = aggro->next)
                           if (aggro->ch && aggro->ch == ich)
                              aggro->value = 10000;
                        fnd = 1;
                        break;
                     }
                     if (!get_eq_char(ich, WEAR_ARM_R) && eqlevel > 3)
                     {
                        for (aggro = ch->first_aggro; aggro; aggro = aggro->next)
                           if (aggro->ch && aggro->ch == ich)
                              aggro->value = 10000;
                        fnd = 1;
                        break;
                     }
                     if (!get_eq_char(ich, WEAR_ARM_L) && eqlevel > 4)
                     {
                        for (aggro = ch->first_aggro; aggro; aggro = aggro->next)
                           if (aggro->ch && aggro->ch == ich)
                              aggro->value = 10000;
                        fnd = 1;
                        break;
                     }
                     if (!get_eq_char(ich, WEAR_LEG_R) && eqlevel > 5)
                     {
                        for (aggro = ch->first_aggro; aggro; aggro = aggro->next)
                           if (aggro->ch && aggro->ch == ich)
                              aggro->value = 10000;
                        fnd = 1;
                        break;
                     }
                     if (!get_eq_char(ich, WEAR_LEG_L) && eqlevel > 6)
                     {
                        for (aggro = ch->first_aggro; aggro; aggro = aggro->next)
                           if (aggro->ch && aggro->ch == ich)
                              aggro->value = 10000;
                        fnd = 1;
                        break;
                     }
                     if (!get_eq_char(ich, WEAR_BODY) && eqlevel > 7)
                     {
                        for (aggro = ch->first_aggro; aggro; aggro = aggro->next)
                           if (aggro->ch && aggro->ch == ich)
                              aggro->value = 10000;
                        fnd = 1;
                        break;
                     }
                     if (eqlevel == 8)
                     {                       
                        shield = get_eq_char(ich, WEAR_SHIELD);
                        if (shield && shield->value[2] >= 40) //switch targets on a decent block percent
                        {
                           if (bpercent == 100)
                           {
                              shield = get_eq_char(ch->fighting->who, WEAR_SHIELD);
                              if (shield)
                                 bpercent = shield->value[2];
                              else
                                 bpercent = 0;
                           }
                           shield = get_eq_char(ich, WEAR_SHIELD);
                           
                           if (!shield && ich != ch && !IS_NPC(ich) && !IS_IMMORTAL(ich))
                           {
                              newtarget = ich;
                              bpercent = 0;
                              continue;
                           }
                           if (shield && shield->value[2] < bpercent && ich != ch && !IS_NPC(ich) && !IS_IMMORTAL(ich))
                           {
                              newtarget = ich;
                              bpercent = shield->value[2];
                           }
                        }
                     }
                  }
               }
            }
            if (fnd == 0 && newtarget)
            {
               for (aggro = ch->first_aggro; aggro; aggro = aggro->next)
                  if (aggro->ch && aggro->ch == newtarget)
                     aggro->value = 10000;
            }
         }
      }
   }
   /*
    * Fun for the whole family!
    */
   for (rch = ch->in_room->first_person; rch; rch = rch_next)
   {
      rch_next = rch->next_in_room;
      
      if (rch->coord->x != ch->coord->x || rch->coord->y != ch->coord->y || rch->map != ch->map)
      {
         continue;
      }

      if (IS_AWAKE(rch) && !rch->fighting)
      {
         if (!IS_NPC(ch) && IS_NPC(rch) && !IS_SET(ch->pcdata->flags, PCFLAG_CNOASSIST))
         {
            if (IN_SAME_ROOM(rch, ch))
            {
               if (IS_NPC(rch) && IS_AFFECTED(rch, AFF_CHARM) && !IS_ACT_FLAG(rch, ACT_MOUNTSAVE) && rch->master == ch
               &&  !rch->fighting)
               {
                  one_hit(rch, victim, TYPE_HIT, LM_BODY);
                  continue;
               }
            }
         }
         /*
          * PC's auto-assist others in their group.
          */
         if (!IS_NPC(ch) || IS_AFFECTED(ch, AFF_CHARM))
         {
            if ((!IS_NPC(rch) || IS_AFFECTED(rch, AFF_CHARM)) && is_same_group(ch, rch))
               one_hit(rch, victim, TYPE_HIT, LM_BODY);
            continue;
         }
         /*
          * NPC's assist NPC's of same type or 12.5% chance regardless.
          */
         if (IS_NPC(rch) && !IS_AFFECTED(rch, AFF_CHARM) && !xIS_SET(rch->act, ACT_NOASSIST))
         {
            if (char_died(ch))
               break;
            if (rch->pIndexData == ch->pIndexData || number_bits(3) == 0)
            {
               CHAR_DATA *vch;
               CHAR_DATA *target;
               int number;
               int hking;
               int iking;

               target = NULL;
               number = 0;
                 
               if (IS_NPC(rch))
                  hking = rch->m4;
               else
                  hking = rch->pcdata->hometown;
            
               for (vch = ch->in_room->first_person; vch; vch = vch->next)
               {
                  if (IS_NPC(vch))
                     iking = vch->m4;
                  else
                     iking = vch->pcdata->hometown;
                        
                  if (can_see_map(rch, vch) && is_same_group(vch, victim) && number_range(0, number) && !is_safe(rch, vch) && (!xIS_SET(vch->act, ACT_MILITARY) || (xIS_SET(vch->act, ACT_MILITARY) && iking != hking)))
                  {
                     if (vch->mount && vch->mount == rch)
                        target = NULL;
                     else
                     {
                        target = vch;
                        number++;
                     }
                  }
               }

               if (target)
                  one_hit(rch, target, TYPE_HIT, LM_BODY);
            }
         }
      }
   }
   for (aggro = ch->first_aggro; aggro; aggro = aggro->next)
   {
      if (!aggro->ch)
         continue;
      if (haggro == -1)
      {
         if (IN_SAME_ROOM(ch, aggro->ch))
            haggro = aggro->value;
      }
      if (aggro->value > haggro)
      {
         if (IN_SAME_ROOM(ch, aggro->ch))
            haggro = aggro->value;
      }
   }
   for (aggro = ch->first_aggro; aggro; aggro = aggro->next)
   {
      if (haggro == aggro->value)
         break;
   }
   if (aggro && ch->fighting && ch->fighting->who && aggro->ch != ch->fighting->who)
   {
      ch->fighting->who = aggro->ch;
      act(AT_WHITE, "$n turns $s head toward $N and focuses $s rage on $N!", ch, NULL, ch->fighting->who, TO_NOTVICT);
      act(AT_WHITE, "$n turns $s head toward you and foruses $s rage on YOU!", ch, NULL, ch->fighting->who, TO_VICT);
   }
   
   if (!IS_NPC(ch) && ch->fight_timer == 0 && ch->fighting && ch->fighting->who)
   {
      if (xIS_SET(ch->act, PLR_TARGET) && !ch->pcdata->autocommand)
      {
         if (ch->pcdata->target_limb == LM_HEAD)
            sprintf(target, "head");
         else if (ch->pcdata->target_limb == LM_BODY)
            sprintf(target, "body");
         else if (ch->pcdata->target_limb == LM_NECK)
            sprintf(target, "neck");
         else if (ch->pcdata->target_limb == LM_RARM)
            sprintf(target, "rarm");
         else if (ch->pcdata->target_limb == LM_LARM)
            sprintf(target, "larm");
         else if (ch->pcdata->target_limb == LM_LLEG)
            sprintf(target, "lleg");
         else if (ch->pcdata->target_limb == LM_RLEG)
            sprintf(target, "rleg");
         else
            sprintf(target, "body");
         sprintf(abuf, "'%s' %s", ch->fighting->who->name, target);
         
         if (ch->pcdata->target == GRIP_SLASH)
            ch->grip = GRIP_SLASH;
         else if (ch->pcdata->target == GRIP_STAB)
            ch->grip = GRIP_STAB;
         else
            ch->grip = GRIP_BASH;
            
         if (ch->position < POS_BERSERK)
            ;
         else if (get_char_room_new(ch, ch->fighting->who->name, 1) == NULL)
            ;
         else if (ch->pcdata->stackbuf[0] != '\0')
         {
            strcpy(commandbuf, "");
            parse_attack_buffer(ch->pcdata->stackbuf, commandbuf);
            if (commandbuf[0] == '\0' && ch->pcdata->stackbuf[0] == '\0')
               do_attack(ch, abuf);
            else
               interpret(ch, commandbuf);
         }
         else
            do_attack(ch, abuf);
      }
   }
   if (xIS_SET(ch->act, PLR_TARGET) && ch->pcdata->autocommand)
   {
      if (ch->pcdata->stackbuf[0] != '\0')
      {
         strcpy(commandbuf, "");
         parse_attack_buffer(ch->pcdata->stackbuf, commandbuf);
         if (commandbuf[0] == '\0' && ch->pcdata->stackbuf[0] == '\0')
            interpret(ch, ch->pcdata->autocommand);
         else
            interpret(ch, commandbuf);
      }
      else
         interpret(ch, ch->pcdata->autocommand);
  }
/*
   for (d = first_descriptor; d; d = d->next)
   {
      if (d->connected == CON_PLAYING && d->character->in_room && d->newstate != 2)
      {
         if (d->character->fighting && can_see(d->character, d->character->fighting->who))
         {
            int percent;

            ch = d->character;
            victim = d->character->fighting->who;
            percent = ((victim->hit * 100) / victim->max_hit);
            if (ch->level >= 15)
               sprintf(buf2, "(%2d%%)", percent);
            else
               sprintf(buf2, "     ");
            ch_printf(ch, "^x&R*&r~&R*&r~&R*&r~&R*&r~&R*&r~&R*&r~&R*&r~&R*&r~&R*&r~&R*&r~&R*&r~&R*&r~&R*&r~&R*&r~&R*\n\r");
            if (victim->hit == victim->max_hit)
               ch_printf(ch, "&R*    &G&W(&r**&R***&Y***&G***&G&W) %s    &R*\n\r", buf2);
            else if (percent >= 90)
               ch_printf(ch, "&R*    &G&W(&r**&R***&Y***&G** &G&W) %s    &R*\n\r", buf2);
            else if (percent >= 80)
               ch_printf(ch, "&R*    &G&W(&r**&R***&Y***&G*  &G&W) %s    &R*\n\r", buf2);
            else if (percent >= 70)
               ch_printf(ch, "&R*    &G&W(&r**&R***&Y***   &G&W) %s    &R*\n\r", buf2);
            else if (percent >= 60)
               ch_printf(ch, "&R*    &G&W(&r**&R***&Y**    &G&W) %s    &R*\n\r", buf2);
            else if (percent >= 50)
               ch_printf(ch, "&R*    &G&W(&r**&R***&Y*     &G&W) %s    &R*\n\r", buf2);
            else if (percent >= 40)
               ch_printf(ch, "&R*    &G&W(&r**&R***      &G&W) %s    &R*\n\r", buf2);
            else if (percent >= 30)
               ch_printf(ch, "&R*    &G&W(&r**&R**       &G&W) %s    &R*\n\r", buf2);
            else if (percent >= 20)
               ch_printf(ch, "&R*    &G&W(&r**&R*        &G&W) %s    &R*\n\r", buf2);
            else if (percent >= 10)
               ch_printf(ch, "&R*    &G&W(&r**         &G&W) %s    &R*\n\r", buf2);
            else
               ch_printf(ch, "&R*    &G&W(&r*          &G&W) %s    &R*\n\r", buf2);
            ch_printf(ch, "&R*&r~&R*&r~&R*&r~&R*&r~&R*&r~&R*&r~&R*&r~&R*&r~&R*&r~&R*&r~&R*&r~&R*&r~&R*&r~&R*&r~&R*\n\r");
         }
      }
   }*/
 }
   return;
}

/*
 * Weapon types, haus
 */
int weapon_prof_bonus_check(CHAR_DATA * ch, OBJ_DATA * wield, int *gsn_ptr)
{
   return 0;
}

/*
 * Calculate the tohit bonus on the object and return RIS values.
 * -- Altrag
 */
int obj_hitroll(OBJ_DATA * obj)
{
   return 0;
}

/*
 * Offensive shield level modifier
 */
sh_int off_shld_lvl(CHAR_DATA * ch)
{
   if (get_curr_int(ch) < 13) //1-12
      return SPOWER_MIN;
   if (get_curr_int(ch) < 17) //13-16
      return SPOWER_MED;
   if (get_curr_int(ch) < 21) //17-20
      return SPOWER_HI;
   if (get_curr_int(ch) < 24) //21-23
      return SPOWER_GREATER;
   else
      return SPOWER_GREATEST; //24+
   
      
   return URANGE(5, (get_curr_int(ch)-12)*5,  50);      
}

void do_grip(CHAR_DATA * ch, char *argument)
{
   if (!str_prefix(argument, "slash"))
   {
      ch->grip = GRIP_SLASH;
      send_to_char("Grip changed to slash.\n\r", ch);
      if (ch->fighting)
      {
         SET_BIT(ch->fight_state, FSTATE_GRIP);
         ch->fight_timer = 2;
      }
      return;
   }
   else if (!str_prefix(argument, "bash"))
   {
      ch->grip = GRIP_BASH;
      send_to_char("Grip changed to bash.\n\r", ch);
      if (ch->fighting)
      {
         SET_BIT(ch->fight_state, FSTATE_GRIP);
         ch->fight_timer = 2;
      }
      return;
   }
   else if (!str_prefix(argument, "stab"))
   {
      ch->grip = GRIP_STAB;
      send_to_char("Grip changed to stab.\n\r", ch);
      if (ch->fighting)
      {
         SET_BIT(ch->fight_state, FSTATE_GRIP);
         ch->fight_timer = 2;
      }
      return;
   }
   else
   {
      send_to_char("Syntax: grip <argument>    argument = slash, bash, stab\n\r", ch);
      return;
   }
}

//Adjusts strength/agility from attack, part of the stat increase/decrease with no levels
//More of a strength drop now for using lighter weapons
void adjust_agi_str(CHAR_DATA *ch, OBJ_DATA *weapon, CHAR_DATA *target)
{
   //1000 for agility 10000 for strengh since it is base 25 and agi is base 100
   int str, agi, mod, mstr, magi, bstr, astr, alow, apercent;
   
   str = ch->perm_str;
   agi = ch->perm_agi;
   mstr = magi = 0;
   
   if (get_eq_char(ch, WEAR_DUAL_WIELD) != NULL)
      learn_from_success(ch, gsn_dual_wield, NULL);
   
   if(weapon == NULL)
      mod = 1;
   else
      mod = weapon->value[3] - race_table[ch->race]->weaponmin + 1;
     
   if (mod == 7)    //largest weapon
   {
      magi += number_range(-1, -2);
      mstr += number_range(2, 3);   
   } 
   if (mod == 6) //2nd largest weapon
   {
      magi += number_range(0, -1);
      mstr += number_range(1, 2);
   }   
   if (mod == 5) //average weapon/heavy, light change in both areas
   {
      magi += number_range(-1, 2);
      mstr += number_range(1, 0);
   }
   if (mod == 4) //average weapon/light, light change in both areas.
   {
      magi += number_range(1, 2);
      mstr += number_range(-1, 1);
   }
   if (mod == 3) //Lighter weapon, increase agi
   {
      magi += number_range(2, 3);
      mstr += number_range(0, -1);
   }
   if (mod == 2) //Lightest weapon, increases agi
   {
      magi += number_range(3, 5);
      mstr += number_range(-2, -3);
   }
   if (mod == 1) //no weapon
   {
      magi += number_range(5, 7);
      mstr += number_range(-3, -5);   
   }
   
   //Increase agility if under 30 no matter what
   if (agi <= 30)
   {
      if (mod == 7)
         magi = 1;
      if (mod == 6)
         magi = number_range(1, 2);
      if (mod == 5)
         magi = number_range(1, 3);
      if (mod == 4)
         magi = number_range(1, 4);
      if (mod == 3)
         magi = number_range(2, 5);
      if (mod == 2)
         magi = number_range(4, 10);
      if (mod == 1)
         magi = number_range(12, 20);
  }
  if (sysdata.stat_gain <= 3)
   {
      if (magi > 0)
         magi = number_range(150*magi/100, 180*magi/100);
      if (mstr > 0)
         mstr = number_range(150*mstr/100, 180*mstr/100);
   }
   else if (sysdata.stat_gain >= 5)
   {
      if (magi > 0)
         magi = number_range(250*magi/100, 300*magi/100);
      if (mstr > 0)
         magi = number_range(250*mstr/100, 300*mstr/100);
   }
   
   
   //strength mods
   if (mstr > 0)
   {
      bstr = 14 + race_table[ch->race]->str_plus;
      if (str == bstr - 4)
         mstr *= 2;
      if (str == bstr - 3)
         mstr *= 1.7;
      if (str == bstr - 2)
         mstr *= 1.5;
      if (str == bstr - 1)
         mstr *= 1.2;
      if (str == bstr)
         mstr *= 1;
      if (str == bstr + 1)
         mstr *= .85;
      if (str == bstr + 2)
         mstr *= .7;
      if (str == bstr + 3)
         mstr *= .6;
      if (str == bstr + 4)
         mstr *= .4;
      if (str == bstr + 5)
         mstr *= .3;
      if (str == bstr + 6)
         mstr *= .275;
      if (str == bstr + 7)
         mstr *= .25;
      if (str == bstr + 8)
         mstr *= .225;
      if (str > bstr + 8) //Base + 8 should be the max unless you screwed it up
         mstr = 0;
      else
      {
         if (mstr == 0)
            mstr = 1;
      }
   }
   else
   {
      bstr = 14 + race_table[ch->race]->str_plus;
      if (str == bstr - 4)
         mstr = 0;
      if (str == bstr - 3)
         mstr *= .3;
      if (str == bstr - 2)
         mstr *= .4;
      if (str == bstr - 1)
         mstr *= .6;
      if (str == bstr)
         mstr *= 1;
      if (str == bstr + 1)
         mstr *= 1.2;
      if (str == bstr + 2)
         mstr *= 1.4;
      if (str == bstr + 3)
         mstr *= 1.6;
      if (str == bstr + 4)
         mstr *= 1.8;
      if (str >= bstr + 5)
         mstr *= 2;
   }
   //agility mods
   if (magi > 0)
   {
      astr = race_table[ch->race]->agi_start;
      alow = astr - race_table[ch->race]->agi_range;
      apercent = (agi - alow) * 100 / (astr - alow);
      magi = magi * (200 - apercent) / 100;
      if (magi <= 0)
         magi = 1;
   }
   else
   {
      astr = race_table[ch->race]->agi_start;
      alow = astr - race_table[ch->race]->agi_range;
      apercent = (agi - alow) * 100 / (astr - alow);
      magi = magi * apercent / 100;
   }
   if (ch->perm_str >= (14 + race_table[ch->race]->str_plus + race_table[ch->race]->str_range + get_talent_increase(ch, 1)) && ch->pcdata->per_str >= 3000 && mstr > 0)
      mstr = 0;
   if (ch->perm_str <= (14 + race_table[ch->race]->str_plus - 5 + race_table[ch->race]->str_range) && ch->pcdata->per_str <= 3000 && mstr < 0)
      mstr = 0;
   if (ch->perm_agi >= (race_table[ch->race]->agi_start + race_table[ch->race]->agi_range + get_talent_increase(ch, 7)) && ch->pcdata->per_agi >= 300)
      magi = 0;     
   if (ch->perm_agi <= (race_table[ch->race]->agi_start - race_table[ch->race]->agi_range) && ch->pcdata->per_agi <= 300 && magi < 0)
      magi = 0;
   if (target && IS_NPC(target) && xIS_SET(target->act, ACT_MOUNTSAVE))
   {
      if (mstr > 0)
         mstr = 0;
      if (magi > 0)
         magi = 0;
   }
   if (magi > 1 && magi < -1)
      magi = magi * race_table[ch->race]->agi_plus/100;
   ch->pcdata->per_agi += magi;
   ch->pcdata->per_str += mstr;
   
   if (ch->pcdata->per_agi > 1000)
   {
      ch->perm_agi++;
      if (ch->perm_agi < 16)
         ch->perm_agi = 16;
      send_to_char("&R*************************************\n\r", ch);
      send_to_char("&R*****You Gain 1 Point of Agility*****\n\r", ch);
      send_to_char("&R*************************************\n\r", ch);
      ch->pcdata->per_agi = 0;
   }
   if (ch->pcdata->per_str > 10000)
   {
      ch->perm_str++;
      send_to_char("&R**************************************\n\r", ch);
      send_to_char("&R*****You Gain 1 Point of Strength*****\n\r", ch);
      send_to_char("&R**************************************\n\r", ch);
      ch->pcdata->per_str = 0;
   }
   if (ch->pcdata->per_agi < 0)
   {
      ch->perm_agi--;
      send_to_char("&r*************************************\n\r", ch);
      send_to_char("&r*****You Lose 1 Point of Agility*****\n\r", ch);
      send_to_char("&r*************************************\n\r", ch);
      ch->pcdata->per_agi = 999;
   }
   if (ch->pcdata->per_str < 0)
   {
      ch->perm_str--;
      send_to_char("&r**************************************\n\r", ch);
      send_to_char("&r*****You Lose 1 Point of Strength*****\n\r", ch);
      send_to_char("&r**************************************\n\r", ch);
      ch->pcdata->per_str = 9999;
   }
}
   
int get_limb_location(int limb)
{
   if (limb == LM_BODY)
      return WEAR_BODY;   
   if (limb == LM_NECK)
      return WEAR_NECK;
   if (limb == LM_HEAD)
      return WEAR_HEAD;
   if (limb == LM_RARM)
      return WEAR_ARM_R;
   if (limb == LM_LARM)
      return WEAR_ARM_L;
   if (limb == LM_RLEG)
      return WEAR_LEG_R;
   if (limb == LM_LLEG)
      return WEAR_LEG_L;
      
   return WEAR_BODY;
}   

//the routine for hit or miss check
//-ac (better tohit) +ac (better armor)
int get_hit_or_miss(CHAR_DATA *ch, CHAR_DATA *victim, int ac, int grip, int limb, int noarmor, OBJ_DATA *wield, int sn)
{
   int crit = 0;
   int spread = 0;
   int value = 0;
   int percent;
   int points;
   AFFECT_DATA *paf;
   int roll;
   int pslice = 0;
   int perfect = 0;
   int bracing;
   int nodeath = 0;
   int addspread = 0;
   
   //critical skill check
   if (!IS_NPC(ch) && ch->pcdata->learned[gsn_critical] > 0 && ch->pcdata->ranking[gsn_critical] > 0)
   {
      percent = number_range(1, 10000);
      points =  POINT_LEVEL(LEARNED(ch, gsn_critical), MASTERED(ch, gsn_critical));
      
      points = number_range(points * 7, points * 10);


      if (percent <= points)
      {
         crit = 1;
         learn_from_success(ch, gsn_critical, victim); 
      }
      else
         learn_from_failure(ch, gsn_critical, victim);
   }
   if (sn == gsn_powerslice)
   {
      int level;
      level = POINT_LEVEL(LEARNED(ch, gsn_powerslice), MASTERED(ch, gsn_powerslice))*2;
      level += (get_curr_str(ch) - get_curr_str(victim)) * 2;
      level += number_range(level*3, level*4);
      level = UMAX(50, level);
      if (number_range(1, 10000) <= level)
         pslice = 1;
         
      if (pslice == 1)
         learn_from_success(ch, gsn_powerslice, victim);   
      else
         learn_from_failure(ch, gsn_powerslice, victim);   
   }
   if (sn == gsn_perfect_shot)
   {
      int level;
      level = POINT_LEVEL(LEARNED(ch, gsn_perfect_shot), MASTERED(ch, gsn_perfect_shot))*3/2;
      level += (get_curr_str(ch) - get_curr_str(victim)) * 2;
      level += number_range(level*2, level*3);
      level = UMAX(50, level);
      if (number_range(1, 10000) <= level)
      {
         perfect = 1;
      }
   }
   if (wield && IS_OBJ_STAT(wield, ITEM_TWOHANDED) && ch->race < MAX_PC_RACE)
   {
      int tpoints = POINT_LEVEL(LEARNED(ch, gsn_weapon_twohanded), MASTERED(ch, gsn_weapon_twohanded));
      int mod = wield->value[3] - race_table[ch->race]->weaponmin + 1;
      if (mod >= 5 && LEARNED(ch, gsn_weapon_twohanded))
      {
         if (tpoints >= 90)
            ac-=3;
         else if (tpoints >= 60)
            ac-=2;
         else if (tpoints >= 30)
            ac-=1;
      }
   }
   ac*=2; //this should make it more defined if you have a better weapon/armor
   ac -= URANGE(-10, ch->apply_tohit, 10);
   ac += URANGE(-10, victim->apply_armor, 10);
   for (paf = victim->first_affect; paf; paf = paf->next)
   {
      if (paf->type == gsn_berserk);
      {
         ac -= UMIN(6, paf->modifier/12+1);
         break;
      }
   }
   if (!IS_NPC(victim) && victim->pcdata->learned[gsn_krundo_style] > 0)
   {
      int level;
      level = POINT_LEVEL(LEARNED(victim, gsn_krundo_style), MASTERED(victim, gsn_krundo_style));
      level = number_range(level*4, level*5);
      level = URANGE(1, level, 400);
      ac += level/100;
      level = level % 100;
      if (number_range(1, 100) <= level)
      {
         ac++;
      }
      learn_from_success(victim, gsn_krundo_style, ch);  
   }
   if (!IS_NPC(ch) && ch->pcdata->learned[gsn_rwundo_style] > 0)
   {
      int level;
      level = POINT_LEVEL(LEARNED(ch, gsn_rwundo_style), MASTERED(ch, gsn_rwundo_style));
      level = number_range(level*4, level*5);
      level = URANGE(1, level, 400);
      ac -= level/100;
      level = level % 100;
      if (number_range(1, 100) <= level)
      {
         ac--;
      }
      learn_from_success(ch, gsn_rwundo_style, victim);  
   }
   if (!IS_NPC(ch) && ch->pcdata->learned[gsn_concentration] > 0)
   {
      int level;
      level = POINT_LEVEL(LEARNED(ch, gsn_concentration), MASTERED(ch, gsn_concentration));
      level = number_range(level*3, level*4);
      level = URANGE(1, level, 300);
      ac -= level/100;
      level = level % 100;
      if (number_range(1, 100) <= level)
      {
         ac--;
      }
   }
   g_tohit = ac;
   if (grip == GRIP_BASH)
      spread = 6;
   else if (grip == GRIP_SLASH)
      spread = 4;
   else if (grip == GRIP_STAB)
      spread = 2;
      
   if (!IS_NPC(ch) && ch->pcdata->learned[gsn_rwundi_style] > 0)
   {
      int level;
      level = POINT_LEVEL(LEARNED(ch, gsn_rwundi_style), MASTERED(ch, gsn_rwundi_style));
      level = number_range(level*2, level*3);
      level = URANGE(1, level, 200);
      spread += level/100;
      level = level % 100;
      if (number_range(1, 100) <= level)
      {
         addspread++;
      }
      learn_from_success(ch, gsn_rwundi_style, victim);  
   }     
      
   roll = number_range(1, TOHIT_SYS);
   if (victim->apply_bracing)
   {
      int sroll;
      bracing = UMAX(1, TOHIT_SYS * victim->apply_bracing / 120);
      sroll = number_range(1, TOHIT_SYS+bracing);
      if (sroll == TOHIT_SYS+bracing || pslice || perfect)
         crit = 1;
      check_aff_learn(victim, "bracing", 0, ch, 1);
   }
   else
   {
      if (roll == TOHIT_SYS || pslice || perfect)
         crit = 1;
   }
   if (limb == LM_HEAD && roll >= TOHIT_SYS-(UMAX(1,TOHIT_SYS/20)))
      crit = 1;
   else if (roll == 1 && !pslice && !perfect)
      crit = -1;
   if (roll > ((TOHIT_SYS/2)-(TOHIT_SYS/10) + ac + spread + (TOHIT_SYS/6)) && limb == LM_NECK)
   {
      if (crit == 0)
         nodeath = 1;
      crit = 1;
   }
   g_roll = roll;
   g_lowtohit = UMAX(1, (TOHIT_SYS/2)-(TOHIT_SYS/10) + ac - spread - addspread);
   g_hitohit = UMAX(1, (TOHIT_SYS/2)-(TOHIT_SYS/10) + ac + spread);
   if (noarmor && crit == 0) //always land against no armor
      return 200;
      
   if (crit && sn == gsn_pincer) //Enough is enough on this one
      return 200;
     
   if (roll < ((TOHIT_SYS/2)-(TOHIT_SYS/10) + ac - spread - addspread) && crit != 1 && crit != -1)
      return DM_MISS;
   if (roll > ((TOHIT_SYS/2)-(TOHIT_SYS/10) + ac + spread) && crit != 1 && crit != -1)
      return 200; //100 percent 200 - 100
   if (crit != 1 && crit != -1)
   {
      value = (TOHIT_SYS/2)-(TOHIT_SYS/10) + ac + spread - roll;
      spread += addspread;
      if (spread == 2)
      {
         value -= addspread*2;
         if (value <= 0)
            return 183;
         else if (value == 1)
            return 166;
         else if (value == 2)
            return 150;
         else if (value == 3)
            return 133;
         else if (value == 4)
            return 116;
      }
      if (spread == 3)
      {
         value -= addspread*2;
         if (value <= 0) 
            return 187;
         else if (value == 1)
            return 175;
         else if (value == 2)
            return 162;
         else if (value == 3)
            return 150;
         else if (value == 4)
            return 137;
         else if (value == 5)
            return 125;
         else if (value == 6)
            return 112;
      }
      if (spread == 4)
      {
         value -= addspread*2;
         if (value <= 0)
            return 190;
         else if (value == 1)
            return 180;
         else if (value == 2)
            return 170;
         else if (value == 3)
            return 160;
         else if (value == 4)
            return 150;
         else if (value == 5)
            return 140;
         else if (value == 6)
            return 130;
         else if (value == 7)
            return 120;
         else if (value == 8)
            return 110;
      }
      if (spread == 5) //8.33
      {
         value -= addspread*2;
         if (value <= 0)
            return 192;
         else if (value == 1)
            return 184;
         else if (value == 2)
            return 175;
         else if (value == 3)
            return 167;
         else if (value == 4)
            return 159;
         else if (value == 5)
            return 150;
         else if (value == 6)
            return 141;
         else if (value == 7)
            return 133;
         else if (value == 8)
            return 125;
         else if (value == 9)
            return 116;
         else if (value == 10)
            return 108;
      }
      if (spread == 6) //7.14
      {
         value -= addspread*2;
         if (value <= 0)
            return 192;
         else if (value == 1)
            return 185;
         else if (value == 2)
            return 178;
         else if (value == 3)
            return 171;
         else if (value == 4)
            return 164;
         else if (value == 5)
            return 157;
         else if (value == 6)
            return 150;
         else if (value == 7)
            return 142;
         else if (value == 8)
            return 135;
         else if (value == 9)
            return 128;
         else if (value == 10)
            return 121;
         else if (value == 11)
            return 114;
         else if (value == 12)
            return 107;
      }
      if (spread == 7) //6.25
      {
         value -= addspread*2;
         if (value <= 0)
            return 193;
         else if (value == 1)
            return 187;
         else if (value == 2)
            return 181;
         else if (value == 3)
            return 175;
         else if (value == 4)
            return 168;
         else if (value == 5)
            return 162;
         else if (value == 6)
            return 156;
         else if (value == 7)
            return 150;
         else if (value == 8)
            return 143;
         else if (value == 9)
            return 137;
         else if (value == 10)
            return 131;
         else if (value == 11)
            return 125;
         else if (value == 12)
            return 118;
         else if (value == 13)
            return 112;
         else if (value == 14)
            return 106;
      }
      if (spread == 8) //5.55
      {
         value -= addspread*2;
         if (value <= 0)
            return 194; 
         else if (value == 1)
            return 188;
         else if (value == 2)
            return 183;
         else if (value == 3)
            return 177;
         else if (value == 4)
            return 172;
         else if (value == 5)
            return 166;
         else if (value == 6)
            return 161;
         else if (value == 7)
            return 155;
         else if (value == 8)
            return 150;
         else if (value == 9)
            return 144;
         else if (value == 10)
            return 138;
         else if (value == 11)
            return 133;
         else if (value == 12)
            return 127;
         else if (value == 13)
            return 122;
         else if (value == 14)
            return 116;
         else if (value == 15)
            return 111;
         else if (value == 16)
            return 105;
      }
   }
   if (crit == -1) //crit miss
   {
      roll = number_range(1, TOHIT_SYS);
      if (roll >= 8 && roll <= 10 && wield && !IS_OBJ_STAT(wield, ITEM_NOBREAK))
      {
         send_to_char("You damage your weapon with your lousy attack.\n\r", ch);
         if (wield->item_type == ITEM_MISSILE_WEAPON)
            wield->value[0] -= number_range(25, 60);
         else
            wield->value[0] -= number_range(50, 100);
         if (wield->value[0] <= 0)
         {
            make_scraps(wield, ch);
         }
      }
      else if (roll >= 14 && roll <= 19)
      {
         send_to_char("Your attack was so bad that you lose your balance and need to take some time to regain it.\n\r", ch);
         ch->fight_timer += number_range(UMAX(3, ch->fight_timer*1), UMAX(6, ch->fight_timer*2));
      }
   }
   if (crit == 1) //crit hit
   {
      int toinsta;
      int blimb = 0;
      roll = number_range(1,TOHIT_SYS);
      if (ch->grip == GRIP_STAB)
      {
         if (roll < TOHIT_SYS-2)
            roll+= 3;
         else
            roll = TOHIT_SYS;
      }
      if (perfect == 1)
         roll = TOHIT_SYS;
      if (roll == TOHIT_SYS && (limb == LM_HEAD || limb == LM_NECK || limb == LM_BODY) && !nodeath)
         return DM_DEATH;
      if (limb == LM_NECK && !nodeath)
      {
         toinsta = URANGE(TOHIT_SYS-14, TOHIT_SYS-10+ac, TOHIT_SYS-4);
         if (roll > toinsta)
            return DM_DEATH;
      }
      else if (limb == LM_HEAD)
      {
         toinsta = URANGE(TOHIT_SYS-10, TOHIT_SYS-6+ac, TOHIT_SYS-2);
         if (roll > toinsta)
            return DM_DEATH;
      }
      else
      {
         if (grip == GRIP_SLASH)
         {
            toinsta = number_range(1, 100)-ac;
            if (toinsta > 95)   
               blimb = 1;
         }
         if (grip == GRIP_BASH)
         {
            toinsta = number_range(1, 100)-ac;
            if (toinsta > 99)   
               blimb = 1;
         }
         if (pslice == 1)
            blimb = 1;
      }
      if (blimb == 0)
         return number_range(250, 350);
      else
         return number_range(-250, -350);
   }
   return DM_MISS;
}   
   	
int fight_unarmed(CHAR_DATA *ch)
{
   BUYKMOB_DATA *kmob;

   if (!IS_NPC(ch))
      return 0;
   if (!IN_WILDERNESS(ch))
      return 0;
   if (!xIS_SET(ch->act, ACT_MILITARY))
      return 0;
     
   for (kmob = first_buykmob; kmob; kmob = kmob->next)
   {
      if (kmob->vnum == ch->pIndexData->vnum)
      {
         if (xIS_SET(kmob->flags, KMOB_SOLDIERUNARMED))
            return 1;
      }
   }   	
   return 0;
}

int wielding_skill_weapon(CHAR_DATA *ch, int missile)
{
   OBJ_DATA *weapon;
   
    if ((weapon = get_eq_char(ch, WEAR_WIELD)) == NULL)
    {
       if (get_eq_char(ch, WEAR_MISSILE_WIELD) && missile)
          return 6;
       else
          return 0;
    }
    if (get_eq_char(ch, WEAR_MISSILE_WIELD) && missile)
       return 6;
    if (weapon->pIndexData->vnum >= OBJ_FORGE_HAND_AXE && weapon->pIndexData->vnum <= OBJ_FORGE_BATTLE_AXE)
       return 1;
    if (weapon->pIndexData->vnum >= OBJ_FORGE_SHORT_SWORD && weapon->pIndexData->vnum <= OBJ_FORGE_FLAMBERGE)
       return 2;
    if (weapon->pIndexData->vnum >= OBJ_FORGE_KNIFE && weapon->pIndexData->vnum <= OBJ_FORGE_STILETTO )
       return 7;
    if (weapon->pIndexData->vnum >= OBJ_FORGE_PILUM && weapon->pIndexData->vnum <= OBJ_FORGE_TRIDENT)
       return 3;
    if (weapon->pIndexData->vnum >= OBJ_FORGE_CLUB && weapon->pIndexData->vnum <= OBJ_FORGE_MAUL)
       return 4;
    if (weapon->pIndexData->vnum >= OBJ_FORGE_SCEPTRE && weapon->pIndexData->vnum <= OBJ_FORGE_BLADED_STAFF)
       return 5;
       
    if (IS_OBJ_STAT(weapon, ITEM_TYPE_AXE))
       return 1;
    if (IS_OBJ_STAT(weapon, ITEM_TYPE_SWORD))
       return 2;
    if (IS_OBJ_STAT(weapon, ITEM_TYPE_DAGGER))
       return 7;
    if (IS_OBJ_STAT(weapon, ITEM_TYPE_POLEARM))
       return 3;
    if (IS_OBJ_STAT(weapon, ITEM_TYPE_BLUNT))
       return 4;
    if (IS_OBJ_STAT(weapon, ITEM_TYPE_STAVES))
       return 5;
       
    return 0;
}  

//Type 0 - (ch is being hit) 1 - (ch is doing the hitting)
int get_fightingstyle_dam(CHAR_DATA *ch, int dam, CHAR_DATA *victim, int type, int learn)
{
   int level;
   int gsnstyle = gsn_style_standard;
   int newdam = 0;
   int dam1;
   int dam2;
   
   if (IS_NPC(ch))
      return dam;
      
   if (ch->style == STYLE_EVASIVE)
      gsnstyle = gsn_style_evasive;
   if (ch->style == STYLE_WIZARDRY)
      gsnstyle = gsn_style_wizardry;
   if (ch->style == STYLE_DIVINE)
      gsnstyle = gsn_style_divine;
   if (ch->position == POS_AGGRESSIVE)
      gsnstyle = gsn_style_aggressive;
   if (ch->position == POS_FIGHTING)
      gsnstyle = gsn_style_standard;
   if (ch->position == POS_BERSERK)
      gsnstyle = gsn_style_berserk;
   if (ch->position == POS_DEFENSIVE)
      gsnstyle = gsn_style_defensive;
      
   if (GET_MASTERY(ch, gsnstyle, 0, ch->level) <= 0)
      learn = 0;
         
   level = POINT_LEVEL(LEARNED(ch, gsnstyle), MASTERED(ch, gsnstyle)); 
   
   if (ch->position == POS_BERSERK)
   {
      if (type == 0)
         newdam = 5 - level/12;
      else
         newdam = 4 + level/12;
   }
   else if (ch->position == POS_AGGRESSIVE)
   {
      if (type == 0)
         newdam = 2 - level/12;
      else
         newdam = 2 + level/12;
   }
   else if (ch->position == POS_FIGHTING)
   {
      if (type == 0)
         newdam = 0 - level/12;
      else
         newdam = 0 + level/12;
   }
   else if (ch->position == POS_DEFENSIVE)
   {
      if (type == 0)
         newdam = -2 - level/12;
      else
         newdam = -2 + level/12;
   }
   else if (ch->position == POS_EVASIVE)
   {
      if (type == 0)
         newdam = -5 - level/12;
      else
         newdam = -4 + level/12;
   }
   dam1 = dam + newdam;
   dam2 = dam * (100+(newdam*3)) / 100;
   
   //If you are hitting choose the least amount of damage, if you are being hit choose the most
   if ((type == 1 && dam1 < dam2) || (type == 0 && dam1 > dam2))
      dam = dam1;
   else
      dam = dam2;
      
   if (learn)
      learn_from_success(ch, gsnstyle, victim);
   return dam;
}

	
/*
 * Hit one guy once.
 */
ch_ret one_hit(CHAR_DATA * ch, CHAR_DATA * victim, int dt, int limb)
{
   OBJ_DATA *wield;
   OBJ_DATA *dual;
   OBJ_DATA *shield;
   OBJ_DATA *eq;
   int victim_ac = 0;
   int armor_ac = 0;
   int weapon_ac = 0;
   int tohit;
   int plusris;
   int dam;
   int level;
   int miss = 0;
   int spec = DM_HIT;
   int holder = 1;
   int percent = 1;
   int counter = 0;
   int attacktype, cnt;
   int prof_bonus;
   ch_ret retcode = rNONE;
   sh_int mastery;
   sh_int hnum;
   int crit = 0;
   int block = 0;
   int suc = 0;
   int slimb = 0;
   int cond;
   AFFECT_DATA *paf;
   int noarmor = 0;
   BUYKMOB_DATA *kmob;

   dual = NULL;
   blockdam = 0;
   g_tohit = g_roll = g_lowtohit = g_hitohit = 0;
   /*
    * Can't beat a dead char!
    * Guard against weird room-leavings.
    */
   if (victim->position == POS_DEAD || ch->in_room != victim->in_room)
      return rVICT_DIED;

   if (get_eq_char(ch, WEAR_DUAL_WIELD) != NULL && dt != gsn_backstab)
   {
      if (number_range(1, 2) == 1)
         wield = get_eq_char(ch, WEAR_WIELD);
      else
         wield = get_eq_char(ch, WEAR_DUAL_WIELD);
   }
   else
      wield = get_eq_char(ch, WEAR_WIELD);
   
   //moved this here so it can use the right weapon for finding values....was moved from violence_update   
   if (IS_NPC(ch))
   {
      if (xIS_SET(ch->act, ACT_NOATTACK))
         return rNONE;
      if (wield && wield == get_eq_char(ch, WEAR_DUAL_WIELD))
      {
         dual = get_eq_char(ch, WEAR_WIELD);
         wield->wear_loc = WEAR_WIELD;
         dual->wear_loc = WEAR_DUAL_WIELD;
         limb = target_chooser(ch, victim);  //sets limb and grip
         dual->wear_loc = WEAR_WIELD;
         wield->wear_loc = WEAR_DUAL_WIELD;
      }      
      else
         limb = target_chooser(ch, victim); //sets limb and grip
   }
          
   //remove this later, but for now they need to be reset;  
   if (wield)
   {
      if (xIS_SET(wield->pIndexData->extra_flags, ITEM_TWOHANDED))
         xSET_BIT(wield->extra_flags, ITEM_TWOHANDED);
   }  
   
   if (victim->position == POS_RIDING)
   {
      victim->position = POS_STANDING;
      if (victim->riding)
      {
         victim->riding->rider = NULL;
         victim->riding = NULL;
      }
   }
   if (victim->rider)
   {
      victim->rider->riding = NULL;
      victim->rider->position = POS_STANDING;
      victim->rider = NULL;
   }

   prof_bonus = 0;
   
   if (!IS_NPC(ch) && ch->pcdata->learned[gsn_combatart] > 0 && wield)
   {
      learn_from_success(ch, gsn_combatart, victim);
   }
   if (dt == gsn_backstab || dt == gsn_circle || dt == gsn_kick_back)
   {
      ch->fight_timer = get_btimer(ch, -1, victim);
   }
   else if (dt < TYPE_PROJECTILE)
   {
      ch->fight_timer = get_btimer(ch, dt, victim);
   }
   else
   {
      ch->fight_timer = get_btimer(ch, -1, victim);
   }

   if (ch->fighting /* make sure fight is already started */
      && dt == TYPE_UNDEFINED && IS_NPC(ch) && !xIS_EMPTY(ch->attacks))
   {
      cnt = 0;
      for (;;)
      {
         attacktype = number_range(0, 6);
         if (xIS_SET(ch->attacks, attacktype))
            break;
         if (cnt++ > 16)
         {
            attacktype = -1;
            break;
         }
      }
      if (attacktype == ATCK_BACKSTAB)
         attacktype = -1;
      if (wield && number_percent() > 15)
         attacktype = -1;
      if (!wield && number_percent() > 30)
         attacktype = -1;

      switch (attacktype)
      {
         default:
            break;
         case ATCK_BITE:
            break;
         case ATCK_CLAWS:
            break;
         case ATCK_TAIL:
            break;
         case ATCK_STING:
            break;
         case ATCK_PUNCH:
            break;
         case ATCK_KICK:
            break;
         case ATCK_TRIP:
            attacktype = 0;
            break;
      }
      if (attacktype >= 0)
         return retcode;
   }

   if (dt == TYPE_UNDEFINED)
   {
      dt = TYPE_HIT;
   }

   /*
    * Replaces that thaco crap, back to a easier to identify base 20 ac
    */
   if ((eq = get_eq_char(victim, get_limb_location(limb))) == NULL)
   {
      if (IS_NPC(victim))
      {
         armor_ac = victim->armor;
         if (victim->armor == 0)
            noarmor = 1;
         if (limb == LM_HEAD)
            armor_ac += 2;
         else if (limb == LM_NECK)
            armor_ac += 3;          
      }
      else
         armor_ac = 0;
         
      if (ch->grip == GRIP_BASH)
      {
         if (wield)
            weapon_ac += wield->value[7];
         else
         {
            if (IS_NPC(ch))
               weapon_ac += ch->tohitbash;
         }
      }
      else if (ch->grip == GRIP_STAB)
      {
         if (wield)
            weapon_ac += wield->value[9];
         else
         {
            if (IS_NPC(ch))
               weapon_ac += ch->tohitstab;
         }
      }
      else if (ch->grip == GRIP_SLASH)
      {
         if (wield)
            weapon_ac += wield->value[8];
         else
         {
            if (IS_NPC(ch))
               weapon_ac += ch->tohitslash;
         }
      }
      else
      {
         if (wield)
            weapon_ac += wield->value[7];
         bug("one_hit: %s has a 0 value for grip.", ch->name);
      }
   }
   else
   {
      if (ch->grip == GRIP_BASH)
      {
         armor_ac = eq->value[0];
         if (wield)
            weapon_ac += wield->value[7];
         else
         {
            if (IS_NPC(ch))
               weapon_ac += ch->tohitbash;
         }
      }
      else if (ch->grip == GRIP_STAB)
      {
         armor_ac = eq->value[2];
         if (wield)
           weapon_ac += wield->value[9];
         else
         {
            if (IS_NPC(ch))
               weapon_ac += ch->tohitstab;
         }
      }
      else if (ch->grip == GRIP_SLASH)
      {
         armor_ac = eq->value[1];
         if (wield)
            weapon_ac += wield->value[8];
         else
         {
            if (IS_NPC(ch))
               weapon_ac += ch->tohitslash;
         }
      }
      else
      {
         armor_ac = eq->value[0];
         if (wield)
            weapon_ac += wield->value[7];
         bug("one_hit: %s has a 0 value for grip.", ch->name);
      }
   }
   if (armor_ac == 0)
      noarmor = 1;
   if (dt == gsn_backstab) //small bonus for backstab because it is not seen
      weapon_ac += 1;
      
   if (MASTERED(ch, gsn_backstab) >= 3 && dt == gsn_backstab) //another bonus for expert and master
      weapon_ac += 1;
      
   if (!wield && fight_unarmed(ch))
      weapon_ac += 5;
   if (eq)
      cond = eq->value[3];
   else
      cond = 1000*victim->hit/victim->max_hit;
   
   if (armor_ac > 0)
   {
      armor_ac -= (3 -(cond / 251));
      if (armor_ac < 1)
         armor_ac = 1;
   }
   if (IS_NPC(ch) && xIS_SET(ch->act, ACT_MILITARY))
   {
      for (kmob = first_buykmob; kmob; kmob = kmob->next)
      {
         if (kmob->vnum == ch->pIndexData->vnum)
         {
            if (xIS_SET(kmob->flags, KMOB_TOHIT1))
               weapon_ac+=1;
            if (xIS_SET(kmob->flags, KMOB_TOHIT2))
               weapon_ac+=2;
            if (xIS_SET(kmob->flags, KMOB_TOHIT3))
               weapon_ac+=4;
            if (xIS_SET(kmob->flags, KMOB_TOHIT4))
               weapon_ac+=6;
         }
      }
   }
   if (IS_NPC(victim) && xIS_SET(victim->act, ACT_MILITARY))
   {
      for (kmob = first_buykmob; kmob; kmob = kmob->next)
      {
         if (kmob->vnum == victim->pIndexData->vnum)
         {
            if (xIS_SET(kmob->flags, KMOB_AC1))
               armor_ac+=1;
            if (xIS_SET(kmob->flags, KMOB_AC2))
               armor_ac+=2;
            if (xIS_SET(kmob->flags, KMOB_AC3))
               armor_ac+=4;
            if (xIS_SET(kmob->flags, KMOB_AC4))
               armor_ac+=6;
         }
      }
   }         
   
   if (wield)
      cond = wield->value[0];
   else
      cond = 1000;
      
   if (weapon_ac > 0)
   {
      weapon_ac -= (3 -(cond / 251));
      if (weapon_ac < 1)
         weapon_ac = 1;
   }
   victim_ac = armor_ac - weapon_ac;  //negative is a better to hit
   /* if you can't see what's coming... */
   if (!can_see(ch, victim))
      victim_ac += 1;
   if (!can_see(victim, ch))
      victim_ac -= 1;

   /*
    * The moment of excitement!
    */
    
   if ((shield = get_eq_char(victim, WEAR_SHIELD)) != NULL && IS_AWAKE(victim))
   {
      int spoints = POINT_LEVEL(GET_POINTS(victim, gsn_shieldblock, 0, 1), GET_MASTERY(victim, gsn_shieldblock, 0, 1));
      if (spoints > 0 && number_range(1, 100) <= UMIN(95, (UMIN(15, URANGE(-20, victim->apply_shield, 20)/2))+ shield->value[2]+ (spoints/4)))
      {
         learn_from_success(victim, gsn_shieldblock, NULL);
         block = 1;
      }
      else
      {
         if (spoints > 0)
            learn_from_failure(victim, gsn_shieldblock, NULL);
      }
   }
   else if (victim->apply_shield > 0)
   {
      if (number_range(1, 100) <= URANGE(-20, victim->apply_shield, 20))
         block = 1;
   }
   
   tohit = get_hit_or_miss(ch, victim, victim_ac, ch->grip, limb, noarmor, wield, dt);
   if (dt == gsn_powerslice) //Don't really need this any longer after the hit or miss check
      dt = TYPE_HIT;
   if (tohit <= -200) //Crit and sliced off a limb
   {
      tohit = tohit*-1;
      slimb = 1;
   }
   if (tohit == DM_MISS || block) //miss or block
   {
      /* Miss. */
      miss = 1;
      if (!IS_NPC(ch) && number_range(1, 4) == 1)
         adjust_agi_str(ch, wield, victim); //adjust agility and strength from attack
   }
   else //hit
   {
      if (!IS_NPC(ch))
         adjust_agi_str(ch, wield, victim); //adjust agility and strength from attack
   }
   /*
    * Calc damage.
    */

   if (!wield) /* bare hand dice formula fixed by Thoric */
   {
      dam = number_range(ch->barenumdie+ch->damplus, (ch->baresizedie * ch->barenumdie)+ch->damplus);
      if (fight_unarmed(ch))
         dam+=number_range(4, 6);
   }
   else
   {
      dam = number_range(wield->value[1], wield->value[2]);
      if (IS_OBJ_STAT(wield, ITEM_TWOHANDED) && ch->race < MAX_PC_RACE)
      {
         int tpoints = POINT_LEVEL(LEARNED(ch, gsn_weapon_twohanded), MASTERED(ch, gsn_weapon_twohanded));
         int tmod = wield->value[3] - race_table[ch->race]->weaponmin + 1;
         int tpercent = 0;
         if (tmod >= 5 && LEARNED(ch, gsn_weapon_twohanded))
         {
            learn_from_success(ch, gsn_weapon_twohanded, victim);
            tpercent += tpoints*2/5;
            if (tmod == 5)
               dam += dam * tpercent / 100;
            if (tmod == 6)
               dam += dam * tpercent * 2 / 100;
            if (tmod == 7)
               dam += dam * tpercent * 3 / 100;
         }
         
      }
   }

   dam += str_app[get_curr_str(ch)].todam; //Strength Bonus   
   if (dam <= 3)
   {
      if (number_range(1, 5) == 1)
         suc = 1;
   }
   else if (dam <= 6)
   {
      if (number_range(1, 3) == 1)
         suc = 1;
   }
   else if (dam <= 10)
   {
      if (number_range(1, 2) == 1)
         suc = 1;
   }
   else
      suc = 1;
   
   if (miss == 0 && (IS_NPC(victim) && !xIS_SET(victim->act, ACT_NOINSTA))) //Cannot crit mobs flagged noinsta
   {
      if (tohit == DM_DEATH)
         crit = 1; //Death
   }
   if (miss != 1)
   {
      dam -= URANGE(-6, victim->apply_stone, 6);
      dam -= URANGE(-4, victim->apply_hardening, 4);
      if (victim->apply_hardening > 0)
         check_aff_learn(victim, "hardening", 0, ch, 1);
      if (!IS_NPC(victim) && victim->pcdata->learned[gsn_krundi_style] > 0)
      {
         int level;
         level = POINT_LEVEL(LEARNED(victim, gsn_krundi_style), MASTERED(victim, gsn_krundi_style));
         level = number_range(level*3, level*4);
         level += 100;
         level = URANGE(100, level, 600);
         dam -= level/100;
         level = level % 100;
         if (number_range(1, 100) <= level)
         {
            dam--;
         }
         learn_from_success(victim, gsn_krundi_style, ch);  
      }  
      dam = UMAX(1, dam);   
   }
   //Calculated fightstyle damage
   if (miss != 1 && suc)
   {
      dam = get_fightingstyle_dam(victim, dam, ch, 0, 1);
      dam = get_fightingstyle_dam(ch, dam, victim, 1, 1);
   }
   else
   {
      dam = get_fightingstyle_dam(victim, dam, ch, 0, 0);
      dam = get_fightingstyle_dam(ch, dam, victim, 1, 0);   
   }
   if (!IS_NPC(ch) && ch->pcdata->learned[gsn_concentration] > 0)
   {
      int dam1, dam2;
      level = POINT_LEVEL(LEARNED(ch, gsn_concentration), MASTERED(ch, gsn_concentration));
      mastery = MASTERED(ch, gsn_concentration);
      
      dam1 = level/15;

      if (mastery == 6)
         hnum = number_range(35, 30);
      else if (mastery == 5)
         hnum = number_range(30, 25);
      else if (mastery == 4)
         hnum = number_range(18, 25);
      else if (mastery == 3)
         hnum = number_range(10, 17);
      else if (mastery == 2)
         hnum = number_range(5, 10);
      else
         hnum = number_range(1, 5);
      dam2 = (int) (dam * hnum / 150);
      
      if (dam1 < dam2)
         dam += dam1;
      else
         dam += dam2;
      if (miss != 1 && suc)
         learn_from_success(ch, gsn_concentration, victim);
   }
   if (!IS_NPC(ch) && ch->pcdata->learned[gsn_enhanced_damage] > 0)
   {
      int dam1, dam2;
      level = POINT_LEVEL(LEARNED(ch, gsn_enhanced_damage), MASTERED(ch, gsn_enhanced_damage));
      mastery = MASTERED(ch, gsn_enhanced_damage);
      
      dam1 = level/10;

      if (mastery == 6)
         hnum = number_range(35, 30);
      else if (mastery == 5)
         hnum = number_range(30, 25);
      else if (mastery == 4)
         hnum = number_range(18, 25);
      else if (mastery == 3)
         hnum = number_range(10, 17);
      else if (mastery == 2)
         hnum = number_range(5, 10);
      else
         hnum = number_range(1, 5);
      dam2 = (int) (dam * hnum / 100);
      
      if (dam1 < dam2)
         dam += dam1;
      else
         dam += dam2;
      if (miss != 1 && suc)
         learn_from_success(ch, gsn_enhanced_damage, victim);
   }
   if (!IS_NPC(ch) && ch->pcdata->learned[gsn_deadly_accuracy] > 0)
   {
      int dam1, dam2;
      level = POINT_LEVEL(LEARNED(ch, gsn_deadly_accuracy), MASTERED(ch, gsn_deadly_accuracy));
      mastery = MASTERED(ch, gsn_deadly_accuracy);
      
      dam1 = level/15;

      if (mastery == 6)
         hnum = number_range(35, 30);
      else if (mastery == 5)
         hnum = number_range(30, 25);
      else if (mastery == 4)
         hnum = number_range(18, 25);
      else if (mastery == 3)
         hnum = number_range(10, 17);
      else if (mastery == 2)
         hnum = number_range(5, 10);
      else
         hnum = number_range(1, 5);

      dam2 = (int) (dam * hnum / 150);
      
      if (dam1 < dam2)
         dam += dam1;
      else
         dam += dam2;
      if (miss != 1 && suc)
         learn_from_success(ch, gsn_deadly_accuracy, victim);
   }
   if (!IS_NPC(ch) && wielding_skill_weapon(ch, 0))
   {
      int wskill = wielding_skill_weapon(ch, 0);
      if (wskill == 1)
      {
         if (ch->pcdata->learned[gsn_weapon_axe] > 0)
         {
            dam += UMAX(1, dam * POINT_LEVEL(LEARNED(ch, gsn_weapon_axe), MASTERED(ch, gsn_weapon_axe)) / 600);
            if (miss != 1 && suc)
               learn_from_success(ch, gsn_weapon_axe, victim);
         }
      }
      if (wskill == 2)
      {
         if (ch->pcdata->learned[gsn_weapon_sword] > 0)
         {
            dam += UMAX(1, dam * POINT_LEVEL(LEARNED(ch, gsn_weapon_sword), MASTERED(ch, gsn_weapon_sword)) / 600);
            if (miss != 1 && suc)
               learn_from_success(ch, gsn_weapon_sword, victim);
         }
      }
      if (wskill == 3)
      {
         if (ch->pcdata->learned[gsn_weapon_polearm] > 0)
         {
            dam += UMAX(1, dam * POINT_LEVEL(LEARNED(ch, gsn_weapon_polearm), MASTERED(ch, gsn_weapon_polearm)) / 600);
            if (miss != 1 && suc)
               learn_from_success(ch, gsn_weapon_polearm, victim);
         }
      }
      if (wskill == 4)
      {
         if (ch->pcdata->learned[gsn_weapon_blunt] > 0)
         {
            dam += UMAX(1, dam * POINT_LEVEL(LEARNED(ch, gsn_weapon_blunt), MASTERED(ch, gsn_weapon_blunt)) / 600);
            if (miss != 1 && suc)
               learn_from_success(ch, gsn_weapon_blunt, victim);
         }
      }
      if (wskill == 5)
      {
         if (ch->pcdata->learned[gsn_weapon_staff] > 0)
         {
            dam += UMAX(1, dam * POINT_LEVEL(LEARNED(ch, gsn_weapon_staff), MASTERED(ch, gsn_weapon_staff)) / 600);
            if (miss != 1 && suc)
               learn_from_success(ch, gsn_weapon_staff, victim);
         }
      }
      if (wskill == 7)
      {
         if (ch->pcdata->learned[gsn_weapon_dagger] > 0)
         {
            dam += UMAX(1, dam * POINT_LEVEL(LEARNED(ch, gsn_weapon_dagger), MASTERED(ch, gsn_weapon_dagger)) / 600);
            if (miss != 1 && suc)
               learn_from_success(ch, gsn_weapon_dagger, victim);
         }
         if (ch->pcdata->learned[gsn_weapon_daggerstudy] > 0)
         {
            dam += UMAX(1, dam * POINT_LEVEL(LEARNED(ch, gsn_weapon_daggerstudy), MASTERED(ch, gsn_weapon_daggerstudy)) / 600);
            if (miss != 1 && suc)
               learn_from_success(ch, gsn_weapon_daggerstudy, victim);
         }
         if (ch->pcdata->learned[gsn_weapon_daggerstrike] > 0)
         {
            dam += UMAX(1, dam * POINT_LEVEL(LEARNED(ch, gsn_weapon_daggerstrike), MASTERED(ch, gsn_weapon_daggerstrike)) / 300);
            if (miss != 1 && suc)
               learn_from_success(ch, gsn_weapon_daggerstrike, victim);
         }
      }
   }
   for (paf = ch->first_affect; paf; paf = paf->next)
   {
      if (paf->type == gsn_berserk);
      {
         dam += UMAX(1, dam * UMIN(paf->modifier/2, 40) / 150);
         break;
      }
   }
      
   if (!IS_AWAKE(victim))
      dam *= 2;
   if (dt == gsn_backstab)
   {
      level = POINT_LEVEL(LEARNED(ch, gsn_backstab), MASTERED(ch, gsn_backstab));
      dam = dam * (150 + (URANGE(25, ((get_curr_dex(ch) - get_curr_dex(victim))*12) + (level*2), 200))) / 100;
   } 
   if (dt == gsn_circle)
   {
      level = POINT_LEVEL(LEARNED(ch, gsn_circle), MASTERED(ch, gsn_circle));
      dam = dam * (150 + (URANGE(25, ((get_curr_dex(ch) - get_curr_dex(victim))*12) + (level*2), 200))) / 150;
   }
   if (dt == gsn_unsheath)
   {
      dam = dam * (number_range(110, 180) / 100);
   }
   /* New Circle like Attack for Swordsman -- Xerves 8/6/99 */
   if (dt == gsn_kick_back)
   {
      level = POINT_LEVEL(LEARNED(ch, gsn_kick_back), MASTERED(ch, gsn_kick_back));
      dam = dam * (150 + (URANGE(25, ((get_curr_str(ch) - get_curr_str(ch))*12) + (level*2), 200))) / 150;
   }
   if (dt == gsn_pincer)
   {
      int plevel;
      plevel = POINT_LEVEL(LEARNED(ch, gsn_pincer), MASTERED(ch, gsn_pincer));
      dam = dam * URANGE(170, (170 + plevel), 240) / 100;
   }
   if (!IS_NPC(victim) && victim->pcdata->learned[gsn_counter] > 0 && victim->pcdata->ranking[gsn_counter] > 0 && !xIS_SET(victim->act, PLR_COUNTER))
   {
      percent = number_range(1, 10000);
      mastery = MASTERED(ch, gsn_counter);

      if (mastery == 6)
         hnum = number_range(220, 200);
      else if (mastery == 5)
         hnum = number_range(180, 160);
      else if (mastery == 4)
         hnum = number_range(135, 150);
      else if (mastery == 3)
         hnum = number_range(90, 105);
      else if (mastery == 2)
         hnum = number_range(50, 90);
      else
         hnum = number_range(20, 45);

      holder = 100 * (hnum / 20);

      if (victim->pcdata->tier > 1)
         holder = holder + 200;
      if (victim->pcdata->caste > 5)
         holder = holder + 100;
      holder += 100 * (get_curr_dex(victim) - get_curr_dex(ch));
      holder += 50 * (get_curr_lck(victim) - get_curr_lck(ch));
      holder += 100 * (get_curr_str(victim) - get_curr_str(ch));
      if (percent < holder)
      {
         counter = 1;
         learn_from_success(victim, gsn_counter, ch);
      }
   } 
   if (dam <= 0)
      dam = 1;
 
   if (IS_NPC(ch))
   {
      dam += number_range(ch->damaddlow, ch->damaddhi);
   }  

   plusris = 0;
   /* immune to damage */
   if (dam == -1)
   {
      if (dt >= 0 && dt < top_sn)
      {
         SKILLTYPE *skill = skill_table[dt];
         bool found = FALSE;

         if (skill->imm_char && skill->imm_char[0] != '\0')
         {
            act(AT_HIT, skill->imm_char, ch, NULL, victim, TO_CHAR);
            found = TRUE;
         }
         if (skill->imm_vict && skill->imm_vict[0] != '\0')
         {
            act(AT_HITME, skill->imm_vict, ch, NULL, victim, TO_VICT);
            found = TRUE;
         }
         if (skill->imm_room && skill->imm_room[0] != '\0')
         {
            act(AT_ACTION, skill->imm_room, ch, NULL, victim, TO_NOTVICT);
            found = TRUE;
         }
         if (found)
            return rNONE;
      }
      dam = 0;
   }
   /* Counter Attack Check -- Xerves 8/25/99 */
   if (counter == 1)
   {  
      retcode = damage(victim, ch, dam, TYPE_HIT, DM_COUNTER, LM_BODY);
      return retcode;
   }
   if (block == 1)
   {
      blockdam = dam;
      dam = 0;    
   }
   if (miss == 0)
      spec = DM_HIT;
   if (miss == 1)
      spec = DM_MISS;
   if (crit == 1)
      spec = DM_DEATH;
   if (dt == gsn_pincer && tohit >= 300)
   {
      spec = DM_HIT;
      tohit = 200;
   }
   if (spec == DM_HIT)
   {
      dam = dam * (tohit-100) / 100;
      if (dam <= 0)
         dam = 1;
   }
   if (tohit >= 250)
   {
      if (slimb == 1)
         spec = DM_SLICEDLIMB;
      else
         spec = DM_CRITICAL;
   }
   if (block == 1)
      spec = DM_BLOCK;
      
   if (limb == LM_RLEG || limb == LM_LLEG)
      dam = dam * 110 / 100;
   if (limb == LM_LARM || limb == LM_RARM)
      dam = dam * 105 / 100;
   if (limb == LM_HEAD)
      dam = dam * 150 / 100;  
   //Already critical don't change
   if (limb == LM_NECK)
      dam = dam * 100 / 100;  
   
   if (spec == DM_HIT)
   {
      dam += URANGE(-15, ch->apply_sanctify, 15);  
      
      if (ch->apply_manaburn > 0)
         check_aff_learn(ch, "manaburn", 0, victim, 1);
      dam += URANGE(-10, ch->apply_manaburn, 10);  
   }
   //Want the melee's to pinch a bit, mainly need this vs players.   
   if (spec == DM_HIT && IS_NPC(ch) && xIS_SET(ch->act, ACT_MILITARY))
   {
      for (kmob = first_buykmob; kmob; kmob = kmob->next)
      {
         if (kmob->vnum == ch->pIndexData->vnum)
         {
            if (xIS_SET(kmob->flags, KMOB_DAM1))
               dam+=2;
            if (xIS_SET(kmob->flags, KMOB_DAM2))
               dam+=3;
            if (xIS_SET(kmob->flags, KMOB_DAM3))
               dam+=5;
            if (xIS_SET(kmob->flags, KMOB_DAM4))
               dam+=7;
         }
      }
   }
      
   if (miss == 0 && dam <= 0)
      dam = 1;

   if (wield && wield->wear_loc == WEAR_DUAL_WIELD)
   {
      if ((dual = get_eq_char(ch, WEAR_WIELD)) != NULL)
      {
         wield->wear_loc = WEAR_WIELD;
         dual->wear_loc = WEAR_DUAL_WIELD;
      }
   }
   if ((retcode = damage(ch, victim, dam, dt, spec, limb)) != rNONE)
   {
      if (dual && dual->wear_loc != -1)
         dual->wear_loc = WEAR_WIELD;
      if (wield && dual && wield->wear_loc != -1)
         wield->wear_loc = WEAR_DUAL_WIELD;
      if (wield && !dual && wield->wear_loc != -1)
         wield->wear_loc = WEAR_WIELD;
   }
   else
   {
      if (dual && dual->wear_loc != -1)
         dual->wear_loc = WEAR_WIELD;
      if (wield && dual && wield->wear_loc != -1)
         wield->wear_loc = WEAR_DUAL_WIELD;
      if (wield && !dual && wield->wear_loc != -1)
         wield->wear_loc = WEAR_WIELD;
   }
   if (char_died(ch))
      return rCHAR_DIED;
   if (char_died(victim))
      return rVICT_DIED;

   retcode = rNONE;
   if (dam == 0)
      return retcode;

   tail_chain();
   return retcode;
}

/*
 * Hit one guy with a projectile.
 * Handles use of missile weapons (wield = missile weapon)
 * or thrown items/weapons
 */

// Moved to archery.c
//ch_ret projectile_hit( CHAR_DATA *ch, CHAR_DATA *victim, OBJ_DATA *wield,
//         OBJ_DATA *projectile, sh_int dist )

/*
 * Calculate damage based on resistances, immunities and suceptibilities
 *					-Thoric
 */
sh_int ris_damage(CHAR_DATA * ch, sh_int dam, int ris)
{
   sh_int modifier = 0;
   
   if (ris == RIS_FIRE)
      modifier = ch->apply_res_fire[0];
   if (ris == RIS_WATER)
      modifier = ch->apply_res_water[0];
   if (ris == RIS_EARTH)
      modifier = ch->apply_res_earth[0];
   if (ris == RIS_ENERGY)
      modifier = ch->apply_res_energy[0];
   if (ris == RIS_AIR)
      modifier = ch->apply_res_air[0];
   if (ris == RIS_NONMAGIC)
      modifier = ch->apply_res_nonmagic[0];
   if (ris == RIS_MAGIC)
      modifier = ch->apply_res_magic[0];
   if (ris == RIS_BLUNT)
      modifier = ch->apply_res_blunt[0];
   if (ris == RIS_PIERCE)
      modifier = ch->apply_res_pierce[0];
   if (ris == RIS_SLASH)
      modifier = ch->apply_res_slash[0];
   if (ris == RIS_PARALYSIS)
      modifier = ch->apply_res_paralysis[0];
   if (ris == RIS_POISON)
      modifier = ch->apply_res_poison[0];
   if (ris == RIS_UNDEAD)
      modifier = ch->apply_res_undead[0];
   if (ris == RIS_UNHOLY)
      modifier = ch->apply_res_unholy[0];
   if (ris == RIS_HOLY)
      modifier = ch->apply_res_holy[0];
      
   if (modifier >= -499 && modifier <= 0)
      modifier = 1;
   if (modifier == -500)
      return -1;
      
   if ((ris == RIS_FIRE || ris == RIS_WATER || ris == RIS_EARTH || ris == RIS_ENERGY || ris == RIS_AIR
   || ris == RIS_UNHOLY || ris == RIS_HOLY || ris == RIS_UNDEAD) && ch->apply_res_magic[0] != 0)
   {
      if (IS_SET(ch->immune, RIS_MAGIC) && !IS_SET(ch->no_immune, RIS_MAGIC))
         return -1;
      if (ch->apply_res_magic[0] == -500)
         return -1;
      if (modifier == 100)
         modifier = ch->apply_res_magic[0];
      if (modifier == 0)
         modifier = 100;
      else if (modifier < 100 && ch->apply_res_magic[0] < 100 && ch->apply_res_magic[0] < modifier)
         modifier = ch->apply_res_magic[0];
      else if (modifier > 100 && ch->apply_res_magic[0] > 100 && ch->apply_res_magic[0] > modifier)
         modifier = ch->apply_res_magic[0];
      else if ((modifier < 100 && ch->apply_res_magic[0] > 100) || (modifier > 100 && ch->apply_res_magic[0] < 100))
      {
         if (modifier > 100)
            modifier = modifier - (100-ch->apply_res_magic[0]);
         else
            modifier = ch->apply_res_magic[0] - (100-modifier);
      }
      if (IS_SET(ch->resistant, RIS_MAGIC) && !IS_SET(ch->no_resistant, RIS_MAGIC) && modifier == 100)
         modifier -= 30;
      if (IS_SET(ch->susceptible, RIS_MAGIC) && !IS_SET(ch->no_susceptible, RIS_MAGIC) && modifier == 100)
         modifier += 50;
   }
   if ((ris == RIS_BLUNT || ris == RIS_PIERCE || ris == RIS_SLASH || ris == RIS_POISON || ris == RIS_PARALYSIS)
   &&  ch->apply_res_nonmagic[0] != 0)
   {
      if (IS_SET(ch->immune, RIS_NONMAGIC) && !IS_SET(ch->no_immune, RIS_NONMAGIC))
         return -1;
      if (ch->apply_res_nonmagic[0] == -500)
         return -1;
      if (modifier == 100)
         modifier = ch->apply_res_nonmagic[0];
      if (modifier < 100 && ch->apply_res_nonmagic[0] < 100 && ch->apply_res_nonmagic[0] < modifier)
         modifier = ch->apply_res_nonmagic[0];
      if (modifier > 100 && ch->apply_res_nonmagic[0] > 100 && ch->apply_res_nonmagic[0] > modifier)
         modifier = ch->apply_res_nonmagic[0];
      if ((modifier < 100 && ch->apply_res_nonmagic[0] > 100) || (modifier > 100 && ch->apply_res_nonmagic[0] < 100))
      {
         if (modifier > 100)
            modifier = modifier - (100-ch->apply_res_nonmagic[0]);
         else
            modifier = ch->apply_res_nonmagic[0] - (100-modifier);
      }
      if (IS_SET(ch->resistant, RIS_NONMAGIC) && !IS_SET(ch->no_resistant, RIS_NONMAGIC) && modifier == 100)
         modifier -= 30;
      if (IS_SET(ch->susceptible, RIS_NONMAGIC) && !IS_SET(ch->no_susceptible, RIS_NONMAGIC) && modifier == 100)
         modifier += 50;
   }

   if (IS_SET(ch->immune, ris) && !IS_SET(ch->no_immune, ris))
      return -1;
   if (IS_SET(ch->resistant, ris) && !IS_SET(ch->no_resistant, ris) && modifier == 100)
      modifier -= 30;
   if (IS_SET(ch->susceptible, ris) && !IS_SET(ch->no_susceptible, ris) && modifier == 100)
      modifier += 50;
   return (dam * modifier) / 100;
}

int get_sore_rate(int race, int maxhp)
{
   if (race == RACE_HUMAN)
      maxhp*=3;
   if (race == RACE_ELF)
      maxhp*=2.8;
   if (race == RACE_HOBBIT)
      maxhp*=2.5;
   if (race == RACE_FAIRY)
      maxhp*=2.1;
   if (race == RACE_DWARF)
      maxhp*=4;
   if (race == RACE_OGRE)
      maxhp*=5;
      
   return URANGE(1, maxhp, 9999);
}

int adjust_mil_damage(CHAR_DATA *ch, int dam)
{
   CHAR_DATA *victim;
   BUYKMOB_DATA *kmob;

   if (!IS_NPC(ch))
      return 0;
   if (!IN_WILDERNESS(ch))
      return 0;
   if (!xIS_SET(ch->act, ACT_MILITARY))
      return 0;
   if (dam == 0)
      return 0;
   
   for (victim = ch->in_room->first_person; victim; victim = victim->next_in_room)
   {
      if (!xIS_SET(victim->act, ACT_MILITARY))
         continue;
      for (kmob = first_buykmob; kmob; kmob = kmob->next)
      {
         if (kmob->vnum == victim->pIndexData->vnum)
            if (xIS_SET(kmob->flags, KMOB_SOLDIERDAM))  
               if (abs(ch->coord->x - victim->coord->x) <= 10 && abs(ch->coord->y - victim->coord->y) <= 10
               && ch->m4 == victim->m4)
                  break;
      }
      if (kmob)
         return UMAX(1, dam*25/100);
   }
   return 0;
}  

int player_stat_worth(CHAR_DATA *ch)
{
   int points = 0;
   int sn;
   
   if (IS_NPC(ch))
      return 0;
      
   for (sn = 0; sn < top_sn && skill_table[sn] && skill_table[sn]->name; sn++)
   {
      points += ch->pcdata->learned[sn];
   }
   points /=3;
   points += ch->max_hit/2;
   points += ch->max_mana/2;
   points += (ch->perm_str - (13+race_table[ch->race]->str_plus)) * 5;
   points += (ch->perm_lck - (13+race_table[ch->race]->lck_plus)) * 5;
   points += (ch->perm_con - (13+race_table[ch->race]->con_plus)) * 5;
   points += (ch->perm_dex - (13+race_table[ch->race]->dex_plus)) * 5;
   points += (ch->perm_int - (13+race_table[ch->race]->int_plus)) * 5;
   points += (ch->perm_wis - (13+race_table[ch->race]->wis_plus)) * 5;
   points += (ch->perm_str - (13+race_table[ch->race]->str_plus)) * 5;
   points += (ch->perm_agi - 15)/2;
   points *= points/2;
   return points;
}

int eqworth_affcheck2(OBJ_DATA *obj, AFFECT_DATA *paf)
{
   int mod;
   int points = 0;
   mod = paf->modifier;
   switch (paf->location % REVERSE_APPLY)
   {
      default:
         bug("eqworth_affcheck2: unknown location %d.", paf->location);
         return 0;
         
      case APPLY_ARMOR:
         if (mod > 0)
            points += 5000*mod;
         break;
      case APPLY_SHIELD:
         if (mod > 0)
            points += 2000*mod;
         break;
      case APPLY_STONE:
         if (mod > 0)
            points += 7000*mod;
         break;
      case APPLY_SANCTIFY:
         if (mod > 0)
            points += 10000*mod;
         break;
      case APPLY_WMOD:
         if (mod < 100)
            points += 500*(100-mod);
         break;         
         
      case APPLY_RFIRE:
      case APPLY_RWATER:
      case APPLY_RAIR:
      case APPLY_REARTH:
      case APPLY_RENERGY:
      case APPLY_RMAGIC:
      case APPLY_RNONMAGIC:
      case APPLY_RBLUNT:
      case APPLY_RPIERCE:
      case APPLY_RSLASH:
      case APPLY_RPOISON:
      case APPLY_RPARALYSIS:
      case APPLY_RHOLY:
      case APPLY_RUNHOLY:
      case APPLY_RUNDEAD:
         if (mod < 100)
            points += 500*(100-mod);
         break;
      case APPLY_MANAFUSE:
         if (mod > 0)
            points += 800*mod;
      case APPLY_FASTING:
         if (mod > 0)
            points += 800*mod;
         break;
      case APPLY_MANASHELL:
         if (mod > 0)
            points += 800*mod;
         break;
      case APPLY_MANASHIELD:
         if (mod > 0)
            points += 800*mod;
         break;
      case APPLY_MANAGUARD:
         if (mod > 0)
            points += 800*mod;
         break;
         
      case APPLY_MANABURN:
         if (mod > 0)
            points += 800*mod;
         break;
      case APPLY_WEAPONCLAMP:
         if (mod > 0)
            points += 800*mod;
         break;  
      case APPLY_ARROWCATCH:
         if (mod > 0)
            points += 800*mod;
         break;  
      case APPLY_BRACING:
         if (mod > 0)
            points += 800*mod;
         break;    
      case APPLY_HARDENING:
         if (mod > 0)
            points += 800*mod;
         break;   
      case APPLY_TOHIT:
         if (mod > 0)
            points += 3000*mod;
         break;
      case APPLY_MANATICK:
         if (mod > 100)
            points += 100*(mod-100);
         break;
      case APPLY_HPTICK:
         if (mod > 100)
            points += 100*(mod-100);
         break;
      case APPLY_STR:
         if (mod > 0)
            points += 7000*mod;
         break;
      case APPLY_DEX:
         if (mod > 0)
            points += 7000*mod;
         break;
      case APPLY_INT:
         if (mod > 0)
            points += 7000*mod;
         break;
      case APPLY_WIS:
         if (mod > 0)
            points += 7000*mod;
         break;
      case APPLY_CON:
         if (mod > 0)
            points += 7000*mod;
         break;
      case APPLY_CHA:
         if (mod > 0)
            points += 7000*mod;
         break;
      case APPLY_LCK:
         if (mod > 0)
            points += 7000*mod;
         break;
      case APPLY_AGI:
         if (mod > 0)
            points += 7000*mod;
         break;
      case APPLY_MANA:
         if (mod > 0)
            points += 800*mod;
         break;
      case APPLY_HIT:
         if (mod > 0)
            points += 800*mod;
         break;
      case APPLY_SAVING_POISON:
         if (mod < 0)
            points += -300*mod;
         break;
      case APPLY_SAVING_ROD:
         if (mod < 0)
            points += -300*mod;
         break;
      case APPLY_SAVING_PARA:
         if (mod < 0)
            points += -300*mod;
         break;
      case APPLY_SAVING_BREATH:
         if (mod < 0)
            points += -300*mod;
         break;
      case APPLY_SAVING_SPELL:
         if (mod < 0)
            points += -300*mod;
         break;
      case APPLY_AFFECT:
         points += 5000;
         break;
      case APPLY_EXT_AFFECT:
         points += 5000;
         break;
      case APPLY_RESISTANT:
         points += 5000;
         break;
      case APPLY_IMMUNE:
         points += 50000;
         break;
      case APPLY_WEAPONSPELL: /* see fight.c */
         points += 50000;
         break;

      case APPLY_WEARSPELL:
      case APPLY_REMOVESPELL:
         points += 30000;
         break;
       
      case APPLY_TRACK:
      case APPLY_HIDE:
      case APPLY_STEAL:
      case APPLY_SNEAK:
      case APPLY_PICK:
      case APPLY_BACKSTAB:
      case APPLY_DETRAP:
      case APPLY_DODGE:
      case APPLY_PEEK:
      case APPLY_SCAN:
      case APPLY_GOUGE:
      case APPLY_SEARCH:
      case APPLY_DIG:
      case APPLY_DISARM:
      case APPLY_PARRY:
      case APPLY_STUN:
      case APPLY_CLIMB:
      case APPLY_GRIP:
      case APPLY_SCRIBE:
      case APPLY_BREW:
      case APPLY_COOK:
         if (mod > 0)
            points += 5000*mod;
         break;

      case APPLY_ROOMFLAG:
      case APPLY_KICK:
      case APPLY_SUSCEPTIBLE:
      case APPLY_REMOVE:
      case APPLY_SEX:
      case APPLY_CLASS:
      case APPLY_LEVEL:
      case APPLY_AGE:
      case APPLY_NONE:
      case APPLY_GOLD:
      case APPLY_EXP:
      case APPLY_HEIGHT:
      case APPLY_WEIGHT:
      case APPLY_FULL:
      case APPLY_THIRST:
      case APPLY_DRUNK:
      case APPLY_MOVE:
      case APPLY_HITROLL:
      case APPLY_DAMROLL:
      case APPLY_BLOOD:
      case APPLY_MENTALSTATE:
      case APPLY_EMOTION:
      case APPLY_CONTAGIOUS:
      case APPLY_ODOR:
      case APPLY_STRIPSN:
      case APPLY_PALM: 
      case APPLY_MOUNT:
      case APPLY_BASH:
      case APPLY_SECTORTYPE:
      case APPLY_ROOMLIGHT:
      case APPLY_PUNCH:
      case APPLY_TELEVNUM:
         break;
   }
   return points;
}

int eqworth_affcheck(OBJ_DATA *obj)
{
   AFFECT_DATA *paf;
   int points = 0;
   
   for (paf = obj->pIndexData->first_affect; paf; paf = paf->next)
      points += eqworth_affcheck2(obj, paf);
   for (paf = obj->first_affect; paf; paf = paf->next)
      points += eqworth_affcheck2(obj, paf);
      
   return points;
}

int eqworth_statcheck(OBJ_DATA *obj)
{
   int points = 0;
   int avdam;
   int mdiff;
   if (obj->item_type == ITEM_MISSILE_WEAPON)
   {
      avdam = (obj->value[1]+obj->value[2])/2;
      points += UMAX(1, avdam * avdam/2)*100;  
      points += UMAX(1, obj->value[9] * obj->value[9]/2)*100;  
      points += UMAX(1, obj->value[10] * obj->value[10]/2)*100;  
   }     
   if (obj->item_type == ITEM_PROJECTILE)
   {
      avdam = (obj->value[1]+obj->value[2])/2;
      points += UMAX(1, avdam * avdam/2)*100;   
      points += UMAX(1, obj->value[9] * obj->value[9]/2)*100;  
   }
   if (obj->item_type == ITEM_WEAPON)
   {
      avdam = (obj->value[1]+obj->value[2])/2;
      points += UMAX(1, avdam * avdam/2)*100;
      if (obj->value[4] > 0 && obj->value[5] >= 1001 && obj->value[5] <= 1007)
      {
         mdiff = skill_table[obj->value[4]]->masterydiff[0];
         points += 1000*mdiff*mdiff*mdiff;
      }
      points += UMAX(1, obj->value[7] * obj->value[7]/2)*100;   
      points += UMAX(1, obj->value[8] * obj->value[8]/2)*100;   
      points += UMAX(1, obj->value[9] * obj->value[9]/2)*100;  
      points += UMAX(1, obj->value[10] * obj->value[10]/2)*100;  
   }
   if (obj->item_type == ITEM_ARMOR && !IS_SET(obj->wear_flags, ITEM_WEAR_SHIELD))
   {
      points += UMAX(1, obj->value[0] * obj->value[0]/2)*100;   
      points += UMAX(1, obj->value[1] * obj->value[1]/2)*100;   
      points += UMAX(1, obj->value[2] * obj->value[2]/2)*100;   
      points += UMAX(1, obj->value[4] * obj->value[4]/2)*100;  
   }
   if (obj->item_type == ITEM_ARMOR && IS_SET(obj->wear_flags, ITEM_WEAR_SHIELD))
   {
      points += obj->value[0]*10;
   }
   return points;
}
   
int player_equipment_worth(CHAR_DATA *ch)
{
   int points = 0;
   OBJ_DATA *obj;
   
   if ((obj=get_eq_char(ch, WEAR_FINGER_R)) != NULL)
      points += eqworth_affcheck(obj);
   if ((obj=get_eq_char(ch, WEAR_FINGER_L)) != NULL)
      points += eqworth_affcheck(obj);
   if ((obj=get_eq_char(ch, WEAR_ABOUT_NECK)) != NULL)
      points += eqworth_affcheck(obj);
   if ((obj=get_eq_char(ch, WEAR_NOCKED)) != NULL)
   {
      points += eqworth_affcheck(obj);
      points += eqworth_statcheck(obj);
   }
   if ((obj=get_eq_char(ch, WEAR_BACK)) != NULL)
   {
      points += eqworth_affcheck(obj);
   }
   if ((obj=get_eq_char(ch, WEAR_WIELD)) != NULL)
   {
      points += eqworth_affcheck(obj);
      points += eqworth_statcheck(obj);
   }
   if ((obj=get_eq_char(ch, WEAR_DUAL_WIELD)) != NULL)
   {
      points += eqworth_affcheck(obj);
      points += eqworth_statcheck(obj);
   }
   if ((obj=get_eq_char(ch, WEAR_MISSILE_WIELD)) != NULL)
   {
      points += eqworth_affcheck(obj);
      points += eqworth_statcheck(obj);
   }
   if ((obj=get_eq_char(ch, WEAR_BODY)) != NULL)
   {
      points += eqworth_affcheck(obj);
      points += eqworth_statcheck(obj);
   }
   if ((obj=get_eq_char(ch, WEAR_HEAD)) != NULL)
   {
      points += eqworth_affcheck(obj);
      points += eqworth_statcheck(obj);
   }
   if ((obj=get_eq_char(ch, WEAR_LEG_L)) != NULL)
   {
      points += eqworth_affcheck(obj);
      points += eqworth_statcheck(obj);
   }
   if ((obj=get_eq_char(ch, WEAR_LEG_R)) != NULL)
   {
      points += eqworth_affcheck(obj);
      points += eqworth_statcheck(obj);
   }
   if ((obj=get_eq_char(ch, WEAR_ARM_L)) != NULL)
   {
      points += eqworth_affcheck(obj);
      points += eqworth_statcheck(obj);
   }
   if ((obj=get_eq_char(ch, WEAR_ARM_R)) != NULL)
   {
      points += eqworth_affcheck(obj);
      points += eqworth_statcheck(obj);
   }
   if ((obj=get_eq_char(ch, WEAR_SHIELD)) != NULL)
   {
      points += eqworth_affcheck(obj);
      points += eqworth_statcheck(obj);
   }
   if ((obj=get_eq_char(ch, WEAR_WAIST)) != NULL)
   {
      points += eqworth_affcheck(obj);
   }
   if ((obj=get_eq_char(ch, WEAR_NECK)) != NULL)
   {
      points += eqworth_affcheck(obj);
      points += eqworth_statcheck(obj);
   }
   return points;
}

int get_player_statlevel(CHAR_DATA *ch)
{
   int ox = 0;
   int x = 0;
   int cnt;
   int points = player_equipment_worth(ch) + player_stat_worth(ch);
   
   for (cnt = 1;cnt <= 2000;cnt++)
   {
      ox = x;
      x = ox +(50*cnt*cnt/3);
      if (points >= ox && points <= x)
         break;
   }
   return cnt;
   
   
   return points / 10000;
}  

void spoint_gain(CHAR_DATA *ch, CHAR_DATA *victim)
{
   CHAR_DATA *gch;
   int members = 0;
   int tpoints = 0;
   int points = 0;
   int tgpoints = 0;   //team points
   int tglpoints = 2000000000;  //team lowest
   int tghpoints = 0;  //team highest
   int gain;
   
   if (victim == ch)
      return;
      
   //Not on mounts
   if (xIS_SET(victim->act, ACT_MOUNTSAVE))
      return;
      
   //Not on players either
   if (!IS_NPC(victim))
      return;
      
   tpoints = UMAX(1, ((victim->max_hit) - 10) * 3);
   tpoints = UMAX(1, (tpoints * number_range(90, 110) / 100));
   
   if (IS_NPC(ch) && IS_AFFECTED(ch, AFF_CHARM) && ch->master && ch->master->in_room == ch->in_room && !IS_NPC(ch->master))
   {
      tpoints = tpoints * 8 / 10;
      ch = ch->master;
   }
   else if (IS_NPC(ch))
      return;
      
   for (gch = ch->in_room->first_person; gch; gch = gch->next_in_room)
   {
      if (is_same_group(gch, ch) && !IS_NPC(gch))
      {
         members++;
         points = player_stat_worth(gch);
         tgpoints += points;
         if (points < tglpoints)
            tglpoints = points;
         if (points > tghpoints)
            tghpoints = points;
      }
   }
   if (members <= 1)
   {
      if (ch->race == RACE_HUMAN)
         tpoints = tpoints * 120/100;
      if (xIS_SET(ch->pcdata->talent, TALENT_SP5))
         tpoints = tpoints * 300/100;
      else if (xIS_SET(ch->pcdata->talent, TALENT_SP4))
         tpoints = tpoints * 250/100;
      else if (xIS_SET(ch->pcdata->talent, TALENT_SP3))
         tpoints = tpoints * 200/100;
      else if (xIS_SET(ch->pcdata->talent, TALENT_SP2))
         tpoints = tpoints * 166/100;
      else if (xIS_SET(ch->pcdata->talent, TALENT_SP1))
         tpoints = tpoints * 133/100;
      #ifdef MCCP         
      if (ch->desc && ch->desc->out_compress)
         tpoints = tpoints * 105/100;
      #endif
      if (ch->desc && ch->desc->mxp && !str_cmp(ch->desc->mxpclient, "zmud") && ch->desc->mxpversion >= 6.5)
         tpoints = tpoints * 110/100;
      else if (ch->desc && ch->desc->mxp)
         tpoints = tpoints * 105/100;
         
      tpoints = UMAX(1, tpoints * sysdata.exp_percent / 100);
      ch->pcdata->spoints += tpoints;
      ch_printf(ch, "&w&WYou gain %d skill points&w\n\r", tpoints);
   }
   else
   {
      if ((tghpoints/2) > tglpoints && tghpoints >= 20 && tglpoints < 150000 && !sysdata.resetgame)
         ;
      else
         tpoints += ((members-1)*35)*tpoints/100;
      for (gch = ch->in_room->first_person; gch; gch = gch->next_in_room)
      {
         if (is_same_group(gch, ch) && !IS_NPC(gch))
         {
            if (tglpoints >= 150000 || sysdata.resetgame)
               gain = tpoints / members;
            else
               gain = UMAX(1, player_stat_worth(gch) * 500 / tgpoints * tpoints / 500);
            
            if (gch->race == RACE_HUMAN)
               gain = gain * 120/100;
            if (xIS_SET(gch->pcdata->talent, TALENT_SP5))
               gain = gain * 300/100;
            else if (xIS_SET(gch->pcdata->talent, TALENT_SP4))
               gain = gain * 250/100;
            else if (xIS_SET(gch->pcdata->talent, TALENT_SP3))
               gain = gain * 200/100;
            else if (xIS_SET(gch->pcdata->talent, TALENT_SP2))
               gain = gain * 166/100;
            else if (xIS_SET(gch->pcdata->talent, TALENT_SP1))
               gain = gain * 133/100;
            #ifdef MCCP
            if (gch->desc && gch->desc->out_compress)
               gain = gain * 105/100;
            #endif
            if (gch->desc && gch->desc->mxp && !str_cmp(gch->desc->mxpclient, "zmud") && gch->desc->mxpversion >= 6.5)
               gain = gain * 110/100;
            else if (gch->desc && gch->desc->mxp)
               gain = gain * 105/100;
            gain = UMAX(1, gain * sysdata.exp_percent / 100);
            gch->pcdata->spoints += gain;
            ch_printf(gch, "&w&WYou gain %d skill points&w\n\r", gain);
         }
      }
   }   
}

//0 - Straight damage
//1 - Magical damage
//2 - Taunt
//3 - A heal
//4 - A manual adjustment, typically used in skills
void adjust_aggression_list(CHAR_DATA *victim, CHAR_DATA *ch, int dam, int type, int sn)
{
   AGGRO_DATA *aggro = NULL;
   int add = 0;
   int level;
   CHAR_DATA *vch;
   
   if (!IS_NPC(victim) && type != 3)
      return;
   
   if (type != 3)
   {
      for (aggro = victim->first_aggro; aggro; aggro = aggro->next)
      {
         if (aggro->ch && ch->name == aggro->ch->name)
            break;
      }
      if (!aggro)
      {
         CREATE(aggro, AGGRO_DATA, 1);
         aggro->ch = ch;
         aggro->owner = victim;
         LINK(aggro, victim->first_aggro, victim->last_aggro, next, prev);
         LINK(aggro, first_global_aggro, last_global_aggro, next_global, prev_global);
      }
   }
   //Don't like magic, not as much as heals though
   if (type == 1)
   {
      add = dam*3/2;
         
      if (victim->fighting && victim->fighting->who && victim->fighting->who == ch)
      {
         if (get_curr_int(victim) >= 19)
            add = add*5/6;
         if (get_curr_int(victim) >= 22)
            add = add*4/6;         
      }
      else
      {         
         if (get_curr_int(victim) >= 16)
            add = add*5/4;
         if (get_curr_int(victim) >= 19)
            add = add*6/4;
         if (get_curr_int(victim) >= 22)
            add = add*7/4;
      }
         
   }
   //Really don't like heals....
   else if (type == 3)
   {
      add = dam*4/2;
      
      for (vch = ch->in_room->first_person; vch; vch = vch->next_in_room)
      {
         if (!IN_SAME_ROOM(vch, ch) || !IS_NPC(vch))
            continue;
         if (vch->fighting && vch->fighting->who && is_same_group( ch, vch->fighting->who ))
         {
            for (aggro = vch->first_aggro; aggro; aggro = aggro->next)
            {
               if (aggro->ch && ch->name == aggro->ch->name)
                  break;
            }
            if (!aggro)
            {
               CREATE(aggro, AGGRO_DATA, 1);
               aggro->ch = ch;
               aggro->owner = vch;
               LINK(aggro, first_global_aggro, last_global_aggro, next_global, prev_global);
               LINK(aggro, vch->first_aggro, vch->last_aggro, next, prev);
            }         
            if (vch->fighting->who == ch)
            {
               if (get_curr_int(vch) >= 16)
                  add = add*7/8;
               if (get_curr_int(vch) >= 19)
                  add = add*5/6;
               if (get_curr_int(vch) >= 22)
                  add = add*4/6;         
            }
            else
            {
               if (get_curr_int(vch) >= 16)
                 add = add*6/4;
               if (get_curr_int(vch) >= 19)
                 add = add*7/4;
               if (get_curr_int(vch) >= 22)
                 add = add*8/4;         
            }
            aggro->value += add;
         }
      }
      return;
   }
   else if (type == 2)
   {
      level = POINT_LEVEL(LEARNED(ch, sn), MASTERED(ch, sn));
      add = URANGE(1, level/15, 5);
      add += dam;
      if (victim->fighting->who != ch)
         add/=2;
   }
   else if (type == 0)
   {
      add = dam;
      if (get_eq_char(ch, WEAR_SHIELD))
         add = add * 2 / 3;
      if (victim->fighting && victim->fighting->who && victim->fighting->who != ch)
         add = add * 3 / 2;
   }
   else if (type == 4)
   {
      add = dam;
   }
   aggro->value += add;
}   
        
void check_limb_status(CHAR_DATA *victim, int limb, int dam, int slimb, CHAR_DATA *ch, int spec)
{  
   int smod;
   int hmod;
   OBJ_DATA *obj;
   
   if (spec == DM_CRITICAL)
      spec = number_range(35,75);
   else
      spec = 0;
   
   if (get_curr_str(victim) < 8)
      smod = 100*2;
   else if (get_curr_str(victim) > 8 && get_curr_str(victim) <= 12)
      smod = 85*2;
   else if (get_curr_str(victim) >= 13 && get_curr_str(victim) <= 16)
      smod = 70*2;
   else if (get_curr_str(victim) >= 17 && get_curr_str(victim) <= 19)
      smod = 55*2;
   else if (get_curr_str(victim) >= 20 && get_curr_str(victim) <= 22)
      smod = 35*2;
   else if (get_curr_str(victim) >= 23 && get_curr_str(victim) >= 24)
      smod = 25*2;
   else
      smod = 15*2;
      
   //arm 14  leg 15 (vnum)
   if (limb == LM_LARM && victim->con_larm > -1 && dam > 0)
   {
      hmod = UMAX(1, dam * smod / victim->max_hit)+spec; 
      victim->con_larm -= hmod;
      if (victim->con_larm < 0 || slimb == 1) //Bye bye Arm
      {
         int gotweapon = 0;
         victim->con_larm = -1;
         //create limb
         obj = create_object(get_obj_index(14), 0);
         obj->timer = number_range(4, 7);
         if (IS_AFFECTED(victim, AFF_POISON))
            obj->value[3] = 10;
         obj = obj_to_room(obj, victim->in_room, victim);
         if (slimb == 1)
         {
            act(AT_WHITE, "[CrItIcAl] $n's left arm is cleanly sliced off from $N's attack.", victim, NULL, ch, TO_NOTVICT);
            act(AT_WHITE, "[CrItIcAl] Your left arm is cleanly sliced off from $N's attack.", victim, NULL, ch, TO_CHAR);
            act(AT_WHITE, "[CrItIcAl] You cleanly slice off $n's left arm with your attack.", victim, NULL, ch, TO_VICT);
         }
         else
         {   
            act(AT_WHITE, "$n's left arm breaks off from $N's attack.", victim, NULL, ch, TO_NOTVICT);
            act(AT_WHITE, "Your left arm breaks off from $N's attack.", victim, NULL, ch, TO_CHAR);
            act(AT_WHITE, "You break off $n's left arm with your attack.", victim, NULL, ch, TO_VICT);
         }
         //remove armor
         obj = get_eq_char(victim, WEAR_ARM_L);
         if (obj)
         {
            unequip_char(victim, obj);
            obj->wear_loc = -1;
            if (IS_NPC(victim))
            {
               separate_obj(obj);
               obj_from_char(obj);
               obj_to_room(obj, victim->in_room, victim);   
            }
            else if (!IS_OBJ_STAT(obj, ITEM_NOGIVE) && !IS_OBJ_STAT(obj, ITEM_NODROP) 
            && (!victim->pcdata->quest || victim->pcdata->quest->questarea != victim->in_room->area))
            {
               separate_obj(obj);
               obj_from_char(obj);
               obj_to_room(obj, victim->in_room, victim);
            }
            act(AT_WHITE, "$n's $p drops to the ground along with $s arm.", victim, obj, NULL, TO_NOTVICT);
            act(AT_WHITE, "Your $p falls to the ground along with your arm.", victim, obj, NULL, TO_CHAR);
            act(AT_WHITE, "$n's $p falls to the ground along with $s arm.", victim, obj, ch, TO_VICT);
         }
         //remove weapon
         if (!IS_NPC(victim) && victim->pcdata->righthanded == 0)
            gotweapon = 1;
         if (IS_NPC(victim) && (number_range(1, 2) == 1 || victim->con_rarm == -1))
            gotweapon = 1;
         if (gotweapon == 0)
         {
            obj = get_eq_char(victim, WEAR_DUAL_WIELD);
            if (obj)
            {
               unequip_char(victim, obj);
               obj->wear_loc = -1;
               if (IS_NPC(victim))
               {
                  separate_obj(obj);
                  obj_from_char(obj);
                  obj_to_room(obj, victim->in_room, victim);   
               }
               else if (!IS_OBJ_STAT(obj, ITEM_NOGIVE) && !IS_OBJ_STAT(obj, ITEM_NODROP) 
               && (!victim->pcdata->quest || victim->pcdata->quest->questarea != victim->in_room->area))
               {
                  separate_obj(obj);
                  obj_from_char(obj);
                  obj_to_room(obj, victim->in_room, victim);
               }
               act(AT_WHITE, "$n's $p drops to the ground along with $s arm.", victim, obj, NULL, TO_NOTVICT);
               act(AT_WHITE, "Your $p falls to the ground along with your arm.", victim, obj, NULL, TO_CHAR);
               act(AT_WHITE, "$n's $p falls to the ground along with $s arm.", victim, obj, ch, TO_VICT);
            }
            obj = get_eq_char(victim, WEAR_SHIELD);
            if (obj)
            {
               unequip_char(victim, obj);
               obj->wear_loc = -1;
               if (IS_NPC(victim))
               {
                  separate_obj(obj);
                  obj_from_char(obj);
                  obj_to_room(obj, victim->in_room, victim);   
               }
               else if (!IS_OBJ_STAT(obj, ITEM_NOGIVE) && !IS_OBJ_STAT(obj, ITEM_NODROP) 
               && (!victim->pcdata->quest || victim->pcdata->quest->questarea != victim->in_room->area))
               {
                  separate_obj(obj);
                  obj_from_char(obj);
                  obj_to_room(obj, victim->in_room, victim);
               }
               act(AT_WHITE, "$n's $p drops to the ground along with $s arm.", victim, obj, NULL, TO_NOTVICT);
               act(AT_WHITE, "Your $p falls to the ground along with your arm.", victim, obj, NULL, TO_CHAR);
               act(AT_WHITE, "$n's $p falls to the ground along with $s arm.", victim, obj, ch, TO_VICT);
            }
         }
         if (gotweapon == 1)
         {
            obj = get_eq_char(victim, WEAR_WIELD);
            if (obj)
            {
               unequip_char(victim, obj);
               obj->wear_loc = -1;
               if (IS_NPC(victim))
               {
                  separate_obj(obj);
                  obj_from_char(obj);
                  obj_to_room(obj, victim->in_room, victim);   
               }
               else if (!IS_OBJ_STAT(obj, ITEM_NOGIVE) && !IS_OBJ_STAT(obj, ITEM_NODROP) 
               && (!victim->pcdata->quest || victim->pcdata->quest->questarea != victim->in_room->area))
               {
                  separate_obj(obj);
                  obj_from_char(obj);
                  obj_to_room(obj, victim->in_room, victim);
               }
               act(AT_WHITE, "$n's $p drops to the ground along with $s arm.", victim, obj, NULL, TO_NOTVICT);
               act(AT_WHITE, "Your $p falls to the ground along with your arm.", victim, obj, NULL, TO_CHAR);
               act(AT_WHITE, "$n's $p falls to the ground along with $s arm.", victim, obj, ch, TO_VICT);
               //if Dual Wielding change it to Wield
               obj = get_eq_char(victim, WEAR_DUAL_WIELD);
               if (obj)
                  obj->wear_loc = WEAR_WIELD;
            }
         }
      }
   }
   if (limb == LM_RARM && victim->con_rarm > -1 && dam > 0)
   {
      hmod = UMAX(1, dam * smod / victim->max_hit)+spec;
      victim->con_rarm -= hmod;
      if (victim->con_rarm < 0 || slimb == 1) //Bye bye Arm
      {
         int gotweapon = 0;
         victim->con_rarm = -1;
         //create limb
         obj = create_object(get_obj_index(14), 0);
         obj->timer = number_range(4, 7);
         if (IS_AFFECTED(victim, AFF_POISON))
            obj->value[3] = 10;
         obj = obj_to_room(obj, victim->in_room, victim);
         if (slimb == 1)
         {
            act(AT_WHITE, "[CrItIcAl] $n's right arm is cleanly sliced off from $N's attack.", victim, NULL, ch, TO_NOTVICT);
            act(AT_WHITE, "[CrItIcAl] Your right arm is cleanly sliced off from $N's attack.", victim, NULL, ch, TO_CHAR);
            act(AT_WHITE, "[CrItIcAl] You cleanly slice off $n's right arm with your attack.", victim, NULL, ch, TO_VICT);
         }
         else
         {   
            act(AT_WHITE, "$n's right arm breaks off from $N's attack.", victim, NULL, ch, TO_NOTVICT);
            act(AT_WHITE, "Your right arm breaks off from $N's attack.", victim, NULL, ch, TO_CHAR);
            act(AT_WHITE, "You break off $n's right arm with your attack.", victim, NULL, ch, TO_VICT);
         }
         //remove armor
         obj = get_eq_char(victim, WEAR_ARM_R);
         if (obj)
         {
            unequip_char(victim, obj);
            obj->wear_loc = -1;
            if (IS_NPC(victim))
            {
               separate_obj(obj);
               obj_from_char(obj);
               obj_to_room(obj, victim->in_room, victim);   
            }
            else if (!IS_OBJ_STAT(obj, ITEM_NOGIVE) && !IS_OBJ_STAT(obj, ITEM_NODROP) 
            && (!victim->pcdata->quest || victim->pcdata->quest->questarea != victim->in_room->area))
            {
               separate_obj(obj);
               obj_from_char(obj);
               obj_to_room(obj, victim->in_room, victim);
            }
            act(AT_WHITE, "$n's $p drops to the ground along with $s arm.", victim, obj, NULL, TO_NOTVICT);
            act(AT_WHITE, "Your $p falls to the ground along with your arm.", victim, obj, NULL, TO_CHAR);
            act(AT_WHITE, "$n's $p falls to the ground along with $s arm.", victim, obj, ch, TO_VICT);
         }
         //remove weapon
         if (!IS_NPC(victim) && victim->pcdata->righthanded == 1)
            gotweapon = 1;
         if (IS_NPC(victim) && (number_range(1, 2) == 1 || victim->con_larm == -1))
            gotweapon = 1;
         if (gotweapon == 0)
         {
            obj = get_eq_char(victim, WEAR_DUAL_WIELD);
            if (obj)
            {
               unequip_char(victim, obj);
               obj->wear_loc = -1;
               if (IS_NPC(victim))
               {
                  separate_obj(obj);
                  obj_from_char(obj);
                  obj_to_room(obj, victim->in_room, victim);   
               }
               else if (!IS_OBJ_STAT(obj, ITEM_NOGIVE) && !IS_OBJ_STAT(obj, ITEM_NODROP) 
               && (!victim->pcdata->quest || victim->pcdata->quest->questarea != victim->in_room->area))
               {
                  separate_obj(obj);
                  obj_from_char(obj);
                  obj_to_room(obj, victim->in_room, victim);
               }
               act(AT_WHITE, "$n's $p drops to the ground along with $s arm.", victim, obj, NULL, TO_NOTVICT);
               act(AT_WHITE, "Your $p falls to the ground along with your arm.", victim, obj, NULL, TO_CHAR);
               act(AT_WHITE, "$n's $p falls to the ground along with $s arm.", victim, obj, ch, TO_VICT);
            }
            obj = get_eq_char(victim, WEAR_SHIELD);
            if (obj)
            {
               unequip_char(victim, obj);
               obj->wear_loc = -1;
               if (IS_NPC(victim))
               {
                  separate_obj(obj);
                  obj_from_char(obj);
                  obj_to_room(obj, victim->in_room, victim);   
               }
               else if (!IS_OBJ_STAT(obj, ITEM_NOGIVE) && !IS_OBJ_STAT(obj, ITEM_NODROP) 
               && (!victim->pcdata->quest || victim->pcdata->quest->questarea != victim->in_room->area))
               {
                  separate_obj(obj);
                  obj_from_char(obj);
                  obj_to_room(obj, victim->in_room, victim);
               }
               act(AT_WHITE, "$n's $p drops to the ground along with $s arm.", victim, obj, NULL, TO_NOTVICT);
               act(AT_WHITE, "Your $p falls to the ground along with your arm.", victim, obj, NULL, TO_CHAR);
               act(AT_WHITE, "$n's $p falls to the ground along with $s arm.", victim, obj, ch, TO_VICT);
            }
         }
         if (gotweapon == 1)
         {
            obj = get_eq_char(victim, WEAR_WIELD);
            if (obj)
            {
               unequip_char(victim, obj);
               obj->wear_loc = -1;
               if (IS_NPC(victim))
               {
                  separate_obj(obj);
                  obj_from_char(obj);
                  obj_to_room(obj, victim->in_room, victim);   
               }
               else if (!IS_OBJ_STAT(obj, ITEM_NOGIVE) && !IS_OBJ_STAT(obj, ITEM_NODROP) 
               && (!victim->pcdata->quest || victim->pcdata->quest->questarea != victim->in_room->area))
               {
                  separate_obj(obj);
                  obj_from_char(obj);
                  obj_to_room(obj, victim->in_room, victim);
               }
               act(AT_WHITE, "$n's $p drops to the ground along with $s arm.", victim, obj, NULL, TO_NOTVICT);
               act(AT_WHITE, "Your $p falls to the ground along with your arm.", victim, obj, NULL, TO_CHAR);
               act(AT_WHITE, "$n's $p falls to the ground along with $s arm.", victim, obj, ch, TO_VICT);
               //if Dual Wielding change it to Wield
               obj = get_eq_char(victim, WEAR_DUAL_WIELD);
               if (obj)
                  obj->wear_loc = WEAR_WIELD;
            }
            
         }
      }
   }
   if (limb == LM_RLEG && victim->con_rleg > -1 && dam > 0)
   {
      hmod = UMAX(1, dam * 80 * smod / victim->max_hit/ 100)+spec;
      victim->con_rleg -= hmod;
      if (victim->con_rleg < 0 || slimb == 1) //Bye bye Leg
      {
         victim->con_rleg = -1;
         //create limb
         obj = create_object(get_obj_index(15), 0);
         obj->timer = number_range(4, 7);
         if (IS_AFFECTED(victim, AFF_POISON))
            obj->value[3] = 10;
         obj = obj_to_room(obj, victim->in_room, victim);
         if (slimb == 1)
         {
            act(AT_WHITE, "[CrItIcAl] $n's right leg is cleanly sliced off from $N's attack.", victim, NULL, ch, TO_NOTVICT);
            act(AT_WHITE, "[CrItIcAl] Your right leg is cleanly sliced off from $N's attack.", victim, NULL, ch, TO_CHAR);
            act(AT_WHITE, "[CrItIcAl] You cleanly slice off $n's right leg with your attack.", victim, NULL, ch, TO_VICT);
         }
         else
         {   
            act(AT_WHITE, "$n's right leg breaks off from $N's attack.", victim, NULL, ch, TO_NOTVICT);
            act(AT_WHITE, "Your right leg breaks off from $N's attack.", victim, NULL, ch, TO_CHAR);
            act(AT_WHITE, "You break off $n's right leg with your attack.", victim, NULL, ch, TO_VICT);
         }
         //remove armor
         obj = get_eq_char(victim, WEAR_LEG_R);
         if (obj)
         {
            unequip_char(victim, obj);
            obj->wear_loc = -1;
            if (IS_NPC(victim))
            {
               separate_obj(obj);
               obj_from_char(obj);
               obj_to_room(obj, victim->in_room, victim);   
            }
            else if (!IS_OBJ_STAT(obj, ITEM_NOGIVE) && !IS_OBJ_STAT(obj, ITEM_NODROP) 
            && (!victim->pcdata->quest || victim->pcdata->quest->questarea != victim->in_room->area))
            {
               separate_obj(obj);
               obj_from_char(obj);
               obj_to_room(obj, victim->in_room, victim);
            }
            act(AT_WHITE, "$n's $p drops to the ground along with $s leg.", victim, obj, NULL, TO_NOTVICT);
            act(AT_WHITE, "Your $p falls to the ground along with your leg.", victim, obj, NULL, TO_CHAR);
            act(AT_WHITE, "$n's $p falls to the ground along with $s leg.", victim, obj, ch, TO_VICT);
         }
      }
   }
   if (limb == LM_LLEG && victim->con_lleg > -1 && dam > 0)
   {
      hmod = UMAX(1, dam * 80 * smod / victim->max_hit/ 100)+spec;
      victim->con_lleg -= hmod;
      if (victim->con_lleg < 0 || slimb == 1) //Bye bye Leg
      {
         victim->con_lleg = -1;
         //create limb
         obj = create_object(get_obj_index(15), 0);
         obj->timer = number_range(4, 7);
         if (IS_AFFECTED(victim, AFF_POISON))
            obj->value[3] = 10;
         obj = obj_to_room(obj, victim->in_room, victim);
         if (slimb == 1)
         {
            act(AT_WHITE, "[CrItIcAl] $n's left leg is cleanly sliced off from $N's attack.", victim, NULL, ch, TO_NOTVICT);
            act(AT_WHITE, "[CrItIcAl] Your left leg is cleanly sliced off from $N's attack.", victim, NULL, ch, TO_CHAR);
            act(AT_WHITE, "[CrItIcAl] You cleanly slice off $n's left leg with your attack.", victim, NULL, ch, TO_VICT);
         }
         else
         {   
            act(AT_WHITE, "$n's left leg breaks off from $N's attack.", victim, NULL, ch, TO_NOTVICT);
            act(AT_WHITE, "Your left leg breaks off from $N's attack.", victim, NULL, ch, TO_CHAR);
            act(AT_WHITE, "You break off $n's left leg with your attack.", victim, NULL, ch, TO_VICT);
         }
         //remove armor
         obj = get_eq_char(victim, WEAR_LEG_L);
         if (obj)
         {
            unequip_char(victim, obj);
            obj->wear_loc = -1;
            if (IS_NPC(victim))
            {
               separate_obj(obj);
               obj_from_char(obj);
               obj_to_room(obj, victim->in_room, victim);   
            }
            else if (!IS_OBJ_STAT(obj, ITEM_NOGIVE) && !IS_OBJ_STAT(obj, ITEM_NODROP) 
            && (!victim->pcdata->quest || victim->pcdata->quest->questarea != victim->in_room->area))
            {
               separate_obj(obj);
               obj_from_char(obj);
               obj_to_room(obj, victim->in_room, victim);
            }
            act(AT_WHITE, "$n's $p drops to the ground along with $s leg.", victim, obj, NULL, TO_NOTVICT);
            act(AT_WHITE, "Your $p falls to the ground along with your leg.", victim, obj, NULL, TO_CHAR);
            act(AT_WHITE, "$n's $p falls to the ground along with $s leg.", victim, obj, ch, TO_VICT);
         }
      }
   }   
}  

/*
 * Inflict damage from a hit.   This is one damn big function.
 */
ch_ret damage(CHAR_DATA * ch, CHAR_DATA * victim, int dam, int dt, int spec, int limb)
{
   char buf[MSL];
   char filename[256];
   OBJ_DATA *obj;
   sh_int dameq;
   sh_int maxdam;
   bool npcvict;
   bool loot;
   OBJ_DATA *damobj;
   ch_ret retcode;
   sh_int dampmod;
   CHAR_DATA *gch /*, *lch */ ;
   sh_int anopc = 0; /* # of (non-pkill) pc in a (ch) */
   sh_int bnopc = 0; /* # of (non-pkill) pc in b (victim) */
   sh_int proj = 0;
   int slimb = 0;
   
   if (spec == DM_SLICEDLIMB)
   {
      spec = DM_CRITICAL;
      slimb = 1;
   }

   if (dt == TYPE_PROJECTILE)
   {
      dt = TYPE_HIT;
      proj = 1;
   }


   retcode = rNONE;

   if (!ch)
   {
      bug("Damage: null ch!", 0);
      return rERROR;
   }
   if (!victim)
   {
      bug("Damage: null victim!", 0);
      return rVICT_DIED;
   }

   if (victim->position == POS_DEAD)
      return rVICT_DIED;

   npcvict = IS_NPC(victim);
   
   if (victim->position == POS_RIDING)
   {
      victim->position = POS_STANDING;
      if (victim->riding)
      {
         victim->riding->rider = NULL;
         victim->riding = NULL;
      }
   }
   if (victim->rider)
   {
      victim->rider->riding = NULL;
      victim->rider->position = POS_STANDING;
      victim->rider = NULL;
   }

   /*
    * Check damage types for RIS    -Thoric
    */
   /* 
    * New Weapon Overhall                             -Xerves
    */
   if (dam && dt != TYPE_UNDEFINED)
   {
      if (IS_FIRE(dt))
         dam = ris_damage(victim, dam, RIS_FIRE);
      else if (IS_WATER(dt))
         dam = ris_damage(victim, dam, RIS_WATER);
      else if (IS_EARTH(dt))
         dam = ris_damage(victim, dam, RIS_EARTH);
      else if (IS_ENERGY(dt))
         dam = ris_damage(victim, dam, RIS_ENERGY);
      else if (IS_HOLY(dt))
         dam = ris_damage(victim, dam, RIS_HOLY);
      else if (IS_UNHOLY(dt))
         dam = ris_damage(victim, dam, RIS_UNHOLY);
      else if (IS_UNDEAD(dt))
         dam = ris_damage(victim, dam, RIS_UNDEAD);
      else if (IS_AIR(dt))
         dam = ris_damage(victim, dam, RIS_AIR);
      else if (dt == gsn_poison)
         dam = ris_damage(victim, dam, RIS_POISON);
      else if (ch->grip == GRIP_BASH)
         dam = ris_damage(victim, dam, RIS_BLUNT);
      else if (ch->grip == GRIP_STAB)
         dam = ris_damage(victim, dam, RIS_PIERCE);
      else if (ch->grip == GRIP_SLASH)
         dam = ris_damage(victim, dam, RIS_SLASH);
      else if (skill_table[dt] && skill_table[dt]->type && skill_table[dt]->type == SKILL_SPELL)
         dam = ris_damage(victim, dam, RIS_MAGIC);
      else if (skill_table[dt] && (dt == gsn_manashot || dt == gsn_manaburst))
         dam = ris_damage(victim, dam, RIS_MAGIC);
      else
         dam = ris_damage(victim, dam, RIS_NONMAGIC);

      if (dam == -1)
      {
         if (dt >= 0 && dt < top_sn)
         {
            bool found = FALSE;
            SKILLTYPE *skill = skill_table[dt];

            if (skill->imm_char && skill->imm_char[0] != '\0')
            {
               act(AT_HIT, skill->imm_char, ch, NULL, victim, TO_CHAR);
               found = TRUE;
            }
            if (skill->imm_vict && skill->imm_vict[0] != '\0')
            {
               act(AT_HITME, skill->imm_vict, ch, NULL, victim, TO_VICT);
               found = TRUE;
            }
            if (skill->imm_room && skill->imm_room[0] != '\0')
            {
               act(AT_ACTION, skill->imm_room, ch, NULL, victim, TO_NOTVICT);
               found = TRUE;
            }
            if (found)
               return rNONE;
         }
         dam = 0;
         spec = DM_MISS;
      }
   }
   //Why was this not Here, ponder......Ha ha
   if (dt > TYPE_UNDEFINED && dt < TYPE_PROJECTILE)
   {
      if (victim->apply_manashell > 0 && victim->mana > 0 && skill_table[dt] && skill_table[dt]->type 
      &&  skill_table[dt]->type == SKILL_SPELL && dt != gsn_poison)
      {
         int mana;
         int nsn = skill_lookup("manashell");
         mana = UMAX(1, dam * 50 / victim->apply_manashell);
         if (nsn > 0 && LEARNED(victim, nsn) > 0)
            learn_from_success(victim, nsn, ch);
         if (mana <= victim->mana)
         {
            dam = 0;
            victim->mana -= mana;
            if (number_range(1, 10) == 1)
               gain_mana_per(victim, ch, mana);
            act(AT_WHITE, "$n's manashell flashes blue and absorbs the magical damage from $N", victim, NULL, ch, TO_NOTVICT);
            act(AT_WHITE, "$n's manashell flashes blue and absorbs the magical damage from you", victim, NULL, ch, TO_VICT);
            act(AT_WHITE, "Your manashell flashes blue and absorbs the magical damage from $N", victim, NULL, ch, TO_CHAR);
            return rNONE;
         }
         else
         {
            dam -= dam * victim->mana / mana;   
            if (number_range(1, 10) == 1)
               gain_mana_per(victim, ch, mana);
            victim->mana = 0;
            act(AT_WHITE, "$n's manashell flashes red and partially absorbs the magical damage from $N", victim, NULL, ch, TO_NOTVICT);
            act(AT_WHITE, "$n's manashell flashes red and partially absorbs the magical damage from you", victim, NULL, ch, TO_VICT);
            act(AT_WHITE, "Your manashell flashes red and partially absorbs the magical damage from $N", victim, NULL, ch, TO_CHAR);
         }
      }
   }
   if ((dt == TYPE_HIT ||dt == gsn_backstab || dt == gsn_circle || dt == gsn_kick_back) && in_same_room(ch, victim)) 
        if (check_dodge(ch, victim, limb))
            return rNONE;
   //Managuard 
   if (dam > 0 && victim->apply_managuard > 0 && spec != DM_MISS && spec != DM_BLOCK && ((dt == TYPE_HIT ||dt == gsn_backstab || dt == gsn_circle || dt == gsn_kick_back) || dt == TYPE_UNDEFINED || dt == TYPE_PROJECTILE 
   || (skill_table[dt] && skill_table[dt]->type && skill_table[dt]->type == SKILL_SKILL)))
   {
      int mana;
      int nsn = skill_lookup("managuard");
      mana = UMAX(1, dam/2 * 50 / victim->apply_managuard);
      if (mana <= victim->mana)
      {
         dam /= 2;
         victim->mana -= mana;
         if (number_range(1, 10) == 1)
            gain_mana_per(victim, ch, mana);
         act(AT_CYAN, "$n's managuard flashes blue and absorbs half the physical damage from $N", victim, NULL, ch, TO_NOTVICT);
         act(AT_CYAN, "$n's managuard flashes blue and absorbs half the physical damage from you", victim, NULL, ch, TO_VICT);
         act(AT_CYAN, "Your managuard flashes blue and absorbs half the physical damage from $N", victim, NULL, ch, TO_CHAR);
         if (dam < 1)
            dam = 1;
      }
      else
      {
         dam -= dam/2 * victim->mana / mana;   
         if (number_range(1, 10) == 1)
            gain_mana_per(victim, ch, mana);
         victim->mana = 0;
         act(AT_CYAN, "$n's managuard flashes red and partially absorbs the physical damage from $N", victim, NULL, ch, TO_NOTVICT);
         act(AT_CYAN, "$n's managuard flashes red and partially absorbs the physical damage from you", victim, NULL, ch, TO_VICT);
         act(AT_CYAN, "Your managuard flashes red and partially absorbs the physical damage from $N", victim, NULL, ch, TO_CHAR);
      }
      if (nsn > 0 && LEARNED(victim, nsn) > 0)
         learn_from_success(victim, nsn, ch);
   }
   /*
    * Precautionary step mainly to prevent people in Hell from finding
    * a way out. --Shaddai
    */
   if (xIS_SET(ch->in_room->room_flags, ROOM_SAFE))
   {
      dam = 0;
      spec = DM_MISS;
   }

   if (dam && npcvict && ch != victim)
   {
      if (!xIS_SET(victim->act, ACT_SENTINEL))
      {
         if (victim->hunting)
         {
            if (victim->hunting->who != ch)
            {
               STRFREE(victim->hunting->name);
               victim->hunting->name = QUICKLINK(ch->name);
               victim->hunting->who = ch;
            }
         }
         else if (!xIS_SET(victim->act, ACT_PACIFIST)) /* Gorog */
            start_hunting(victim, ch);
      }

      if (victim->hating)
      {
         if (victim->hating->who != ch)
         {
            STRFREE(victim->hating->name);
            victim->hating->name = QUICKLINK(ch->name);
            victim->hating->who = ch;
         }
      }
      else if (!xIS_SET(victim->act, ACT_PACIFIST)) /* Gorog */
         start_hating(victim, ch);
   }

   /*
    * Stop up any residual loopholes.
    */
   if (dt == gsn_backstab)
      maxdam = 300;
   else
      maxdam = 250;
   if (!IS_NPC(ch))
   {
      if (xIS_SET(ch->pcdata->talent, TALENT_DAMCAP3))
         maxdam += 200;
      else if (xIS_SET(ch->pcdata->talent, TALENT_DAMCAP3))
         maxdam += 100;
      else
         maxdam += 50;
   }
   if (IS_NPC(ch))
      maxdam *= 2;
   if (dt > 0 && dt < top_sn && skill_table[dt] && skill_table[dt]->name && skill_table[dt]->type == SKILL_SPELL && !IS_NPC(ch))
      maxdam = maxdam * 5/4;
   if (dam > maxdam)
      dam = maxdam;
   if (dam > maxdam*2)
   {
      sprintf(buf, "Damage: %d more than %d points!", dam, maxdam);
      bug(buf, dam);
      sprintf(buf, "** %s (lvl %d) -> %s **", ch->name, ch->level, victim->name);
      bug(buf, 0);
   }
   if (IS_AFFECTED(victim, AFF_WEB) || IS_AFFECTED(victim, AFF_SNARE))
   {
      int bchance;
      int bdam = dam;
      
      if (dt > 0 && dt < top_sn && skill_table[dt] && skill_table[dt]->name && skill_table[dt]->type == SKILL_SPELL)
      {
         if (IS_FIRE(dt))
            bdam *= 4;
         else
            bdam *= 2;
      }      
      if (proj == 1)
         bdam *= 2;
      if (IS_AFFECTED(victim, AFF_SNARE))
         bdam /=2;
      if (!IS_NPC(victim))
         bdam*=2;
      bchance = URANGE(1, bdam/6, 80);
      if (number_range(1, 100) <= bdam)
      {
         act(AT_WHITE, "$n's last attack knocked the entanglement loose that was holding back $N.", ch, NULL, victim, TO_NOTVICT);
         act(AT_WHITE, "Your last attack knocked the entanglement loose that was holding back $N.", ch, NULL, victim, TO_CHAR);
         act(AT_WHITE, "%n's last attack knocked the entanglement loose that was holding you back!", ch, NULL, victim, TO_VICT);
         affect_strip(victim, gsn_web);
         affect_strip(victim, gsn_snare);
      }
   }        
   if (victim != ch)
   {
      /*
       * Certain attacks are forbidden.
       * Most other attacks are returned.
       */
      if (is_safe(ch, victim))
         return rNONE;
      check_attacker(ch, victim);
      /* Check for no wander which WAS not in the code -- Xerves 11/99 */
      if (xIS_SET(ch->act, ACT_NOWANDER))
      {
         xREMOVE_BIT(ch->act, ACT_NOWANDER);
         if (xIS_SET(ch->act, ACT_MOUNTABLE))
            xSET_BIT(ch->act, ACT_SCARED);
      }
       
      if (victim->position > POS_STUNNED)
      {
         if (!victim->fighting && victim->in_room == ch->in_room)
         {
            if (((dt >= 0 && dt < top_sn && skill_table[dt] && skill_table[dt]->type == SKILL_SPELL) ||  proj == 1) 
            && (!IS_AWAKE(victim) || IS_AFFECTED(victim, AFF_WEB) || IS_AFFECTED(victim, AFF_SNARE))) //Don't want to start a fight if it is magic or a projectile
               ;
            else
               set_fighting(victim, ch);
         }

         /*
            vwas: victim->position = POS_FIGHTING; 
          */
         if (IS_NPC(victim) && victim->fighting)
            victim->position = POS_FIGHTING;
         else if (victim->fighting)
         {
            switch (victim->style)
            {
               case (STYLE_EVASIVE): case (STYLE_DIVINE): case (STYLE_WIZARDRY):
                  victim->position = POS_EVASIVE;
                  break;
               case (STYLE_DEFENSIVE):
                  victim->position = POS_DEFENSIVE;
                  break;
               case (STYLE_AGGRESSIVE):
                  victim->position = POS_AGGRESSIVE;
                  break;
               case (STYLE_BERSERK):
                  victim->position = POS_BERSERK;
                  break;
               default:
                  victim->position = POS_FIGHTING;
            }

         }

      }

      if (victim->position > POS_STUNNED)
      {
         if (!ch->fighting)
         {
            if (((dt >= 0 && dt < top_sn && skill_table[dt] && skill_table[dt]->type == SKILL_SPELL) ||  proj == 1) 
            && (!IS_AWAKE(victim) || IS_AFFECTED(victim, AFF_WEB) || IS_AFFECTED(victim, AFF_SNARE))) //Don't want to start a fight if it is magic or a projectile
               ;
            else
               set_fighting(ch, victim);
         }

         /*
          * If victim is charmed, ch might attack victim's master.
          */
         if (IS_NPC(ch)
            && npcvict && IS_AFFECTED(victim, AFF_CHARM) && victim->master && victim->master->in_room == ch->in_room && number_bits(3) == 0)
         {
            stop_fighting(ch, FALSE);
            retcode = one_hit(ch, victim->master, TYPE_HIT, LM_BODY);
            return retcode;
         }
      }
      
      /*
       * More charm stuff.
       */
      if (victim->master == ch)
         stop_follower(victim);

      /*
       * Pkill stuff.  If a deadly attacks another deadly or is attacked by
       * one, then ungroup any nondealies.  Disabled untill I can figure out
       * the right way to do it.
       */

#ifdef UNUNSED
      /* count the # of non-pkill pc in a ( not including == ch ) */
// for (gch = ch->in_room->first_person; gch; gch = gch->next_in_room)
//     if (is_same_group(ch, gch) && !IS_NPC(gch)
//  && !IS_PKILL(gch) && (ch != gch))
//  anopc++;

      /* count the # of non-pkill pc in b ( not including == victim ) */
// for (gch = victim->in_room->first_person; gch; gch = gch->next_in_room)
//     if (is_same_group(victim, gch) && !IS_NPC(gch)
//  && !IS_PKILL(gch) && (victim != gch))
//  bnopc++;


      /* only consider disbanding if both groups have 1(+) non-pk pc */
      if ((bnopc > 0) && (anopc > 0))
      {
         /* look at group a through ch's leader first */
         lch = ch->leader ? ch->leader : ch;
         if (lch != ch)
         {
            /* stop following leader if it isn't pk */
            if (!IS_NPC(lch) && !IS_PKILL(lch))
               stop_follower(ch);
            else
            {
               /* disband non-pk members from lch's group if it is pk */
               for (gch = ch->in_room->first_person; gch; gch = gch->next_in_room)
               {
                  if (is_same_group(lch, gch) && (lch != gch) && !IS_NPC(gch) && !IS_PKILL(gch))
                     stop_follower(gch);
               }
            }
         }
         else
            for (gch = ch->in_room->first_person; gch; gch = gch->next_in_room)
            {
               /* ch is leader - disband non-pks from group */
               if (is_same_group(ch, gch) && (ch != gch) && (!IS_PKILL(gch) && !IS_NPC(gch)))
                  stop_follower(gch);
            }

         /* time to look at the victims group through its leader */
         lch = victim->leader ? victim->leader : victim;

         if (lch != victim)
         {
            /* if leader isn't deadly, stop following lch */
            if (!IS_PKILL(lch) && !IS_NPC(lch))
               stop_follower(victim);
            else
            {
               /* lch is pk, disband non-pk's from group */
               for (gch = victim->in_room->first_person; gch; gch = gch->next_in_room)
               {
                  if (is_same_group(lch, gch) && (lch != gch) && (!IS_PKILL(gch) && !IS_NPC(gch)))
                     stop_follower(gch);
               }
            }
         }
         else
         {
            /* victim is leader of group - disband non-pks */
            for (gch = victim->in_room->first_person; gch; gch = gch->next_in_room)
            {
               if (is_same_group(victim, gch) && (victim != gch) && !IS_PKILL(gch) && !IS_NPC(gch))
                  stop_follower(gch);
            }
         }
      }
#endif

      /*
         count the # of non-pkill pc in a ( not including == ch ) 
       */
// for (gch = ch->in_room->first_person; gch; gch = gch->next_in_room)
//     if (is_same_group(ch, gch) && !IS_NPC(gch)
//  && !IS_PKILL(gch) && (ch != gch))
//  anopc++;

      /*
         count the # of non-pkill pc in b ( not including == victim ) 
       */
// for (gch = victim->in_room->first_person; gch; gch = gch->next_in_room)
//     if (is_same_group(victim, gch) && !IS_NPC(gch)
//  && !IS_PKILL(gch) && (victim != gch))
//  bnopc++;


      /*
         only consider disbanding if both groups have 1(+) non-pk pc,
         or when one participant is pc, and the other group has 1(+)
         pk pc's (in the case that participant is only pk pc in group) 
       */
      if ((bnopc > 0 && anopc > 0) || (bnopc > 0 && !IS_NPC(ch)) || (anopc > 0 && !IS_NPC(victim)))
      {
         /*
            Disband from same group first 
          */
         if (is_same_group(ch, victim))
         {
            /*
               Messages to char and master handled in stop_follower
             */
            act(AT_ACTION, "$n disbands from $N's group.",
               (ch->leader == victim) ? victim : ch, NULL, (ch->leader == victim) ? victim->master : ch->master, TO_NOTVICT);
            if (ch->leader == victim)
               stop_follower(victim);
            else
               stop_follower(ch);
         }
         /*
            if leader isnt pkill, leave the group and disband ch 
          */
         if (ch->leader != NULL && !IS_NPC(ch->leader) && !IS_PKILL(ch->leader))
         {
            act(AT_ACTION, "$n disbands from $N's group.", ch, NULL, ch->master, TO_NOTVICT);
            stop_follower(ch);
         }
         else
         {
            for (gch = ch->in_room->first_person; gch; gch = gch->next_in_room)
               if (is_same_group(gch, ch) && !IS_NPC(gch) && !IS_PKILL(gch) && gch != ch)
               {
                  act(AT_ACTION, "$n disbands from $N's group.", ch, NULL, gch->master, TO_NOTVICT);
                  stop_follower(gch);
               }
         }
         /*
            if leader isnt pkill, leave the group and disband victim 
          */
         if (victim->leader != NULL && !IS_NPC(victim->leader) && !IS_PKILL(victim->leader))
         {
            act(AT_ACTION, "$n disbands from $N's group.", victim, NULL, victim->master, TO_NOTVICT);
            stop_follower(victim);
         }
         else
         {
            for (gch = victim->in_room->first_person; gch; gch = gch->next_in_room)
               if (is_same_group(gch, victim) && !IS_NPC(gch) && !IS_PKILL(gch) && gch != victim)
               {
                  act(AT_ACTION, "$n disbands from $N's group.", gch, NULL, gch->master, TO_NOTVICT);
                  stop_follower(gch);
               }
         }
      }

/*
	for ( gch = ch->in_room->first_person; gch; gch = gch->next_in_room )
	{
	    if ( is_same_group( ch, gch )
	    && ( IS_PKILL( ch ) != IS_PKILL( gch ) ) )
	    {
		stop_follower( ch );
		stop_follower( gch );
	    }
	}

	for ( gch = victim->in_room->first_person; gch; gch = gch->next_in_room )
	{
	    if ( is_same_group( victim, gch ) 
	    && ( IS_PKILL( victim ) != IS_PKILL( gch ) ) )
	    {
		stop_follower( victim ); 
		stop_follower( gch );
	    }
	}
 */

      /*
       * Inviso attacks ... not.
       */
      if (IS_AFFECTED(ch, AFF_INVISIBLE))
      {
         affect_strip(ch, gsn_invis);
         affect_strip(ch, gsn_mass_invis);
         xREMOVE_BIT(ch->affected_by, AFF_INVISIBLE);
         act(AT_MAGIC, "$n fades into existence.", ch, NULL, NULL, TO_ROOM);
      }

      /* Take away Hide */
      if (IS_AFFECTED(ch, AFF_HIDE))
      {
         xREMOVE_BIT(ch->affected_by, AFF_HIDE);
         act(AT_RED, "$n quickly appears from the shadows.", ch, NULL, NULL, TO_ROOM);
      }
      /* Take away STALK */
      if (IS_AFFECTED(ch, AFF_STALK))
      {
         xREMOVE_BIT(ch->affected_by, AFF_STALK);
         affect_strip(ch, gsn_stalk);
         act(AT_RED, "$n quickly appears from the shadows.", ch, NULL, NULL, TO_ROOM);
      }         
      if (dt > 0 && dt < top_sn && skill_table[dt] && skill_table[dt]->name && skill_table[dt]->type == SKILL_SPELL && ch->race == RACE_FAIRY)
         dam = dam * 135 / 100;
         
      if (dt > 0 && dt < top_sn && skill_table[dt] && skill_table[dt]->name && skill_table[dt]->type == SKILL_SPELL && ch->race == RACE_OGRE)
         dam = dam * 50 / 100;        
         
      if ((dt < TYPE_HIT && dt != gsn_backstab && dt != gsn_circle && dt != gsn_kick_back) || proj)
         ;
      else
      {
         if(IS_NPC(victim) && xIS_SET(victim->act, ACT_UNDEAD))
         {
            obj = get_eq_char(ch, WEAR_WIELD);
            if(!obj)
            {
              dam = 0;
              spec = DM_UNDEAD;
            }
           
            if(obj)
            {  
               if(!xIS_SET(obj->extra_flags, ITEM_BLESS) && !xIS_SET(obj->extra_flags, ITEM_SANCTIFIED))
               {
                   dam = 0;
                   spec = DM_UNDEAD;
               }
               if(xIS_SET(obj->extra_flags, ITEM_BLESS) && obj->bless_dur > 0)
               {
                   if(dam > 0)
                   {
                       obj->bless_dur -= 1;
                   }
               }
            
               if(xIS_SET(obj->extra_flags, ITEM_BLESS) && obj->bless_dur <= 0)
               {
                   xTOGGLE_BIT(obj->extra_flags, ITEM_BLESS);
                   act(AT_MAGIC, "Your $p stops glowing...\n\r", ch, obj, NULL, TO_CHAR);
               }
            }
         }
         if(IS_NPC(victim) && xIS_SET(victim->act, ACT_LIVING_DEAD))
         {
            obj = get_eq_char(ch, WEAR_WIELD);
            if(!obj)
            {
               dam = dam / 2;
            }
          
            if(obj)
            {
               if(!xIS_SET(obj->extra_flags, ITEM_BLESS) && !xIS_SET(obj->extra_flags, ITEM_SANCTIFIED))
               {
                  dam = dam / 2;
               }
          
               if(xIS_SET(obj->extra_flags, ITEM_BLESS) || xIS_SET(obj->extra_flags, ITEM_SANCTIFIED))
               {
                  dam = dam * 2;
               }
          
          
               if(xIS_SET(obj->extra_flags, ITEM_BLESS) && obj->bless_dur == 0)
               {
                  xTOGGLE_BIT(obj->extra_flags, ITEM_BLESS);
                  act(AT_MAGIC, "Your $p stops glowing...\n\r", ch, obj, NULL, TO_CHAR);
               }
               if(xIS_SET(obj->extra_flags, ITEM_BLESS) && obj->bless_dur > 0)
               {
                  if(dam > 0)
                  {
                     obj->bless_dur -= 1;
                  }
               }
            }
         }
      }
      /*
       * Check for disarm, trip, parry, and dodge.
       */
      if ((dt == TYPE_HIT ||dt == gsn_backstab || dt == gsn_circle || dt == gsn_kick_back) && in_same_room(ch, victim))
      {
         int pvalue = 0;

         if (IS_NPC(ch) && xIS_SET(ch->defenses, DFND_DISARM) && number_percent() < 12) /* Was 2 try this --Shaddai */
            disarm(ch, victim);

         if (IS_NPC(ch) && xIS_SET(ch->attacks, ATCK_TRIP) && number_percent() <= 15)
            trip(ch, victim);

         if ((!IS_NPC(victim) && xIS_SET(victim->act, PLR_PARRY)) || IS_NPC(victim))
         {
            pvalue = check_parry(ch, victim);     
            if (pvalue > 0)
            {
               OBJ_DATA *dweapon = get_eq_char(victim, WEAR_WIELD);
               if (dweapon)
               {
                  if (number_range(1, 100) > (40 + (get_obj_resistance(dweapon, victim) * 3)))
                  {
                     set_cur_obj(dweapon);   
                     damage_obj(dweapon, victim, proj, dam);
                  }
               }
            }    
            if (pvalue == TRUE)
               return rNONE;
            if (pvalue > 1)
            {
               dam = dam * pvalue / 100;
               dam = UMAX(1, dam);
            }
         }
      }
      /*
       * Check control panel settings and modify damage
       */
      if (IS_NPC(ch))
      {
         if (npcvict)
            dampmod = sysdata.dam_mob_vs_mob;
         else
            dampmod = sysdata.dam_mob_vs_plr;
      }
      else
      {
         if (npcvict)
            dampmod = sysdata.dam_plr_vs_mob;
         else
            dampmod = sysdata.dam_plr_vs_plr;
      }
      if (dampmod > 0)
         dam = (dam * dampmod) / 100;
         
      if (dam > 0 && spec != DM_UNDEAD && spec != DM_BLOCK)
      {
         if (spec == DM_MISS)
         {
            if (ch->grip == GRIP_BASH)
               dam/=2;
            if (ch->grip == GRIP_SLASH)
               dam/=4;
            if (ch->grip == GRIP_STAB)
               dam/=8;
         }
         check_limb_status(victim, limb, dam, slimb, ch, spec);
      }
         
      if (spec == DM_UNDEAD || spec == DM_MISS || spec == DM_BLOCK)
         dam = 0;
      else
      {
         if (dam < 1)
            dam = 1;
      }
      adjust_aggression_list(victim, ch, dam, 0, -1);
      if (IS_NPC(ch) && !IS_NPC(victim))
      {
         int per = 0;
         int level;
         
         if (LEARNED(victim, gsn_greater_focus_aggression) > 0)
         {
            level = POINT_LEVEL(LEARNED(victim, gsn_greater_focus_aggression), MASTERED(victim, gsn_greater_focus_aggression));
            per = 35+level/4;
            learn_from_success(victim, gsn_greater_focus_aggression, ch);
         }
         else if (LEARNED(victim, gsn_focus_aggression) > 0)
         {
            level = POINT_LEVEL(LEARNED(victim, gsn_focus_aggression), MASTERED(victim, gsn_focus_aggression));
            per = 20+level/5;
            learn_from_success(victim, gsn_focus_aggression, ch);
         }
         else if (LEARNED(victim, gsn_greater_draw_aggression) > 0)
         {
            level = POINT_LEVEL(LEARNED(victim, gsn_greater_draw_aggression), MASTERED(victim, gsn_greater_draw_aggression));
            per = 10+level/7;
            learn_from_success(victim, gsn_greater_draw_aggression, ch);
         }
         else if (LEARNED(victim, gsn_draw_aggression) > 0)
         {
            level = POINT_LEVEL(LEARNED(victim, gsn_draw_aggression), MASTERED(victim, gsn_draw_aggression));
            per = 2+level/10;
            learn_from_success(victim, gsn_draw_aggression, ch);
         }
         if (per > 0)
         {
            per = UMAX(1, dam * per /100);
            adjust_aggression_list(ch, victim, per, 4, -1);   
         }
      }
      if (proj == 1)
         new_dam_message(ch, victim, dam, TYPE_PROJECTILE, NULL, spec, limb);
      else
         new_dam_message(ch, victim, dam, dt, NULL, spec, limb);
   }
          
   /*
    * Makes since that if it does not penetrate it might damage armor, 
    * will also make newbie armor last longer
    */
   //Insert limb code here :-)
   if ((dt == TYPE_HIT ||dt == gsn_backstab || dt == gsn_circle || dt == gsn_kick_back) && limb > -1 && (spec == DM_HIT || spec == DM_CRITICAL || spec == DM_SLICEDLIMB))
   {
      /* damage eq */
      dameq = get_limb_location(limb);
      damobj = get_eq_char(victim, dameq);
      if (damobj)
      {
         if (number_range(1, 100) > (50 + (get_obj_resistance(damobj, victim) * 5/2)))
         {
            set_cur_obj(damobj);
            damage_obj(damobj, victim, proj, dam);
         }
      }
   }
   damobj = NULL;
   // Weapon deteriates over time...
   if ((dt == TYPE_HIT ||dt == gsn_backstab || dt == gsn_circle || dt == gsn_kick_back) && (spec == DM_HIT || spec == DM_CRITICAL || spec == DM_SLICEDLIMB))
   {
      damobj = get_eq_char(ch, WEAR_WIELD);
      if (damobj)
      {
         if (number_range(1, 100) > (40 + (get_obj_resistance(damobj, ch) * 3)))
         {
            set_cur_obj(damobj);   
            damage_obj(damobj, ch, proj, dam);
         }
      }
   } 
   if ((dt == TYPE_HIT ||dt == gsn_backstab || dt == gsn_circle || dt == gsn_kick_back) && spec == DM_BLOCK)
   {
      damobj = get_eq_char(victim, WEAR_SHIELD);
      if (damobj)
      {
         set_cur_obj(damobj);
         damage_obj(damobj, ch, proj, blockdam);
      }
   }
   dam = dam + adjust_mil_damage(ch, dam);
   /*
    * Hurt the victim.
    * Inform the victim of his new state.
    */
   victim->hit -= dam;
   
   if (victim->apply_manafuse > 0 && dam > 0)
   {
      victim->mana += UMAX(1, dam * UMIN(40, victim->apply_manafuse) / 100); 
      if (victim->mana > victim->max_mana)
         victim->mana = victim->max_mana;
      if (LEARNED(victim, gsn_manafuse) >= 1)
         learn_from_success(victim, gsn_manafuse, ch);
   }
   
   //Health additions
   if (!IS_NPC(victim) && dam > 0)
   {
      int mhp = 1;
      int hpi = 1;
      
      victim->pcdata->hit_cnt+=number_range(dam*6/10, dam*8/10);
      
      if (sysdata.stat_gain <= 1)
         mhp = number_range(dam*80/100, dam*105/100);
      else if (sysdata.stat_gain <= 3)
         mhp = number_range(dam*110/100, dam*135/100);
      else if (sysdata.stat_gain >= 5)
         mhp = number_range(dam*150/100, dam*200/100);
      
      if (victim->race == RACE_OGRE) //Just a slight bonus
      mhp = mhp * 125 / 100;
      
      //500 is map hp      
      if (victim->max_hit < 30)
         mhp *= 5;
      else if (victim->max_hit < 40)
         mhp *= 4.5;
      else if (victim->max_hit < 50)
         mhp *= 4;
      else if (victim->max_hit < 60)
         mhp *= 3;
      else if (victim->max_hit < 70)
         mhp *= 2.5;
      else if (victim->max_hit < 80)
         mhp *= 2;
      else if (victim->max_hit < 90)
         mhp *= 1.5;
      else if (victim->max_hit < 125)
         mhp *= 1.1;
      else if (victim->max_hit < 150)
         mhp *= .95;
      else if (victim->max_hit < 175)
         mhp *= .9;
      else if (victim->max_hit < 200)
         mhp *= .8;
      else if (victim->max_hit < 300)
         mhp *= .7;
      else if (victim->max_hit < 400)
         mhp *= .6;
      else if (victim->max_hit < 600)
         mhp *= .5;
      else if (victim->max_hit < 700)
         mhp *= .4;
      else if (victim->max_hit < 1000)
         mhp *= .35;
      else if (victim->max_hit < 1500)
         mhp *= .3;
      else
         mhp *= .25;
      
      if (victim->perm_con < 11)
         mhp *= .8;
      if (victim->perm_con >= 11 && victim->perm_con <= 13)
         mhp *= .9;
      if (victim->perm_con >= 14 && victim->perm_con <= 16)  
         mhp *= 1.05;
      if (victim->perm_con >= 17 && victim->perm_con <= 19)
         mhp *= 1.15;
      if (victim->perm_con >= 20 && victim->perm_con <= 22)
         mhp *= 1.3;
      if (victim->perm_con >= 23 && victim->perm_con < 25)
         mhp *= 1.5;
      if (victim->perm_con == 25) //25 is max
         mhp *= 2;
         
      if (victim->pcdata->hit_cnt >= get_sore_rate(victim->race, victim->max_hit))
      {
         send_to_char("&rYou are starting to develop sores where you are being hit, might want to rest.\n\r", victim);
         victim->hit -= 1;
         mhp = number_range(-3, -8);
      }
         
      if (mhp == 0)
         mhp = 1;   
      
      if (victim->race == RACE_OGRE) //Just a slight bonus
      {
          if (mhp == 1)
             mhp = 2;
      }
      
      if (mhp > 0 && victim->max_hit >= (700+get_talent_increase(victim, 9)) && victim->pcdata->per_hp >= 300)
         mhp = 0;
         
      if (mhp < 0 && victim->max_hit <= 20)
         mhp = 0;
         
      if (victim == ch)
         mhp = 0;
         
      if (victim && IS_NPC(victim) && xIS_SET(victim->act, ACT_MOUNTSAVE))
      {
         if (mhp > 0)
            mhp = 0;
      } 
      
      victim->pcdata->per_hp += mhp;
         
      if (victim->pcdata->per_hp > 1000)
      {
         if (sysdata.stat_gain <= 1)
         {
            if (victim->max_hit < 70)
               hpi = number_range(5, 7);
            else if (victim->max_hit < 100)
               hpi = number_range(4, 6);
            else if (victim->max_hit < 150)
               hpi = number_range(2, 4);
            else if (victim->max_hit < 200)
               hpi = number_range(1, 3);
            else
               hpi = 1;
         }
         else if (sysdata.stat_gain <= 2)
         {
            if (victim->max_hit < 70)
               hpi = number_range(5, 7);
            else if (victim->max_hit < 100)
               hpi = number_range(4, 6);
            else if (victim->max_hit < 200)
               hpi = number_range(3, 5);
            else if (victim->max_hit < 300)
               hpi = number_range(2, 4);
            else
               hpi = number_range(1, 2);
         }
         else if (sysdata.stat_gain >= 4)
         {
            if (victim->max_hit < 150)
               hpi = number_range(5, 7);
            else if (victim->max_hit < 300)
               hpi = number_range(4, 6);
            else if (victim->max_hit < 600)
               hpi = number_range(3, 5);
            else if (victim->max_hit < 900)
               hpi = number_range(2, 4);
            else
               hpi = number_range(1, 2);
         }
            
         victim->max_hit += hpi;
         send_to_char("&R**************************************\n\r", victim);
         ch_printf(victim, "&R******You Gain %d Point of Health******\n\r", hpi);
         send_to_char("&R**************************************\n\r", victim);
         victim->pcdata->per_hp = 0;
      }  
      if (victim->pcdata->per_hp < 0)
      {
         if (victim->max_hit < 50)
            hpi = number_range(5, 7);
         else if (victim->max_hit < 75)
            hpi = number_range(4, 6);
         else if (victim->max_hit < 100)
            hpi = number_range(2, 4);
         else if (victim->max_hit < 150)
            hpi = number_range(1, 3);
         else
            hpi = 1;
            
         victim->max_hit -= hpi;
         send_to_char("&r**************************************\n\r", victim);
         ch_printf(victim, "&R******You Lose %d Point of Health******\n\r", hpi);
         send_to_char("&r**************************************\n\r", victim);
         victim->pcdata->per_hp = 999;
      }     
   }
      
   if (victim->hit < victim->max_hit /2 && !IS_NPC(victim) && dam > 0)
   {
      int mcon, bcon;
      
      mcon = number_range(15, 30);
      
      if (sysdata.stat_gain <= 1)
         mcon = number_range(15, 30);
      else if (sysdata.stat_gain <= 3)
         mcon = number_range(35, 50);
      else if (sysdata.stat_gain >= 5)
         mcon = number_range(60, 80);
         
      bcon = 14 + race_table[victim->race]->con_plus;
      if (victim->perm_con == bcon - 4)
         mcon *= 2;
      if (victim->perm_con == bcon - 3)
         mcon *= 1.7;
      if (victim->perm_con == bcon - 2)
         mcon *= 1.5;
      if (victim->perm_con == bcon - 1)
         mcon *= 1.2;
      if (victim->perm_con == bcon)
         mcon *= 1;
      if (victim->perm_con == bcon + 1)
         mcon *= .85;
      if (victim->perm_con == bcon + 2)
         mcon *= .7;
      if (victim->perm_con == bcon + 3)
         mcon *= .6;
      if (victim->perm_con == bcon + 4)
         mcon *= .4;
      if (victim->perm_con == bcon + 5)
         mcon *= .3;
      if (victim->perm_con == bcon + 6)
         mcon *= .275;
      if (victim->perm_con == bcon + 7)
         mcon *= .25;
      if (victim->perm_con == bcon + 8)
         mcon *= .225;
      if (victim->perm_con > bcon + 8) //Base + 8 should be the max unless you screwed it up
         mcon = 0;
      else
      {
         if (mcon == 0)
            mcon = 1;
      }
         
      if (victim->hit < victim->max_hit * 3/10)
         mcon *= 1.2;
      else if (victim->hit < victim->max_hit * 15/100)
         mcon *= 1.35;
      else if (victim->hit < victim->max_hit * 5/100)
         mcon *= 1.5;
         
      if (victim->hit < 0)
      {
         mcon = number_range(-300, -500);
         victim->pcdata->lostcon += mcon;
      }
         
         
      if (mcon == 0)
         mcon = 1;    
         
      if (victim->perm_con >= (14 + race_table[victim->race]->con_plus + race_table[victim->race]->con_range + get_talent_increase(victim, 6)) &&
          mcon > 0 && victim->pcdata->per_con >= 3000)
         mcon = 0;
      if (victim->perm_con <= (14 + race_table[victim->race]->con_plus - 5 + race_table[victim->race]->con_range) &&
          mcon < 0)
         mcon = 0;
         
      if (ch && IS_NPC(ch) && xIS_SET(ch->act, ACT_MOUNTSAVE))
      {
         if (mcon > 0)
            mcon = 0;
      } 
      
      if (victim == ch)
         mcon = 0;
         
      victim->pcdata->per_con += mcon;
      if (victim->pcdata->per_con > 10000)
      {
         victim->perm_con++;
         send_to_char("&R******************************************\n\r", victim);
         send_to_char("&R*****You Gain 1 Point of Constitution*****\n\r", victim);
         send_to_char("&R******************************************\n\r", victim);
         victim->pcdata->per_con = 0;
      }
      if (victim->pcdata->per_con < 0)
      {
         victim->perm_con--;
         send_to_char("&r******************************************\n\r", victim);
         send_to_char("&r*****You Lose 1 Point of Constitution*****\n\r", victim);
         send_to_char("&r******************************************\n\r", victim);
         victim->pcdata->per_con = 9999;
      }
   }
   
   if (spec == DM_DEATH)
      victim->hit = -11;
   if (!IS_NPC(victim) && victim->level >= LEVEL_IMMORTAL && victim->hit < 1)
      victim->hit = 1;

   /* Make sure newbies dont die */

   if (!IS_NPC(victim) && NOT_AUTHED(victim) && victim->hit < 1)
      victim->hit = 1;

   if (dam > 0 && (dt == TYPE_HIT ||dt == gsn_backstab || dt == gsn_circle || dt == gsn_kick_back)
      && !IS_AFFECTED(victim, AFF_POISON)
      && is_wielding_poisoned(ch) && !is_immune(victim, -1, RIS_POISON) && !saves_poison_death(ch->level, victim))
   {
      AFFECT_DATA af;

      af.type = gsn_poison;
      af.duration = 20;
      af.location = APPLY_STR;
      af.modifier = -1;
      af.bitvector = meb(AFF_POISON);
      affect_join(victim, &af);
      victim->mental_state = URANGE(20, (victim->mental_state + 2), 100);
   }

   /*
    * Vampire self preservation    -Thoric
    */
   if (IS_VAMPIRE(victim))
   {
      if (dam >= (victim->max_hit / 10)) /* get hit hard, lose blood */
         gain_condition(victim, COND_BLOODTHIRST, -1);
      if (victim->hit <= (victim->max_hit / 8) && victim->pcdata->condition[COND_BLOODTHIRST] > 5)
      {
         gain_condition(victim, COND_BLOODTHIRST, -number_range(2, 6));
         victim->hit += URANGE(4, (victim->max_hit / 30), 15);
         set_char_color(AT_BLOOD, victim);
         send_to_char("You howl with rage as the beast within stirs!\n\r", victim);
      }
   }

   if (!npcvict && get_trust(victim) >= LEVEL_IMMORTAL && get_trust(ch) >= LEVEL_IMMORTAL && victim->hit < 1)
      victim->hit = 1;
      
   update_pos(victim);

   switch (victim->position)
   {
      case POS_MORTAL:
         act(AT_DYING, "$n is mortally wounded, and will die soon, if not aided.", victim, NULL, NULL, TO_ROOM);
         act(AT_DANGER, "You are mortally wounded, and will die soon, if not aided.^x", victim, NULL, NULL, TO_CHAR);
         break;

      case POS_INCAP:
         act(AT_DYING, "$n is incapacitated and will slowly die, if not aided.", victim, NULL, NULL, TO_ROOM);
         act(AT_DANGER, "You are incapacitated and will slowly die, if not aided.^x", victim, NULL, NULL, TO_CHAR);
         break;

      case POS_STUNNED:
         if (!IS_AFFECTED(victim, AFF_PARALYSIS))
         {
            act(AT_ACTION, "$n is stunned, but will probably recover.", victim, NULL, NULL, TO_ROOM);
            act(AT_HURT, "You are stunned, but will probably recover.", victim, NULL, NULL, TO_CHAR);
         }
         break;

      case POS_DEAD:
         if (dt >= 0 && dt < top_sn)
         {
            SKILLTYPE *skill = skill_table[dt];

            if (skill->die_char && skill->die_char[0] != '\0')
               act(AT_DEAD, skill->die_char, ch, NULL, victim, TO_CHAR);
            if (skill->die_vict && skill->die_vict[0] != '\0')
               act(AT_DEAD, skill->die_vict, ch, NULL, victim, TO_VICT);
            if (skill->die_room && skill->die_room[0] != '\0')
               act(AT_DEAD, skill->die_room, ch, NULL, victim, TO_NOTVICT);
         }
         act(AT_DEAD, "$n is DEAD!!", victim, 0, 0, TO_ROOM);
         act(AT_DEAD, "You have been KILLED!!\n\r", victim, 0, 0, TO_CHAR);
         break;

      default:
         if (dam > victim->max_hit / 4)
         {
            act(AT_HURT, "That really did HURT!", victim, 0, 0, TO_CHAR);
            if (number_bits(3) == 0)
               worsen_mental_state(victim, 1);
         }
         if (victim->hit < victim->max_hit / 4)

         {
            act(AT_DANGER, "You wish that your wounds would stop BLEEDING so much!^x", victim, 0, 0, TO_CHAR);
            if (number_bits(2) == 0)
               worsen_mental_state(victim, 1);
         }
         break;
   }

   /*
    * Sleep spells and extremely wounded folks.
    */
   //Change this so no-aggro mobs will sometimes finish a player off and nomercy flagged mobs will do it 100 percent (same as aggressive
   //for area mobs)
   if (!IS_AWAKE(victim) /* lets make NPC's not slaughter PC's */
      && !IS_AFFECTED(victim, AFF_PARALYSIS) && !xIS_SET(ch->act, ACT_NOMERCY) && number_range(1,100) <= 85 )
   {
      if (victim->fighting && victim->fighting->who->hunting && victim->fighting->who->hunting->who == victim)
         stop_hunting(victim->fighting->who);

      if (victim->fighting && victim->fighting->who->hating && victim->fighting->who->hating->who == victim)
         stop_hating(victim->fighting->who);

      if (!npcvict && IS_NPC(ch))
         stop_fighting(victim, TRUE);
      else
         stop_fighting(victim, FALSE);
   }

   /*
    * Payoff for killing things.
    */
   if (victim->position == POS_DEAD)
   {
      group_gain(ch, victim);
      spoint_gain(ch, victim);

      if (!npcvict)
      {
         sprintf(log_buf, "%s killed by %s at %d",
            victim->name, (IS_NPC(ch) ? ch->short_descr : ch->name), victim->in_room->vnum);
         log_string(log_buf);
         to_channel(log_buf, CHANNEL_MONITOR, "Monitor", LEVEL_IMMORTAL);

         if (!IS_NPC(ch) && !IS_IMMORTAL(ch) && ch->pcdata->clan
            && ch->pcdata->clan->clan_type != CLAN_ORDER && ch->pcdata->clan->clan_type != CLAN_GUILD && victim != ch)
         {
            sprintf(filename, "%s%s.record", CLAN_DIR, ch->pcdata->clan->name);
            sprintf(log_buf, "&P%-12s &wvs &P%s ... &w%s",
               ch->name, victim->name, ch->in_room->area->name);
            if (victim->pcdata->clan && victim->pcdata->clan->name == ch->pcdata->clan->name)
               ;
            else
               append_to_file(filename, log_buf);
         }
      }
      else if (!IS_NPC(ch)) /* keep track of mob vnum killed */
         add_kill(ch, victim);

      if (!IS_NPC(ch) && !IS_NPC(victim))
      {
         add_pkill(ch, victim); //Keep track of player killings for pranking
         update_pranking(ch, victim); //Updating the pranking
      }
      check_killer(ch, victim);

      if ((IN_WILDERNESS(ch) && ch->coord->x == victim->coord->x && ch->coord->y == victim->coord->y
            && ch->map == victim->map) 
            || (!IN_WILDERNESS(ch) && ch->in_room == victim->in_room))
         loot = legal_loot(ch, victim);
      else
         loot = FALSE;

      set_cur_char(victim);
      raw_kill(ch, victim);
      victim = NULL;

      if (!IS_NPC(ch) && loot)
      {
         /* Autogold by Scryn 8/12 */
         if (xIS_SET(ch->act, PLR_AUTOGOLD))
         {
            do_get(ch, "coins corpse");
         }
         if (xIS_SET(ch->act, PLR_AUTOLOOT) && victim != ch) /* prevent nasty obj problems -- Blodkai */
            do_get(ch, "all corpse");
         else
            do_look(ch, "in corpse");
         

         if (xIS_SET(ch->act, PLR_AUTOSAC))
            do_sacrifice(ch, "corpse");
      }

      if (IS_SET(sysdata.save_flags, SV_KILL))
         save_char_obj(ch);
      return rVICT_DIED;
   }

   if (victim == ch)
      return rNONE;

   /*
    * Take care of link dead people.
    */
   if (!npcvict && !victim->desc && !IS_SET(victim->pcdata->flags, PCFLAG_NORECALL))
   {
      if (number_range(0, victim->wait) == 0)
      {
         do_recall(victim, "");
         return rNONE;
      }
   }
   if (victim->position >= POS_BERSERK && victim->apply_weaponclamp > 0 && get_eq_char(ch, WEAR_WIELD) && ch != victim)
   {
      int chance;
      int sn = skill_lookup("weaponclamp");
      chance = URANGE(1, victim->apply_weaponclamp/10, 10);
      if (get_eq_char(victim, WEAR_DUAL_WIELD) == NULL)
         chance = UMAX(1, chance/2);
      if (number_range(1, 100) <= chance)
      {
         act(AT_WHITE,"$n quickly attempts a weaponclamp against $N after $N's attack.", victim, NULL, ch, TO_NOTVICT);
         act(AT_WHITE,"You quickly attempt a weaponclamp against $N after $N's attack.", victim, NULL, ch, TO_CHAR);
         act(AT_WHITE,"$n quickly attempts a weaponclamp against you after your attack.", victim, NULL, ch, TO_VICT);
         if (sn > 0 && LEARNED(victim, sn) > 0)
            learn_from_success(victim, sn, ch);
         disarm(victim, ch);
      }
   }
   /*
    * Wimp out?
    */
   if (npcvict && dam > 0)
   {
      if ((xIS_SET(victim->act, ACT_WIMPY) && number_bits(1) == 0 && victim->fight_timer == 0
            && victim->hit < victim->max_hit / 2) || (IS_AFFECTED(victim, AFF_CHARM) && victim->master && victim->master->in_room != victim->in_room))
      {
         start_fearing(victim, ch);
         stop_hunting(victim);
         do_flee(victim, "");
      }
   }

   if (!npcvict && victim->hit > 0 && victim->hit <= victim->wimpy && victim->wait == 0 && victim->fight_timer == 0)
      do_flee(victim, "");
   else if (!npcvict && xIS_SET(victim->act, PLR_FLEE))
      do_flee(victim, "");
      
   if (ch && victim && dam)
   {
      OBJ_DATA *wield;
      /*
       * Weapon spell support    -Thoric
       * Each successful hit casts a spell
       */
      if ((dt == TYPE_HIT ||dt == gsn_backstab || dt == gsn_circle || dt == gsn_kick_back) && ((wield=get_eq_char(ch, WEAR_WIELD)) != NULL) && !is_immune(victim, -1, RIS_MAGIC) && !wIS_SET(victim, ROOM_NO_MAGIC) 
      &&  !xIS_SET(victim->in_room->room_flags, ROOM_NO_MAGIC))
      {
         AFFECT_DATA *aff;

         for (aff = wield->pIndexData->first_affect; aff; aff = aff->next)
            if (aff->location == APPLY_WEAPONSPELL && IS_VALID_SN(aff->modifier) && skill_table[aff->modifier]->spell_fun)
               retcode = (*skill_table[aff->modifier]->spell_fun) (aff->modifier, (wield->level + 3) / 3, ch, victim);
         if (retcode != rNONE || char_died(ch) || char_died(victim))
            return retcode;
         for (aff = wield->first_affect; aff; aff = aff->next)
            if (aff->location == APPLY_WEAPONSPELL && IS_VALID_SN(aff->modifier) && skill_table[aff->modifier]->spell_fun)
               retcode = (*skill_table[aff->modifier]->spell_fun) (aff->modifier, (wield->level + 3) / 3, ch, victim);
         if (retcode != rNONE || char_died(ch) || char_died(victim))
            return retcode;
      }

      /*
       * magic shields that retaliate    -Thoric
       */
      if (dt != skill_lookup("flare") && dt != skill_lookup("iceshard") && dt != skill_lookup("torrent")
      &&  dt != skill_lookup("manatorrent"))
      {
         if (IS_AFFECTED(victim, AFF_FIRESHIELD) && !IS_AFFECTED(ch, AFF_FIRESHIELD))
            retcode = spell_smaug(skill_lookup("flare"), off_shld_lvl(victim), victim, ch);
         if (retcode != rNONE || char_died(ch) || char_died(victim))
            return retcode;

         if (IS_AFFECTED(victim, AFF_ICESHIELD) && !IS_AFFECTED(ch, AFF_ICESHIELD))
            retcode = spell_smaug(skill_lookup("iceshard"), off_shld_lvl(victim), victim, ch);
         if (retcode != rNONE || char_died(ch) || char_died(victim))
            return retcode;

         if (IS_AFFECTED(victim, AFF_SHOCKSHIELD) && !IS_AFFECTED(ch, AFF_SHOCKSHIELD))
            retcode = spell_smaug(skill_lookup("torrent"), off_shld_lvl(victim), victim, ch);
         if (retcode != rNONE || char_died(ch) || char_died(victim))
            return retcode;
      
         if (victim->apply_manashield > 0)
         {
            int nsn = skill_lookup("manashield");
            retcode = spell_smaug(skill_lookup("manatorrent"), victim->apply_manashield, victim, ch);
            if (retcode != rNONE || char_died(ch) || char_died(victim))
               return retcode;
            if (nsn > 0 && LEARNED(victim, nsn) > 0)
               learn_from_success(victim, nsn, ch);
         }
      }
   }
   tail_chain();
   return rNONE;
}

//just in case later if some more things need to be checked to determine room safe
bool is_room_safe(CHAR_DATA * ch)
{
   if (ch->in_room && xIS_SET(ch->in_room->room_flags, ROOM_SAFE))
      return TRUE;

   return FALSE;
}

const char *cpstatus[MAX_PEACEVALUE] = {
   "WAR", "Neutral", "Trading", "Peace"
};

bool is_safe(CHAR_DATA * ch, CHAR_DATA * victim)
{
   /* Thx Josh! */
   if (who_fighting(ch) == ch)
      return FALSE;

   if (!victim) /*Gonna find this is_safe crash bug -Blod */
   {
      bug("Is_safe: %s opponent does not exist!", ch->name);
      return TRUE;
   }
   if (!victim->in_room)
   {
      bug("Is_safe: %s has no physical location!", victim->name);
      return TRUE;
   }
   if (!IS_NPC(victim) && (xIS_SET(victim->act, PLR_ATTACKER) || xIS_SET(victim->act, PLR_KILLER) || xIS_SET(victim->act, PLR_THIEF)))
   {
      return FALSE; // They are never safe.
   }
   if (has_artifact(victim) == TRUE) //Hunt the pig
      return FALSE;

   if ((is_room_safe(ch) || is_room_safe(victim)))
   {
      set_char_color(AT_MAGIC, ch);
      send_to_char("A magical force prevents you from attacking.\n\r", ch);
      return TRUE;
   }

   if ((IS_PACIFIST(ch)) && !IN_ARENA(ch)) /* Fireblade */
   {
      set_char_color(AT_MAGIC, ch);
      ch_printf(ch, "You are a pacifist and will not fight.\n\r");
      return TRUE;
   }

   if (IS_NPC(victim) && xIS_SET(victim->act, ACT_PACIFIST)) /* Gorog */
   {
      char buf[MSL];

      sprintf(buf, "%s is a pacifist and will not fight.\n\r", capitalize(victim->short_descr));
      set_char_color(AT_MAGIC, ch);
      send_to_char(buf, ch);
      return TRUE;
   }

   if (!IS_NPC(ch) && ch->level >= LEVEL_IMMORTAL)
      return FALSE;
      
   if (!IS_NPC(victim) && victim->level >= LEVEL_IMMORTAL)
      return FALSE;

   if (!IS_NPC(ch) && !IS_NPC(victim) && ch != victim && ((check_room_pk(ch) == 1) || check_room_pk(victim) == 1))
   {
      set_char_color(AT_IMMORT, ch);
      send_to_char("The gods have forbidden player killing in this area.\n\r", ch);
      return TRUE;
   }
   if (!IS_NPC(ch) && !IS_NPC(victim) && IN_ARENA(ch) && IN_ARENA(victim))
      return FALSE;
   //Check for same clan/same kingdom/same ip, etc.
   if (!IS_NPC(ch) && !IS_NPC(victim))
   {
      /*if (ch->desc && victim->desc && ch->desc->host && victim->desc->host && !str_cmp(ch->desc->host, victim->desc->host))
      {
         send_to_char("Killing a multi is NOT ALLOWED.\n\r", ch);
         return TRUE;
      }*/
      //Check to see if they can kill the player while on caste map
      if (kingdom_table[ch->pcdata->hometown]->peace[victim->pcdata->hometown] >= 2)
      {
         ch_printf(ch, "Your kingdom has a policy of %s with %s's kingdom.\n\r",
            cpstatus[kingdom_table[ch->pcdata->hometown]->peace[victim->pcdata->hometown]], victim->name);
         return TRUE;
      }
      if (IS_SET(ch->in_room->area->flags, AFLAG_CARPENTER))
      {
         if (kingdom_table[ch->pcdata->hometown]->peace[victim->pcdata->hometown] >= 3)
         {
            ch_printf(ch, "You are at peace with %s's kingdom.\n\r", PERS_MAP(victim, ch));
            return TRUE;
         }
      }
   }
   if (IS_NPC(ch) || IS_NPC(victim))
      return FALSE;

   return FALSE;
}

/*
 * just verify that a corpse looting is legal
 */
bool legal_loot(CHAR_DATA * ch, CHAR_DATA * victim)
{
   /* anyone can loot mobs */
   if (IS_NPC(victim))
      return TRUE;
   /* non-charmed mobs can loot anything */
   if (IS_NPC(ch) && !ch->master)
      return TRUE;
   /* members of different clans can loot too! -Thoric */
   if (check_room_pk(ch) == 4)
      return TRUE;
   return FALSE;
}

/*
 * just verify that stealing coins is legal
 */
bool legal_loot_coins(CHAR_DATA * ch, CHAR_DATA * victim)
{
   /* anyone can loot mobs */
   if (IS_NPC(victim))
      return TRUE;
   /* non-charmed mobs can loot anything */
   if (IS_NPC(ch) && !ch->master)
      return TRUE;
   /* members of different clans can loot too! -Thoric */
   if (check_room_pk(ch) >= 2)
      return TRUE;
   return FALSE;
}

bool can_see_intro(CHAR_DATA *ch, CHAR_DATA *victim)
{
   int mod;
   OBJ_DATA *light;
   
   if (get_wear_hidden_cloak(victim))
      return FALSE;
      
   if (!IN_WILDERNESS(ch))
   {
      if (!can_see(ch, victim))
         return FALSE;
   }
   
   if (!can_see_map(ch, victim))
      return FALSE;
   if (gethour() > 21 || gethour() < 6)
   {
      mod = 2;
      light = get_eq_char(victim, WEAR_LIGHT);
      if (light && light->item_type == ITEM_LIGHT)
         mod = 4;
   }
   else
   {
      mod = 5;
   }
   if (abs(ch->coord->x - victim->coord->x) > mod || abs(ch->coord->y - victim->coord->y) > mod)
   {
      return FALSE;
   } 
   return TRUE;
}

/*
 * See if an attack justifies a KILLER flag.
 */
void check_killer(CHAR_DATA * ch, CHAR_DATA * victim)
{
   int oldb;
   CHAR_DATA *rch;
   INTRO_DATA *intro;

   oldb = barena;
   /*
    * NPC's are fair game.
    */
   if (IS_NPC(victim))
   {
      if (!IS_NPC(ch))
      {
         int level_ratio;

         level_ratio = number_range(2, 5);
         if (ch->pcdata->clan)
            ch->pcdata->clan->mkills++;
         ch->pcdata->mkills++;
	 ch->fame = ch->fame + 1;
         ch->in_room->area->mkills++;
         if (ch->pcdata->deity)
         {
            if (victim->race == ch->pcdata->deity->npcrace)
               adjust_favor(ch, 3, level_ratio);
            else if (victim->race == ch->pcdata->deity->npcfoe)
               adjust_favor(ch, 17, level_ratio);
            else
               adjust_favor(ch, 2, level_ratio);
         }
      }
      return;
   }
   //NPC and Charmees first....
   /*
    * Charm-o-rama.
    */
   if (IS_AFFECTED(ch, AFF_CHARM))
   {
      if (!ch->master)
      {
         char buf[MSL];

         sprintf(buf, "Check_killer: %s bad AFF_CHARM", IS_NPC(ch) ? ch->short_descr : ch->name);
         bug(buf, 0);
         affect_strip(ch, gsn_charm_person);
         xREMOVE_BIT(ch->affected_by, AFF_CHARM);
         return;
      }

      /* stop_follower( ch ); */
      if (ch->master)
         check_killer(ch->master, victim);
      return;
   }

   /*
    * NPC's are cool of course (as long as not charmed).
    * Hitting yourself is cool too (bleeding).
    * So is being immortal (Alander's idea).
    * And current killers stay as they are.
    */
   if (IS_NPC(ch))
   {
      if (!IS_NPC(victim))
      {
         int level_ratio;

         if (victim->pcdata->clan)
            victim->pcdata->clan->mdeaths++;
         victim->pcdata->mdeaths++;
         victim->in_room->area->mdeaths++;
         level_ratio = number_range(2, 5);
         if (victim->pcdata->deity)
         {
            if (ch->race == victim->pcdata->deity->npcrace)
               adjust_favor(victim, 12, level_ratio);
            else if (ch->race == victim->pcdata->deity->npcfoe)
               adjust_favor(victim, 15, level_ratio);
            else
               adjust_favor(victim, 11, level_ratio);
         }
      }
      return;
   }


   /*
    * If you kill yourself nothing happens.
    */

   if (ch == victim || ch->level >= LEVEL_IMMORTAL)
      return;
      
   //PC Stuff now that we are all returned

   if ((xIS_SET(victim->act, PLR_KILLER) || xIS_SET(victim->act, PLR_THIEF) || xIS_SET(victim->act, PLR_ATTACKER)) && !IS_NPC(victim))
   {
      if (!IS_NPC(ch))
      {
         if (ch->pcdata->clan)
         {
            ch->pcdata->clan->pkills[1]++;
         }
         ch->pcdata->pkills++;
         ch->in_room->area->pkills++;
         ch->hit = ch->max_hit;
         ch->hit += ch->max_hit / 3;
         ch->mana = ch->max_mana;
         ch->mana += ch->max_mana / 3;
         ch->move = ch->max_move;
         if (ch->pcdata)
            ch->pcdata->condition[COND_BLOODTHIRST] = (10 + ch->level);
         update_pos(victim);
         if (victim != ch)
         {
            act(AT_MAGIC, "Bolts of red energy rise from the corpse, seeping into $n.", ch, NULL, NULL, TO_ROOM);
            act(AT_MAGIC, "Bolts of red energy rise from the corpse, seeping into you.", ch, NULL, NULL, TO_CHAR);
         }
         if (victim->pcdata->clan)
         {
            victim->pcdata->clan->pdeaths[1]++;

         }
         victim->pcdata->pdeaths++;
         adjust_favor(victim, 11, 1);
         adjust_favor(ch, 2, 1);
         barena = 1;
         //type 0 - win 1 - losses 2 - ties 3 - games 4 - numavg 5 - update 6 - kill 7 - pkill
//8 - pdeath 9 - pranking
         update_barena(ch, 5);
         update_barena(ch, 7);
         update_barena(ch, 9);
         update_barena(victim, 5);
         update_barena(victim, 8);
         update_barena(victim, 9);
         save_barena_data();
         barena = oldb;
         WAIT_STATE(victim, 6 * PULSE_VIOLENCE);
      }
   }
   else if (!IS_NPC(ch) && !IS_NPC(victim))
   {
      /* not of same clan? Go ahead and kill!!! */
      if (check_room_pk(ch) > 1)
      {
         if (!ch->pcdata->clan || !victim->pcdata->clan || ch->pcdata->clan != victim->pcdata->clan)
         {
            if (ch->pcdata->clan)
            {
               ch->pcdata->clan->pkills[1]++;
            }
            ch->pcdata->pkills++;
	        ch->fame = ch->fame + 7;
            ch->hit = ch->max_hit;
            ch->mana = ch->max_mana;
            ch->move = ch->max_move;
            if (ch->pcdata)
               ch->pcdata->condition[COND_BLOODTHIRST] = (10 + ch->level);
            update_pos(victim);
            if (victim != ch)
            {
               act(AT_MAGIC, "Bolts of blue energy rise from the corpse, seeping into $n.", ch, NULL, NULL, TO_ROOM);
               act(AT_MAGIC, "Bolts of blue energy rise from the corpse, seeping into you.", ch, NULL, NULL, TO_CHAR);
            }
            if (victim->pcdata->clan)
            {
               victim->pcdata->clan->pdeaths[1]++;
            }
            victim->pcdata->pdeaths++;
            adjust_favor(victim, 11, 1);
            adjust_favor(ch, 2, 1);
            barena = 1;
            //type 0 - win 1 - losses 2 - ties 3 - games 4 - numavg 5 - update 6 - kill 7 - pkill
            //8 - pdeath 9 - pranking
            update_barena(ch, 5);
            update_barena(ch, 7);
            update_barena(ch, 9);
            update_barena(victim, 5);
            update_barena(victim, 8);
            update_barena(victim, 9);
            save_barena_data();
            barena = oldb;
            WAIT_STATE(victim, 3 * PULSE_VIOLENCE);
         }
      }
   }
   else if (!IS_NPC(victim))
   {
      if (victim->pcdata->clan)
      {
         victim->pcdata->clan->pdeaths[1]++;
      }
      victim->pcdata->pdeaths++;
      victim->in_room->area->pdeaths++;
      barena = 1;
      //type 0 - win 1 - losses 2 - ties 3 - games 4 - numavg 5 - update 6 - kill 7 - pkill
      //8 - pdeath 9 - pranking
      update_barena(victim, 5);
      update_barena(victim, 8);
      update_barena(victim, 9);
      save_barena_data();
      barena = oldb;
   }
   
   //No need to mess with intros in an arena fight.
   if (IN_ARENA(ch) || IN_ARENA(victim))
   {
      save_char_obj(victim);       
      save_char_obj(ch);
      return;
   }
   for (intro = ch->pcdata->first_introduction; intro; intro = intro->next)
   {
      if (intro->pid == victim->pcdata->pid)
      {
         if (intro->value < 0)
            intro->value *=-1;

         REMOVE_BIT(intro->flags, INTRO_ATTACKER);
         REMOVE_BIT(intro->flags, INTRO_KILLER);
         REMOVE_BIT(intro->flags, INTRO_THIEF);
         REMOVE_BIT(intro->flags, INTRO_MYATTACKER);
         REMOVE_BIT(intro->flags, INTRO_MYKILLER);
         REMOVE_BIT(intro->flags, INTRO_MYTHIEF);
         break;
      }
   }

   for (intro = victim->pcdata->first_introduction; intro; intro = intro->next)
   {
      if (intro->pid == ch->pcdata->pid && can_see_intro(ch, victim))
      {
         if (intro->value > 0)
            intro->value *=-1;
         intro->value -=15000;
         if (intro->value < -150000)
            intro->value = -150000;
         SET_BIT(intro->flags, INTRO_MYKILLER);
         REMOVE_BIT(intro->flags, INTRO_KILLER);
         intro->lastseen = time(0);
         break;
      }
   }
   
   if (!intro && can_see_intro(ch, victim))
   {
      CREATE(intro, INTRO_DATA, 1);
      intro->pid = ch->pcdata->pid;
      intro->value = -15000;
      intro->lastseen = time(0);
      SET_BIT(intro->flags, INTRO_MYKILLER);
      LINK(intro, victim->pcdata->first_introduction, victim->pcdata->last_introduction, next, prev);   
   }

   for (rch = ch->in_room->first_person; rch; rch = rch->next)
   {
      if (!IS_NPC(rch))
      {
         for (intro = rch->pcdata->first_introduction; intro; intro = intro->next)
         {
            if (ch->pcdata->pid == intro->pid && rch != ch && rch != victim && can_see_intro(rch, victim))
            {
               if (intro->value > 100000)
                  continue;
               if (intro->value > 0)
                  intro->value *=-1;
               intro->value -=15000;
               if (intro->value < -150000)
                  intro->value = -150000;
               intro->lastseen = time(0);
              
               if (!IS_SET(intro->flags, INTRO_MYKILLER))
                   SET_BIT(intro->flags, INTRO_KILLER);
               break;
            }
         }
         if (!intro && can_see_intro(rch, victim) && rch != ch && rch != victim)
         {
            CREATE(intro, INTRO_DATA, 1);
            intro->pid = ch->pcdata->pid;
            intro->value = -15000;
            intro->lastseen = time(0);
            SET_BIT(intro->flags, INTRO_KILLER);
            LINK(intro, rch->pcdata->first_introduction, rch->pcdata->last_introduction, next, prev);   
         }  
         save_char_obj(rch);
      }
   }
   save_char_obj(victim);       
   save_char_obj(ch);
   return;
}

/*
 * See if an attack justifies a ATTACKER flag.
 */
void check_attacker(CHAR_DATA * ch, CHAR_DATA * victim)
{
   CHAR_DATA *rch;
   INTRO_DATA *intro;
/* 
 * Made some changes to this function Apr 6/96 to reduce the prolifiration
 * of attacker flags in the realms. -Narn
 */
   /*
    * NPC's are fair game.
    * So are killers and thieves.
    */
   if (IS_NPC(victim) || xIS_SET(victim->act, PLR_KILLER) || xIS_SET(victim->act, PLR_THIEF) || xIS_SET(victim->act, PLR_ATTACKER))
      return;

   //no attack flag for legal kills you know :-) 
   if (in_arena(ch))
      return;

/* Pkiller versus pkiller will no longer ever make an attacker flag
    { if ( !(ch->pcdata->clan && victim->pcdata->clan
      && ch->pcdata->clan == victim->pcdata->clan ) )  return; }
*/

   /*
    * Charm-o-rama.
    */
   if (IS_AFFECTED(ch, AFF_CHARM))
   {
      if (!ch->master)
      {
         char buf[MSL];

         sprintf(buf, "Check_attacker: %s bad AFF_CHARM", IS_NPC(ch) ? ch->short_descr : ch->name);
         bug(buf, 0);
         affect_strip(ch, gsn_charm_person);
         xREMOVE_BIT(ch->affected_by, AFF_CHARM);
         return;
      }

      /* Won't have charmed mobs fighting give the master an attacker 
         flag.  The killer flag stays in, and I'll put something in 
         do_murder. -Narn */
      /* xSET_BIT(ch->master->act, PLR_ATTACKER); */
      /* stop_follower( ch ); */
      return;
   }

   /*
    * NPC's are cool of course (as long as not charmed).
    * Hitting yourself is cool too (bleeding).
    * So is being immortal (Alander's idea).
    * And current killers stay as they are.
    */
   if (IS_NPC(ch) || ch == victim || ch->level >= LEVEL_IMMORTAL || xIS_SET(ch->act, PLR_ATTACKER) || xIS_SET(ch->act, PLR_KILLER) || IN_ARENA(ch))
      return;
      
   for (intro = victim->pcdata->first_introduction; intro; intro = intro->next)
   {
      if (intro->pid == ch->pcdata->pid && can_see_intro(ch, victim))
      {
         if (intro->value > 0)
            intro->value *=-1;
         intro->value -=15000;
         if (intro->value < -150000)
            intro->value = -150000;
         if (!IS_SET(intro->flags, INTRO_MYKILLER))
            SET_BIT(intro->flags, INTRO_MYATTACKER);
         REMOVE_BIT(intro->flags, INTRO_ATTACKER);
         intro->lastseen = time(0);
         break;
      }
   }
   
   if (!intro && can_see_intro(ch, victim))
   {
      CREATE(intro, INTRO_DATA, 1);
      intro->pid = ch->pcdata->pid;
      intro->value = -15000;
      intro->lastseen = time(0);
      SET_BIT(intro->flags, INTRO_MYATTACKER);
      LINK(intro, victim->pcdata->first_introduction, victim->pcdata->last_introduction, next, prev);   
   }

   for (rch = ch->in_room->first_person; rch; rch = rch->next)
   {
      if (!IS_NPC(rch))
      {
         for (intro = rch->pcdata->first_introduction; intro; intro = intro->next)
         {
            if (rch->pcdata->pid == intro->pid && rch != ch && rch != victim && can_see_intro(rch, victim))
            {
               if (intro->value > 100000)
                  continue;
               if (intro->value > 0)
                  intro->value *=-1;
               intro->value -=15000;
               if (intro->value < -150000)
                  intro->value = -150000;
               intro->lastseen = time(0);
               if (!IS_SET(intro->flags, INTRO_MYKILLER) || !IS_SET(intro->flags, INTRO_MYATTACKER) || !IS_SET(intro->flags, INTRO_KILLER))
                   SET_BIT(intro->flags, INTRO_ATTACKER);
               break;
            }
         }
         if (!intro && can_see_intro(rch, victim) && rch != ch && rch != victim)
         {
            CREATE(intro, INTRO_DATA, 1);
            intro->pid = ch->pcdata->pid;
            intro->value = -15000;
            intro->lastseen = time(0);
            SET_BIT(intro->flags, INTRO_ATTACKER);
            LINK(intro, rch->pcdata->first_introduction, rch->pcdata->last_introduction, next, prev);   
         }  
         save_char_obj(rch);
      }
   }
   save_char_obj(victim);       
   save_char_obj(ch);
   return;
}

//I want to die now :-)
void do_giveup(CHAR_DATA *ch, char *argument)
{
   if (argument[0] == '\0')
   {
      send_to_char("Syntax:  giveup now\n\rThis command will kill you if your health is <= -3\n\r", ch);
      return;
   }
   if (ch->hit <= -3)
   {
      act(AT_RED, "It looks like $n give up hope in surviving and passed on.", ch, NULL, NULL, TO_ROOM);
      ch_printf(ch, "You giveup the battle and die!\n\r", ch);
      ch->hit = -16;
      update_pos(ch);
      return;
   }
   else
   {
      send_to_char("You can only use this if your health is at -3 or below.\n\r", ch);
      return;
   }
}

/*
 * Set position of a victim.
 */
void update_pos(CHAR_DATA * victim)
{
   if (!victim)
   {
      bug("update_pos: null victim", 0);
      return;
   }

   if (victim->hit > 0)
   {
      if (victim->position <= POS_STUNNED)
         victim->position = POS_STANDING;
      if (IS_AFFECTED(victim, AFF_PARALYSIS))
         victim->position = POS_STUNNED;
      return;
   }

   if (IS_NPC(victim) || victim->hit < -15)
   {
      if (victim->mount)
      {
         act(AT_ACTION, "$n falls from $N.", victim, NULL, victim->mount, TO_ROOM);
         xREMOVE_BIT(victim->mount->act, ACT_MOUNTED);
         victim->mount = NULL;
      }
      victim->position = POS_DEAD;
      return;
   }

   if (victim->hit < -11)
      victim->position = POS_MORTAL;
   else if (victim->hit < -3)
      victim->position = POS_INCAP;
   else
      victim->position = POS_STUNNED;

   if (victim->position > POS_STUNNED && IS_AFFECTED(victim, AFF_PARALYSIS))
      victim->position = POS_STUNNED;

   if (victim->mount)
   {
      act(AT_ACTION, "$n falls unconscious from $N.", victim, NULL, victim->mount, TO_ROOM);
      xREMOVE_BIT(victim->mount->act, ACT_MOUNTED);
      victim->mount = NULL;
   }
   return;
}


/*
 * Start fights.
 */
void set_fighting(CHAR_DATA * ch, CHAR_DATA * victim)
{
   FIGHT_DATA *fight;

   if (ch->fighting)
   {
      char buf[MSL];

      sprintf(buf, "Set_fighting: %s -> %s (already fighting %s)", ch->name, victim->name, ch->fighting->who->name);
      bug(buf, 0);
      return;
   }
   
   if (ch->coord->x != victim->coord->x || ch->coord->y != victim->coord->y || ch->map != victim->map)
      return;

   if (IS_AFFECTED(ch, AFF_SLEEP))
      affect_strip(ch, gsn_sleep);

   /* Limit attackers -Thoric */
   if (victim->num_fighting > max_fight(victim))
   {
      send_to_char("There are too many people fighting for you to join in.\n\r", ch);
      return;
   }

   CREATE(fight, FIGHT_DATA, 1);
   fight->who = victim;
   if (sysdata.resetgame && check_powerlevel(ch, victim) 
   &&  (get_player_statlevel(ch) > get_player_statlevel(victim) + 15))
   {
      fight->twinkpoints = get_player_statlevel(ch) - get_player_statlevel(victim) - 11;
      fight->twinkpoints = UMIN(25, fight->twinkpoints);
   }
   fight->xp = (int) xp_compute(ch, victim) * 0.85;
   /*
      fight->align = align_compute( ch, victim );
    */
   if (!IS_NPC(ch) && IS_NPC(victim))
      fight->timeskilled = times_killed(ch, victim);
   ch->num_fighting = 1;
   ch->fighting = fight;
   /* ch->position = POS_FIGHTING; */
   if (IS_NPC(ch))
      ch->position = POS_FIGHTING;
   else
      switch (ch->style)
      {
         case (STYLE_EVASIVE): case (STYLE_DIVINE): case (STYLE_WIZARDRY):
            ch->position = POS_EVASIVE;
            break;
         case (STYLE_DEFENSIVE):
            ch->position = POS_DEFENSIVE;
            break;
         case (STYLE_AGGRESSIVE):
            ch->position = POS_AGGRESSIVE;
            break;
         case (STYLE_BERSERK):
            ch->position = POS_BERSERK;
            break;
         default:
            ch->position = POS_FIGHTING;
      }
   victim->num_fighting++;
   if (victim->switched && IS_AFFECTED(victim->switched, AFF_POSSESS))
   {
      send_to_char("You are disturbed!\n\r", victim->switched);
      do_return(victim->switched, "");
   }
   return;
}

void do_parry(CHAR_DATA *ch, char *argument)
{
   if (argument[0] == '\0')
   {
      send_to_char("parry [on/off]\n\r", ch);
      return;
   }
   if (!str_cmp(argument, "on"))
   {
      xSET_BIT(ch->act, PLR_PARRY);
      send_to_char("You will now parry in battle.\n\r", ch);
      return;
   }
   else if (!str_cmp(argument, "off"))
   {
      xREMOVE_BIT(ch->act, PLR_PARRY);
      send_to_char("You will no longer parry in battle.\n\r", ch);
      return;
   }
   else
   {
      do_parry(ch, "");
      return;
   }
}

void do_dodge(CHAR_DATA *ch, char *argument)
{
   if (argument[0] == '\0')
   {
      send_to_char("dodge [on/off]\n\r", ch);
      return;
   }
   if (!str_cmp(argument, "on"))
   {
      xREMOVE_BIT(ch->act, PLR_DODGE);
      send_to_char("You will now dodge in battle.\n\r", ch);
      return;
   }
   else if (!str_cmp(argument, "off"))
   {
      xSET_BIT(ch->act, PLR_DODGE);
      send_to_char("You will no longer dodge in battle.\n\r", ch);
      return;
   }
   else
   {
      do_dodge(ch, "");
      return;
   }
}

void do_tumble(CHAR_DATA *ch, char *argument)
{
   if (argument[0] == '\0')
   {
      send_to_char("tumble [on/off]\n\r", ch);
      return;
   }
   if (!str_cmp(argument, "on"))
   {
      xREMOVE_BIT(ch->act, PLR_TUMBLE);
      send_to_char("You will now tumble in battle.\n\r", ch);
      return;
   }
   else if (!str_cmp(argument, "off"))
   {
      xSET_BIT(ch->act, PLR_TUMBLE);
      send_to_char("You will no longer tumble in battle.\n\r", ch);
      return;
   }
   else
   {
      do_tumble(ch, "");
      return;
   }
}

void do_counter(CHAR_DATA *ch, char *argument)
{
   if (argument[0] == '\0')
   {
      send_to_char("counter [on/off]\n\r", ch);
      return;
   }
   if (!str_cmp(argument, "on"))
   {
      xREMOVE_BIT(ch->act, PLR_COUNTER);
      send_to_char("You will now counter in battle.\n\r", ch);
      return;
   }
   else if (!str_cmp(argument, "off"))
   {
      xSET_BIT(ch->act, PLR_COUNTER);
      send_to_char("You will no longer counter in battle.\n\r", ch);
      return;
   }
   else
   {
      do_counter(ch, "");
      return;
   }
}


CHAR_DATA *who_fighting(CHAR_DATA * ch)
{
   if (!ch)
   {
      bug("who_fighting: null ch", 0);
      return NULL;
   }
   if (!ch->fighting)
      return NULL;
   return ch->fighting->who;
}

void free_fight(CHAR_DATA * ch)
{
   if (!ch)
   {
      bug("Free_fight: null ch!", 0);
      return;
   }
   if (ch->fighting)
   {
      if (!char_died(ch->fighting->who))
         --ch->fighting->who->num_fighting;
      DISPOSE(ch->fighting);
   }
   ch->fighting = NULL;
   if (ch->mount)
      ch->position = POS_MOUNTED;
   else
      ch->position = POS_STANDING;
   /* Berserk wears off after combat. -- Altrag */
   if (IS_AFFECTED(ch, AFF_BERSERK))
   {
      affect_strip(ch, gsn_berserk);
      set_char_color(AT_WEAROFF, ch);
      send_to_char(skill_table[gsn_berserk]->msg_off, ch);
      send_to_char("\n\r", ch);
   }
   return;
}


/*
 * Stop fights.
 */
void stop_fighting(CHAR_DATA * ch, bool fBoth)
{
   CHAR_DATA *fch;

   free_fight(ch);
   update_pos(ch);
   
   //Used with flee timer, don't remove the npc check
   if (!IS_NPC(ch))
      ch->fight_timer = 0;
   ch->agi_meter = 0;
   if (!IS_NPC(ch))
      strcpy(ch->pcdata->stackbuf, "");
   
   if (!fBoth) /* major short cut here by Thoric */
      return;

   for (fch = first_char; fch; fch = fch->next)
   {
      if (who_fighting(fch) == ch)
      {
         free_fight(fch);
         update_pos(fch);
      }
   }
   return;
}

/* Vnums for the various bodyparts */
int part_vnums[] = { 12, /* Head */
   14, /* arms */
   15, /* legs */
   13, /* heart */
   44, /* brains */
   16, /* guts */
   45, /* hands */
   46, /* feet */
   47, /* fingers */
   48, /* ear */
   49, /* eye */
   50, /* long_tongue */
   51, /* eyestalks */
   52, /* tentacles */
   53, /* fins */
   54, /* wings */
   55, /* tail */
   56, /* scales */
   59, /* claws */
   87, /* fangs */
   58, /* horns */
   57, /* tusks */
   55, /* tailattack */
   85, /* sharpscales */
   84, /* beak */
   86, /* haunches */
   83, /* hooves */
   82, /* paws */
   81, /* forelegs */
   80, /* feathers */
   0, /* r1 */
   0 /* r2 */
};

/* Messages for flinging off the various bodyparts */
char *part_messages[] = {
   "$n's severed head plops from its neck.",
   "$n's arm is sliced from $s dead body.",
   "$n's leg is sliced from $s dead body.",
   "$n's heart is torn from $s chest.",
   "$n's brains spill grotesquely from $s head.",
   "$n's guts spill grotesquely from $s torso.",
   "$n's hand is sliced from $s dead body.",
   "$n's foot is sliced from $s dead body.",
   "A finger is sliced from $n's dead body.",
   "$n's ear is sliced from $s dead body.",
   "$n's eye is gouged from its socket.",
   "$n's tongue is torn from $s mouth.",
   "An eyestalk is sliced from $n's dead body.",
   "A tentacle is severed from $n's dead body.",
   "A fin is sliced from $n's dead body.",
   "A wing is severed from $n's dead body.",
   "$n's tail is sliced from $s dead body.",
   "A scale falls from the body of $n.",
   "A claw is torn from $n's dead body.",
   "$n's fangs are torn from $s mouth.",
   "A horn is wrenched from the body of $n.",
   "$n's tusk is torn from $s dead body.",
   "$n's tail is sliced from $s dead body.",
   "A ridged scale falls from the body of $n.",
   "$n's beak is sliced from $s dead body.",
   "$n's haunches are sliced from $s dead body.",
   "A hoof is sliced from $n's dead body.",
   "A paw is sliced from $n's dead body.",
   "$n's foreleg is sliced from $s dead body.",
   "Some feathers fall from $n's dead body.",
   "r1 message.",
   "r2 message."
};

/*
 * Improved Death_cry contributed by Diavolo.
 * Additional improvement by Thoric (and removal of turds... sheesh!)  
 * Support for additional bodyparts by Fireblade
 */
void death_cry(CHAR_DATA * ch)
{
   ROOM_INDEX_DATA *was_in_room;
   char *msg;
   EXIT_DATA *pexit;
   int vnum, shift, index, i;

   if (!ch)
   {
      bug("DEATH_CRY: null ch!", 0);
      return;
   }

   vnum = 0;
   msg = NULL;

   switch (number_range(0, 5))
   {
      default:
         msg = "You hear $n's death cry.";
         break;
      case 0:
      case 1:
         msg = "$n hits the ground ... DEAD.";
         break;
      case 2:
      case 3:
         msg = "$n splatters blood on your armor.";
         break;
      case 4:
      case 5:
         shift = number_range(0, 31);
         index = 1 << shift;

         for (i = 0; i < 32 && ch->xflags; i++)
         {
            if (HAS_BODYPART(ch, index) && i != 1 && i != 2) //no arm/leg
            {
               msg = part_messages[shift];
               vnum = part_vnums[shift];
               break;
            }
            else
            {
               shift = number_range(0, 31);
               index = 1 << shift;
            }
         }

         if (!msg)
            msg = "You hear $n's death cry.";
         break;
   }

   act(AT_CARNAGE, msg, ch, NULL, NULL, TO_ROOM);

   if (vnum)
   {
      OBJ_DATA *obj;

      if (!get_obj_index(vnum))
      {
         bug("death_cry: invalid vnum", 0);
         return;
      }

      obj = create_object(get_obj_index(vnum), 0);
      obj->timer = number_range(4, 7);
      if (IS_AFFECTED(ch, AFF_POISON))
         obj->value[3] = 10;

      obj = obj_to_room(obj, ch->in_room, ch);
   }

   if (IS_NPC(ch))
      msg = "You hear something's death cry.";
   else
      msg = "You hear someone's death cry.";

   was_in_room = ch->in_room;
   for (pexit = was_in_room->first_exit; pexit; pexit = pexit->next)
   {
      if (pexit->to_room && pexit->to_room != was_in_room)
      {
         ch->in_room = pexit->to_room;
         act(AT_CARNAGE, msg, ch, NULL, NULL, TO_ROOM);
      }
   }
   ch->in_room = was_in_room;

   return;
}

//2 hour tick down
char *get_duel_time(int starttime)
{
   static char buf[MSL];
   int seconds = starttime + 7200 - time(0);
   int minutes;
   int hours;
   
   hours = seconds / 3600;
   minutes = seconds / 60;
   minutes = minutes % 60;
   seconds = seconds % 60;
   sprintf(buf, "%d:%2.2d:%2.2d", hours, minutes, seconds);
   return buf;
}

void do_duel(CHAR_DATA *ch, char *argument)
{
   DESCRIPTOR_DATA *d;
   ROOM_INDEX_DATA *room;
   CHAR_DATA *victim;
   
   if (check_npc(ch))
      return;
      
   if (!sysdata.resetgame)
      return;
   if (argument[0] == '\0')
   {
      send_to_char("Syntax:  duel show\n\r", ch);
      send_to_char("Syntax:  duel <player>\n\r", ch);
      send_to_char("Syntax:  duel accept\n\r", ch);
      send_to_char("Syntax:  duel deny\n\r", ch);
      return;
   }
   if (!str_cmp(argument, "deny"))
   {
      if (ch->pcdata->dual_receive_name > -1)
      {
         for (d = first_descriptor; d; d = d->next)
         {
            if (d->character && d->character->pcdata->pid == ch->pcdata->dual_receive_name)
            {
               break;
            }
         }
         if (!d)
         {
            send_to_char("The challenger is no longer online, you escaped this time.\n\r", ch);
            act(AT_RED, "$n lucked out of $s duel.", ch, NULL, NULL, TO_MUD);
            ch->pcdata->dual_receive_name = -1;
            ch->pcdata->duel_receive_pranking = 0;
            ch->pcdata->duel_receive_time = 0;
            return;
         }
         else
         {
            ch->pcdata->power_ranking -= ch->pcdata->duel_receive_pranking;
            d->character->pcdata->power_ranking += ch->pcdata->duel_receive_pranking;
            ch_printf(ch, "You lose %d Power Ranking points for your cowardness.\n\r", ch->pcdata->duel_receive_pranking);
            ch_printf(d->character, "Your challenge for a duel was denied, you are rewarded %d Power Ranking Points",
               ch->pcdata->duel_receive_pranking);
            act(AT_RED, "$n has turned down $N'd duel, what a coward!.", ch, NULL, d->character, TO_MUD);
            ch->pcdata->dual_receive_name = -1;
            ch->pcdata->duel_receive_pranking = 0;
            ch->pcdata->duel_receive_time = 0;
            d->character->pcdata->duel_offer_name = -1;
            d->character->pcdata->duel_offer_pranking = 0;
            d->character->pcdata->duel_offer_time = 0;
            return;
         }
      }
      else
      {
         send_to_char("You have not received a challenge for a duel let.\n\r", ch);
         return;
      }
   }
   if (!str_cmp(argument, "accept"))
   {
      if (ch->position < POS_STANDING)
      {
         send_to_char("You need to be standing to accept a duel.\n\r", ch);
         return;
      }
      if (ch->pcdata->dual_receive_name > -1)
      {
         for (d = first_descriptor; d; d = d->next)
         {
            if (d->character && d->character->pcdata->pid == ch->pcdata->dual_receive_name)
            {
               break;
            }
         }
         if (!d)
         {
            send_to_char("The challenger is no longer online, you escaped this time.\n\r", ch);
            act(AT_RED, "$n lucked out of $s duel.", ch, NULL, NULL, TO_MUD);
            ch->pcdata->dual_receive_name = -1;
            ch->pcdata->duel_receive_pranking = 0;
            ch->pcdata->duel_receive_time = 0;
            return;
         }
         else
         {
            room = get_room_index(number_range(60097, 60094));
            char_from_room(ch);
            char_to_room(ch, room); 
            REMOVE_ONMAP_FLAG(ch);
            ch->coord->x = -1;
            ch->coord->y = -1;
            ch->map = -1;
            if (d->character->fighting)
               stop_fighting(d->character, TRUE);
            room = get_room_index(number_range(60070, 60073));
            char_from_room(d->character);
            char_to_room(d->character, room); 
            REMOVE_ONMAP_FLAG(d->character);
            d->character->coord->x = -1;
            d->character->coord->y = -1;
            d->character->map = -1;
            send_to_char("You accepted the duel and your challenger is online, prepare to fight to the death!.\n\r", ch);
            send_to_char("Your duel has been accepted, prepare to fight to the death.\n\r", d->character);
            act(AT_RED, "$n accepted $N's challenge for a duel.", ch, NULL, d->character, TO_MUD);
            ch->pcdata->dual_receive_name = -1;
            ch->pcdata->duel_receive_pranking = 0;
            ch->pcdata->duel_receive_time = 0;
            d->character->pcdata->duel_offer_name = -1;
            d->character->pcdata->duel_offer_pranking = 0;
            d->character->pcdata->duel_offer_time = 0;
            do_look(ch, "auto");
            do_look(d->character, "auto");
            save_char_obj(ch);
            save_char_obj(d->character);
            return;
         }
      }
      else
      {
         send_to_char("You have not received a challenge for a duel let.\n\r", ch);
         return;
      }
   }
   if (!str_cmp(argument, "show"))
   {
      if (ch->pcdata->duel_offer_name > -1)
      {
         for (d = first_descriptor; d; d = d->next)
         {
            if (d->character && d->character->pcdata->pid == ch->pcdata->duel_offer_name)
            {
               ch_printf(ch, "Your challenges : %s for %d points with %s time left\n\r\n\r", 
                  PERS_MAP(d->character, ch), ch->pcdata->duel_offer_pranking, get_duel_time(ch->pcdata->duel_offer_time));
               break;
            }
         }
         if (!d)
            ch_printf(ch, "Your challenges : Offline for %d points with %s time left\n\r\n\r",
               ch->pcdata->duel_offer_pranking, get_duel_time(ch->pcdata->duel_offer_time));
      }
      else
         send_to_char("You have no outstanding challenges that you have issued.\n\r\n\r", ch);
      if (ch->pcdata->dual_receive_name > -1)
      {
         for (d = first_descriptor; d; d = d->next)
         {
            if (d->character && d->character->pcdata->pid == ch->pcdata->dual_receive_name)
            {
               ch_printf(ch, "Challenges you received : %s for %d points with %s time left\n\r", 
                  PERS_MAP(d->character, ch), ch->pcdata->duel_receive_pranking, get_duel_time(ch->pcdata->duel_receive_time));
               break;
            }
         }
         if (!d)
            ch_printf(ch, "Challenges you received : Offline for %d points with %s time left\n\r",
               ch->pcdata->duel_receive_pranking, get_duel_time(ch->pcdata->duel_receive_time));
      }
      else
         send_to_char("You have no outstanding challenges that you have received.\n\r", ch);
      return;
   }
   if ((victim = get_char_world(ch, argument)) != NULL)
   {
      if (IS_NPC(victim))
      {
         send_to_char("Not on NPCs.\n\r", ch);
         return;
      }
      if (victim == ch)
      {
         send_to_char("You cannot duel yourself.\n\r", ch);
         return;
      }
      if (get_player_statlevel(ch) -5 > get_player_statlevel(victim))
      {
         send_to_char("You have to be within 5 Power Levels to challenge someone.\n\r", ch);
         return;
      }
      act(AT_RED, "$n has challenged $N to a duel.", ch, NULL, victim, TO_MUD);
      act(AT_RED, "You have challenged $N to a duel.", ch, NULL, victim, TO_CHAR);
      act(AT_RED, "$n challenged you to a duel.", ch, NULL, victim, TO_VICT);
      victim->pcdata->duel_receive_time = time(0);
      ch->pcdata->duel_offer_time = time(0);
      victim->pcdata->dual_receive_name = ch->pcdata->pid;
      ch->pcdata->duel_offer_name = victim->pcdata->pid;
      victim->pcdata->duel_receive_pranking = victim->pcdata->power_ranking/4;
      ch->pcdata->duel_offer_pranking = victim->pcdata->power_ranking/4;
      return;
   }
   do_duel(ch, "");
}

void do_spar(CHAR_DATA *ch, char *argument)
{
   return;
}

void raw_kill(CHAR_DATA * ch, CHAR_DATA * victim)
{
   OBJ_DATA *dobj;
   CHAR_DATA *gch;
   char buf[MIL];
   int x;
   int twinkpoints = 0;

   if (!victim)
   {
      bug("raw_kill: null victim!", 0);
      return;
   }
/* backup in case hp goes below 1 */
   if (NOT_AUTHED(victim))
   {
      bug("raw_kill: killing unauthed", 0);
      return;
   }
   if (!IS_NPC(ch) && !IN_ARENA(victim) && ch->fighting && victim != ch->fighting->who && !IS_NPC(victim))
   {
      if (sysdata.resetgame && check_powerlevel(ch, victim) 
      &&  (get_player_statlevel(ch) > get_player_statlevel(victim) + 15))
      {
         twinkpoints = get_player_statlevel(ch) - get_player_statlevel(victim) - 11;
         twinkpoints = UMIN(25, ch->fighting->twinkpoints);
         ch->pcdata->twink_points += twinkpoints;   
         ch_printf(ch, "You have been assigned %d Twink Points, if you are now over 100 you will be deleted in a few seconds.", ch->fighting->twinkpoints);
      }
   }
   else
   {
      if (sysdata.resetgame && !IN_ARENA(victim) && !IS_NPC(ch) && ch->fighting && ch->fighting->twinkpoints)
      {
         ch->pcdata->twink_points += ch->fighting->twinkpoints;   
         twinkpoints = ch->fighting->twinkpoints;
         ch_printf(ch, "You have been assigned %d Twink Points, if you are now over 100 you will be deleted in a few seconds.", ch->fighting->twinkpoints);
      }
   }
   //No Power Ranking points for twink kills
   if (sysdata.resetgame && ch != victim && !IN_ARENA(victim) && !IS_NPC(ch) && !IS_NPC(victim) && !twinkpoints)
   {
      int perranking;
      int persworth;
      int percent;
      int points;
      
      perranking = (100 * victim->pcdata->power_ranking / ch->pcdata->power_ranking)-100;
      persworth = (100 * get_player_statlevel(victim) / get_player_statlevel(ch))-100;
      percent = 10 + ((perranking+persworth)/2);
      points = URANGE(1, percent * victim->pcdata->power_ranking / 100, victim->pcdata->power_ranking/2);
      points = UMIN(victim->pcdata->power_ranking-1, points);
      ch->pcdata->power_ranking += points;
      victim->pcdata->power_ranking -= points;
      ch_printf(ch, "&w&RYou earned %d Power Ranking points for your kill.&w\n\r", points);
      ch_printf(victim, "&w&RYou lost %d Power Ranking points for your death.&w\n\r", points);
   }
      
   stop_fighting(victim, TRUE);
   /* Take care of morphed characters */
   if (victim->morph)
   {
      do_unmorph_char(victim);
      raw_kill(ch, victim);
      return;
   }
   
   if (!IS_NPC(ch) && IS_NPC(victim))
   {
      if (ch->pcdata->quest && ch->pcdata->quest->questarea == ch->in_room->area 
      && ch->pcdata->quest->timeleft > 0 && ch->pcdata->quest->mission == 3 && xIS_SET(victim->act, ACT_BOSS) 
      && !IS_AFFECTED(victim, AFF_CHARM) && !IS_ACT_FLAG(victim, ACT_MOUNTSAVE))
      {
         if (ch->pcdata->quest->traveltime > -1)
            ch->pcdata->quest->traveltime = -1;
         for (x = 0; x <= 5; x++)
         {
            if (ch->pcdata->quest->player[x] == ch->pcdata->pid)
            {
               ch_printf(ch, "\n\r^r&CYou have completed your quest, your reward is %d QP^x\n\r\n\r", ch->pcdata->quest->qp[x]);
               ch->pcdata->quest_curr += ch->pcdata->quest->qp[x];
               ch->pcdata->quest_accum += ch->pcdata->quest->qp[x];
               ch->pcdata->quest_wins++;
            }
         }
         for (gch = first_char; gch; gch = gch->next)
         {
            if (IS_NPC(gch))
               continue;
            if (gch == ch)
               continue;
            if (!gch->pcdata->quest)
               continue;
            if (gch->pcdata->quest->questarea != ch->in_room->area)
               continue;
            if (gch->pcdata->quest != ch->pcdata->quest)
               continue;
            for (x = 0; x <= 5; x++)
            {
               if (gch->pcdata->quest->player[x] == gch->pcdata->pid)
               {
                  ch_printf(gch, "\n\r^r&CYou have completed your quest, your reward is %d QP^x\n\r\n\r", gch->pcdata->quest->qp[x]);
                  gch->pcdata->quest_curr += gch->pcdata->quest->qp[x];
                  gch->pcdata->quest_accum += gch->pcdata->quest->qp[x];
                  gch->pcdata->quest_wins++;
                  gch->pcdata->quest->timeleft = -1;
                  gch->pcdata->quest->tillnew = 25;
               }
            }
         }
         ch->pcdata->quest->timeleft = -1;
         ch->pcdata->quest->tillnew = 25;
      }   
      
      if (ch->pcdata->quest && ch->pcdata->quest->questarea == ch->in_room->area 
      && ch->pcdata->quest->timeleft > 0 && ch->pcdata->quest->mission == 1 
      && !IS_AFFECTED(victim, AFF_CHARM) && !IS_ACT_FLAG(victim, ACT_MOUNTSAVE))
      {
         ch->pcdata->quest->killed++;
         if (ch->pcdata->quest->traveltime > -1)
            ch->pcdata->quest->traveltime = -1;
         if (ch->pcdata->quest->killed == ch->pcdata->quest->tokill) //Win
         {
            for (x = 0; x <= 5; x++)
            {
               if (ch->pcdata->quest->player[x] == ch->pcdata->pid)
               {
                  ch_printf(ch, "\n\r^r&CYou have completed your quest, your reward is %d QP^x\n\r\n\r", ch->pcdata->quest->qp[x]);
                  ch->pcdata->quest_curr += ch->pcdata->quest->qp[x];
                  ch->pcdata->quest_accum += ch->pcdata->quest->qp[x];
                  ch->pcdata->quest_wins++;
               }
            }
            for (gch = first_char; gch; gch = gch->next)
            {
               if (IS_NPC(gch))
                  continue;
               if (gch == ch)
                  continue;
               if (!gch->pcdata->quest)
                  continue;
               if (gch->pcdata->quest->questarea != ch->in_room->area)
                  continue;
               if (gch->pcdata->quest != ch->pcdata->quest)
                  continue;
               for (x = 0; x <= 5; x++)
               {
                  if (gch->pcdata->quest->player[x] == gch->pcdata->pid)
                  {
                     ch_printf(gch, "\n\r^r&CYou have completed your quest, your reward is %d QP^x\n\r\n\r", gch->pcdata->quest->qp[x]);
                     gch->pcdata->quest_curr += gch->pcdata->quest->qp[x];
                     gch->pcdata->quest_accum += gch->pcdata->quest->qp[x];
                     gch->pcdata->quest_wins++;
                     gch->pcdata->quest->timeleft = -1;
                     gch->pcdata->quest->tillnew = 25;
                  }
               }
            }
            ch->pcdata->quest->timeleft = -1;
            ch->pcdata->quest->tillnew = 25;
         }
      }
   }        
   if (IN_WILDERNESS(victim) && IS_NPC(victim))
   {
      WBLOCK_DATA *wblock;
      
      for (wblock = first_wblock; wblock; wblock = wblock->next)
      {
         if (victim->coord->x >= wblock->stx && victim->coord->x <= wblock->endx
         &&  victim->coord->y >= wblock->sty && victim->coord->y <= wblock->endy && victim->map == wblock->map)
         {
            wblock->kills++;
         }
      }
   } 
   if (in_arena(victim) && !IS_NPC(victim) && !xIS_SET(victim->in_room->room_flags, ROOM_PERMDEATH))
   {
      if (ch->desc && ch->desc->arena)
      {
         make_corpse(victim, ch);
         make_blood(victim);
         update_players_map(victim, -1, -1, -1, 1, get_room_index(21001));
         victim->hit = victim->max_hit;
         victim->position = POS_RESTING;
         //type 0 - win 1 - losses 2 - ties 3 - games 4 - numavg 5 - update 6 - kill
         update_barena(victim, 1);
         update_barena(ch, 6);
         do_look(victim, "auto");
         send_to_char("You lost, better luck next time.\n\r", ch);
      }
      else
      {
         make_blood(victim);
         update_players_map(victim, -1, -1, -1, 1, get_room_index(21001));
         victim->hit = victim->max_hit;
         victim->position = POS_RESTING;
         do_look(victim, "auto");
         send_to_char("You lost, better luck next time.\n\r", ch);
      }
      return;
   }
   if (IS_NPC(victim))
   {
      if (xIS_SET(victim->act, ACT_MOUNTSAVE))
      {
         if (!in_arena(victim))
         {
            victim->m1 = 0;
            victim->mover -= number_range(1, 2);
         }
         victim->hunting = NULL;
         victim->hating = NULL;
         update_players_map(victim, -1, -1, -1, 2, get_room_index(21001));
         victim->hit = 1;
         victim->move = 200;
         victim->position = POS_STANDING;
         return;
      }
   }
   mprog_death_trigger(ch, victim);
   if (char_died(victim))
      return;
   /* death_cry( victim ); */

   rprog_death_trigger(ch, victim);
   if (char_died(victim))
      return;


   //So this only works on an actual pkill
   if (check_room_pk(victim) == 3 && !IS_NPC(ch) && !IS_NPC(victim))
   {
      int ocnt = -1;
      int opk;

      for (dobj = victim->first_carrying; dobj; dobj = dobj->next_content)
      {
         if (dobj->wear_loc != WEAR_NONE && !IS_OBJ_STAT(dobj, ITEM_NODROP))
         {
            ++ocnt;
         }
      }
      if (ocnt != -1)
      {
         opk = number_range(0, ocnt);
         ocnt = -1;
         for (dobj = victim->first_carrying; dobj; dobj = dobj->next_content)
         {
            if (dobj->wear_loc != WEAR_NONE)
            {
               if (++ocnt == opk && !IS_OBJ_STAT(dobj, ITEM_NODROP))
               {
                  obj_from_char(dobj);
                  obj_to_room(dobj, victim->in_room, victim);
                  act(AT_ACTION, "$p falls to the ground right before $n dies.", victim, dobj, NULL, TO_CANSEE);
                  act(AT_ACTION, "$P falls from you right before you DIE.", victim, dobj, NULL, TO_CHAR);
                  break;
               }
            }
         }
      }
   }
   if (!IS_NPC(ch) && !IS_NPC(victim))
   {
      for (dobj = victim->first_carrying; dobj; dobj = dobj->next_content)
      {
         if (IS_OBJ_STAT(dobj, ITEM_ARTIFACT))
         {
            obj_from_char(dobj);
            obj_to_room(dobj, victim->in_room, victim);
            act(AT_ACTION, "The ARTIFACT $p falls to the ground right before $n dies.", victim, dobj, NULL, TO_CANSEE);
            act(AT_ACTION, "The ARTIFACT $P falls from you right before you DIE.", victim, dobj, NULL, TO_CHAR);
            break;
         }
      }
   }
   if (IS_NPC(victim) && xIS_SET(victim->act, ACT_KINGDOMMOB))
   {
      char buf[MIL];
      int change =  victim->in_room->area->population / 100;
      victim->in_room->area->population -= change;
      if (victim->in_room->area->population < 1000)
         victim->in_room->area->population = 1000;
      ch_printf(ch, "&G&W>>>>>The population of this kingdom has dropped by %d by killing these civilians.<<<<<\n\r", change);
      sprintf(buf, "%s has slaughtered your population and dropped it by %d", PERS_KINGDOM(ch, victim->in_room->area->kingdom), change);
      write_kingdom_logfile(victim->in_room->area->kingdom, buf, KLOG_POP_VICTIM);
      if ((!IS_NPC(ch) && ch->pcdata->hometown > 1 && ch->pcdata->hometown < sysdata.max_kingdom)
      || (IS_NPC(ch) && xIS_SET(victim->act, ACT_MILITARY) && ch->m4 > 1 && ch->m4 < sysdata.max_kingdom))
      {
         int sking;
         if (IS_NPC(ch))
            sking = ch->m4;
         else
            sking = ch->pcdata->hometown;
            
         sprintf(buf, "%s has slaughtered %d in the kingdom of %s", PERS_KINGDOM(ch, sking), change, kingdom_table[victim->in_room->area->kingdom]->name);
         write_kingdom_logfile(sking, buf, KLOG_POP_ATTACKER);
      }
   }
   if (IS_NPC(victim) && xIS_SET(victim->act, ACT_MILITARY))
   {
      do_kingdomtalk(victim, "May my death not be in vane my lords.");
      sprintf(buf, "%s has been dealt a decise death blow by %s", PERS_KINGDOM(victim, victim->m4), PERS_KINGDOM(ch, victim->m4));
      write_kingdom_logfile(victim->m4, buf, KLOG_MIL_VICTIM);
      sprintf(buf, "%s of %s has been killed by %s", victim->name, kingdom_table[victim->m4]->name, ch->name);
      bug(buf, 0);
      if ((IS_NPC(ch) && xIS_SET(ch->act, ACT_MILITARY)) || (!IS_NPC(ch) && ch->pcdata->hometown > 1 && ch->pcdata->hometown < sysdata.max_kingdom))
      {
         if (IS_NPC(ch))
         {
            sprintf(buf, "%s has been dispatched.", PERS_KINGDOM(victim, IS_NPC(ch) ? ch->m4 : ch->pcdata->hometown));
            do_kingdomtalk(ch, buf);
         }
         sprintf(buf, "%s has been dispatched by %s.", PERS_KINGDOM(victim, IS_NPC(ch) ? ch->m4 : ch->pcdata->hometown), PERS_KINGDOM(ch, IS_NPC(ch) ? ch->m4 : ch->pcdata->hometown));
         if (IS_NPC(ch))
            write_kingdom_logfile(ch->m4, buf, KLOG_MIL_ATTACKER);
         else
            write_kingdom_logfile(ch->pcdata->hometown, buf, KLOG_MIL_ATTACKER);
      }
   }
   if (IS_NPC(victim) && xIS_SET(victim->act, ACT_EXTRACTMOB))
   {
      do_kingdomtalk(victim, "May my death not be in vane my lords.");
      sprintf(buf, "%s has been dealt a decise death blow by %s", PERS_KINGDOM(victim, victim->m4), PERS_KINGDOM(ch, victim->m4));
      write_kingdom_logfile(victim->m4, buf, KLOG_MIL_VICTIM);
      sprintf(buf, "%s of %s has been killed by %s", victim->name, kingdom_table[victim->m4]->name, ch->name);
      bug(buf, 0);
      if ((IS_NPC(ch) && xIS_SET(ch->act, ACT_MILITARY)) || (!IS_NPC(ch) && ch->pcdata->hometown > 1 && ch->pcdata->hometown < sysdata.max_kingdom))
      {
         if (IS_NPC(ch))
         {
            sprintf(buf, "%s has been dispatched.", PERS_KINGDOM(victim, IS_NPC(ch) ? ch->m4 : ch->pcdata->hometown));
            do_kingdomtalk(ch, buf);
         }
         sprintf(buf, "%s has been dispatched by %s.", PERS_KINGDOM(victim, IS_NPC(ch) ? ch->m4 : ch->pcdata->hometown), PERS_KINGDOM(ch, IS_NPC(ch) ? ch->m4 : ch->pcdata->hometown));
         if (IS_NPC(ch))
            write_kingdom_logfile(ch->m4, buf, KLOG_MIL_ATTACKER);
         else
            write_kingdom_logfile(ch->pcdata->hometown, buf, KLOG_MIL_ATTACKER);
      }
   }
   if (!IS_NPC(victim) && victim->pcdata->hometown > 1 && victim->pcdata->hometown < sysdata.max_kingdom)
   {
      if ((IS_NPC(ch) && xIS_SET(ch->act, ACT_MILITARY)) || (!IS_NPC(ch) && ch->pcdata->hometown > 1 && ch->pcdata->hometown < sysdata.max_kingdom))
      {
         if (IS_NPC(ch))
         {
            sprintf(buf, "%s has been dispatched.", PERS_KINGDOM(victim, IS_NPC(ch) ? ch->m4 : ch->pcdata->hometown));
            do_kingdomtalk(ch, buf);
         }
         sprintf(buf, "%s has been dealt a decise death blow by %s", PERS_KINGDOM(victim, victim->pcdata->hometown), PERS_KINGDOM(ch, victim->pcdata->hometown));
         write_kingdom_logfile(victim->pcdata->hometown, buf, KLOG_MIL_VICTIM);
         sprintf(buf, "%s has been dispatched by %s.", PERS_KINGDOM(victim, IS_NPC(ch) ? ch->m4 : ch->pcdata->hometown), PERS_KINGDOM(ch, IS_NPC(ch) ? ch->m4 : ch->pcdata->hometown));
         if (IS_NPC(ch))     
            write_kingdom_logfile(ch->m4, buf, KLOG_MIL_ATTACKER);
         else
            write_kingdom_logfile(ch->pcdata->hometown, buf, KLOG_MIL_ATTACKER);
      }
   }    
   make_corpse(victim, ch);
   if (victim->in_room->sector_type == SECT_OCEANFLOOR
      || victim->in_room->sector_type == SECT_UNDERWATER
      || victim->in_room->sector_type == SECT_WATER_SWIM || victim->in_room->sector_type == SECT_WATER_NOSWIM)
      act(AT_BLOOD, "$n's blood slowly clouds the surrounding water.", victim, NULL, NULL, TO_ROOM);
   else if (victim->in_room->sector_type == SECT_AIR)
      act(AT_BLOOD, "$n's blood sprays wildly through the air.", victim, NULL, NULL, TO_ROOM);
   else
      make_blood(victim);
      
   if (!IS_NPC(ch) && !ch->fighting)
   {
      for (gch = ch->in_room->first_person; gch; gch = gch->next_in_room)
      {
         if (!IN_SAME_ROOM(gch, ch) || gch == victim)
            continue;
         if (gch->fighting && gch->fighting->who && gch->fighting->who == ch)
         {
            set_fighting(ch, gch);
            break;
         }
      }
   }

   if (IS_NPC(victim))
   {
      victim->pIndexData->killed++;
      extract_char(victim, TRUE);
      victim = NULL;
      return;
   }
   if (xIS_SET(ch->in_room->room_flags, ROOM_PERMDEATH) && sysdata.resetgame && !IS_IMMORTAL(victim))
   {
      char dirname[MSL];
      char sname[MSL];
      ROOM_INDEX_DATA *proom;
         
      sprintf(sname, victim->name);
      act(AT_RED, "$n has fallen in a Permdeath battle.", victim, NULL, NULL, TO_MUD);
      send_to_char("You died in a duel or a permdeath arena battle, your pfile is being deleted.\n\r", victim);      
      extract_char(victim, TRUE);
      sprintf(dirname, "%s%c/", PLAYER_DIR, LOWER(sname[0]));
      read_pfile2(dirname, sname);
      proom = get_room_index(ROOM_VNUM_TEMPLE);
      char_from_room(ch);
      char_to_room(ch, proom);
      save_char_obj(ch);
      do_look(ch, "auto");
      return;
   }

   set_char_color(AT_DIEMSG, victim);
   if (victim->pcdata->mdeaths + victim->pcdata->pdeaths < 3)
      do_help(victim, "new_death");
   else
      do_help(victim, "_DIEMSG_");

   extract_char(victim, FALSE);
   if (!victim)
   {
      bug("oops! raw_kill: extract_char destroyed pc char", 0);
      return;
   }
   while (victim->first_affect)
      affect_remove(victim, victim->first_affect);
   victim->affected_by = race_table[victim->race]->affected;
   victim->resistant = 0;
   victim->susceptible = 0;
   victim->immune = 0;
   victim->attacks = race_table[victim->race]->attacks;
   victim->defenses = race_table[victim->race]->defenses;
   victim->mod_str = 0;
   victim->mod_dex = 0;
   victim->mod_wis = 0;
   victim->mod_int = 0;
   victim->mod_con = 0;
   victim->mod_cha = 0;
   victim->mod_lck = 0;
   victim->damroll = 0;
   victim->hitroll = 0;
   victim->mental_state = -10;
   victim->alignment = URANGE(-1000, victim->alignment, 1000);
/*  victim->alignment		= race_table[victim->race]->alignment;
-- switched lines just for now to prevent mortals from building up
days of bellyaching about their angelic or satanic humans becoming
neutral when they die given the difficulting of changing align */

   victim->saving_poison_death = race_table[victim->race]->saving_poison_death;
   victim->saving_wand = race_table[victim->race]->saving_wand;
   victim->saving_para_petri = race_table[victim->race]->saving_para_petri;
   victim->saving_breath = race_table[victim->race]->saving_breath;
   victim->saving_spell_staff = race_table[victim->race]->saving_spell_staff;
   victim->position = POS_RESTING;
   victim->hit = 1;
   victim->mana = 1;
   victim->move = 200;
   victim->con_rarm = 1;
   victim->con_larm = 1;
   victim->con_rleg = 1;
   victim->con_lleg = 1;

   /*
    * Pardon crimes...      -Thoric
    */
   if (xIS_SET(victim->act, PLR_ATTACKER) && !IS_NPC(ch))
   {
      xREMOVE_BIT(victim->act, PLR_ATTACKER);
      send_to_char("The gods have pardoned you for your mistakes.\n\r", victim);
   }
//    if ( xIS_SET( victim->act, PLR_KILLER) && !IS_NPC(ch) )
//    {
//      xREMOVE_BIT( victim->act, PLR_KILLER);
//      send_to_char("The gods have pardoned you for your murderous acts.\n\r",victim);
//    }
//    if ( xIS_SET( victim->act, PLR_THIEF) && !IS_NPC(ch) )
//    {
//      xREMOVE_BIT( victim->act, PLR_THIEF);
//      send_to_char("The gods have pardoned you for your thievery.\n\r",victim);
//    }
   victim->pcdata->condition[COND_FULL] = 12;
   victim->pcdata->condition[COND_THIRST] = 12;
   if (IS_VAMPIRE(victim))
      victim->pcdata->condition[COND_BLOODTHIRST] = (victim->level / 2);

   if (IS_SET(sysdata.save_flags, SV_DEATH))
      save_char_obj(victim);
   return;
}

void group_gain(CHAR_DATA * ch, CHAR_DATA * victim)
{
   CHAR_DATA *gch;
   CHAR_DATA *lch;
   int members;

   /*
    * Monsters don't get kill xp's or alignment changes.
    * Dying of mortal wounds or poison doesn't give xp to anyone!
    */
   if (IS_NPC(ch) || victim == ch)
      return;

   members = 0;
   for (gch = ch->in_room->first_person; gch; gch = gch->next_in_room)
   {
      if (is_same_group(gch, ch))
         members++;
   }

   if (members == 0)
   {
      bug("Group_gain: members.", members);
      members = 1;
   }

   lch = ch->leader ? ch->leader : ch;

   for (gch = ch->in_room->first_person; gch; gch = gch->next_in_room)
   {
      OBJ_DATA *obj;
      OBJ_DATA *obj_next;

      if (!is_same_group(gch, ch))
         continue;

      /*
         gch->alignment = align_compute( gch, victim );
       */

      for (obj = ch->first_carrying; obj; obj = obj_next)
      {
         obj_next = obj->next_content;
         if (obj->wear_loc == WEAR_NONE)
            continue;
      }
   }

   return;
}

/* The below is not used anymore -- Xerves 8/1/99 */
int align_compute(CHAR_DATA * gch, CHAR_DATA * victim)
{
   int align, newalign, divalign;

   align = gch->alignment - victim->alignment;

   /* slowed movement in good & evil ranges by a factor of 5, h */
   /* Added divalign to keep neutral chars shifting faster -- Blodkai */
   /* This is obviously gonna take a lot more thought */

   if (gch->alignment > -350 && gch->alignment < 350)
      divalign = 4;
   else
      divalign = 20;

   if (align > 500)
      newalign = UMIN(gch->alignment + (align - 500) / divalign, 1000);
   else if (align < -500)
      newalign = UMAX(gch->alignment + (align + 500) / divalign, -1000);
   else
      newalign = gch->alignment - (int) (gch->alignment / divalign);

   return 0;
}


/*
 * Calculate how much XP gch should gain for killing victim
 * Lots of redesigning for new exp system by Thoric
 */
/*
 * New calculations for a new exp system
 * March 6 1999 - Xerves
 */

 // A few more modifications for Remorts :-)
int xp_compute(CHAR_DATA * gch, CHAR_DATA * victim)
{   
   return 0;
}


/*
 * Revamped by Thoric to be more realistic
 * Added code to produce different messages based on weapon type - FB
 * Added better bug message so you can track down the bad dt's -Shaddai
 */
void new_dam_message(CHAR_DATA * ch, CHAR_DATA * victim, int dam, int dt, OBJ_DATA * obj, int spec, int limb)
{
   char buf1[256], buf2[256], buf3[256], lbuf[20], gbuf[20], sbuf[100], awbuf[100];
   char bugbuf[MSL];
   char bknowledgea[MSL];
   char bknowledgev[MSL];
   unsigned char bmessagec[180];
   unsigned char bmessager[180];
   unsigned char bmessagev[180];
   char ddesc[50];
   char dcolor[10];
   char dchar[10];
   char dtt[20];
   unsigned char c, d, e;
   int x, y, z;
   const char *vs;
   const char *vp;
   const char *attack;
   char vc[10];
   char cc[10];
   char rc[10];
   char punct;
   sh_int dampc;
   struct skill_type *skill = NULL;
   bool gcflag = FALSE;
   bool gvflag = FALSE;
   int d_index, w_index;
   int dpercent;
   ROOM_INDEX_DATA *was_in_room;
   OBJ_DATA *weapon, *shield, *aweapon;
   char wbuf[128];
   
   strcpy(sbuf, "");

   if (!dam)
      dampc = 0;
   else
      dampc = ((dam * 1000) / victim->max_hit) + (50 - ((victim->hit * 50) / victim->max_hit));
   dpercent = ((100 * dam) / victim->max_hit);
   
  if (limb == LM_RARM)
     sprintf(lbuf, "right arm");
  else if (limb == LM_LARM)
     sprintf(lbuf, "left arm");
  else if (limb == LM_RLEG)
     sprintf(lbuf, "right leg");
  else if (limb == LM_LLEG)
     sprintf(lbuf, "left leg");
  else if (limb == LM_HEAD)
     sprintf(lbuf, "head");
  else if (limb == LM_NECK)
     sprintf(lbuf, "neck");
  else if (limb == LM_BODY)
     sprintf(lbuf, "chest");
  else
     strcpy(lbuf, "");
     
  if (dt == TYPE_PROJECTILE)
     strcpy(gbuf, "pierce");
  else
  {   
     if (ch->grip == GRIP_BASH)
        sprintf(gbuf, "bash");
     else if (ch->grip == GRIP_SLASH)
        sprintf(gbuf, "slash");
     else    
        sprintf(gbuf, "stab");
   }
   if (ch->in_room != victim->in_room)
   {
      was_in_room = ch->in_room;
      char_from_room(ch);
      char_to_room(ch, victim->in_room);
   }
   else
      was_in_room = NULL;
      
   /* Get the weapon index */
   /*  if ( dt == TYPE_HIT)
      {
      w_index = 0;
      }
      else
      if ( dt >= TYPE_HIT && dt < TYPE_HIT + sizeof(attack_table)/sizeof(attack_table[0]) )
      {
      w_index = dt - TYPE_HIT;
      }
      else
      {
      sprintf(bugbuf, "Dam_message: bad dt %d from %s in %d.",
      dt, ch->name, ch->in_room->vnum );
      bug( bugbuf, 0);
      dt = TYPE_HIT;
      w_index = 0;
      } */
   w_index = 0;
   if (dt < TYPE_UNDEFINED || dt > TYPE_HIT)
   {
      sprintf(bugbuf, "Dam_message: bad dt %d from %s in %d.", dt, ch->name, ch->in_room->vnum);
      bug(bugbuf, 0);
      dt = TYPE_HIT;
   }
   /* get the damage index */
   if (dam == 0)
      d_index = 0;
   else if (dampc < 0)
      d_index = 1;
   else if (dampc <= 100)
      d_index = 1 + dampc / 10;
   else if (dampc <= 200)
      d_index = 11 + (dampc - 100) / 20;
   else if (dampc <= 900)
      d_index = 16 + (dampc - 200) / 100;
   else
      d_index = 23;
   
   /*   
   &w&w 0
   &w&W 1 - 3
   &w&z 4 - 6
   &w&Y 7 - 9
   &w&O 10 - 12
   &w&P 13 - 15
   &w&R 17 - 18
   &w&r 19 - 21
   
   ----- 1 - 21
   ***** 22 - 42
   >>>>> 43 - 63
   +++++ 64 - 84
   DDDDD 85 - 105
   KKKKK 106 - 126
   !!!!! 127 - 147 */
   
   if (dam <= 0)
      sprintf(ddesc, " &w&B[&c&w NODAM &w&B]");
   else
   {
      if (dam % 24 == 0)
         sprintf(dchar, "*******");
      else if (dam % 24 <= 3)
         sprintf(dchar, "-------");
      else if (dam % 24 <= 6)
         sprintf(dchar, "*------");
      else if (dam % 24 <= 9)
         sprintf(dchar, "**-----");
      else if (dam % 24 <= 12)
         sprintf(dchar, "***----");
      else if (dam % 24 <= 15)
         sprintf(dchar, "****---");
      else if (dam % 24 <= 18)
         sprintf(dchar, "*****--");
      else if (dam % 24 <= 21)
         sprintf(dchar, "******-");
      else if (dam % 24 <= 23)
         sprintf(dchar, "*******");
         
      if (dam <= 24)
         sprintf(dcolor, "&w&z");
      else if (dam <= 48)
         sprintf(dcolor, "&w&W");
      else if (dam <= 72)
         sprintf(dcolor, "&w&g");
      else if (dam <= 96)
         sprintf(dcolor, "&w&G");
      else if (dam <= 120)
         sprintf(dcolor, "&w&c");
      else if (dam <= 144)
         sprintf(dcolor, "&w&C");
      else if (dam <= 168)
         sprintf(dcolor, "&w&O");
      else if (dam <= 192)
         sprintf(dcolor, "&w&Y");
      else if (dam <= 216)
         sprintf(dcolor, "&w&p");
      else if (dam <= 240)
         sprintf(dcolor, "&w&P");
      else if (dam <= 264)
         sprintf(dcolor, "&w&R");
      else
         sprintf(dcolor, "&w&r");  
         
      sprintf(ddesc, " &w&B[%s%s&w&B]", dcolor, dchar);
   }

   if (spec == DM_COUNTER)
      sprintf(dtt, "[Counter] ");
   else if (spec == DM_CRITICAL)
      sprintf(dtt, "[CriTicAL] ");
   else if (spec == DM_DEATH)
   {
      sprintf(dtt, "[DeaTH] ");
   }
   else if (spec == DM_UNDEAD)
   {
        sprintf(dtt, "[Undead] ");
   }
   else if (spec == DM_BLOCK)
   {
      sprintf(dtt, "[BLOCKED] ");
   }
   else
      strcpy(dtt, "");
      
   if ((shield = get_eq_char(victim, WEAR_SHIELD)) != NULL)
   {
      sprintf(sbuf, "%s", shield->short_descr);
   }

   /* Lookup the damage message */
   vs = s_message_table[w_index][d_index];
   vp = p_message_table[w_index][d_index];


   punct = (dampc <= 30) ? '.' : '!';

   if (dam == 0 && (!IS_NPC(ch) && (IS_SET(ch->pcdata->flags, PCFLAG_GAG))))
      gcflag = TRUE;

   if (dam == 0 && (!IS_NPC(victim) && (IS_SET(victim->pcdata->flags, PCFLAG_GAG))))
      gvflag = TRUE;

   if (dt >= 0 && dt < top_sn)
      skill = skill_table[dt];
      
   sprintf(vc, "%s", char_color_str(AT_HITME, ch));
   sprintf(cc, "%s", char_color_str(AT_HIT, ch));
   sprintf(rc, "%s", char_color_str(AT_ACTION, ch));
   
   strcpy(bknowledgea, "");
   strcpy(bknowledgev, "");
   if (g_roll > 0)
   {
      if (!IS_NPC(ch) && MASTERED(ch, gsn_battle_knowledge) >= 1)
      {
         if (MASTERED(ch, gsn_battle_knowledge) >= 5)
         {
            if (xIS_SET(ch->act, PLR_NOTOHIT))
               sprintf(bknowledgea, " &w&P<&w&W%d&w&P>", dam);
            else
               sprintf(bknowledgea, " &w&P<&w&W%d&w&P>&w&R<&c&w%d|%d-%d r%d&w&R>", dam, g_tohit, g_lowtohit, g_hitohit, g_roll);
         }
         else if (MASTERED(ch, gsn_battle_knowledge) >= 3 && !xIS_SET(ch->act, PLR_NOTOHIT))
            sprintf(bknowledgea, " &w&R<&c&w%d|%d-%d r%d&w&R>", g_tohit, g_lowtohit, g_hitohit, g_roll);
         else if (!xIS_SET(ch->act, PLR_NOTOHIT))
            sprintf(bknowledgea, " &w&R<&w&W%d&w&R>", g_tohit);
         learn_from_success(ch, gsn_battle_knowledge, victim);
      }
      if (!IS_NPC(victim) && MASTERED(victim, gsn_battle_knowledge) >= 2)
      {
         if (MASTERED(victim, gsn_battle_knowledge) >= 6)
         {
            if (xIS_SET(victim->act, PLR_NOTOHIT))
               sprintf(bknowledgev, " &w&P<&w&W%d&w&P>", dam);
            else
               sprintf(bknowledgev, " &w&P<&w&W%d&w&P>&w&R<&c&w%d|%d-%d r%d&w&R>", dam, g_tohit, g_lowtohit, g_hitohit, g_roll);
         }
         else if (MASTERED(victim, gsn_battle_knowledge) >= 4 && !xIS_SET(victim->act, PLR_NOTOHIT))
            sprintf(bknowledgev, " &w&R<&c&w%d|%d-%d r%d&w&R>", g_tohit, g_lowtohit, g_hitohit, g_roll);
         else if (!xIS_SET(victim->act, PLR_NOTOHIT))
            sprintf(bknowledgev, " &w&R<&w&W%d&w&R>", g_tohit);
         learn_from_success(victim, gsn_battle_knowledge, ch);
      }
   }
   else
   {
      if (!IS_NPC(ch) && MASTERED(ch, gsn_battle_knowledge) >= 5)
      {
         if (MASTERED(ch, gsn_battle_knowledge) >= 5)
            sprintf(bknowledgea, " &w&P<&w&W%d&w&P>", dam);
         learn_from_success(ch, gsn_battle_knowledge, victim);
      }
      if (!IS_NPC(victim) && MASTERED(victim, gsn_battle_knowledge) >= 6)
      {
         if (MASTERED(victim, gsn_battle_knowledge) >= 6)
            sprintf(bknowledgev, " &w&P<&w&W%d&w&P>", dam);
         learn_from_success(victim, gsn_battle_knowledge, ch);
      }
   }   
   
   weapon = get_eq_char(ch, WEAR_WIELD);
   
   if (dt == TYPE_PROJECTILE)
      sprintf(wbuf, "projectile");
   else if (weapon)
      sprintf(wbuf, "%s", weapon->name);
   else
      sprintf(wbuf, "fist");
      
   aweapon = get_eq_char(victim, WEAR_WIELD);
   
   if (aweapon)
      sprintf(awbuf, "%s", aweapon->name);
   else
      sprintf(awbuf, "fist");
      
   if ((dt == gsn_backstab || dt == gsn_circle || dt == gsn_kick_back) && spec == DM_UNDEAD)
   {
      if(weapon)
      {
         if(!xIS_SET(weapon->extra_flags, ITEM_BLESS) && !xIS_SET(weapon->extra_flags, ITEM_SANCTIFIED))
         {
            sprintf(buf1, "%s$n's weapon passes right through $N.", dtt);
            sprintf(buf2, "%sYour weapon passes right through $N.", dtt);
            sprintf(buf3, "%s$n's weapon passes right through you.", dtt);
         }
      }
      else if(!weapon)
      {
         sprintf(buf1, "%s$n's fist passes right through $N.", dtt);
         sprintf(buf2, "%sYour fist passes right through $N.", dtt);
         sprintf(buf3, "%s$n's fist passes right through you.", dtt);
      }
   }
   else if (dt == TYPE_HIT || dt == TYPE_PROJECTILE)
   {
      if (spec == DM_UNDEAD)
      {
        if(weapon)
        {
            if(!xIS_SET(weapon->extra_flags, ITEM_BLESS) && !xIS_SET(weapon->extra_flags, ITEM_SANCTIFIED))
            {
                sprintf(buf1, "%s$n's weapon passes right through $N.", dtt);
                sprintf(buf2, "%sYour weapon passes right through $N.", dtt);
                sprintf(buf3, "%s$n's weapon passes right through you.", dtt);
            }
        }
        else if(!weapon)
        {
            sprintf(buf1, "%s$n's fist passes right through $N.", dtt);
            sprintf(buf2, "%sYour fist passes right through $N.", dtt);
            sprintf(buf3, "%s$n's fist passes right through you.", dtt);
        }
      }
      else if (dt != gsn_backstab && dt != gsn_circle && dt != gsn_kick_back)
      {
        if (spec == DM_DEATH)
        {
           vp = "___KILLS___";
           dpercent = 100;
        }
        //wbuf - Weapon buffer
        //lbuf - Limb buffer
        //gbuf - Grip buffer
        
        if (ch->grip == GRIP_BASH)
           x = 0;
        else if (ch->grip == GRIP_SLASH)
           x = 1;
        else
           x = 2;
           
        z = 0;
        if (dam < 1)
           z = 1; //miss
        if (spec == DM_BLOCK)
           z = 2;
        if (spec == DM_DEATH)
           z = 6;
        
        y = number_range(0, high_value[z][x]-1);
        
        //To the Char
        d = -1;
        for (c = 0; c < 100; c++)
        {
           if (battle_descriptions[z][x][y][c] == '$')
           {
              if (battle_descriptions[z][x][y][c+1] == 'B')
              {
                 e = 0;
                 for (;;)
                 {
                    if (lbuf[e] != '\0')
                    {
                       bmessagec[++d] = lbuf[e++];
                    }
                    else
                       break;
                 }
                 e = 0;
                 c++;
              } 
              if (battle_descriptions[z][x][y][c+1] == 'a')
              {
                 bmessagec[++d] = 's';
                 c++;
              }
              if (battle_descriptions[z][x][y][c+1] == 'A')
              {
                 bmessagec[++d] = 'e';
                 bmessagec[++d] = 's';
                 c++;
              }
              if (battle_descriptions[z][x][y][c+1] == 'o')
              {
                 c++;
              }
              if (battle_descriptions[z][x][y][c+1] == 'O')
              {
                 c++;
              }
              if (battle_descriptions[z][x][y][c+1] == 'b')
              {
                 e = 0;
                 if (sbuf[0] != '\0')
                 {
                    for (;;)
                    {
                       if (sbuf[e] != '\0')
                       {
                          bmessagec[++d] = sbuf[e++];
                       }
                       else
                          break;
                    }
                 }
                 else
                 {
                     bmessagec[++d] = 's';
                     bmessagec[++d] = 'h';
                     bmessagec[++d] = 'i';
                     bmessagec[++d] = 'e';
                     bmessagec[++d] = 'l';
                     bmessagec[++d] = 'd';
                 }
                 e = 0;
                 c++;
              } 
              if (battle_descriptions[z][x][y][c+1] == 'p')
              {
                 e = 0;
                 bmessagec[++d] = 'y';
                 bmessagec[++d] = 'o';
                 bmessagec[++d] = 'u';
                 bmessagec[++d] = 'r';
                 /*
                 for (;;)
                 {
                    if (attacker[e] != '\0')
                    {
                       bmessaget[++d] = attacker[e++];
                    }
                    else
                       break;
                 } */
                 e = 0;
                 c++;
              } 
              if (battle_descriptions[z][x][y][c+1] == 'P')
              {
                 e = 0;
                 bmessagec[++d] = '$';
                 bmessagec[++d] = 'N';
                 bmessagec[++d] = 39; // ASCII for the ' character
                 bmessagec[++d] = 's';
                 e = 0;
                 c++;
              }  
              if (battle_descriptions[z][x][y][c+1] == 'G')
              {
                 e = 0;
                 for (;;)
                 {
                    if (gbuf[e] != '\0')
                    {
                       bmessagec[++d] = gbuf[e++];
                    }
                    else
                       break;
                 }
                 e = 0;
                 c++;
              } 
              if (battle_descriptions[z][x][y][c+1] == 'W')
              {
                 e = 0;
                 for (;;)
                 {
                    if (wbuf[e] != '\0')
                    {
                       bmessagec[++d] = wbuf[e++];
                    }
                    else
                       break;
                 }
                 e = 0;
                 c++;
              }
              if (battle_descriptions[z][x][y][c+1] == 'w')
              {
                 e = 0;
                 for (;;)
                 {
                    if (awbuf[e] != '\0')
                    {
                       bmessagec[++d] = awbuf[e++];
                    }
                    else
                       break;
                 }
                 e = 0;
                 c++;
              }  
              if (battle_descriptions[z][x][y][c+1] == 'e' || battle_descriptions[z][x][y][c+1] == 'E'
              ||  battle_descriptions[z][x][y][c+1] == 'm' || battle_descriptions[z][x][y][c+1] == 'M'
              ||  battle_descriptions[z][x][y][c+1] == 's' || battle_descriptions[z][x][y][c+1] == 'S'
              ||  battle_descriptions[z][x][y][c+1] == 'n' || battle_descriptions[z][x][y][c+1] == 'N')
              {
                 d++;
                 bmessagec[d] = battle_descriptions[z][x][y][c];
              }
                 
           }
           else
           {
              d++;
              bmessagec[d] = battle_descriptions[z][x][y][c];
              if (battle_descriptions[z][x][y][c] == '\0')
              {
                 break;
              }
           }
        }
        
        //To the Victim
        d = -1;
        for (c = 0; c < 100; c++)
        {
           if (battle_descriptions[z][x][y][c] == '$')
           {
              if (battle_descriptions[z][x][y][c+1] == 'B')
              {
                 e = 0;
                 for (;;)
                 {
                    if (lbuf[e] != '\0')
                    {
                       bmessagev[++d] = lbuf[e++];
                    }
                    else
                       break;
                 }
                 e = 0;
                 c++;
              }
              if (battle_descriptions[z][x][y][c+1] == 'a')
                 c++;
              if (battle_descriptions[z][x][y][c+1] == 'A') 
                 c++;
              if (battle_descriptions[z][x][y][c+1] == 'o')
              {
                 bmessagev[++d] = 's';
                 c++;
              }
              if (battle_descriptions[z][x][y][c+1] == 'O')
              {
                 bmessagev[++d] = 'e';
                 bmessagev[++d] = 's';
                 c++;
              }
              if (battle_descriptions[z][x][y][c+1] == 'b')
              {
                 e = 0;
                 if (sbuf[0] != '\0')
                 {
                    for (;;)
                    {
                       if (sbuf[e] != '\0')
                       {
                          bmessagev[++d] = sbuf[e++];
                       }
                       else
                          break;
                    }
                 }
                 else
                 {
                     bmessagev[++d] = 's';
                     bmessagev[++d] = 'h';
                     bmessagev[++d] = 'i';
                     bmessagev[++d] = 'e';
                     bmessagev[++d] = 'l';
                     bmessagev[++d] = 'd';
                 }
                 e = 0;
                 c++;
              } 
              if (battle_descriptions[z][x][y][c+1] == 'p')
              {
                 e = 0;
                 bmessagev[++d] = '$';
                 bmessagev[++d] = 'n';
                 bmessagev[++d] = 39; // ASCII for the ' character
                 bmessagev[++d] = 's';
                 e = 0;
                 c++;
              } 
              if (battle_descriptions[z][x][y][c+1] == 'P')
              {
                 e = 0;
                 bmessagev[++d] = 'y';
                 bmessagev[++d] = 'o';
                 bmessagev[++d] = 'u';
                 bmessagev[++d] = 'r';
                 /*
                 for (;;)
                 {
                    if (attackee[e] != '\0')
                    {
                       bmessaget[++d] = attackee[e++];
                    }
                    else
                       break;
                 }
                 bmessaget[++d] = 39; // ASCII for the ' character
                 bmessaget[++d] = 's';
                 */
                 e = 0;
                 c++;
              }  
              if (battle_descriptions[z][x][y][c+1] == 'G')
              {
                 e = 0;
                 for (;;)
                 {
                    if (gbuf[e] != '\0')
                    {
                       bmessagev[++d] = gbuf[e++];
                    }
                    else
                       break;
                 }
                 e = 0;
                 c++;
              } 
              if (battle_descriptions[z][x][y][c+1] == 'W')
              {
                 e = 0;
                 for (;;)
                 {
                    if (wbuf[e] != '\0')
                    {
                       bmessagev[++d] = wbuf[e++];
                    }
                    else
                       break;
                 }
                 e = 0;
                 c++;
              }
              if (battle_descriptions[z][x][y][c+1] == 'w')
              {
                 e = 0;
                 for (;;)
                 {
                    if (awbuf[e] != '\0')
                    {
                       bmessagev[++d] = awbuf[e++];
                    }
                    else
                       break;
                 }
                 e = 0;
                 c++;
              }  
              if (battle_descriptions[z][x][y][c+1] == 'e' || battle_descriptions[z][x][y][c+1] == 'E'
              ||  battle_descriptions[z][x][y][c+1] == 'm' || battle_descriptions[z][x][y][c+1] == 'M'
              ||  battle_descriptions[z][x][y][c+1] == 's' || battle_descriptions[z][x][y][c+1] == 'S'
              ||  battle_descriptions[z][x][y][c+1] == 'n' || battle_descriptions[z][x][y][c+1] == 'N')
              {
                 d++;
                 bmessagev[d] = battle_descriptions[z][x][y][c];
              } 
           }
           else
           {
              d++;
              bmessagev[d] = battle_descriptions[z][x][y][c];
              if (battle_descriptions[z][x][y][c] == '\0')
              {
                 break;
              }
           }
        }
        
        //To the Room
        d = -1;
        for (c = 0; c < 100; c++)
        {
           if (battle_descriptions[z][x][y][c] == '$')
           {
              if (battle_descriptions[z][x][y][c+1] == 'B')
              {
                 e = 0;
                 for (;;)
                 {
                    if (lbuf[e] != '\0')
                    {
                       bmessager[++d] = lbuf[e++];
                    }
                    else
                       break;
                 }
                 e = 0;
                 c++;
              }
              if (battle_descriptions[z][x][y][c+1] == 'a')
              {
                 bmessager[++d] = 's';
                 c++;
              }
              if (battle_descriptions[z][x][y][c+1] == 'A')
              {
                 bmessager[++d] = 'e';
                 bmessager[++d] = 's';
                 c++;
              }
              if (battle_descriptions[z][x][y][c+1] == 'o')
              {
                 bmessager[++d] = 's';
                 c++;
              }
              if (battle_descriptions[z][x][y][c+1] == 'O')
              {
                 bmessager[++d] = 'e';
                 bmessager[++d] = 's';
                 c++;
              }
              if (battle_descriptions[z][x][y][c+1] == 'b')
              {
                 e = 0;
                 if (sbuf)
                 {
                    for (;;)
                    {
                       if (sbuf[e] != '\0')
                       {
                          bmessager[++d] = sbuf[e++];
                       }
                       else
                          break;
                    }
                 }
                 else
                 {
                     bmessager[++d] = 's';
                     bmessager[++d] = 'h';
                     bmessager[++d] = 'i';
                     bmessager[++d] = 'e';
                     bmessager[++d] = 'l';
                     bmessager[++d] = 'd';
                 }
                 e = 0;
                 c++;
              }  
              if (battle_descriptions[z][x][y][c+1] == 'p')
              {
                 e = 0;
                 bmessager[++d] = '$';
                 bmessager[++d] = 'n';
                 bmessager[++d] = 39; // ASCII for the ' character
                 bmessager[++d] = 's';
                 e = 0;
                 c++;
              } 
              if (battle_descriptions[z][x][y][c+1] == 'P')
              {
                 e = 0;
                 bmessager[++d] = '$';
                 bmessager[++d] = 'N';
                 bmessager[++d] = 39; // ASCII for the ' character
                 bmessager[++d] = 's';
                 e = 0;
                 c++;
              }  
              if (battle_descriptions[z][x][y][c+1] == 'G')
              {
                 e = 0;
                 for (;;)
                 {
                    if (gbuf[e] != '\0')
                    {
                       bmessager[++d] = gbuf[e++];
                    }
                    else
                       break;
                 }
                 e = 0;
                 c++;
              } 
              if (battle_descriptions[z][x][y][c+1] == 'W')
              {
                 e = 0;
                 for (;;)
                 {
                    if (wbuf[e] != '\0')
                    {
                       bmessager[++d] = wbuf[e++];
                    }
                    else
                       break;
                 }
                 e = 0;
                 c++;
              }
              if (battle_descriptions[z][x][y][c+1] == 'w')
              {
                 e = 0;
                 for (;;)
                 {
                    if (awbuf[e] != '\0')
                    {
                       bmessager[++d] = awbuf[e++];
                    }
                    else
                       break;
                 }
                 e = 0;
                 c++;
              }  
              if (battle_descriptions[z][x][y][c+1] == 'e' || battle_descriptions[z][x][y][c+1] == 'E'
              ||  battle_descriptions[z][x][y][c+1] == 'm' || battle_descriptions[z][x][y][c+1] == 'M'
              ||  battle_descriptions[z][x][y][c+1] == 's' || battle_descriptions[z][x][y][c+1] == 'S'
              ||  battle_descriptions[z][x][y][c+1] == 'n' || battle_descriptions[z][x][y][c+1] == 'N')
              {
                 d++;
                 bmessager[d] = battle_descriptions[z][x][y][c];
              } 
           }
           else
           {
              d++;
              bmessager[d] = battle_descriptions[z][x][y][c];
              if (battle_descriptions[z][x][y][c] == '\0')
              {
                 break;
              }
           }
        }
        bmessager[0] = UPPER(bmessager[0]);
        bmessagec[0] = UPPER(bmessagec[0]);
        bmessagev[0] = UPPER(bmessagev[0]);
        
        sprintf(buf1, "%s%s %s", dtt,bmessager, ddesc); //to notvict (room)
        sprintf(buf2, "%s%s %s%s", dtt,bmessagec, ddesc, bknowledgea); //to char
        sprintf(buf3, "%s%s %s%s", dtt,bmessagev, ddesc, bknowledgev); //to char
      }
   }
   else
   {
      if (skill)
      {
         attack = skill->noun_damage;
         if (dam == 0)
         {
            bool found = FALSE;

            if (skill->miss_char && skill->miss_char[0] != '\0')
            {
               act(AT_HIT, skill->miss_char, ch, NULL, victim, TO_CHAR);
               found = TRUE;
            }
            if (skill->miss_vict && skill->miss_vict[0] != '\0')
            {
               act(AT_HITME, skill->miss_vict, ch, NULL, victim, TO_VICT);
               found = TRUE;
            }
            if (skill->miss_room && skill->miss_room[0] != '\0')
            {
               if (strcmp(skill->miss_room, "supress"))
                  act(AT_ACTION, skill->miss_room, ch, NULL, victim, TO_NOTVICT);
               found = TRUE;
            }
            if (found) /* miss message already sent */
            {
               if (was_in_room)
               {
                  char_from_room(ch);
                  char_to_room(ch, was_in_room);
               }
               return;
            }
         }
         else
         {
            bool found = FALSE;
            
            if (skill->hit_char && skill->hit_char[0] != '\0')
            {
               sprintf(buf2, "%s %s%s", skill->hit_char, ddesc, bknowledgea);
               act(AT_HIT, buf2, ch, NULL, victim, TO_CHAR);
               found = TRUE;
            }
            if (skill->hit_vict && skill->hit_vict[0] != '\0')
            { 
               sprintf(buf3, "%s %s%s", skill->hit_vict, ddesc, bknowledgev);
               act(AT_HITME, buf3, ch, NULL, victim, TO_VICT);
               found = TRUE;
            }
            if (skill->hit_room && skill->hit_room[0] != '\0')
            {
               sprintf(buf1, "%s %s", skill->hit_room, ddesc);
               act(AT_ACTION, buf1, ch, NULL, victim, TO_NOTVICT);
               found = TRUE;
            }
            if (found) /* miss message already sent */
            {
               if (was_in_room)
               {
                  char_from_room(ch);
                  char_to_room(ch, was_in_room);
               }
               return;
            }
         }
      }
      else if (dt >= TYPE_UNDEFINED || (dt >= TYPE_HIT && dt < TYPE_HIT + sizeof(attack_table) / sizeof(attack_table[0])))
      {
         if (obj)
            attack = obj->short_descr;
         else
            attack = attack_table[0];
      }
      else
      {
         sprintf(bugbuf, "Dam_message: bad dt %d from %s in %d.", dt, ch->name, ch->in_room->vnum);
         bug(bugbuf, 0);
         dt = TYPE_HIT;
         attack = attack_table[0];
      }
      if (dt == gsn_unsheath)
         attack = "UnShEaThEd AtTaCk";
         
      if (spec == DM_DEATH)
      {
         vp = "___KILLS___";
         vs = "___KILL___";
         dpercent = 100;
      }
      
      sprintf(buf1, "%s$n's %s %s $N%c %s", dtt, attack, vp, punct, ddesc);
      sprintf(buf2, "%sYour %s %s $N%c %s%s", dtt, attack, vp, punct, ddesc, bknowledgea);
      sprintf(buf3, "%s$n's %s %s you%c %s%s", dtt, attack, vp, punct, ddesc, bknowledgev);
   }


   if (dam > 0)
      act(AT_ACTION, buf1, ch, NULL, victim, TO_NOTVICT);
   if (!gcflag)
      act(AT_HIT, buf2, ch, NULL, victim, TO_CHAR);
   if (!gvflag)
      act(AT_HITME, buf3, ch, NULL, victim, TO_VICT);

   if (was_in_room)
   {
      char_from_room(ch);
      char_to_room(ch, was_in_room);
   }
   return;
}

//Used to step out of battle if your enemies cannot move
void do_stepback(CHAR_DATA *ch, char *argument)
{
   CHAR_DATA *victim;
   int cnt = 0;
   
   if (check_npc(ch))
      return;
   
   if (!ch->fighting)
   {
      send_to_char("You need to be fighting to use this command.\n\r", ch);
      return;
   }
   //If affected by web or paralysis (stun) allow a step out of battle
   for (victim = ch->in_room->first_person; victim; victim = victim->next_in_room)
   {
      if (!IN_SAME_ROOM(ch, victim))
         continue;
      if (IS_AFFECTED(victim, AFF_WEB) || IS_AFFECTED(victim, AFF_SNARE))  
      {
         stop_fighting(victim, TRUE);
         cnt++;
         continue;
      }
      if (IS_AFFECTED(victim, AFF_PARALYSIS))
      {
         stop_fighting(victim, TRUE);
         cnt++;
         continue;
      }
   }   
   if (!ch->fighting)
   {
      for (victim = ch->in_room->first_person; victim; victim = victim->next_in_room)
      {
         if (!IN_SAME_ROOM(ch, victim))
            continue;  
         if (victim->fighting && victim->fighting->who && victim->fighting->who == ch)
         {
            set_fighting(ch, victim);
            break;
         }
      }
   }
   if (cnt > 0 && ch->fighting)
   {
      send_to_char("You step back out of battle but you still have a few enemies.\n\r", ch);
      return;
   }
   else if (cnt > 0 && !ch->fighting)
   {
      send_to_char("You step back out of battle and no one gives chase.\n\r", ch);
      return;
   }
   else
   {
      send_to_char("You step back out of battle but everyone gives chase.\n\r", ch);
      return;
   }
}

int check_powerlevel(CHAR_DATA *ch, CHAR_DATA *victim)
{
   INTRO_DATA *intro;
   
   if (IS_NPC(ch) || IS_NPC(victim))
      return FALSE;
   if (in_arena(ch))
      return FALSE;
  if (in_arena(victim))
      return FALSE;
   for (intro = ch->pcdata->first_introduction; intro; intro = intro->next)
   {
      if (intro->pid == victim->pcdata->pid)
         if (IS_SET(intro->flags, INTRO_MYTHIEF) || IS_SET(intro->flags, INTRO_MYATTACKER)
         ||  IS_SET(intro->flags, INTRO_MYKILLER))
            return FALSE;
   }
   if (get_wear_hidden_cloak(victim))
      return FALSE;
   if (ch->pcdata->hometown < 2)
      return TRUE;
   if (victim->pcdata->hometown < 2)
      return TRUE;
   if (kingdom_table[ch->pcdata->hometown]->peace[victim->pcdata->hometown] > 0)
      return TRUE;
      
   return FALSE;
}
void do_attack(CHAR_DATA * ch, char *argument)
{
   char arg[MIL];
   CHAR_DATA *victim;
   OBJ_DATA *shield;
   int limb;

   argument = one_argument(argument, arg);

   if (arg[0] == '\0')
   {
      send_to_char("Attack whom?\n\r", ch);
      return;
   }

   if ((victim = get_char_room_new(ch, arg, 1)) == NULL)
   {
      send_to_char("They aren't here.\n\r", ch);
      return;
   }
   
   if (ch->position == POS_RIDING)
   {
      send_to_char("You need to stop riding if you want to fight.\n\r", ch);
      return;
   }
   
   if (ch->rider)
   {
      send_to_char("You have someone on your back, hard to fight like that you know!.\n\r", ch);
      return;
   }

   if (victim == ch)
   {
      send_to_char("Not wise to attack yourself.\n\r", ch);
      return;
   }

   if (is_safe(ch, victim))
      return;

   if (IS_AFFECTED(ch, AFF_CHARM))
   {
      if (ch->master == victim)
      {
         act(AT_PLAIN, "$N is your beloved master.", ch, NULL, victim, TO_CHAR);
         return;
      }
   }

   if (ch->position == POS_FIGHTING
      || ch->position == POS_EVASIVE || ch->position == POS_DEFENSIVE || ch->position == POS_AGGRESSIVE || ch->position == POS_BERSERK)
   {
      if( ch->fight_timer > 0)
      {
        send_to_char("You do the best you can!\n\r", ch);
        return;
      }
   }
   
   if ((shield = get_eq_char(ch, WEAR_SHIELD)) != NULL && IS_OBJ_STAT(shield, ITEM_TWOHANDED))
   {
      send_to_char("You cannot attack while holding a two-handed shield.\n\r", ch);
      return;
   }
   
   if (ch->position <= POS_STUNNED)
   {
      send_to_char("Sorry, kind of hard to do that when you cannot move.\n\r", ch);
      return;
   }

   if (!IS_NPC(victim) && xIS_SET(ch->act, PLR_NICE))
   {
      send_to_char("You feel too nice to do that!\n\r", ch);
      return;
   }
/*
    if ( !IS_NPC( victim ) && xIS_SET(victim->act, PLR_PK ) )
*/
   if (!IS_NPC(victim) && !IS_NPC(ch) && get_trust(ch) >= LEVEL_IMMORTAL)
   {
      sprintf(log_buf, "%s: immortal attempting player murder of %s.", ch->name, victim->name);
      log_string_plus(log_buf, LOG_NORMAL, LEVEL_ADMIN);
      send_to_char("Sorry, you cannot murder players.\n\r", ch);
      return;
   }
   if (!IS_NPC(victim) && !IS_NPC(ch) && get_trust(victim) >= LEVEL_IMMORTAL)
   {
      sprintf(log_buf, "%s: player attempted immortal murder of %s.", ch->name, victim->name);
      log_string_plus(log_buf, LOG_NORMAL, LEVEL_ADMIN);
      send_to_char("Sorry, you cannot murder immortals.\n\r", ch);
      return;
   }
   /*if (!IS_NPC(victim))
   {
      sprintf(log_buf, "%s: murder %s.", ch->name, victim->name);
      log_string_plus(log_buf, LOG_NORMAL, ch->level);
   }*/
   
   if (sysdata.resetgame && check_powerlevel(ch, victim) 
   &&  (get_player_statlevel(ch) > get_player_statlevel(victim) + 5))
   {
      argument = one_argument(argument, arg);
      if (str_cmp(arg, "lowbie"))
      {
         send_to_char("Your Power Level is too high for your target, you will need to type:\n\r", ch);
         send_to_char("kill <target> lowbie [limb] if you want to do such a thing.\n\r", ch);
         return;
      }
      send_to_char("You will be assigned twink points for your kill, if you reach 100 you will be DELETED!\n\r", ch);
   }

   check_illegal_pk(ch, victim);
   check_attacker(ch, victim);
   if (argument[0] == '\0')
   {
      one_hit(ch, victim, TYPE_HIT, LM_BODY);
   }
   else
   {
      if (!str_cmp(argument, "rarm"))
         limb = LM_RARM;
      else if (!str_cmp(argument, "larm"))
         limb = LM_LARM;
      else if (!str_cmp(argument, "rleg"))
         limb = LM_RLEG;
      else if (!str_cmp(argument, "lleg"))
         limb = LM_LLEG;
      else if (!str_cmp(argument, "body"))
         limb = LM_BODY;
      else if (!str_cmp(argument, "head"))
         limb = LM_HEAD;
      else if (!str_cmp(argument, "neck"))
         limb = LM_NECK;
      else
      {
         send_to_char("Need to choose a limb: rarm, larm, rleg, lleg, body, head, neck", ch);
         return;
      }  
      one_hit(ch, victim, TYPE_HIT, limb);
   }
   
   if ( ch && char_died(ch))          
        stop_fighting(ch, TRUE);
   
   return;
}
int npcrace_agi(int race)
{
   switch(race)
   {
      case 6: return 6;  //half-ogre
      case 7: return 5;  //half-orc
      case 8: return 5;  //half-troll
      case 9: return 4;  //half-elf
      case 10: return 3; //gith
      case 11: return 3; //drow
      case 12: return 3; //sea-elf
      case 13: return 5; //lizardman
      case 14: return 2; //gnome
      case 15: return 4; //gnoll
      case 16: return 4; //gnome
      case 17: return 4; //goblin
      case 18: return 4; //kobold
      case 19: return 5; //troll
      case 20: return 5; //minotaur
      case 21: return 4; //skeleton
   }
   return 0;
}
       	
int add_agi_found(CHAR_DATA *ch)
{
   CHAR_DATA *victim;
   BUYKMOB_DATA *kmob;

   if (!IS_NPC(ch))
      return 0;
   if (!IN_WILDERNESS(ch))
      return 0;
   if (!xIS_SET(ch->act, ACT_MILITARY))
      return 0;
      
   for (kmob = first_buykmob; kmob; kmob = kmob->next)
   {
      if (kmob->vnum == ch->pIndexData->vnum)
         if (xIS_SET(kmob->flags, KMOB_SOLDIERADDAGI))  
            break;
   }
   if (!kmob)
      return 0;
   for (victim = ch->in_room->first_person; victim; victim = victim->next_in_room)
   {
      if (!xIS_SET(victim->act, ACT_MILITARY))
         continue;
      for (kmob = first_buykmob; kmob; kmob = kmob->next)
      {
         if (kmob->vnum == victim->pIndexData->vnum)
            if (xIS_SET(kmob->flags, KMOB_SOLDIERAGI))  
               if (abs(ch->coord->x - victim->coord->x) <= 10 && abs(ch->coord->y - victim->coord->y) <= 10
               && ch->m4 == victim->m4)
                  break;
      }
      if (kmob)
         return 1;
   }
   return 0;
} 
      

int get_btimer(CHAR_DATA *ch, int sn, CHAR_DATA *victim)
{
   int timer = 1;
   int mweap = 0;
   int tweight = 0;
   int agi;
   OBJ_DATA *armor;
   OBJ_DATA *shield;
   OBJ_DATA *weapon = NULL;
   OBJ_DATA *dual = NULL;
   int wtype;
   int percent = 0;
   int cweight = 0;
   int combatsn = 0;
   int extra;
   
   if (sn == gsn_pincer || sn == gsn_backstab || sn == gsn_circle || sn == gsn_kick_back || sn == gsn_powerslice
   ||  sn == gsn_drive )
      combatsn = 1;
   
   if (sn > -1 && sn != 1000 && !combatsn)  //1000 is for firing a weapon
   {
      timer = skill_table[sn]->beats; 
   }
   else
   {
      if (ch->race < LAST_H_RACE)
      {
         if (ch->race < MAX_RACE)
            mweap = race_table[ch->race]->weaponmin;
         else
            mweap = npcrace_agi(ch->race);
         weapon = get_eq_char(ch, WEAR_WIELD);
         dual = get_eq_char(ch, WEAR_DUAL_WIELD);
      }
   
      if (weapon == NULL)
      {
         if (!IS_NPC(ch))
            timer = 3;
         else
         {
            timer = 6;
         }
      }      
      else
      {
         timer = 3 + (weapon->value[3] - mweap);
         if (dual)
         {
            cweight += dual->weight;
            percent = 95 - (POINT_LEVEL(LEARNED(ch, gsn_dual_wield), MASTERED(ch, gsn_dual_wield))/2.5);
            timer = timer * percent / 100;
            if ((((3 + (weapon->value[3] - mweap)) * percent) % 100) >= 50)
               timer++;
         }
         cweight += weapon->weight;
         if (cweight > str_app[get_curr_str(ch)].wield)
         {
            timer += UMAX(0, (cweight - str_app[get_curr_str(ch)].wield) * 3 / 2);
         }
      }
      if (sn == 1000) //firing weapons
         timer += 2;
   }
   if (!IS_NPC(ch) && xIS_SET(ch->act, PLR_PARRY))
   {
      if (MASTERED(ch, gsn_parry) == 2)
         timer += 1;
      else if (MASTERED(ch, gsn_parry) >= 3)
         timer += 0;
      else
         timer += 2;
   }
   armor = get_eq_char(ch, WEAR_BODY);
   if (armor)
      tweight += armor->weight;
   armor = get_eq_char(ch, WEAR_HEAD); 
   if (armor)
      tweight += armor->weight;
   armor = get_eq_char(ch, WEAR_NECK);  
   if (armor)
      tweight += armor->weight;
   armor = get_eq_char(ch, WEAR_ARM_R);
   if (armor)
      tweight += armor->weight;
   armor = get_eq_char(ch, WEAR_ARM_L); 
   if (armor)
      tweight += armor->weight;
   armor = get_eq_char(ch, WEAR_LEG_R);
   if (armor)
      tweight += armor->weight;
   armor = get_eq_char(ch, WEAR_LEG_L);  
   if (armor)
      tweight += armor->weight;
      
   if ((shield = get_eq_char(ch, WEAR_SHIELD)) != NULL)
   {
      int mshield;
      mshield = MASTERED(ch, gsn_shieldblock);
      if (mshield == 2)
         mshield = 1;
      else if (mshield == 3)
         mshield = 2;
      else if (mshield == 4)
         mshield = 4;
      timer += UMAX(0, shield->value[3]-mshield);
   }
      
   tweight = tweight - str_app[get_curr_str(ch)].weight;
      
   agi = get_curr_agi(ch);
   if (add_agi_found(ch))
      agi += 10;
   //Two things for dual wield, a little much...
   ch->agi_meter = 1000 - (number_range(agi*7/2, agi*5));
   if (tweight > 0) 
   {
      tweight = tweight * 100 / str_app[get_curr_str(ch)].weight * 7;
      ch->agi_meter += number_range(tweight*7/10, tweight*1);
   }   
   if (!IS_NPC(ch) && ch->pcdata->learned[gsn_combatart] > 0 && weapon && (sn == -1 || sn == 1000))
   {
      ch->agi_meter -= URANGE(6, POINT_LEVEL(LEARNED(ch, gsn_combatart), MASTERED(ch, gsn_combatart))*2/3, 50);
   }
   if (!IS_NPC(ch) && ch->pcdata->learned[gsn_attack_frenzy] > 0 && weapon && (sn == -1 || sn == 1000))
   {
      ch->agi_meter -= URANGE(15, POINT_LEVEL(LEARNED(ch, gsn_attack_frenzy), MASTERED(ch, gsn_attack_frenzy))*4/3, 100);
      if (victim)
         learn_from_success(ch, gsn_attack_frenzy, victim);
   }
   if (sn == 1000)
      wtype = wielding_skill_weapon(ch, 1);
   else if (sn == -1)
      wtype = wielding_skill_weapon(ch, 0);
   else
      wtype = 0;
   if (!IS_NPC(ch) && wtype)
   {
      int wskill = wielding_skill_weapon(ch, 1);
      //No gains here, there is also the damage mod in one_hit
      if (wskill == 1)
      {
         if (ch->pcdata->learned[gsn_weapon_axe] > 0)
         {
            ch->agi_meter -= URANGE(3, POINT_LEVEL(LEARNED(ch, gsn_weapon_axe), MASTERED(ch, gsn_weapon_axe))*2/5, 25);
         }
      }
      if (wskill == 2)
      {
         if (ch->pcdata->learned[gsn_weapon_sword] > 0)
         {
            ch->agi_meter -= URANGE(3, POINT_LEVEL(LEARNED(ch, gsn_weapon_sword), MASTERED(ch, gsn_weapon_sword))*2/5, 25);
         }
      }
      if (wskill == 3)
      {
         if (ch->pcdata->learned[gsn_weapon_polearm] > 0)
         {
            ch->agi_meter -= URANGE(3, POINT_LEVEL(LEARNED(ch, gsn_weapon_polearm), MASTERED(ch, gsn_weapon_polearm))*2/5, 25);
         }
      }
      if (wskill == 4)
      {
         if (ch->pcdata->learned[gsn_weapon_blunt] > 0)
         {
            ch->agi_meter -= URANGE(3, POINT_LEVEL(LEARNED(ch, gsn_weapon_blunt), MASTERED(ch, gsn_weapon_blunt))*2/5, 25);
         }
      }
      if (wskill == 5)
      {
         if (ch->pcdata->learned[gsn_weapon_staff] > 0)
         {
            ch->agi_meter -= URANGE(3, POINT_LEVEL(LEARNED(ch, gsn_weapon_staff), MASTERED(ch, gsn_weapon_staff))*2/5, 25);
         }
      }
      if (wskill == 7)
      {
         if (ch->pcdata->learned[gsn_weapon_dagger] > 0)
         {
            ch->agi_meter -= URANGE(3, POINT_LEVEL(LEARNED(ch, gsn_weapon_dagger), MASTERED(ch, gsn_weapon_dagger))*2/5, 25);
            ch->agi_meter -= URANGE(3, POINT_LEVEL(LEARNED(ch, gsn_weapon_daggerstudy), MASTERED(ch, gsn_weapon_daggerstudy))*3/5, 50);
            ch->agi_meter -= URANGE(3, POINT_LEVEL(LEARNED(ch, gsn_weapon_daggerstrike), MASTERED(ch, gsn_weapon_daggerstrike))*2/5, 25);
         }
      }
      if (wskill == 6)
      {
         if (ch->pcdata->learned[gsn_weapon_projectile] > 0)
         {
            ch->agi_meter -= URANGE(3, POINT_LEVEL(LEARNED(ch, gsn_weapon_projectile), MASTERED(ch, gsn_weapon_projectile))*2/5, 25);
         }
      }
   }
   if (weapon == NULL && IS_NPC(ch))
   {
      if (IS_NPC(ch) && agi >= 50) //50
         timer -= 1;
      if (IS_NPC(ch) && agi >= 70) //70
         timer -= 1;
      if (IS_NPC(ch) && agi >= 90) //90
         timer -= 1;
   }
   if (weapon && shield && !IS_NPC(ch))
   {
      if (IS_OBJ_STAT(weapon, ITEM_TWOHANDED))
      {
         if (ch->pcdata->learned[gsn_inhuman_strength] <= 0)
            bug("%s is wearing a two-handed weapon and a shield!", ch->name);
         else if (MASTERED(ch, gsn_inhuman_strength) == 1)
            timer+= 4;
         else if (MASTERED(ch, gsn_inhuman_strength) == 2)  
            timer+= 3;
         else if (MASTERED(ch, gsn_inhuman_strength) == 3)  
            timer+= 2;
         else if (MASTERED(ch, gsn_inhuman_strength) == 4)  
            timer+= 0;
            
         if (victim)
            learn_from_success(ch, gsn_inhuman_strength, victim);
      }
   }    
   extra = (timer * ch->agi_meter / 10) % 100;  
   timer = timer * ch->agi_meter / 1000;       
   if (number_range(1, 100) <= extra)
      timer++;
   if (sn == gsn_pincer) //a double attack essentially
   {
      int plevel = POINT_LEVEL(LEARNED(ch, gsn_pincer), MASTERED(ch, gsn_pincer));
      timer = timer * (200 - (plevel/5)) /100;
   }
   //sorry cannot go below the minimum beats on a spell....
   if (sn > -1 && sn != 1000 && !combatsn)  //1000 is for firing a weapon
   {
      if (skill_table[sn]->beats > timer)
         return skill_table[sn]->beats;
   }
   if (sn == gsn_pincer && timer < 2)
      timer = 2;
   if (IS_AFFECTED(ch, AFF_NERVEPINCH))
      timer*=2;
   if (!ch->fighting)
      WAIT_STATE(ch, timer*2);
   return URANGE(1, timer, 24);
}
      

/*
 * Check to see if the player is in an "Arena".
 */
bool in_arena(CHAR_DATA * ch)
{
   if (xIS_SET(ch->in_room->room_flags, ROOM_ARENA))
      return TRUE;
   if (!str_cmp(ch->in_room->area->filename, "arena.are"))
      return TRUE;

   return FALSE;
}

bool check_illegal_pk(CHAR_DATA * ch, CHAR_DATA * victim)
{
   char buf[MSL];
   char buf2[MSL];

   if (victim && !IS_NPC(victim) && !IS_NPC(ch) && victim->in_room)
   {
      if (((check_room_pk(ch) == 1) && !IN_ARENA(ch) && ch != victim) || (IS_IMMORTAL(ch) || IS_IMMORTAL(victim)))
      {
         if (IS_NPC(ch))
            sprintf(buf, " (%s)", ch->name);
         if (IS_NPC(victim))
            sprintf(buf2, " (%s)", victim->name);

         sprintf(log_buf, "&p%s on %s%s in &W***&rILLEGAL PKILL&W*** &pattempt at %d",
            (lastplayercmd), (IS_NPC(victim) ? victim->short_descr : victim->name), (IS_NPC(victim) ? buf2 : ""), victim->in_room->vnum);
         last_pkroom = victim->in_room->vnum;
         log_string(log_buf);
         to_channel(log_buf, CHANNEL_MONITOR, "Monitor", LEVEL_IMMORTAL);
         return TRUE;
      }
   }
   return FALSE;
}

int bad_flee_sector(CHAR_DATA *ch, int x, int y)
{
   OBJ_DATA *obj;
   if (IS_MOUNTAIN(map_sector[ch->map][x][y]))
   {
      if (MASTERED(ch, gsn_mountain_climb) < 1)
      {
         if ((obj = get_objtype(ch, ITEM_MCLIMB)) == NULL)
         {
            return TRUE;
         }
      }
   }
   if (IS_NOSWIM(map_sector[ch->map][x][y]))
   {
      if ((ch->mount && !IS_FLOATING(ch->mount)) || !IS_FLOATING(ch))
      {
         /*
          * Look for a boat.
          * We can use the boat obj for a more detailed description.
          */
         if ((obj = get_objtype(ch, ITEM_BOAT)) == NULL)
         {
            return TRUE;
         }
      }
   }
   return FALSE;
}

int get_mapmovement_value(CHAR_DATA *ch, int dir, int type)
{
   if (type == 0) //x
   {
      if (dir == 1) //e
         return +1;
      if (dir == 3) //w
         return -1;
      if (dir == 6) //ne
         return +1;
      if (dir == 7) //nw
         return -1;
      if (dir == 8) //se
         return +1;
      if (dir == 9) //sw
         return -1;
      return 0;
   }
   else  //y
   {
      if (dir == 0) //n
         return -1;
      if (dir == 2) //s
         return +1;
      if (dir == 6) //ne
         return -1;
      if (dir == 7) //nw
         return -1;
      if (dir == 8) //se
         return +1;
      if (dir == 9) //sw
         return +1;
      return 0;   
   }
   return 0;
}
   
void adjust_flee_timers(CHAR_DATA *ch)
{
   CHAR_DATA *victim;
   
   for (victim = ch->in_room->first_person; victim; victim = victim->next_in_room)
   {
      if (victim->fighting && victim->fighting->who == ch)
      {
         victim->fight_timer = 6;
         WAIT_STATE(victim, 12);
      }
   }
}
void do_flee(CHAR_DATA * ch, char *argument)
{
   ROOM_INDEX_DATA *was_in;
   ROOM_INDEX_DATA *now_in;
   CHAR_DATA *foch;
   CHAR_DATA *wf;
   int attempt;
   sh_int door;
   int oldmap;
   int x = 0;
   int broken = 0;
   sh_int addx = 0, addy = 0;
   EXIT_DATA *pexit = NULL;
   AFFECT_DATA af;
   int escapism = 0;
   int retreatchance = 0;
   int retreat = 0;
   int vanish = 0;
   int oldx = 0, oldy = 0, kingdom = 0;
   
   oldx = ch->coord->x;
   oldy = ch->coord->y;

   oldmap = ch->fightm;

   if (!who_fighting(ch))
   {
      if (ch->position == POS_FIGHTING
      || ch->position == POS_EVASIVE || ch->position == POS_DEFENSIVE || ch->position == POS_AGGRESSIVE || ch->position == POS_BERSERK)
      {
         if (ch->mount)
            ch->position = POS_MOUNTED;
         else
            ch->position = POS_STANDING;
      } 
      send_to_char("You aren't fighting anyone.\n\r", ch);
      return;
   }
   if (IS_AFFECTED(ch, AFF_BERSERK))
   {
      send_to_char("You aren't thinking very clearly...\n\r", ch);
      return;
   }
   if (ch->move <= 0)
   {
      send_to_char("You're too exhausted to flee from combat!\n\r", ch);
      return;
   }
   /* No fleeing while more aggressive than standard or hurt. - Haus */
   if (!IS_NPC(ch) && ch->position < POS_FIGHTING && ch->position != POS_AGGRESSIVE)
   {
      send_to_char("Not right now ...\n\r", ch);
      return;
   }
   if (HAS_WAIT(ch))
   {
      send_to_char("You are too busy in battle to do that.\n\r", ch);
      return;
   }
   if (IS_NPC(ch) && ch->position <= POS_SLEEPING)
      return;
      
   if (ch->con_rleg == -1 && ch->con_lleg == -1)
   {
      send_to_char("It is impossible to flee when you have no legs.\n\r", ch);
      return;
   }
   //add broken/damaged legs mod, harder to flee if your legs aren't there or hurt
   broken = 0;
   if (ch->con_rleg <= -1)
      broken += 25;
   else if (ch->con_rleg <= 100)
      broken += 15;
   else if (ch->con_rleg <= 300)
      broken += 10;
   else if (ch->con_rleg <= 500)
      broken += 5;   
   
   if (ch->con_lleg <= -1)
      broken += 25;
   else if (ch->con_lleg <= 100)
      broken += 15;
   else if (ch->con_lleg <= 300)
      broken += 10;
   else if (ch->con_lleg <= 500)
      broken += 5;    
      
   if (!IS_NPC(ch) && ch->pcdata->learned[gsn_escapism] > 0)
   {
      escapism = POINT_LEVEL(GET_POINTS(ch, gsn_escapism, 0, 1), GET_MASTERY(ch, gsn_escapism, 0, 1));
      escapism = UMAX(5, escapism*2/5);
   }
   if (ch->fighting && IS_AFFECTED(ch->fighting->who, AFF_BLIND))
      escapism += 20;
   if (!IS_NPC(ch) && ch->pcdata->learned[gsn_vanish] > 0)
   {
      vanish = POINT_LEVEL(GET_POINTS(ch, gsn_vanish, 0, 1), GET_MASTERY(ch, gsn_vanish, 0, 1));   
      if ((60 + (vanish*2/3)) >= number_range(1, 100))
         vanish = TRUE;
      else
         vanish = FALSE;
   }

   if (argument[0] != '\0')
   {
      if (check_npc(ch))
         return;
         
      if (ch->pcdata->learned[gsn_retreat] > 0)
         retreatchance = POINT_LEVEL(GET_POINTS(ch, gsn_retreat, 0, 1), GET_MASTERY(ch, gsn_retreat, 0, 1));  
         
      if (ch->pcdata->learned[gsn_retreat] <= 0)
      {
         send_to_char("You can only specify a direction if you are knowledgeable in the retreat skill.\n\r", ch);
         return;
      }
      else if (number_range(1, 100) > 50+(retreatchance*3/4))
      {
         learn_from_failure(ch, gsn_retreat, who_fighting(ch));
         send_to_char("&R**********You attempt a planned retreat but you can only find a random exit.**********&w\n\r", ch);
      }
      else
      {
         int dir;
         if ((dir = get_new_dir(argument, 1)) == -1)
         {
            send_to_char("That is not a valid direction.\n\r", ch);
            return;
         }
         if (!IN_WILDERNESS(ch))
         {
            if ((pexit = get_exit(ch->in_room, dir)) == NULL
            || !pexit->to_room
            || IS_SET(pexit->exit_info, EX_NOFLEE)
            || (IS_SET(pexit->exit_info, EX_CLOSED)
            && !IS_AFFECTED(ch, AFF_PASS_DOOR)) || (IS_NPC(ch) && xIS_SET(pexit->to_room->room_flags, ROOM_NO_MOB)))
            {
               send_to_char("There is something blocking you from retreating in that direction.\n\r", ch);
               return;
            }
            else
            {
               retreat = 1;
               learn_from_success(ch, gsn_retreat, who_fighting(ch));
            }
         }
         else
         {
            addx = get_mapmovement_value(ch, dir, 0);
            addy = get_mapmovement_value(ch, dir, 1);
            ch->coord->x += addx;
            ch->coord->y += addy;
            if (ch->coord->x < 1 || ch->coord->x > MAX_X)
            {
               ch->coord->x = oldx;
               ch->coord->y = oldy;
               send_to_char("There is something blocking you from retreating in that direction.\n\r", ch);
               return;
            }
            if (ch->coord->y < 1 || ch->coord->y > MAX_Y)
            {
               ch->coord->x = oldx;
               ch->coord->y = oldy;
               send_to_char("There is something blocking you from retreating in that direction.\n\r", ch);
               return;
            }
            if (sect_show[(int)map_sector[ch->map][ch->coord->x][ch->coord->y]].canpass == TRUE)
            {             
               kingdom = kingdom_sector[ch->map][ch->coord->x][ch->coord->y];
                          
               if (bad_flee_sector(ch, ch->coord->x, ch->coord->y)) //mountains and rivers and stuff
               {
                  ch->coord->x = oldx;
                  ch->coord->y = oldy;
                  send_to_char("There is something blocking you from retreating in that direction.\n\r", ch);
                  return;
               }
               
               if (IS_NPC(ch) && wIS_SET(ch, ROOM_NO_MOB))
               {
                  ch->coord->x = oldx;
                  ch->coord->y = oldy;
                  send_to_char("There is something blocking you from retreating in that direction.\n\r", ch);
                  return;
               }
               if (room_is_private_wilderness(ch, ch->in_room, ch->coord->x, ch->coord->y, ch->map))
               {
                  ch->coord->x = oldx;
                  ch->coord->y = oldy;
                  send_to_char("There is something blocking you from retreating in that direction.\n\r", ch);
                  return;
               }
               if (kingdom_sector[ch->map][ch->coord->x][ch->coord->y] != kingdom) //don't want them fleeing into a blocked out town
               {
                  ch->coord->x = oldx;
                  ch->coord->y = oldy;
                  send_to_char("There is something blocking you from retreating in that direction.\n\r", ch);
                  return;
               }   
            }
            else
            {
               ch->coord->x = oldx;
               ch->coord->y = oldy;
               send_to_char("There is something blocking you from retreating in that direction.\n\r", ch);
               return;
            }
            retreat = 1;
            learn_from_success(ch, gsn_retreat, who_fighting(ch));
         }
      }
   }
   
   // Check to see if player is fleeing while on a map (but not fleeing from one map to another)
   if (ch->coord->x > -1 || ch->coord->y > -1 || ch->map > -1)
   {
      x = 0;

      if (vanish || number_range(1, 100) <= UMIN(85, (45 - broken + escapism + UMIN(5, (get_curr_lck(ch) - 14)) + UMIN(5, (get_curr_dex(ch) - 14)))))
      {
         wf = who_fighting(ch);
         if (retreat == 0)
         {
            for (;;)
            {
               if (x >= 1000)
               {
                  bug("do_flee:  Search for an escape coord 1000 times and did not find one.  %d %d", ch->coord->x, ch->coord->y);
                  return;
               }
               addx = number_range(-5, 5);
               addy = number_range(-5, 5);
               if (addx == 0 && addy == 0)
               {
                  if (number_range(1, 2) == 1)
                     addx += 1;
                  else
                     addy += 1;
               }
               if (ch->coord->x + addx < 1 || ch->coord->x + addx > MAX_X)
               {
                  x++;
                  continue;
               }
               if (ch->coord->y + addy < 1 || ch->coord->y + addy > MAX_Y)
               {
                  x++;
                  continue;
               }
               if (sect_show[(int)map_sector[ch->map][ch->coord->x + addx][ch->coord->y + addy]].canpass == TRUE)
               {                 
                  kingdom = kingdom_sector[ch->map][ch->coord->x][ch->coord->y];
                  
                  oldx = ch->coord->x;
                  oldy = ch->coord->y;
               
                  if (bad_flee_sector(ch, ch->coord->x + addx, ch->coord->y + addy)) //mountains and rivers and stuff
                  {
                     x++;
                     continue;
                  }
               
                  ch->coord->x += addx;
                  ch->coord->y += addy;
                  if (IS_NPC(ch) && wIS_SET(ch, ROOM_NO_MOB))
                  {
                     ch->coord->x = oldx;
                     ch->coord->y = oldy;
                     x++;
                     continue;
                  }
                  if (room_is_private_wilderness(ch, ch->in_room, ch->coord->x, ch->coord->y, ch->map))
                  {
                     ch->coord->x = oldx;
                     ch->coord->y = oldy;
                     x++;
                     continue;
                  }
                  if (kingdom_sector[ch->map][ch->coord->x][ch->coord->y] != kingdom) //don't want them fleeing into a blocked out town
                  {
                     ch->coord->x = oldx;
                     ch->coord->y = oldy;
                     x++;
                     continue;
                  }
                  break;
               }
               else
                  x++;
            }
         }
         adjust_flee_timers(ch);
         if (ch->mount)
         {
            send_to_char("Just before you flee, you yell for your mount to leave.\n\r", ch);
            stop_fighting(ch->mount, TRUE);
            ch->mount->coord->x += addx;
            ch->mount->coord->y += addy;
            ch->mount->map = ch->map;
            update_objects(ch->mount, -1, -1, -1); 
         }
         for (foch = ch->in_room->first_person; foch; foch = foch->next_in_room)
         {
            if (foch != ch /* loop room bug fix here by Thoric */
               && foch->master == ch && (foch->position == POS_STANDING || foch->position == POS_MOUNTED) && foch != ch->mount && IS_NPC(foch))
            {
               if (foch->coord->x == ch->coord->x && foch->coord->y == ch->coord->y && foch->map == ch->map)
               {
                  stop_fighting(foch, TRUE);
                  foch->coord->x += addx;
                  foch->coord->y += addy;
                  foch->map = ch->map;
                  update_objects(foch, -1, -1, -1); 
               }
            }
         }

         affect_strip(ch, gsn_sneak);
         xREMOVE_BIT(ch->affected_by, AFF_SNEAK);
         if (ch->mount && ch->mount->fighting)
            stop_fighting(ch->mount, TRUE);
         act(AT_FLEE, "$n flees head over heels!", ch, NULL, NULL, TO_ROOM);
          //ch->coord->x += addx;
          //ch->coord->y += addy;
          update_objects(ch, -1, -1, -1);
          add_timer(ch, TIMER_RECENTFIGHT, 60, NULL, 0);/*-60 Seconds-*/ 

         act(AT_FLEE, "$n glances around for signs of pursuit.", ch, NULL, NULL, TO_ROOM);
         act(AT_FLEE, "You flee head over heels from combat!", ch, NULL, NULL, TO_CHAR);
         if (!IS_NPC(ch) && ch->pcdata->learned[gsn_escapism] > 0)
            learn_from_success(ch, gsn_escapism, who_fighting(ch));
         if (!IS_NPC(ch) && ch->pcdata->learned[gsn_vanish] > 0)
            learn_from_success(ch, gsn_vanish, who_fighting(ch));
         if (wf && !IS_NPC(ch) && ch->pcdata->deity)
         {
            int level_ratio = number_range(2, 5);

            if (wf && wf->race == ch->pcdata->deity->npcrace)
               adjust_favor(ch, 1, level_ratio);
            else if (wf && wf->race == ch->pcdata->deity->npcfoe)
               adjust_favor(ch, 16, level_ratio);
            else
               adjust_favor(ch, 0, level_ratio);
         }
         stop_fighting(ch, TRUE);

         do_look(ch, "auto");
         return;
      }
      ch->coord->x = oldx;
      ch->coord->y = oldy;
      act(AT_FLEE, "You attempt to flee from combat, but can't escape!", ch, NULL, NULL, TO_CHAR);
      act(AT_FLEE, "$n tries to flee, but fails miserably!", ch, NULL, NULL, TO_ROOM);
      if (!IS_NPC(ch) && ch->pcdata->learned[gsn_escapism] > 0)
         learn_from_failure(ch, gsn_escapism, who_fighting(ch));
      if (!IS_NPC(ch) && ch->pcdata->learned[gsn_vanish] > 0)
         learn_from_failure(ch, gsn_vanish, who_fighting(ch));
      ch->fight_timer = 3;
      if (number_range(1, 2) == 1)
      {
         wf = who_fighting(ch); 
         af.type = gsn_balance;
         af.duration = 3;
         af.location = APPLY_ARMOR;
         af.modifier = -1;
         af.bitvector = meb(AFF_BALANCE); 
         affect_to_char(ch, &af);
         act(AT_RED, "You are nearly tripped up with your failed attempt to escape", ch, NULL, NULL, TO_CHAR);
         act(AT_RED, "$n tries to flee, but nearly trips trying to escape!", ch, NULL, NULL, TO_ROOM);
      }
      return;
   }

   was_in = ch->in_room;
   if (retreat == 1) //god this is getting messy, rofl
   {
      if (vanish || number_range(1, 100) <= UMIN(85, (45 - broken + escapism + UMIN(5, (get_curr_lck(ch) - 14)) + UMIN(5, (get_curr_dex(ch) - 14)))))
      {
         affect_strip(ch, gsn_sneak);
         xREMOVE_BIT(ch->affected_by, AFF_SNEAK);
         adjust_flee_timers(ch);
         if (ch->mount && ch->mount->fighting)
            stop_fighting(ch->mount, TRUE);
         move_char(ch, pexit, 0);
         now_in = ch->in_room;
         ch->in_room = was_in;
         act(AT_FLEE, "$n flees head over heels!", ch, NULL, NULL, TO_ROOM);
         ch->in_room = now_in;
         add_timer(ch, TIMER_RECENTFIGHT, 60, NULL, 0);/*-60 Seconds-*/ 
         act(AT_FLEE, "$n glances around for signs of pursuit.", ch, NULL, NULL, TO_ROOM);
         wf = who_fighting(ch);
         if (!IS_NPC(ch))
         {
            act(AT_FLEE, "You flee head over heels from combat!", ch, NULL, NULL, TO_CHAR);
            if (!IS_NPC(ch) && ch->pcdata->learned[gsn_escapism] > 0)
               learn_from_success(ch, gsn_escapism, who_fighting(ch));
            if (!IS_NPC(ch) && ch->pcdata->learned[gsn_vanish] > 0)
               learn_from_success(ch, gsn_vanish, who_fighting(ch));
            if (wf && ch->pcdata->deity)
            {
               int level_ratio = number_range(2, 5);

               if (wf && wf->race == ch->pcdata->deity->npcrace)
                  adjust_favor(ch, 1, level_ratio);
               else if (wf && wf->race == ch->pcdata->deity->npcfoe)
                  adjust_favor(ch, 16, level_ratio);
               else
                  adjust_favor(ch, 0, level_ratio);
            }
         }
         stop_fighting(ch, TRUE);
         return;
      }
      act(AT_FLEE, "You attempt to flee from combat, but can't escape!", ch, NULL, NULL, TO_CHAR);
      act(AT_FLEE, "$n tries to flee, but fails miserably!", ch, NULL, NULL, TO_ROOM);
      if (!IS_NPC(ch) && ch->pcdata->learned[gsn_escapism] > 0)
         learn_from_failure(ch, gsn_escapism, who_fighting(ch));
      if (!IS_NPC(ch) && ch->pcdata->learned[gsn_vanish] > 0)
         learn_from_failure(ch, gsn_vanish, who_fighting(ch));
      ch->fight_timer = 3;
      if (number_range(1, 2) == 1)
      {
         wf = who_fighting(ch); 
         af.type = gsn_balance;
         af.duration = 3;
         af.location = APPLY_ARMOR;
         af.modifier = -1;
         af.bitvector = meb(AFF_BALANCE);
         affect_to_char(ch, &af);
         act(AT_RED, "You are nearly tripped up with your failed attempt to escape", ch, NULL, NULL, TO_CHAR);
         act(AT_RED, "$n tries to flee, but nearly trips trying to escape!", ch, NULL, NULL, TO_ROOM);
      }
      return;
   }   
   for (attempt = 0; attempt < 50; attempt++)
   {
      door = number_door();
      if ((pexit = get_exit(was_in, door)) == NULL
         || !pexit->to_room
         || IS_SET(pexit->exit_info, EX_NOFLEE)
         || (IS_SET(pexit->exit_info, EX_CLOSED)
&& !IS_AFFECTED(ch, AFF_PASS_DOOR)) || (IS_NPC(ch) && xIS_SET(pexit->to_room->room_flags, ROOM_NO_MOB)))
         continue;
         
      if (number_range(1, 100) <= UMIN(85, (45 - broken + escapism + UMIN(5, (get_curr_lck(ch) - 14)) + UMIN(5, (get_curr_dex(ch) - 14)))))
      {
         affect_strip(ch, gsn_sneak);
         xREMOVE_BIT(ch->affected_by, AFF_SNEAK);
         if (ch->mount && ch->mount->fighting)
            stop_fighting(ch->mount, TRUE);
         adjust_flee_timers(ch);
         move_char(ch, pexit, 0);
         if ((now_in = ch->in_room) == was_in)
            continue;
         ch->in_room = was_in;
         act(AT_FLEE, "$n flees head over heels!", ch, NULL, NULL, TO_ROOM);
         ch->in_room = now_in;
         add_timer(ch, TIMER_RECENTFIGHT, 60, NULL, 0);/*-60 Seconds-*/ 
         act(AT_FLEE, "$n glances around for signs of pursuit.", ch, NULL, NULL, TO_ROOM);
         wf = who_fighting(ch);
         if (!IS_NPC(ch))
         {
            act(AT_FLEE, "You flee head over heels from combat!", ch, NULL, NULL, TO_CHAR);
            if (!IS_NPC(ch) && ch->pcdata->learned[gsn_escapism] > 0)
               learn_from_success(ch, gsn_escapism, who_fighting(ch));
            if (!IS_NPC(ch) && ch->pcdata->learned[gsn_vanish] > 0)
               learn_from_success(ch, gsn_vanish, who_fighting(ch));
            if (wf && ch->pcdata->deity)
            {
               int level_ratio = number_range(2, 5);

               if (wf && wf->race == ch->pcdata->deity->npcrace)
                  adjust_favor(ch, 1, level_ratio);
               else if (wf && wf->race == ch->pcdata->deity->npcfoe)
                  adjust_favor(ch, 16, level_ratio);
               else
                  adjust_favor(ch, 0, level_ratio);
            }
         }
         stop_fighting(ch, TRUE);
         return;
      }
      else
         break;
   }
   act(AT_FLEE, "You attempt to flee from combat, but can't escape!", ch, NULL, NULL, TO_CHAR);
   act(AT_FLEE, "$n tries to flee, but fails miserably!", ch, NULL, NULL, TO_ROOM);
   if (!IS_NPC(ch) && ch->pcdata->learned[gsn_escapism] > 0)
      learn_from_failure(ch, gsn_escapism, who_fighting(ch));
   if (!IS_NPC(ch) && ch->pcdata->learned[gsn_vanish] > 0)
      learn_from_failure(ch, gsn_vanish, who_fighting(ch));
   ch->fight_timer = 3;
   if (number_range(1, 2) == 1)
   {
      wf = who_fighting(ch); 
      af.type = gsn_balance;
      af.duration = 3;
      af.location = APPLY_ARMOR;
      af.modifier = -1;
      af.bitvector = meb(AFF_BALANCE);
      affect_to_char(ch, &af);
      act(AT_RED, "You are nearly tripped up with your failed attempt to escape", ch, NULL, NULL, TO_CHAR);
      act(AT_RED, "$n tries to flee, but nearly trips trying to escape!", ch, NULL, NULL, TO_ROOM);
   }
   return;
}


void do_sla(CHAR_DATA * ch, char *argument)
{
   send_to_char("If you want to SLAY, spell it out.\n\r", ch);
   return;
}

/*old slay code editted out 7/25/99 by Shai'tan
**
**void do_slay( CHAR_DATA *ch, char *argument )
**{
**    CHAR_DATA *victim;
**    char arg[MIL];
**    char arg2[MIL];
**
**    argument = one_argument( argument, arg );
**    one_argument( argument, arg2 );
**    if ( arg[0] == '\0' )
**    {
**	send_to_char( "Slay whom?\n\r", ch );
**	return;
**    }
**
**    if ( ( victim = get_char_room( ch, arg ) ) == NULL )
**    {
**	send_to_char( "They aren't here.\n\r", ch );
**	return;
**    }
**
**    if ( ch == victim )
**    {
**	send_to_char( "Suicide is a mortal sin.\n\r", ch );
**	return;
**    }
**
**    if ( !IS_NPC(victim) && get_trust( victim ) >= get_trust( ch ) )
**    {
**	send_to_char( "You failed.\n\r", ch );
**	return;
**    }
**
**    if ( !str_cmp( arg2, "immolate" ) )
**    {
**      act( AT_FIRE, "Your fireball turns $N into a blazing inferno.",  ch, NULL, victim, TO_CHAR    );
**      act( AT_FIRE, "$n releases a searing fireball in your direction.", ch, NULL, victim, TO_VICT    );
**      act( AT_FIRE, "$n points at $N, who bursts into a flaming inferno.",  ch, NULL, victim, TO_NOTVICT );
**    }
**
**    else if ( !str_cmp( arg2, "shatter" ) )
**  {
**    act( AT_LBLUE, "You freeze $N with a glance and shatter the frozen corpse into tiny shards.",  ch, NULL, victim, TO_CHAR    );
**    act( AT_LBLUE, "$n freezes you with a glance and shatters your frozen body into tiny shards.", ch, NULL, victim, TO_VICT    );
**    act( AT_LBLUE, "$n freezes $N with a glance and shatters the frozen body into tiny shards.",  ch, NULL, victim, TO_NOTVICT );
**  }
**
**  else if ( !str_cmp( arg2, "demon" ) )
**  {
**    act( AT_IMMORT, "You gesture, and a slavering demon appears.  With a horrible grin, the",  ch, NULL, victim, TO_CHAR );
**    act( AT_IMMORT, "foul creature turns on $N, who screams in panic before being eaten alive.",  ch, NULL, victim, TO_CHAR );
**    act( AT_IMMORT, "$n gestures, and a slavering demon appears.  The foul creature turns on",  ch, NULL, victim, TO_VICT );
**   act( AT_IMMORT, "you with a horrible grin.   You scream in panic before being eaten alive.",  ch, NULL, victim, TO_VICT );
**    act( AT_IMMORT, "$n gestures, and a slavering demon appears.  With a horrible grin, the",  ch, NULL, victim, TO_NOTVICT );
**    act( AT_IMMORT, "foul creature turns on $N, who screams in panic before being eaten alive.",  ch, NULL, victim, TO_NOTVICT );
**  }
**
**  else if ( !str_cmp( arg2, "pounce" ) )
**  {
**    act( AT_BLOOD, "Leaping upon $N with bared fangs, you tear open $S throat and toss the corpse to the ground...",  ch, NULL, victim, TO_CHAR );
**    act( AT_BLOOD, "In a heartbeat, $n rips $s fangs through your throat!  Your blood sprays and pours to the ground as your life ends...", ch, NULL, victim, TO_VICT );
**    act( AT_BLOOD, "Leaping suddenly, $n sinks $s fangs into $N's throat.  As blood sprays and gushes to the ground, $n tosses $N's dying body away.",  ch, NULL, victim, TO_NOTVICT );
**  }
**
**  else if ( !str_cmp( arg2, "slit" ) )
**  {
**    act( AT_BLOOD, "You calmly slit $N's throat.", ch, NULL, victim, TO_CHAR );
**    act( AT_BLOOD, "$n reaches out with a clawed finger and calmly slits your throat.", ch, NULL, victim, TO_VICT );
**      act( AT_BLOOD, "$n calmly slits $N's throat.", ch, NULL, victim, TO_NOTVICT );
**    }
**
**    else if ( !str_cmp( arg2, "dog" ) )
**    {
**      act( AT_BLOOD, "You order your dogs to rip $N to shreds.", ch, NULL, victim, TO_CHAR );
**      act( AT_BLOOD, "$n orders $s dogs to rip you apart.", ch, NULL, victim, TO_VICT );
**     act( AT_BLOOD, "$n orders $s dogs to rip $N to shreds.", ch, NULL, victim, TO_NOTVICT );
**    }
**
**    else
**    {
**      act( AT_IMMORT, "You slay $N in cold blood!",  ch, NULL, victim, TO_CHAR    );
**      act( AT_IMMORT, "$n slays you in cold blood!", ch, NULL, victim, TO_VICT    );
**     act( AT_IMMORT, "$n slays $N in cold blood!",  ch, NULL, victim, TO_NOTVICT );
**    }
**
**    set_cur_char(victim);
**    raw_kill( ch, victim );
**    return;
**}
*/