Argila2.0/
Argila2.0/pp/
Argila2.0/pp/lib/save/objs/g/
Argila2.0/pp/lib/save/player/g/
Argila2.0/pp/regions/
Argila2.0/pp/regions/Lscripts/
Argila2.0/pp/src/lib/
/** 
*	\file fight.c
*	Central Combat Processor
*
*	This module deals with combat, wounds, rescue and death. 
*
*	Copyright 2005, Mary C. Huston, All rights reserved.
*	Copyright (C) 2004, Shadows of Isildur: Traithe	
*
*	The program(s) may be used and/or copied only with written
*	permission or in accordance with the terms and conditions
*	stipulated in the license from DIKU GAMMA (0.0) and SOI.
*
*	\author Mary Huston
*	\author Email:  auroness@gmail.com
*
******************************************************************************
*/
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <ctype.h>
#include <time.h>
#include <unistd.h>

#include "structs.h"
#include "protos.h"
#include "utils.h"
#include "decl.h"

CHAR_DATA *combat_list = NULL;
CHAR_DATA *combat_next_dude = NULL; /* Next dude global trick           */


void compete (CHAR_DATA *src, CHAR_DATA *tar, int iterations);

/* Weapon attack texts */

void load_messages(void)
{
	FILE *f1;
	int i,type;
	struct message_type *messages;
	char chk[100];

	if (!(f1 = fopen(MESS_FILE, "r"))){
		perror("read messages");
		abort();	
	}

	for (i = 0; i < MAX_MESSAGES; i++)
	{
		fight_messages[i].a_type = 0;
		fight_messages[i].number_of_attacks=0;
		fight_messages[i].msg = 0;
	}

	fscanf(f1, " %s \n", chk);

	while(*chk == 'M')
	{
		fscanf(f1," %d\n", &type);
		for (i = 0; (i < MAX_MESSAGES) && (fight_messages[i].a_type!=type) &&
		    (fight_messages[i].a_type); i++);
		if(i>=MAX_MESSAGES){
			system_log ("Too many combat messages.", TRUE);
			abort();
		}

		CREATE(messages,struct message_type,1);
		fight_messages[i].number_of_attacks++;
		fight_messages[i].a_type=type;
		messages->next=fight_messages[i].msg;
		fight_messages[i].msg=messages;

		messages->die_msg.attacker_msg      = fread_string(f1);
		messages->die_msg.victim_msg        = fread_string(f1);
		messages->die_msg.room_msg          = fread_string(f1);
		messages->miss_msg.attacker_msg     = fread_string(f1);
		messages->miss_msg.victim_msg       = fread_string(f1);
		messages->miss_msg.room_msg         = fread_string(f1);
		messages->hit_msg.attacker_msg      = fread_string(f1);
		messages->hit_msg.victim_msg        = fread_string(f1);
		messages->hit_msg.room_msg          = fread_string(f1);
		messages->god_msg.attacker_msg      = fread_string(f1);
		messages->god_msg.victim_msg        = fread_string(f1);
		messages->god_msg.room_msg          = fread_string(f1);
		fscanf(f1, " %s \n", chk);
	}

	fclose(f1);
}




void add_criminal_time (CHAR_DATA *ch, int zone, int penalty_time)
{
	AFFECTED_TYPE	*af;

	magic_add_affect (ch, MAGIC_CRIM_BASE + zone, penalty_time, 0, 0, 0, 0);

	af = get_affect (ch, MAGIC_CRIM_BASE + zone);

	if ( af->a.spell.duration > 36 )
		af->a.spell.duration = 36;
}

void criminalize (CHAR_DATA *ch, CHAR_DATA *vict, int zone, int crime)
{
	int				criminalize_him = 0;
	int				penalty_time = 0;
	AFFECTED_TYPE	*af;
	ROOM_DATA		*room;
	CHAR_DATA		*tch;
	char			*date = NULL;
	char			msg [MAX_STRING_LENGTH] = {'\0'};

	if ( crime == CRIME_KILL )
		penalty_time = 24;
	else if ( crime == CRIME_STEAL )
		penalty_time = 8;
	else if ( crime == CRIME_PICKLOCK )
		penalty_time = 4;
	else
		penalty_time = 4;

    /* This allows someone to avoid criminalization by assisting a guard and
       then turning on the guard, or other similar things. This is bad. */

	if ( !ch || !vict )
		return;

    	if ( ch->fighting )
		return;

	room = ch->room;

	if ( is_area_enforcer (ch) )
		return;

	if ( !IS_SET (room->room_flags, LAWFUL) )
		return;

	if ( vict ) {
		if ( IS_SET (vict->act, ACT_CRIMINAL) )
			return;

		if ( IS_SET (vict->act, ACT_WILDLIFE) )
			return;

		if ( IS_SET (vict->act, ACT_AGGRESSIVE) )
			return;

		if ( IS_SET (vict->act, ACT_PARIAH) )
			return;

		if ( (get_affect (vict, MAGIC_CRIM_BASE + zone) ||
			  get_affect (vict, MAGIC_CRIM_HOODED + zone)) &&
			 !get_affect (ch, MAGIC_CRIM_BASE + zone) )
			return;
	}

	if ( is_hooded (ch) ) {

		if ( (!OUTSIDE (ch) && !IS_LIGHT (room)) ||
			 (OUTSIDE (ch) && IS_NIGHT) ) {

			if ( !(af = get_affect (ch, MAGIC_CRIM_HOODED + zone)) ) 
				magic_add_affect (ch, MAGIC_CRIM_HOODED + zone, 1, penalty_time, 0, 0, 0);
			else
				af->a.spell.modifier += penalty_time;

			for ( tch = ch->room->people; tch; tch = tch->next_in_room )
				enforcer (tch, ch, 1, 1);

			if ( !ch->deleted && !af ) {
				af = get_affect (ch, MAGIC_CRIM_HOODED + zone);
				affect_remove (ch, af);
			}

			return;
		}
				
		else if ( !number (0, 4) )
			criminalize_him = 1;
		else
			magic_add_affect (ch, MAGIC_CRIM_HOODED + zone, 40, penalty_time, 0, 0, 0);

	} else
		criminalize_him = 1;

	if ( criminalize_him ) {
		send_to_char ("An onlooker gasps at your actions and runs off to find "
					  "help!\n", ch);

			/* Add hooded crim affect with penalty of 0 as a marker */

		magic_add_affect (ch, MAGIC_CRIM_HOODED + zone, 40, 0, 0, 0, 0);

		add_criminal_time (ch, zone, penalty_time);

		/* Interconnected city zones */

		if ( zone == 1 ) {
			magic_add_affect (ch, MAGIC_CRIM_HOODED + 3, 40, 0, 0, 0, 0);
			add_criminal_time (ch, 3, penalty_time);
		}
		else if ( zone == 3 ) {
			magic_add_affect (ch, MAGIC_CRIM_HOODED + 1, 40, 0, 0, 0, 0);
			add_criminal_time (ch, 1, penalty_time);
		}

		if ( IS_MORTAL (ch) ) {
       		 	date = timestr(date);
		
			if ( crime == CRIME_KILL )
				snprintf (msg, MAX_STRING_LENGTH, "Flagged wanted for Assault in %s for %d hours. [%d]\n", zone_table[ch->room->zone].name, penalty_time, ch->in_room);
			else if ( crime == CRIME_STEAL )
				snprintf (msg, MAX_STRING_LENGTH, "Flagged wanted for Attempted Theft in %s for %d hours. [%d]\n", zone_table[ch->room->zone].name, penalty_time, ch->in_room);
			else if ( crime == CRIME_PICKLOCK )
				snprintf (msg, MAX_STRING_LENGTH, "Flagged wanted for Breaking and Entering in %s for %d hours. [%d]\n", zone_table[ch->room->zone].name, penalty_time, ch->in_room);
			else
				snprintf (msg, MAX_STRING_LENGTH, "Flagged wanted in %s for %d hours. [%d]\n", zone_table[ch->room->zone].name, penalty_time, ch->in_room);

			if ( !IS_NPC (ch) ) {	
				add_message (ch->tname, 3, "Server", date, "Wanted.", "", msg, 0);
				add_message ("Crimes", 2, "Server", date, ch->tname, "", msg, 0);
			}
		}
	}

		/* Immediate guard response */

	for ( tch = ch->room->people; tch; tch = tch->next_in_room )
		enforcer (tch, ch, 1, 1);
}


void stop_fighting_sounds (CHAR_DATA *ch, ROOM_DATA *room)
{
	int			dir, from_dir;
	ROOM_DIRECTION_DATA	*exit_room;
	ROOM_DATA		*next_room;
	char			buf [MAX_STRING_LENGTH] = {'\0'};
	char			*e_dirs [] = { "to the north", "to the east", "to the south", "to the west", "above", "below" };
	AFFECTED_TYPE		*af;

	if ( !ch->room )
		return;

	if ( !room )
		return;

	for ( dir = 0; dir <= 5; dir++ ) {
		if ( !(exit_room = PASSAGE (ch, dir)) )
			continue;
		if ( !(next_room = vtor (exit_room->to_room)) )
			continue;
		if ( dir == 0 )
			from_dir = 2;
		else if ( dir == 1 )
			from_dir = 3;
		else if ( dir == 2 )
			from_dir = 0;
		else if ( dir == 3 )
			from_dir = 1;
		else if ( dir == 4 )
			from_dir = 5;
		else from_dir = 4;
		if ( next_room->affects &&
			next_room->affects->type == MAGIC_ROOM_FIGHT_NOISE &&
			next_room->affects->a.room.duration == from_dir ) {
				next_room->affects = next_room->affects->next;
		}
		else for ( af = next_room->affects; af; af = af->next ) {
			if ( !af->next )
				break;
			if ( af->next->type != MAGIC_ROOM_FIGHT_NOISE )
				continue;
			if ( af->next->a.room.duration != from_dir )
				continue;
			af->next = af->next->next;
		}
		snprintf (buf, MAX_STRING_LENGTH,  "The sounds of an armed conflict %s have died away.", e_dirs[from_dir]);
		send_to_room (buf, next_room->virtual);
	}
}

void fighting_sounds (CHAR_DATA *ch)
{
	int			dir, from_dir;
	ROOM_DIRECTION_DATA	*exit_room;
	ROOM_DATA		*next_room;
	AFFECTED_TYPE		*af;
	char			buf [MAX_STRING_LENGTH] = {'\0'};
	char			*e_dirs [] = { "the north", "the east", "the south", "the west", "above", "below" };
	bool			found = FALSE;

	for ( dir = 0; dir <= 5; dir++ ) {
		if ( !(exit_room = PASSAGE (ch, dir)) )
			continue;
		if ( !(next_room = vtor (exit_room->to_room)) )
			continue;
		if ( dir == 0 )
			from_dir = 2;
		else if ( dir == 1 )
			from_dir = 3;
		else if ( dir == 2 )
			from_dir = 0;
		else if ( dir == 3 )
			from_dir = 1;
		else if ( dir == 4 )
			from_dir = 5;
		else from_dir = 4;
		for ( af = next_room->affects; af; af = af->next ) {
			if ( af->type != MAGIC_ROOM_FIGHT_NOISE )
				continue;
			if ( af->a.room.duration != from_dir )
				continue;
			found = TRUE;
		}
		if ( !found ) {
			if ( !next_room->affects ) {
				next_room->affects = (AFFECTED_TYPE *)alloc (sizeof (AFFECTED_TYPE), 13);
				next_room->affects->type = MAGIC_ROOM_FIGHT_NOISE;
				next_room->affects->a.room.duration = from_dir;
				next_room->affects->next = NULL;
			}
			else for ( af = next_room->affects; af; af = af->next ) {
				if ( !af->next ) {
					af->next = (AFFECTED_TYPE *)alloc (sizeof (AFFECTED_TYPE), 13);
					af->next->type = MAGIC_ROOM_FIGHT_NOISE;
					af->next->a.room.duration = from_dir;
					af->next->next = NULL;
					break;
				}
			}
			snprintf (buf, MAX_STRING_LENGTH,  "You hear the sounds of armed battle erupt from %s!", e_dirs[from_dir]);
			send_to_room (buf, next_room->virtual);
		}
	}
}

void set_fighting (CHAR_DATA *ch, CHAR_DATA *vict)
{
	AFFECTED_TYPE	*af;

	clear_pmote(ch);

	if ( IS_SET (ch->flags, FLAG_COMPETE) ||
		 IS_SET (vict->flags, FLAG_COMPETE) )
		return;

	if ( ch->fighting ) {
		return;
	}

	if ( ch == vict )		/* No way, not in this game :( */
		return;

	ch->next_fighting = combat_list;
	combat_list = ch;

	if ( (af = get_affect (ch, MAGIC_AFFECT_SLEEP)) )
		affect_remove (ch, af);

	if ( GET_FLAG (ch, FLAG_AUTOFLEE) && AWAKE(ch) ) {
		send_to_char ("You try to escape!\n\r", ch);
		act ("$n tries to escape!",
				FALSE, ch, 0, 0, TO_ROOM);
        	SET_BIT (ch->flags, FLAG_FLEE);
	}

	if ( (IS_SET (vict->act, ACT_PURSUE) ||
		(!morale_broken(vict) && !IS_SET (vict->act, ACT_SENTINEL) &&
		(IS_SET (vict->act, ACT_AGGRESSIVE) || IS_SET (vict->act, ACT_ENFORCER)))) &&
		!vict->following ) {
		/* vict->following = ch; */
		vict->speed = ch->speed;
	}

	if ( (IS_SET (ch->act, ACT_PURSUE) ||
		(!morale_broken(ch) && !IS_SET (ch->act, ACT_SENTINEL) &&
		(IS_SET (ch->act, ACT_AGGRESSIVE) || IS_SET (ch->act, ACT_ENFORCER)))) &&
		!ch->following ) {
		/* vict->following = ch; */
		ch->speed = vict->speed;
	}

        if ( (af = is_crafting(ch)) ) {
                act ("$n stops doing $s craft.", FALSE, ch, 0, 0, TO_ROOM);
                send_to_char ("You stop doing your craft.\n", ch);
                af->a.craft->timer = 0;
        }

        if ( (af = is_crafting(vict)) ) {
                act ("$n stops doing $s craft.", FALSE, vict, 0, 0, TO_ROOM);
                send_to_char ("You stop doing your craft.\n", vict);
                af->a.craft->timer = 0;
        }

	ch->fighting = vict;

	/* fighting_sounds(ch); */

	add_threat (vict, ch, 2);
	add_threat (ch, vict, 2);

	clear_moves (ch);
	clear_moves (vict);

	if ( IS_NPC(ch) &&
		 !ch->desc &&
		 (is_area_enforcer(ch) || ch->race == RACE_WOLF)
		 && IS_SET (ch->flags, FLAG_KILL) )
		do_alert (ch, "", 0);

	if ( IS_NPC(vict) &&
		 !vict->desc &&
		 (is_area_enforcer(vict) || vict->race == RACE_WOLF)
		 && IS_SET (vict->flags, FLAG_KILL) )
		do_alert (vict, "", 0);
}

void stop_fighting (CHAR_DATA *ch)
{
	CHAR_DATA *tch;
	bool		fighting = FALSE;

	for ( tch = ch->room->people; tch; tch = tch->next_in_room ) {
		if ( tch == ch )
			continue;
		if ( tch->fighting )
			fighting = TRUE;
	}

	if (ch == combat_next_dude)
		combat_next_dude = ch->next_fighting;

	if ( combat_list == ch )
		combat_list = ch->next_fighting;
	else {
		for (tch = combat_list; tch && (tch->next_fighting != ch);
		    tch = tch->next_fighting);
		if (!tch) {
			system_log ("Char fighting not found Error (fight.c, stop_fighting)", TRUE);
			sigsegv(SIGSEGV);
		}
		tch->next_fighting = ch->next_fighting;
	}

	ch->next_fighting = 0;
	ch->fighting = 0;
	if ( GET_POS (ch) == FIGHT )
		GET_POS (ch) = STAND;

	REMOVE_BIT (ch->flags, FLAG_KILL);

	if ( ch->mount && !IS_SET (ch->act, ACT_MOUNT) && ch->mount->fighting )
		stop_fighting (ch->mount);

	if ( IS_NPC(ch) ) {
		ch->speed = 0;
		ch->threats = NULL;
		ch->attackers = NULL;
	}
}

void make_statue (CHAR_DATA *ch)
{
	OBJ_DATA		*statue;
	OBJ_DATA		*o;
	WOUND_DATA		*wound;
	WOUND_DATA		*cwound;
	LODGED_OBJECT_INFO	*lodged;
	LODGED_OBJECT_INFO	*clodged;
	char			buf [MAX_STRING_LENGTH] = {'\0'};
	char			buf2 [MAX_STRING_LENGTH] = {'\0'};
	int				i;
	OBJ_DATA		*temp_arg = NULL;
	
	statue = load_object (VNUM_STATUE);

	if ( !IS_NPC (ch) )
		snprintf (buf, MAX_STRING_LENGTH,  "statue pc_%s", GET_NAME (ch));
	else {
		(void)one_argument (GET_NAME (ch), buf2);
		snprintf (buf, MAX_STRING_LENGTH,  "statue npc_%s", buf2);
	}

	statue->name = str_dup (buf);

	snprintf (buf, MAX_STRING_LENGTH,  "An eerily lifelike statue of %s looms here.", ch->short_descr);
	statue->description = str_dup(buf);

	snprintf (buf, MAX_STRING_LENGTH,  "an eerily lifelike statue of %s", ch->short_descr);
	statue->short_description = str_dup(buf);

	for ( wound = ch->wounds; wound; wound = wound->next ) {
		if ( !statue->wounds ) {
			CREATE (statue->wounds, WOUND_DATA, 1);
			statue->wounds->location = add_hash(wound->location);
			statue->wounds->type = add_hash(wound->type);
			statue->wounds->name = add_hash(wound->name);
			statue->wounds->severity = add_hash(wound->severity);
			statue->wounds->bleeding = 0;
			statue->wounds->poison = wound->poison;
			statue->wounds->infection = wound->infection;
			statue->wounds->healerskill = wound->healerskill;
			statue->wounds->lasthealed = wound->lasthealed;
			statue->wounds->lastbled = wound->lastbled;
			statue->wounds->next = NULL;
		}
		else for ( cwound = statue->wounds; cwound; cwound = cwound->next ) {
			if ( cwound->next )
				continue;
			CREATE (cwound->next, WOUND_DATA, 1);
			cwound->next->location = add_hash(wound->location);
			cwound->next->type = add_hash(wound->type);
			cwound->next->name = add_hash(wound->name);
			cwound->next->severity = add_hash(wound->severity);
			cwound->next->bleeding = 0;
			cwound->next->poison = wound->poison;
			cwound->next->infection = wound->infection;
			cwound->next->healerskill = wound->healerskill;
			cwound->next->lasthealed = wound->lasthealed;
			cwound->next->lastbled = wound->lastbled;
			cwound->next->next = NULL;
			break;
		}
	}

	for ( lodged = ch->lodged; lodged; lodged = lodged->next ) {
		if ( !statue->lodged ) {
			CREATE (statue->lodged, LODGED_OBJECT_INFO, 1);
			statue->lodged->vnum = lodged->vnum;
			statue->lodged->location = add_hash(lodged->location);
			statue->lodged->next = NULL;
		}
		else for ( clodged = statue->lodged; clodged; clodged = clodged->next ) {
			if ( !clodged->next ) {
				CREATE (clodged->next, LODGED_OBJECT_INFO, 1);
				clodged->next->vnum = lodged->vnum;
				clodged->next->location = add_hash(lodged->location);
				clodged->next->next = NULL;
				break;
			}
		}
	}

	if ( ch->right_hand ) {
		o = ch->right_hand;
		ch->right_hand = NULL;
		o->equiped_by = NULL;
		o->carried_by = NULL;
		o->next_content = NULL;
		obj_to_obj (o, statue);
	}

	if ( ch->left_hand ) {
		o = ch->left_hand;
		ch->left_hand = NULL;
		o->equiped_by = NULL;
		o->carried_by = NULL;
		o->next_content = NULL;
		obj_to_obj (o, statue);
	}

	statue->obj_flags.weight = get_weight (ch) * 5;

	for ( i = 0; i < MAX_WEAR; i++ )
		if ( get_equip (ch, i) ){
			temp_arg = unequip_char(ch, i);
			obj_to_obj (temp_arg, statue);
		}
	IS_CARRYING_N (ch) = 0;

	obj_to_room (statue, ch->in_room);
}

#define MAX_NPC_CORPSE_TIME 12 /* 3 RL hours -- corpses are saved. */
#define MAX_PC_CORPSE_TIME 96 /* 1 RL day -- corpses are saved. */

void make_corpse (CHAR_DATA *ch)
{
	OBJ_DATA		*corpse;
	OBJ_DATA		*o;
	WOUND_DATA		*wound;
	WOUND_DATA		*cwound;
	LODGED_OBJECT_INFO	*lodged;
	LODGED_OBJECT_INFO	*clodged;
	char			buf [MAX_STRING_LENGTH] = {'\0'};
	char			buf2 [MAX_STRING_LENGTH] = {'\0'};
	int				i;
	OBJ_DATA		*temp_arg = NULL;
	
	corpse = load_object (VNUM_CORPSE);

	if ( !IS_NPC (ch) )
		snprintf (buf, MAX_STRING_LENGTH,  "corpse pc_%s", GET_NAME (ch));
	else {
		(void)one_argument (GET_NAME (ch), buf2);
		snprintf (buf, MAX_STRING_LENGTH,  "corpse npc_%s", buf2);
	}

	corpse->name = str_dup (buf);

	snprintf (buf, MAX_STRING_LENGTH,  "The corpse of %s is lying here.", ch->short_descr);
	corpse->description = str_dup(buf);

	snprintf (buf, MAX_STRING_LENGTH,  "the corpse of %s", ch->short_descr);
	corpse->short_description = str_dup(buf);

	for ( wound = ch->wounds; wound; wound = wound->next ) {
		if ( !corpse->wounds ) {
			CREATE (corpse->wounds, WOUND_DATA, 1);
			corpse->wounds->location = add_hash(wound->location);
			corpse->wounds->type = add_hash(wound->type);
			corpse->wounds->name = add_hash(wound->name);
			corpse->wounds->severity = add_hash(wound->severity);
			corpse->wounds->bleeding = 0;
			corpse->wounds->poison = wound->poison;
			corpse->wounds->infection = wound->infection;
			corpse->wounds->healerskill = wound->healerskill;
			corpse->wounds->lasthealed = wound->lasthealed;
			corpse->wounds->lastbled = wound->lastbled;
			corpse->wounds->next = NULL;
		}
		else for ( cwound = corpse->wounds; cwound; cwound = cwound->next ) {
			if ( cwound->next )
				continue;
			CREATE (cwound->next, WOUND_DATA, 1);
			cwound->next->location = add_hash(wound->location);
			cwound->next->type = add_hash(wound->type);
			cwound->next->name = add_hash(wound->name);
			cwound->next->severity = add_hash(wound->severity);
			cwound->next->bleeding = 0;
			cwound->next->poison = wound->poison;
			cwound->next->infection = wound->infection;
			cwound->next->healerskill = wound->healerskill;
			cwound->next->lasthealed = wound->lasthealed;
			cwound->next->lastbled = wound->lastbled;
			cwound->next->next = NULL;
			break;
		}
	}

	for ( lodged = ch->lodged; lodged; lodged = lodged->next ) {
		if ( !corpse->lodged ) {
			CREATE (corpse->lodged, LODGED_OBJECT_INFO, 1);
			corpse->lodged->vnum = lodged->vnum;
			corpse->lodged->location = add_hash(lodged->location);
			corpse->lodged->next = NULL;
		}
		else for ( clodged = corpse->lodged; clodged; clodged = clodged->next ) {
			if ( !clodged->next ) {
				CREATE (clodged->next, LODGED_OBJECT_INFO, 1);
				clodged->next->vnum = lodged->vnum;
				clodged->next->location = add_hash(lodged->location);
				clodged->next->next = NULL;
				break;
			}
		}
	}

	if ( ch->right_hand ) {
		o = ch->right_hand;
		ch->right_hand = NULL;
		o->equiped_by = NULL;
		o->carried_by = NULL;
		o->next_content = NULL;
		obj_to_obj (o, corpse);
	}

	if ( ch->left_hand ) {
		o = ch->left_hand;
		ch->left_hand = NULL;
		o->equiped_by = NULL;
		o->carried_by = NULL;
		o->next_content = NULL;
		obj_to_obj (o, corpse);
	}

	if ( ch->mob ) {
		if ( GET_FLAG (ch, FLAG_WILLSKIN) ) {
			corpse->o.od.value [2] = -ch->mob->skinned_vnum;
			corpse->o.od.value [3] = -ch->mob->carcass_vnum;
		} else {
			corpse->o.od.value [2] = ch->mob->skinned_vnum;
			corpse->o.od.value [3] = ch->mob->carcass_vnum;
		}
	} else {
		corpse->o.od.value [2] = 0;
		corpse->o.od.value [3] = 0;
	}

	corpse->obj_flags.weight = get_weight (ch);

	if ( IS_NPC (ch) )
		corpse->obj_timer = MAX_NPC_CORPSE_TIME;
	else
		corpse->obj_timer = MAX_PC_CORPSE_TIME;

	SET_BIT (corpse->obj_flags.extra_flags, ITEM_TIMER);

	for ( i = 0; i < MAX_WEAR; i++ ) {
		if ( get_equip (ch, i) ) {
			if ( GET_ITEM_TYPE (get_equip(ch, i)) == ITEM_CONTAINER && IS_SET (ch->plr_flags, NEW_PLAYER_TAG) )
				continue;
			temp_arg = unequip_char(ch, i);
			obj_to_obj (temp_arg, corpse);
		}
	}

	IS_CARRYING_N (ch) = 0;

	obj_to_room (corpse, ch->in_room);
}

void remove_guest_skills (CHAR_DATA *ch)
{
	int		i;

	if ( !IS_SET (ch->flags, FLAG_GUEST) )
		return;

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

        ch->speaks = db_race_table[ch->race].race_speaks;
        ch->skills [ch->speaks] = calc_lookup(ch, REG_CAP, db_race_table[ch->race].race_speaks);
        ch->pc->skills [ch->speaks] = ch->skills [ch->speaks];

}

void death_email (CHAR_DATA *ch)
{
	char		buf [MAX_STRING_LENGTH] = {'\0'};
	MYSQL_RES	*result;
	MYSQL_ROW	row;
	ACCOUNT_DATA	*account;
	FILE		*fp;
	bool		found = FALSE;

	if ( !ch || !ch->pc || !ch->pc->account )
		return;

	if ( !(account = load_account (ch->pc->account)) )
		return;

	if ( !(fp = fopen(ch->tname, "w+")) )
		return;

	fprintf (fp, 	"From: %s <%s>\n"
		     	"To: %s\n"
			"X-Sender: %s"
			"Mime-Version: 1.0\n"
			"Content-type: text/plain;charset=\"us-ascii\"\n"
			"Organization: %s\n"
			"Subject: %s's Recent Demise\n"
			"\n", MUD_NAME, MUD_EMAIL, account->email, MUD_EMAIL, MUD_NAME, ch->tname);

	result = NULL;

	fprintf (fp, 	"Hello,\n\n"
			"   Our records indicate that your PC, %s, has recently passed on. For\n"
			"your convenience and future reference, we have taken the liberty of\n"
			"compiling all of %s journal entries, in-game board posts and in-\n"
			"character writings; they are attached below.\n\n"
			"   Thanks for playing, and we hope to see you back again soon.\n"
			"\n"
			"\n"
			"                                           Best Regards,\n"
			"                                           The Admin Team\n\n", ch->tname, HSHR(ch));
 
	mysql_safe_query ("SELECT * FROM player_journals WHERE name = '%s' ORDER BY post_number ASC", ch->tname);
	result = mysql_store_result(database);
	if ( mysql_num_rows (result) ) {
		fprintf (fp, "Journal Entries:\n\n");
		while ( (row = mysql_fetch_row(result)) ) {
			found = TRUE;
			fprintf (fp, "--\nDate: %s\nSubject: %s\n\n%s\n", row[4], row[2], row[5]);
		}
		fprintf (fp, "\n");
		mysql_free_result (result);
		result = NULL;
	}

	mysql_safe_query ("SELECT * FROM boards WHERE author = '%s' ORDER BY board_name,post_number ASC", ch->tname);
	result = mysql_store_result(database);
	if ( mysql_num_rows (result) ) {
		fprintf (fp, "In-Game Board Posts:\n\n");	
		while ( (row = mysql_fetch_row(result)) ) {
			found = TRUE;
			fprintf (fp, "--\nDate: %s [%s]\nSubject: %s\n\n%s\n", row[5], row[4],row[2], row[6]);
		}
		fprintf (fp, "\n");
		mysql_free_result (result);
		result = NULL;
	}

	mysql_safe_query ("SELECT * FROM player_writing WHERE author = '%s' ORDER BY db_key,page ASC", ch->tname);
	result = mysql_store_result(database);
	if ( mysql_num_rows(result) ) {
		fprintf (fp, "In-Character Writings:\n\n");
		while ( (row = mysql_fetch_row(result)) ) {
			found = TRUE;
			fprintf (fp, "--\nDate: %s\n\n%s\n", row[3], row[8]);
		}
		fprintf (fp, "\n");
		mysql_free_result (result);
		result = NULL;
	}

	if ( !found )
		fprintf (fp, "--\nNo writing was found in our database.\n");

	fclose (fp);

	snprintf (buf, MAX_STRING_LENGTH,  "/usr/sbin/sendmail %s < %s", account->email, ch->tname);
	system (buf);

	unlink (ch->tname);

	free_account (account);
	account = NULL;
}

void raw_kill (CHAR_DATA *ch)
{
	CHAR_DATA	*tch;
	DESCRIPTOR_DATA	*d;

	if ( ch->fighting ) {
		if (ch == combat_next_dude)
			combat_next_dude = ch->next_fighting;

		if ( combat_list == ch )
			combat_list = ch->next_fighting;
		else {
                        for (tch = combat_list; tch && (tch->next_fighting != ch);
                                tch = tch->next_fighting);
                        if (!tch) {
                                system_log ("Char fighting not found Error (fight.c, stop_fighting)", TRUE);
				sigsegv (SIGSEGV);
                        }
                        tch->next_fighting = ch->next_fighting;
		}

		ch->next_fighting = 0;
		ch->fighting = 0;
	}

	for ( tch = character_list; tch; tch = tch->next ) {
		if ( tch->deleted )
			continue;
		if ( tch->aiming_at == ch && ch->room != tch->room )
			act ("$n collapses, slain. You lower your weapon.", FALSE, ch, 0, tch, TO_VICT | TO_ACT_FORMAT);
	}

	if ( !IS_SET (ch->plr_flags, FLAG_PETRIFIED) )
		make_corpse (ch);
	else make_statue (ch);

	if ( IS_SET (ch->plr_flags, FLAG_PETRIFIED) ) {
		act ("$n suddenly seems to grow stiff, turning to stone before your very eyes!", TRUE, ch, 0, 0, TO_ROOM | TO_ACT_FORMAT);
		act ("As the hated rays of the sun strike your skin, you suddenly grow stiff, and your mind is awash in helpless rage before -- nothing...", TRUE, ch, 0, 0, TO_CHAR | TO_ACT_FORMAT);
	}
	else if ( !ch->mount ) {
		send_to_room ("\n", ch->in_room);
		if ( GET_POS (ch) >= 7 ) 
			act ("$n collapses to the ground, dead.", TRUE, ch, 0, 0, TO_ROOM | TO_ACT_FORMAT);
		else
			act ("$n expires with a ragged exhalation.", TRUE, ch, 0, 0, TO_ROOM | TO_ACT_FORMAT);
		ch->mount = NULL;
	}
	else if ( ch->mount && IS_SET (ch->act, ACT_MOUNT) ) {
		send_to_room ("\n", ch->in_room);
		act ("$n collapses, dead, dumping $N to the ground in the process.", TRUE, ch, 0, ch->mount, TO_NOTVICT | TO_ACT_FORMAT);
		act ("$n collapses, dead, dumping you to the ground in the process.", TRUE, ch, 0, ch->mount, TO_VICT | TO_ACT_FORMAT);
		ch->mount->mount = NULL;
		ch->mount = NULL;	
	}
	else if ( ch->mount && !IS_SET (ch->act, ACT_MOUNT) ) {
		send_to_room ("\n", ch->in_room);
		act ("$n falls to the ground from atop $N, dead.", TRUE, ch, 0, ch->mount, TO_NOTVICT | TO_ACT_FORMAT);
		act ("$n falls to the ground from atop you, dead.", TRUE, ch, 0, ch->mount, TO_VICT | TO_ACT_FORMAT);
		ch->mount->mount = NULL;
		ch->mount = NULL;
	}

	if ( (!IS_NPC(ch) && !IS_SET (ch->flags, FLAG_GUEST)) || (IS_SET (ch->flags, FLAG_GUEST) && ch->desc) ) {
		GET_POS(ch) = POSITION_STANDING;
		while ( ch->wounds )
			wound_from_char (ch, ch->wounds);
		while ( ch->lodged )
			lodge_from_char (ch, ch->lodged);
		ch->damage = 0;
		if ( IS_SET (ch->flags, FLAG_GUEST) ) {
			nanny_create_guest (ch->desc, "recreate");
		}
		else {
			d = ch->desc;
			extract_char (ch);
                        SEND_TO_Q ("#0Your character has, regrettably, passed away. Our condolences. . .#0\n\n"
                                   "#0Thank you for playing - we hope to see you back again soon!#0\n", d);
			d->connected = CON_ACCOUNT_MENU;
			nanny (d, "");
			if ( IS_MORTAL (ch) && !ch->pc->mortal_mode ) {
				death_email (ch);
				mysql_safe_query ("UPDATE newsletter_stats SET pc_deaths=pc_deaths+1");
			}
		}
	}
	else {
		extract_char(ch);
	}
}


void die (CHAR_DATA *ch)
{
	int			duration = 0;
	STORED_PC_DATA  	*pc;
	char			*date = NULL;
	char			buf [MAX_STRING_LENGTH] = {'\0'};
	char			msg [MAX_STRING_LENGTH] = {'\0'};
	char			buf2 [MAX_STRING_LENGTH] = {'\0'};
	

	
	if ( ch->combat_log ) {
		system_log (ch->combat_log, FALSE);
	}

	if ( !IS_NPC (ch) ) {

		if ( !IS_SET (ch->flags, FLAG_GUEST) ) {
			date = timestr(date);

			if ( IS_SET (ch->plr_flags, FLAG_PETRIFIED) )
				snprintf (msg, MAX_STRING_LENGTH, "Location: %s [%d]\n\nDied of petrification.\n", ch->room->name, ch->in_room);
			else if ( ch->delay_info1 && ch->delay_ch && !IS_SET (ch->flags, FLAG_BINDING) ) {
				snprintf (buf2, MAX_STRING_LENGTH,  " [%s]", ch->delay_ch->tname);
				snprintf (msg, MAX_STRING_LENGTH, "Location: %s [%d]\n\nAssailant: #5%s#0%s\n\nWeapon: #2%s#0\n", ch->room->name, ch->in_room, ch->delay_ch->short_descr, !IS_NPC(ch->delay_ch) ? buf2 : "", vtoo(ch->delay_info1)->short_description);
			}
			else if ( ch->delay_ch && !ch->delay_info1 && !IS_SET (ch->flags, FLAG_BINDING) ) {
				snprintf (buf2, MAX_STRING_LENGTH,  " [%s]", ch->delay_ch->tname);
				snprintf (msg, MAX_STRING_LENGTH, "Location: %s [%d]\n\nAssailant: #5%s#0%s\n", ch->room->name, ch->in_room, ch->delay_ch->short_descr, !IS_NPC(ch->delay_ch) ? buf2 : "");
			}
			else 
				snprintf (msg, MAX_STRING_LENGTH, "Location: %s [%d]\n\nDied of unspecified causes, e.g. bloodloss or falling.\n", ch->room->name, ch->in_room);

			add_message (ch->tname, 3, "Server", date, "Died.", "", msg, 0);
			add_message ("Deaths", 2, "Server", date, ch->tname, "", msg, 0);

			if ( ch->desc && ch->desc->account ) {
				for ( pc = ch->desc->account->pc; pc; pc = pc->next ) {
					if ( !str_cmp (pc->name, ch->tname) ) {
						pc->state = STATE_DIED;
						break;
					}
				}
			}

			mem_free (date);
		}

		if ( !IS_SET (ch->flags, FLAG_GUEST) ) {
			if ( !IS_SET (ch->plr_flags, FLAG_PETRIFIED) )
				snprintf (buf, MAX_STRING_LENGTH,  "%s has been slain!\n", ch->tname); 
			else snprintf (buf, MAX_STRING_LENGTH,  "%s has been petrified!\n", ch->tname);
			send_to_gods (buf);
		}
	
		ch->delay_ch = 0;
		ch->delay_info1 = 0;

			/* NOTE:  af doesn't point to anything after affects are removed */

		if ( duration > 100 )	/* Fix a bug where some players have a LARGE */
			duration = 1;		/* number of hours */

		while ( ch->hour_affects )
			affect_remove (ch, ch->hour_affects);

		ch->pc->create_state = STATE_DIED;
		ch->pc->last_died = time (0);

		save_char (ch, TRUE);
	}

	raw_kill (ch);

	if ( IS_SET (ch->plr_flags, FLAG_PETRIFIED) )
		REMOVE_BIT (ch->plr_flags, FLAG_PETRIFIED);
}

char *replace_string(char *str, char *weapon, char *local)
{
	static char		buf [MAX_STRING_LENGTH] = {'\0'};		/* Leave as static */
	char			*cp;

	cp = buf;

	for (; *str; str++) {
		if (*str == '#') {
			switch(*(++str)) {
			case 'W' :
				for (; *weapon; *(cp++) = *(weapon++));
				break;
			case 'L' :
				for (;*local;*(cp++)=*(local++));
				break;
			default :
				*(cp++) = '#';
				break;
			}
		} else {
			*(cp++) = *str;
		}

		*cp = 0;
	} /* For */

	return(buf);
}

int damage (CHAR_DATA *ch, CHAR_DATA *victim, int dam, int attacktype)
{
	int			i,j,nr;
	struct message_type *messages;
	char		buf [MAX_STRING_LENGTH] = {'\0'};
	OBJ_DATA	*temp_arg = NULL;
	
	if ( GET_POS(victim) <= POSITION_DEAD ) {
		snprintf (buf, MAX_STRING_LENGTH,  "kill -SEGV %d", getpid());
		system (buf);
	}

	if ((GET_TRUST(victim)>3) && !IS_NPC(victim))
		dam=0;

	if (victim != ch) {
		if ( GET_POS (ch) > POSITION_STUNNED &&
			 !ch->fighting )
			set_fighting (ch, victim);

		if (GET_POS(victim) > POSITION_STUNNED) {
			if (!(victim->fighting))
				set_fighting(victim, ch);
			GET_POS(victim) = POSITION_FIGHTING;
		}

	}

	if ( dam > 0 )
		GET_HIT (victim) -= dam;

			/* God knows how the victim was hit */

	else {

		for(i = 0; i < MAX_MESSAGES; i++) {
			if (fight_messages[i].a_type == attacktype) {
				nr = dice (1, fight_messages[i].number_of_attacks);
				for(j=1,messages=fight_messages[i].msg;(j<nr)&&(messages);j++)
					messages=messages->next;

				if ( !IS_NPC (victim) && !IS_MORTAL (victim) ) {
					temp_arg = get_equip (ch, WEAR_PRIM);
					act (messages->god_msg.attacker_msg, FALSE, ch,
						 temp_arg, victim, TO_CHAR);
					act (messages->god_msg.victim_msg, FALSE, ch,
						 temp_arg, victim, TO_VICT);
					act (messages->god_msg.room_msg, FALSE, ch,
						 temp_arg, victim, TO_NOTVICT);
				} else if (dam != 0) {
					if (GET_POS(victim) == POSITION_DEAD) {
						temp_arg = get_equip (ch, WEAR_PRIM);
						act (messages->die_msg.attacker_msg, FALSE, ch,
								temp_arg, victim, TO_CHAR);
						act (messages->die_msg.victim_msg, FALSE, ch,
								temp_arg, victim, TO_VICT);
						act (messages->die_msg.room_msg, FALSE, ch,
								temp_arg, victim, TO_NOTVICT);
					} else {
						temp_arg = get_equip (ch, WEAR_PRIM);
						act (messages->hit_msg.attacker_msg, FALSE, ch,
								temp_arg, victim, TO_CHAR);
						act (messages->hit_msg.victim_msg, FALSE, ch,
								temp_arg, victim, TO_VICT);
						act (messages->hit_msg.room_msg, FALSE, ch,
								temp_arg, victim, TO_NOTVICT);
					}
				} else { /* Dam == 0 */
					temp_arg = get_equip (ch, WEAR_PRIM);
					act (messages->miss_msg.attacker_msg, FALSE, ch,
								temp_arg, victim, TO_CHAR);
					act (messages->miss_msg.victim_msg, FALSE, ch,
								temp_arg, victim, TO_VICT);
					act (messages->miss_msg.room_msg, FALSE, ch,
								temp_arg, victim, TO_NOTVICT);
				}
			}
		}
	}

	if (GET_POS(victim) < POSITION_DEAD)
		if (ch->fighting == victim)
			stop_fighting(ch);

	if (!AWAKE(victim))
		if (victim->fighting)
			stop_fighting(victim);

	if (GET_POS(victim) == POSITION_DEAD) {
		if (IS_NPC(victim) || victim->desc)
			if (!IS_NPC(victim)) {
				snprintf (buf, MAX_STRING_LENGTH,  "%s killed by %s at %s", GET_NAME(victim), (IS_NPC(ch) ? ch->short_descr : GET_NAME(ch)), vtor (victim->in_room)->name);
				if (IS_NPC(ch) && IS_SET(ch->act,ACT_MEMORY)) 
					forget (ch, victim);
			}
		die(victim);
		return 1;
	}

	return 0;
}

#define		SINGLE		1
#define		PRIMARY		2
#define		SECONDARY	3


void hit_char (CHAR_DATA *ch, CHAR_DATA *victim, int smite_parm)
{
	int			killed = 0;
	OBJ_DATA	*weapon;
	AFFECTED_TYPE	*temp_aff = NULL;

	if ( !ch || !victim )
		return;

	if ( IS_SET (victim->act, ACT_FLYING) && !IS_SET (ch->act, ACT_FLYING) && AWAKE(victim) ) {
		send_to_char ("They are flying out of reach!\n", ch);
		return;
	}

	if ( IS_NPC(ch) && !ch->desc ) {
		ready_melee_weapons (ch);
	}

	if ( IS_NPC (victim) && !victim->desc ) {
		ready_melee_weapons (victim);
	}

	if ( victim->delay && victim->delay_type != DEL_LOAD_WEAPON )
		break_delay (victim);

	if ( ch->delay && ch->delay_type != DEL_LOAD_WEAPON )
		break_delay (ch);

	if ( GET_POS (ch) != POSITION_DEAD && GET_POS (victim) != POSITION_DEAD )
		criminalize (ch, victim, victim->room->zone, CRIME_KILL);

	if ( !ch->fighting && !smite_parm )
		set_fighting (ch, victim);

	if ( IS_SUBDUEE (victim) ) {
		act ("$n takes a swing at $N.", FALSE, ch, 0, victim, TO_NOTVICT);
		act ("$N takes a swing at you.", FALSE, victim, 0, ch, TO_CHAR);
	}

	if ( IS_SUBDUEE (ch) ) {
		if ( ch->fighting )
			stop_fighting (ch);
		return;
	}

	if ( GET_FLAG (ch, FLAG_FLEE) ) {

		if ( !ch->primary_delay && !flee_attempt (ch) )
			ch->primary_delay = 16;

		return;
	}

	guard_check (victim);

	if ( IS_SUBDUER (ch) )
		return;

	if ( get_affect (victim, AFFECT_GUARD_DIR) ) {
		act ("The attack prevents you from continuing to guard the exit.", FALSE, victim, 0, 0, TO_CHAR);
		act ("The attack prevents $n from continuing to guard the exit.", FALSE, victim, 0, 0, TO_ROOM | TO_ACT_FORMAT);
		temp_aff = get_affect (victim, AFFECT_GUARD_DIR);
		affect_remove (victim, temp_aff);
	}

		/* Empty handed attack / Primary / Dual */

	if ( !ch->primary_delay &&
		 (get_equip (ch, WEAR_PRIM) ||
		  get_equip (ch, WEAR_BOTH) ||
		  (!get_equip (ch, WEAR_PRIM) &&
		   !get_equip (ch, WEAR_BOTH) &&
		   !get_equip (ch, WEAR_SEC))) ) {

		if ( GET_FLAG (ch, FLAG_SUBDUING) ) {

			if ( !(weapon = get_equip (ch, WEAR_PRIM)) )
				return;

			if ( weapon->o.weapon.use_skill != SKILL_LIGHT_EDGE )
				return;
		}

		if ( get_affect (ch, MAGIC_AFFECT_DIZZINESS) && !number (0, 3) ) {
			send_to_char ("You battle your dizziness as you ready your attack.", ch);
			act ("$N staggers, appearing dizzy.", TRUE, ch, 0, 0, TO_ROOM);
			ch->primary_delay += 5 * 4;
		} else
			smite (ch, victim, 1);
	}

	if ( ch->deleted || victim->deleted || !victim->room || !ch->room )
		killed = 1;

	if ( !killed && !can_move (victim) && !GET_FLAG (ch, FLAG_KILL) &&
         ch->fighting ) {

		act ("$N can't move.", FALSE, ch, 0, victim, TO_CHAR);

			/* Aggressives don't stop trying to kill */

		if ( !ch->mob || !IS_SET (ch->act, ACT_AGGRESSIVE) )
			stop_fighting (ch);

		return;
	}

		/* Secondary weapon attack */

	if ( !killed && !ch->secondary_delay && get_equip (ch, WEAR_SEC) ) {

		if ( GET_FLAG (ch, FLAG_SUBDUING) &&
			 !((weapon = get_equip (ch, WEAR_SEC)) &&
				weapon->o.weapon.use_skill != SKILL_LIGHT_EDGE ) )
			return;

		smite (ch, victim, 2);
	}

	if ( !ch->deleted && !victim->deleted && ch->fighting &&
		 ch->room && victim->room && IS_SUBDUEE (victim) )
		stop_fighting (ch);

	if ( !ch->deleted && !victim->deleted && ch->fighting && !killed &&
		 !can_move (victim) && !GET_FLAG (ch, FLAG_KILL) ) {

		act ("$N can't move.", FALSE, ch, 0, victim, TO_CHAR);

			/* Aggressives don't stop trying to kill */

		if ( !ch->mob || !IS_SET (ch->act, ACT_AGGRESSIVE) )
			stop_fighting (ch);
	}

	if ( !ch->deleted && !ch->fighting && GET_POS (ch) == FIGHT )
		GET_POS (ch) = STAND;
}	


char *get_dam_word (int damage)
{
	if ( damage <= 6 )
		return " ";

	if ( damage <= 10 )
		return " hard ";

	if ( damage <= 15 )
		return " very hard ";

	if ( damage <= 20 )
		return " extremely hard ";

	return " incredibly hard ";
}

int combat_roll (int ability)
{
	int		r;
	int		roll_result;

	r = number (1, 100);

	if ( ability > 98 )
		ability = 98;

	if ( ability < 5 )
		ability = 5;

	if ( r > ability )
		roll_result = SUC_MF - ((r % 5) ? 0 : 1);
	else
		roll_result = SUC_MS + ((r % 5) ? 0 : 1);

	return roll_result;
}

#define AD (fd + strlen (fd))

void advance (CHAR_DATA *src, CHAR_DATA *tar)
{
	if ( src->distance_to_target >= 2 ) {
		act("You begin advancing on $N, preparing for battle.", FALSE, src, 0, tar, TO_CHAR);
		act("$n begins advancing on $N, preparing for battle.", FALSE, src, 0, tar, TO_NOTVICT);
		act("$n begins advancing on you, preparing for battle.", FALSE, src, 0, tar, TO_VICT);
	}
	else if ( src->distance_to_target == 1 ) {
		act("You close to polearm range on $N!", FALSE, src, 0, tar, TO_CHAR);
		act("$n closes to polearm range on $N!", FALSE, src, 0, tar, TO_NOTVICT);
		act("$n closes to polearm range on you!", FALSE, src, 0, tar, TO_VICT);
	}
	else if ( src->distance_to_target == 0 ) {
		act("You close to melee range on $N!", FALSE, src, 0, tar, TO_CHAR);
		act("$n closes to melee range on $N!", FALSE, src, 0, tar, TO_NOTVICT);
		act("$n closes to melee range on you!", FALSE, src, 0, tar, TO_VICT);
	}
	src->primary_delay = 20;
	src->distance_to_target -= 1;
	tar->distance_to_target -= 1;

}


int smite (CHAR_DATA *src, CHAR_DATA *tar, int attack_num)
{
	float			defense = 0;
	float			attack = 0;
	int			off_success = 0;
	int			def_success = 0;
	int			off_result = 0;
	int			def_result = 0;
	int			defense_hand = 0;
	int			location = 0;
	int			damage = 0;
	int			hit_type = 0;
	int			i = 0;
	int			j = 0;
	int			wear_loc1 = 0;
	int			wear_loc2 = 0;
	char			loc[MAX_STRING_LENGTH] = {'\0'};
	OBJ_DATA		*tar_prim = get_equip (tar, WEAR_PRIM);
	OBJ_DATA		*tar_sec  = get_equip (tar, WEAR_SEC);
	OBJ_DATA		*tar_both = get_equip (tar, WEAR_BOTH);
	OBJ_DATA		*src_prim = get_equip (src, WEAR_PRIM);
	OBJ_DATA		*src_sec  = get_equip (src, WEAR_SEC);
	OBJ_DATA		*src_dual = get_equip (src, WEAR_BOTH);
	OBJ_DATA		*attack_weapon = NULL;
	OBJ_DATA		*defense_weapon = NULL;
	OBJ_DATA		*shield = NULL;
	OBJ_DATA		*attack_shield = NULL;
	OBJ_DATA		*eq1 = NULL;
	OBJ_DATA		*eq2 = NULL;
	OBJ_DATA		*broken_eq = NULL;
	CHAR_DATA		*mount;
	AFFECTED_TYPE	*af = NULL;
	int				bonus = 0;
	float			attack_modifier = 0;
	float			defense_modifier = 0;
	float			r1 = 0;
	char			fd [MAX_STRING_LENGTH] = {'\0'};
	CHAR_DATA		*dch= NULL;
	char			*temp_arg = NULL;

	*fd = 0;

	if ( IS_SET (src->act, ACT_VEHICLE) )
		return 0;

	snprintf (AD, MAX_STRING_LENGTH, "%s [%d hp %d mvs] strike %d %s [%d hp %d mvs]  ",
				GET_NAME (src), GET_HIT (src), GET_MOVE (src), attack_num,
				GET_NAME (tar), GET_HIT (tar), GET_MOVE (tar));

	attack_modifier = 100.0;
	defense_modifier = 100.0;

	if ( src->in_room != tar->in_room )
		return 0;

	if ( attack_num == 1 )
		attack_weapon = src_prim ? src_prim : src_dual;
	else
		attack_weapon = src_sec;

	if ( attack_weapon &&
	     (attack_weapon->o.weapon.use_skill == SKILL_SHORTBOW ||
             attack_weapon->o.weapon.use_skill == SKILL_LONGBOW ||
	     attack_weapon->o.weapon.use_skill == SKILL_CROSSBOW ||
	     attack_weapon->o.weapon.use_skill == SKILL_SLING ||
	     attack_weapon->o.weapon.use_skill == SKILL_THROWN) )
		return 0;

	if ( attack_weapon && GET_ITEM_TYPE (attack_weapon) != ITEM_WEAPON &&
		GET_ITEM_TYPE (attack_weapon) != ITEM_SHIELD )
		attack_weapon = NULL;

	if ( IS_SET (src->flags, FLAG_PACIFIST) )
		return 0;

	if ( attack_weapon )
		snprintf (AD, MAX_STRING_LENGTH, "%s\n\r", attack_weapon->short_description);
	else {
		attack = src->skills [SKILL_BRAWLING];		/* default attack */
		snprintf (AD, MAX_STRING_LENGTH, "BRAWLING\n\r");
	}

	if ( attack_weapon )
		attack = src->skills [attack_weapon->o.weapon.use_skill];

	if ( attack < src->offense ) {
		attack = src->offense;
		snprintf (AD, MAX_STRING_LENGTH, "Using Offense %d ", (int) attack);
	}

	snprintf (AD, MAX_STRING_LENGTH, "ABase %d ", (int) attack);

			/* Weapon bonus/penalty */

	bonus = 100;

	if ( attack_weapon ) {
		for ( af = attack_weapon->xaffected; af; af = af->next )
			switch ( af->a.spell.location ) {
				case APPLY_OFFENSE:
				case APPLY_CLUB:
				case APPLY_SPEAR:
				case APPLY_SWORD:
				case APPLY_DAGGER:
				case APPLY_AXE:
				case APPLY_WHIP:
				case APPLY_POLEARM:
					snprintf (AD, MAX_STRING_LENGTH, "+%d WEAP-AFF ", af->a.spell.modifier);
					bonus += af->a.spell.modifier;
					break;
				default: break;
			}
	}

	if ( (attack_shield = get_equip (src, WEAR_SHIELD)) ) {

		for ( af = attack_shield->xaffected; af; af = af->next ) {
			if ( af->a.spell.location == APPLY_OFFENSE ) {
				snprintf (AD, MAX_STRING_LENGTH, "%d OFF/SHIELD PEN ", af->a.spell.modifier);
				bonus += af->a.spell.modifier;
			}
		}
	}

	if ( bonus < 0 )
		attack_modifier = 0.0;
	else
		attack_modifier = attack_modifier * bonus / 100.0;

	snprintf (AD, MAX_STRING_LENGTH, "weapmod %d ", bonus);

			/* Fatigue penalty */

	if ( GET_MAX_MOVE (src) > 0 )
		j = GET_MOVE (src) * 100 / GET_MAX_MOVE (src);
	else
		j = 0;

	if ( j > 100 )
		j = 100;

	for ( i = 0; j > fatigue [i].percent; i++ )
		;

	snprintf (AD, MAX_STRING_LENGTH, "fatigue %3.2f ", fatigue [i].penalty);

	attack_modifier = attack_modifier * fatigue [i].penalty;

			/* Dual wield penalty */

	if ( attack_num == 2 ) {
		r1 = .60 + .40 * src->skills [SKILL_DUAL] / 100.0;
		snprintf (AD, MAX_STRING_LENGTH, "Dual Pen %3.2f ", r1);
		attack_modifier = attack_modifier * r1;
	}

			/* Encumberance penalty */

	for ( i = 0; i < CUMBERANCE_ENTRIES; i++ ) {
		if ( GET_STR (src) * enc_tab [i].str_mult_wt >= IS_CARRYING_W (src) )
			break;
	}

	attack_modifier = attack_modifier * enc_tab [i].penalty;

	snprintf (AD, MAX_STRING_LENGTH, "Enc %3.2f ", enc_tab [i].penalty);

			/* Fightmode modifier */

	attack_modifier = attack_modifier *
					  fight_tab [src->fight_mode].offense_modifier;

	if ( get_affect (src, MAGIC_AFFECT_FURY) ) {
		attack_modifier = attack_modifier * 1.25;
		snprintf (AD, MAX_STRING_LENGTH, "* 1.25 [FURY] ");
	}

	if ( get_affect (src, MAGIC_AFFECT_DIZZINESS) ) {
		attack_modifier = attack_modifier * 0.75;
		snprintf (AD, MAX_STRING_LENGTH, "* 0.75 [DIZZINESS] ");
	}

	snprintf (AD, MAX_STRING_LENGTH, "FM %3.2f ", fight_tab [src->fight_mode].offense_modifier);
	snprintf (AD, MAX_STRING_LENGTH, " = OFFENSE %3.0f\n", attack * attack_modifier / 100);

			/* DEFENSE */

		/* We need to know which weapon to defend with */

	shield = get_equip (tar, WEAR_SHIELD);

	if ( shield && shield->obj_flags.type_flag != ITEM_SHIELD ) {
		printf ("Non-shield object %d, on %d(%s), at %d\n",
				shield->virtual, IS_NPC (tar) ? tar->mob->virtual : 0,
				tar->name, tar->room->virtual);
		fflush (stdout);
	}

	defense_weapon = NULL;

	if ( tar_both ) {
		defense_weapon = tar_both;
		defense_hand = 1;
	}

	else if ( tar_prim && !tar_sec && !shield ) {
		defense_weapon = tar_prim;
		defense_hand = 1;
	}

	else if ( tar_sec && !tar_prim && !shield ) {
		defense_weapon = tar_sec;
		defense_hand = 2;
	}

	else if ( shield && !tar_prim && !tar_sec ) {
		defense_weapon = shield;
		defense_hand = 1;
	}

	else if ( shield && tar_prim ) {
		if ( tar->primary_delay > tar->secondary_delay ) {
			defense_weapon = shield;
			defense_hand = 2;
		} else {
			defense_weapon = tar_prim;
			defense_hand = 1;
		}
	}

	else if ( shield && tar_sec ) {
		if ( tar->primary_delay > tar->secondary_delay ) {
			defense_weapon = tar_sec;
			defense_hand = 2;
		} else {
			defense_weapon = shield;
			defense_hand = 1;
		}
	}

	else if ( tar_prim && tar_sec ) {
		if ( tar->primary_delay > tar->secondary_delay ) {
			defense_weapon = tar_sec;
			defense_hand = 2;
		} else {
			defense_weapon = tar_prim;
			defense_hand = 1;
		}
	}

	else {
		defense_weapon = NULL;
		defense_hand = 1;
	}

	if ( shield != defense_weapon )
		shield = NULL;

	if ( defense_weapon && GET_ITEM_TYPE (defense_weapon) != ITEM_WEAPON 
		&& GET_ITEM_TYPE (defense_weapon) != ITEM_SHIELD )
		defense_weapon = NULL;

	if ( !defense_weapon )
		defense = tar->skills [SKILL_DODGE];
	else if ( defense_weapon->obj_flags.type_flag == ITEM_SHIELD )
		defense = tar->skills [SKILL_BLOCK];
	else if ( defense_weapon->obj_flags.type_flag == ITEM_WEAPON ) {
		if ( defense_weapon->o.weapon.use_skill == SKILL_LONGBOW ||
		     defense_weapon->o.weapon.use_skill == SKILL_SHORTBOW ||
	             defense_weapon->o.weapon.use_skill == SKILL_CROSSBOW ||
		     defense_weapon->o.weapon.use_skill == SKILL_SLING ||
	             defense_weapon->o.weapon.use_skill == SKILL_THROWN ) {
			defense = tar->skills [SKILL_DODGE];
			defense_weapon = NULL;
		}
		else defense = tar->skills [SKILL_PARRY];
	}
	else {
		defense = 0;
	}

	if ( real_skill (tar, SKILL_DANGER_SENSE) )
		if ( skill_use (tar, SKILL_DANGER_SENSE, 0) )
			defense += tar->skills [SKILL_DANGER_SENSE] / 5;
			/*
			* On a successful use of the Danger Sense skill, if
			* the skill being checked is a defensive combat skill,
			* it grants them a bonus; they are able to sense the
			* impending blow before it lands. (Nexus)
			*/

	if ( IS_SET (tar->flags, FLAG_PACIFIST) )
		defense += 10;

	if ( defense > 95 ) defense = 95;

	/* Unless you're Legolas, using bows in melee isn't so bright... */
	if ( tar->aiming_at )
		defense -= 20;

	snprintf (AD, MAX_STRING_LENGTH, "DBase %d ", (int) defense);

			/* Fatigue penalty */

	if ( GET_MAX_MOVE (tar) > 0 )
		j = GET_MOVE (tar) * 100 / GET_MAX_MOVE (tar);
	else {
		j = 0;
	}

	if ( j > 100 )
		j = 100;

	for ( i = 0; j > fatigue [i].percent; i++ )
		;

	snprintf (AD, MAX_STRING_LENGTH, "Fatigue %3.2f ", fatigue [i].penalty);

	defense_modifier = defense_modifier * fatigue [i].penalty;

			/* Encumberance penalty */

	for ( i = 0; i < CUMBERANCE_ENTRIES; i++ ) {
		if ( GET_STR (tar) * enc_tab [i].str_mult_wt >= IS_CARRYING_W (tar) )
			break;
	}

	snprintf (AD, MAX_STRING_LENGTH, "Enc %3.2f ", enc_tab [i].penalty);

	defense_modifier = defense_modifier * enc_tab [i].penalty;


			/* Fightmode modifier */

	defense_modifier = defense_modifier *
					   fight_tab [tar->fight_mode].defense_modifier;

	snprintf (AD, MAX_STRING_LENGTH, "FM %3.2f ", fight_tab [tar->fight_mode].defense_modifier);

			/* Hand delay modifier */

	if ( defense_hand == 1 )
		r1 = (100 - 5 * tar->primary_delay) / 100.0;
	else
		r1 = (100 - 5 * tar->secondary_delay) / 100.0;

	if ( r1 < .25 )		/* Maximum 75% penalty for being delayed. */
		r1 = .25;

	defense_modifier = defense_modifier * r1;

	snprintf (AD, MAX_STRING_LENGTH, "DelayPen %3.2f ", r1);

			/* Weapon/shield defense */

	if ( defense_weapon ) {

		bonus = 100;

		for ( af = defense_weapon->xaffected; af; af = af->next ) {

			if ( defense_weapon->obj_flags.type_flag == ITEM_SHIELD ) {
				if ( af->a.spell.location == APPLY_BLOCK )
					bonus += af->a.spell.modifier;
			}

			else if ( af->a.spell.location == APPLY_PARRY )
				bonus += af->a.spell.modifier;
		}

		if ( bonus < 0 )
			defense_modifier = 0.0;
		else
			defense_modifier = defense_modifier * bonus / 100.0;

		snprintf (AD, MAX_STRING_LENGTH, "Weapbon %d ", bonus);
	}

	defense = defense * defense_modifier / 100;
	attack = attack * attack_modifier / 100;

	if ( attack_weapon && (attack_weapon->o.od.value[3] == SKILL_MEDIUM_EDGE || attack_weapon->o.od.value[3] == SKILL_MEDIUM_BLUNT ||
		attack_weapon->o.od.value[3] == SKILL_MEDIUM_PIERCE) ) {
		if ( attack_weapon->location == WEAR_SEC )
			attack -= 10;
	}

	if ( attack_weapon && (attack_weapon->o.od.value[3] == SKILL_HEAVY_EDGE || attack_weapon->o.od.value[3] == SKILL_HEAVY_BLUNT ||
		attack_weapon->o.od.value[3] == SKILL_HEAVY_PIERCE) ) {
		if ( attack_weapon->location == WEAR_PRIM )
			attack -= 10;
		if ( attack_weapon->location == WEAR_SEC )
			attack -= 20;
	}

	if ( defense_weapon && (defense_weapon->o.od.value[3] == SKILL_HEAVY_EDGE || defense_weapon->o.od.value[3] == SKILL_HEAVY_BLUNT ||
		defense_weapon->o.od.value[3] == SKILL_HEAVY_PIERCE) ) { 
		if ( defense_weapon->location == WEAR_PRIM )
			defense -= 10;
		if ( defense_weapon->location == WEAR_SEC )
			defense -= 20;
	}

       

	snprintf (AD, MAX_STRING_LENGTH, " = DEFENSE %d\n", (int) defense);

	attack = figure_wound_skillcheck_penalties (src, attack);
	defense = figure_wound_skillcheck_penalties (tar, defense);

	defense = MAX (5, defense);
	attack = MAX (5, attack);

	snprintf (AD, MAX_STRING_LENGTH,  "End Result: %f Attack\n", attack);

	off_success = combat_roll (attack);

	def_success = combat_roll (defense);

        if ( attack_weapon )
                hit_type = attack_weapon->o.weapon.hit_type;
        else {
                if ( src->nat_attack_type == 0 )
                        hit_type = 9;
                else if ( src->nat_attack_type == 1 || src->nat_attack_type == 3 )
                        hit_type = 7;
                else if ( src->nat_attack_type == 2 )
                        hit_type = 8;
        }

		/* Must be standing or fighting AND not in frantic mode */

	if ( (GET_POS (tar) != STAND && GET_POS (tar) != FIGHT) ||
		 tar->fight_mode == 0 ) {
		def_result = RESULT_NONE;
		off_result = ignore_offense [off_success];
		snprintf (AD, MAX_STRING_LENGTH, "IGNORE:  %s = %s\n",
					 cs_name [off_success], rs_name [off_result]);
	}

	else if ( defense_hand == 1 && !defense_weapon ) {
		off_result = dodge_offense [off_success] [def_success];
		def_result = dodge_defense [off_success] [def_success];
		snprintf (AD, MAX_STRING_LENGTH, "DODGE:  %s(%d) = %s(%d);    %s(%d) = %s(%d)\n",
			cs_name [off_success], off_success, rs_name [off_result], off_result,
			cs_name [def_success], def_success, rs_name [def_result], def_result);
	}

	else if ( defense_weapon ) {
		off_result = shield_parry_offense [off_success] [def_success];
		def_result = shield_parry_defense [off_success] [def_success];

		if ( off_result == RESULT_BLOCK && defense_weapon != shield ) {
			off_result = RESULT_PARRY;
			def_result = RESULT_PARRY;
		}

		snprintf (AD, MAX_STRING_LENGTH, "BLOCK/PARRY:  %s = %s;    %s = %s\n",
			cs_name [off_success], rs_name [off_result],
			cs_name [def_success], rs_name [def_result]);
	}

	figure_damage (src,
				   tar,
				   attack_weapon,
				   off_result,
				   &damage,
				   &location);

	temp_arg = figure_location(tar, location);
	snprintf (loc, MAX_STRING_LENGTH, "%s",temp_arg );

        wear_loc1 = body_tab [0] [location].wear_loc1; 
        wear_loc2 = body_tab [0] [location].wear_loc2;
        eq1 = get_equip (tar, wear_loc1);                
        eq2 = get_equip (tar, wear_loc2);

	if ( eq2 && IS_SET (eq2->obj_flags.wear_flags, ITEM_WEAR_ABOUT) && (name_is ("cloak", eq2->name) || name_is("cape", eq2->name)) && number(0,2) )
		eq2 = NULL;

	if ( off_result == RESULT_FUMBLE ) {

		if ( GET_DEX (src) <= number (1, 21) ) {
			if ( attack_weapon && number (0, 1) )
				off_result = RESULT_NEAR_FUMBLE;
			else
				off_result = RESULT_NEAR_STUMBLE;
		}

		else if ( !attack_weapon || number (0, 1) )
			off_result = RESULT_STUMBLE;

		if ( off_result != RESULT_FUMBLE )
			snprintf (AD, MAX_STRING_LENGTH, "offensive result -> %s\n", rs_name [off_result]);
	}

	if ( def_result == RESULT_FUMBLE ) {

		if ( GET_DEX (tar) <= number (1, 21) ) {
			if ( defense_weapon && number (0, 1) )
				def_result = RESULT_NEAR_FUMBLE;
			else
				def_result = RESULT_NEAR_STUMBLE;
		}

		else if ( !defense_weapon || number (0, 1) )
			def_result = RESULT_STUMBLE;

		if ( def_result != RESULT_FUMBLE )
			snprintf (AD, MAX_STRING_LENGTH, "defensive result -> %s\n", rs_name [def_result]);
	}

		/* DA can occur only if defending a primary attacker */

	if ( def_result == RESULT_ADV && tar->fighting != src )
		def_result = RESULT_NONE;

	if ( attack_weapon && (off_result == RESULT_BLOCK || off_result == RESULT_PARRY) ) {

		if ( attack_weapon && ((defense_weapon && attack_weapon->quality <= defense_weapon->quality) || (shield && attack_weapon->quality <= shield->quality)) && number (1,100) > attack_weapon->quality ) {
			if ( shield )
				damage_to_obj (attack_weapon, number(1,MAX(damage,5)), 3);
			else
				damage_to_obj (attack_weapon, number(1,MAX(damage,5)), defense_weapon->o.weapon.hit_type);
			if ( (number(1,100) > attack_weapon->quality && number(1,100) > attack_weapon->item_wear) || attack_weapon->item_wear <= 0 )
				off_result = RESULT_WEAPON_BREAK;
		}
		else if ( attack_weapon && defense_weapon && number (1,100) > defense_weapon->quality ) {
			damage_to_obj (defense_weapon, number(1,MAX(damage,5)), hit_type);
			if ( (number(1,100) > defense_weapon->quality && number(1,100) > defense_weapon->item_wear) || defense_weapon->item_wear <= 0 )
				def_result = RESULT_WEAPON_BREAK;
		}
		else if ( attack_weapon && shield && number(1,100) > shield->quality ) {
			damage_to_obj (shield, number(1,MAX(damage,5)), hit_type);
			if ( (number(1,100) > shield->quality && number(1,100) > shield->item_wear) || shield->item_wear <= 0 )
				def_result = RESULT_SHIELD_BREAK;
		}
		else if ( attack_weapon && ((defense_weapon && attack_weapon->quality > defense_weapon->quality) || (shield && attack_weapon->quality > shield->quality)) && attack_weapon->quality > defense_weapon->quality && number(1,100) > attack_weapon->quality ) {
			if ( shield )
				damage_to_obj (attack_weapon, number(1,MAX(damage,5)), 3);
			else
				damage_to_obj (attack_weapon, number(1,MAX(damage,5)), defense_weapon->o.weapon.hit_type);
			if ( (number(1,100) > attack_weapon->quality && number(1,100) > attack_weapon->item_wear) || attack_weapon->item_wear <= 0 )
				off_result = RESULT_WEAPON_BREAK;
		}
	}

	if ( (off_result == RESULT_HIT1 || off_result == RESULT_HIT2 || off_result == RESULT_HIT3 || off_result == RESULT_HIT4) &&
		attack_weapon && (eq1 || eq2) ) {
		if ( attack_weapon && eq1 && eq1->o.od.value[0] > 2 && attack_weapon->quality <= eq1->quality && number (1,100) > attack_weapon->quality ) {
			damage_to_obj (attack_weapon, number(1,MAX(damage,5)), 3);
			if ( (number(1,100) > attack_weapon->quality && number(1,100) > attack_weapon->item_wear) || attack_weapon->item_wear <= 0 ) {
				off_result = RESULT_WEAPON_BREAK;
				def_result = RESULT_ANY;
			}
		}
		else if ( attack_weapon && eq2 && eq2->o.od.value[0] > 2 && attack_weapon->quality <= eq2->quality && number (1,100) > attack_weapon->quality ) {
			damage_to_obj (attack_weapon, number(1,MAX(damage,5)), 3);
			if ( (number(1,100) > attack_weapon->quality && number(1,100) > attack_weapon->item_wear) || attack_weapon->item_wear <= 0 ) {
				off_result = RESULT_WEAPON_BREAK;
				def_result = RESULT_ANY;
			}
		}
		else if ( attack_weapon && eq1 && number (1,100) > eq1->quality ) {
			if ( GET_ITEM_TYPE (eq1) == ITEM_ARMOR )
				damage_to_obj (eq1, number(1,MAX(damage,5)), hit_type);
			else
				damage_to_obj (eq1, number(1,MAX(damage,5)), hit_type);
			if ( (number(1,100) > eq1->quality && number(1,100) > eq1->item_wear) || eq1->item_wear <= 0 )
				broken_eq = eq1;
		}
		else if ( attack_weapon && eq2 && number (1,100) > eq2->quality ) {
			if ( GET_ITEM_TYPE (eq2) == ITEM_ARMOR )
				damage_to_obj (eq2, number(1,MAX(damage,5)), hit_type);
			else
				damage_to_obj (eq2, number(1,MAX(damage,5)), hit_type);
			if ( number(1,100) > eq2->quality && number(1,100) > eq2->item_wear )
				broken_eq = eq2;
		}
		else if ( attack_weapon && eq1 && eq1->o.od.value[0] > 2 && attack_weapon->quality > eq1->quality && number (1,100) > attack_weapon->quality ) {
			damage_to_obj (attack_weapon, number(1,MAX(damage,5)), 3);
			if ( (number(1,100) > attack_weapon->quality && number(1,100) > attack_weapon->item_wear) || attack_weapon->item_wear <= 0 ) {
				off_result = RESULT_WEAPON_BREAK;
				def_result = RESULT_ANY;
			}
		}
		else if ( attack_weapon && eq2 && eq2->o.od.value[0] > 2 && attack_weapon->quality > eq2->quality && number (1,100) > attack_weapon->quality ) {
			damage_to_obj (attack_weapon, number(1,MAX(damage,5)), 3);
			if ( (number(1,100) > attack_weapon->quality && number(1,100) > attack_weapon->item_wear) || attack_weapon->item_wear <= 0 ) {
				off_result = RESULT_WEAPON_BREAK;
				def_result = RESULT_ANY;
			}
		}
	}

	if ( IS_SET (tar->flags, FLAG_COMPETE) ) {
		if ( attack_weapon )
			return wound_to_char (tar, loc, damage, attack_weapon->o.weapon.hit_type, 0, 0, 0);
		else
			return wound_to_char (tar, loc, damage, src->nat_attack_type, 0, 0, 0);
	}
        combat_results (src,
                        tar,
                        attack_weapon,
                        defense_weapon,
						broken_eq,
                        damage,
                        loc,
                        off_result,
                        def_result,
                        attack_num,
                        fd,
                        off_success,
                        def_success);

        snprintf (AD, MAX_STRING_LENGTH, "---------------------------------------\n");

        for ( dch = src->room->people; dch; dch = dch->next_in_room )
                if ( IS_SET (dch->debug_mode, DEBUG_FIGHT) )
                        send_to_char (fd, dch);

	if ( tar->deleted )
		return 1;
	else {
		if ( IS_RIDER (tar) ) {

			mount = tar->mount;
/*
			if ( mount && (mount->skills [SKILL_RIDE] < 33 ||
				 (mount->skills [SKILL_RIDE] < 66 &&
				  !skill_use (mount, SKILL_RIDE, 0))) ) {
				dump_rider (tar, FALSE);
				flee_attempt (mount);
			}
*/
		}

		return 0;
	}
}

void combat_msg_substitute (char *msg, char *template, CHAR_DATA *src,
							CHAR_DATA *tar, OBJ_DATA *attack_weapon,
						    OBJ_DATA *defense_weapon, char *location,
							int damage)
{
	int		aw_type = 6;
	char	loc[MAX_STRING_LENGTH] = {'\0'};
	char	*temp_arg = NULL;
	
	if ( attack_weapon )
		aw_type = attack_weapon->o.weapon.hit_type;

	*msg = '\0';

	while ( *template ) {

		if ( *template != '#' ) {
			*msg = *template;
			template++;
			msg++;
			*msg = '\0';
		}

		else {
			switch ( template [1] ) {
			case 'S':
				if ( aw_type == 6 )
					strcat (msg, attack_names_plural [src->nat_attack_type]);
				else
					strcat (msg, wtype2 [aw_type * 2 + number (0, 1)]);
				break;
			case 's':
				if ( aw_type == 6 )
					strcat (msg, attack_names [src->nat_attack_type]);
				else
					strcat (msg, wtype [aw_type * 2 + number (0, 1)]);
				break;
			case 'O':
				if ( !attack_weapon )
					strcat (msg, attack_part [src->nat_attack_type]);
				else{
					temp_arg = see_object_in(tar, attack_weapon);
					strcat (msg, temp_arg);
				}
				break;
			case 'o':
				if ( !defense_weapon )
					strcat (msg, "fist");
				else{
					temp_arg = see_object_in(src,defense_weapon); 
					strcat (msg, temp_arg);
				}	
				break;
			case 'L': 
				temp_arg = expand_wound_loc(location);
				snprintf (loc, MAX_STRING_LENGTH, "%s", temp_arg);
				strcat (msg, loc);
				break;
			case 'C':
				strcat (msg, crithits [aw_type * 2 + number (0, 1)]);
				break;
			case 'c': 
				strcat (msg, crithit [aw_type * 2 + number (0, 1)]);
				break;
			case 'B': 
				strcat (msg, break_def [aw_type * 2 + 1]);
				break;
			case 'b': 
				strcat (msg, break_def [aw_type * 2]);
				break;
			case 'D': 
				temp_arg = get_dam_word (damage);
				strcat (msg, temp_arg);
				break;
			case 'R': 
				strcat (msg, "\n\r");
				break;
			default:
				*msg = *template;		/* Not a variable */
				msg [1] = '\0';
				template--;				/* Work around for advance 2 chars */
				break;
         	}

			msg = &msg [strlen (msg)];

			template = &template [2];		/* Advance two characters */
		}
	}
}

void combat_results (CHAR_DATA *src, CHAR_DATA *tar, OBJ_DATA *attack_weapon,
					 OBJ_DATA *defense_weapon, OBJ_DATA *broken_eq, int damage, char *location,
					 int off_result, int def_result, int attack_num,
					 char *fd, int off_success, int def_success)
{
	int					attack_delay = 0;
	int					i = 0;
	int					j = 0;
	int					skill = 0;
	int					delay_modifier = 0;
	int					hit_type = 0;
	int					table = 0;
	int					current_sum = 0;
	int					best_sum = 0;
	AFFECTED_TYPE		*invulnerability = NULL;
	COMBAT_MSG_DATA		*best_cm = NULL;
	COMBAT_MSG_DATA		*tcm = NULL;
	CHAR_DATA			*tch = NULL;
	OBJ_DATA			*tobj = NULL;
	OBJ_DATA			*temp_obj = NULL;
	char				msg1 [MAX_STRING_LENGTH] = {'\0'};
	char				msg2 [MAX_STRING_LENGTH] = {'\0'};
	char				msg3 [MAX_STRING_LENGTH] = {'\0'};
	char				buf [MAX_STRING_LENGTH] = {'\0'};
	char				log_message [MAX_STRING_LENGTH] = {'\0'};
	char				*temp_arg = NULL;

	*log_message = '\0';

	if ( tar ) {
		snprintf (log_message, MAX_STRING_LENGTH, "by %s", src->short_descr);
		if ( IS_NPC (src) )
			snprintf (log_message + strlen (log_message), MAX_STRING_LENGTH, " (%d)",
						src->mob->virtual);
		else
			snprintf (log_message + strlen (log_message), MAX_STRING_LENGTH, " (PC %s)",
						src->tname);
	}

	if ( attack_weapon )
		snprintf (log_message + strlen (log_message), MAX_STRING_LENGTH, " w/ %s (%d)",
				attack_weapon->short_description, attack_weapon->virtual);

	if ( (off_result < RESULT_HIT || off_result > RESULT_HIT4) &&
		 !number (0, 1) ) {

		skill = SKILL_BRAWLING;

		if ( attack_weapon )
			skill = attack_weapon->o.weapon.use_skill;

		if ( attack_num == 1 )
			skill_use (src, skill, 0);

		else if ( number (0, 1) ) {
			if ( number (0, 1) )
				skill_use (src, SKILL_DUAL, 0);
			else
				skill_use (src, skill, 0);
		}

		fix_offense (src);
	}

	if ( off_result >= RESULT_HIT && off_result <= RESULT_HIT4 &&
		 !number (0, 1) ) {

		if ( GET_POS (tar) == STAND || GET_POS (tar) == FIGHT ) {

			if ( !defense_weapon )
				skill = SKILL_DODGE;
			else if ( defense_weapon->obj_flags.type_flag == ITEM_WEAPON )
				skill = SKILL_PARRY;
			else if ( defense_weapon->obj_flags.type_flag == ITEM_SHIELD )
				skill = SKILL_BLOCK;
			else {
				skill = SKILL_PARRY;
			}

			skill_use (tar, skill, 0);

			fix_offense (tar);
		}
	}


	if ( tar->fight_mode == 0 &&		/* frantic mode */
		 (GET_POS (tar) == STAND || GET_POS (tar) == FIGHT) )
		table = 'F';

	else if ( GET_POS (tar) != STAND && GET_POS (tar) != FIGHT &&
		 tar->fight_mode != 0 )
		table = 'I';		/* Ignore */

	else if ( !defense_weapon )
		table = 'D';		/* Dodge */

	else if ( defense_weapon->obj_flags.type_flag == ITEM_SHIELD )
		table = 'B';		/* Block */

	else
		table = 'P';		/* Parry */

	for ( tcm = cm_list; tcm; tcm = tcm->next ) {

		if ( off_result != tcm->off_result )
			continue;

		if ( tcm->table != '*' && tcm->table != table )
			continue;

		if ( tcm->def_result != RESULT_ANY && tcm->def_result != def_result )
			continue;

		if ( !best_cm ) {
			best_cm = tcm;
			continue;
		}

		/* Hierarchy                */
		/*		x any * msg			*/
		/*		x any t msg			*/
		/*		x y   * msg			*/
		/*		x y   t msg			*/

		current_sum = 0;
		if ( best_cm->def_result != RESULT_ANY )
			current_sum += 2;

		if ( best_cm->table != '*' )
			current_sum += 1;

		if ( current_sum == 3 )
			break;

		best_sum = 0;

		if ( tcm->def_result != RESULT_ANY )
			best_sum += 2;

		if ( tcm->table != '*' )
			best_sum += 1;

		if ( current_sum < best_sum )
			best_cm = tcm;
	}

	combat_msg_substitute (msg1, best_cm->def_msg, src, tar, attack_weapon,
						   defense_weapon, location, damage);
	combat_msg_substitute (msg2, best_cm->off_msg, src, tar, attack_weapon,
						   defense_weapon, location, damage);
	combat_msg_substitute (msg3, best_cm->other_msg, src, tar, attack_weapon,
						   defense_weapon, location, damage);

		/* Oh wait, vehicles get a generic message */

	if ( IS_SET (tar->act, ACT_VEHICLE) ) {
		if ( attack_weapon ) {
			act ("You attack $N with your $o.",
					FALSE, src, attack_weapon, tar, TO_CHAR);
			act ("$n attacks you with his $o.",
					FALSE, src, attack_weapon, tar, TO_VICT);
			act ("$n attacks $N with $s $o.",
					FALSE, src, attack_weapon, tar, TO_NOTVICT);
		} else {
			act ("You kick at $N, trying to destroy it.",
					FALSE, src, 0, tar, TO_CHAR);
			act ("$n kicks at you, trying to break you.",
					FALSE, src, 0, tar, TO_VICT);
			act ("$n kicks at $N, trying to break it.",
					FALSE, src, 0, tar, TO_NOTVICT);
		}
	} else {
		act (msg1, FALSE, tar, attack_weapon, src, TO_CHAR | TO_ACT_FORMAT | TO_ACT_COMBAT);
		act (msg2, FALSE, tar, attack_weapon, src, TO_VICT | TO_ACT_FORMAT | TO_ACT_COMBAT);
		act (msg3, FALSE, tar, attack_weapon, src, TO_NOTVICT | TO_ACT_FORMAT | TO_ACT_COMBAT);
	}

		/* Make sure invulnerability is set last in the IF clause below. */

	if ( damage &&
		 attack_weapon &&
		 !IS_SET (attack_weapon->obj_flags.extra_flags, ITEM_MAGIC) &&
		 (invulnerability = get_affect (tar, MAGIC_AFFECT_INVULNERABILITY)) ) {
		act ("$n appears undamaged!", FALSE, tar, 0, 0, TO_ROOM);
		act ("$n's $o didn't wound you.",
					FALSE, src, attack_weapon, tar, TO_VICT);
	}

	if ( damage ) {

		if ( attack_weapon )
			hit_type = attack_weapon->o.weapon.hit_type;
		else
			hit_type = 6;		/* natural attack */

		if ( off_result != RESULT_HIT  && off_result != RESULT_HIT1 &&
			 off_result != RESULT_HIT2 && off_result != RESULT_HIT3 &&
			 off_result != RESULT_HIT4 )
			system_log ("Damage result without a HIT.", TRUE);
	}

	else if ( off_result == RESULT_STUMBLE ) {
		GET_POS (src) = SIT;
		add_second_affect (SPA_STAND, 8, src, NULL, NULL, 0);

		if ( IS_SET (tar->flags, FLAG_FLEE) )
			flee_attempt (tar);
	}

	else if ( off_result == RESULT_FUMBLE ) {
		if ( (tobj = get_equip (src, WEAR_PRIM)) == attack_weapon && !IS_SET(src->flags, FLAG_COMPETE) ){
			temp_obj = unequip_char (src, WEAR_PRIM);
			obj_to_room (temp_obj, src->in_room);
		}
		
		else if ( (tobj = get_equip (src, WEAR_SEC)) == attack_weapon && !IS_SET(src->flags, FLAG_COMPETE) ){
			temp_obj = unequip_char (src, WEAR_SEC);
			obj_to_room (temp_obj, src->in_room);
		}
		
		else if ( (tobj = get_equip (src, WEAR_BOTH)) == attack_weapon && !IS_SET(src->flags, FLAG_COMPETE) ){
			temp_obj = unequip_char (src, WEAR_BOTH);
			obj_to_room (temp_obj, src->in_room);
		}
		
		else if ( !IS_SET (src->flags, FLAG_COMPETE) ){
			system_log("Disarm, but couldn't find weapons's hand. (attacker)", TRUE);
		}

		if ( !IS_SET (src->flags, FLAG_COMPETE) ) {
			if ( attack_weapon == src->right_hand )
				src->right_hand = NULL;
			else if ( attack_weapon == src->left_hand )
				src->left_hand = NULL;
			add_second_affect (SPA_GET_OBJ, 6, src, attack_weapon, "", 0);
			add_second_affect (SPA_WEAR_OBJ, 10, src, attack_weapon, "", 0);
			SET_BIT (attack_weapon->tmp_flags, SPA_DROPPED);
		}
	}

	else if ( off_result == RESULT_WEAPON_BREAK ) {
		if ( get_equip (src, WEAR_PRIM) == attack_weapon ){
			temp_obj = unequip_char (src, WEAR_PRIM);
			extract_obj (temp_obj);
		}
		
		else if ( get_equip (src, WEAR_SEC) == attack_weapon ){
			temp_obj =  unequip_char (src, WEAR_SEC);
			extract_obj (temp_obj);
		}
		
		else if ( get_equip (src, WEAR_BOTH) == attack_weapon ){
			temp_obj = unequip_char (src, WEAR_BOTH);
			extract_obj (temp_obj);
		}
		
		else{
			system_log("Weapon Break, but couldn't find weapons's hand. (attacker)", TRUE);
	}
		if ( attack_weapon == src->right_hand )
			src->right_hand = NULL;
		else if ( attack_weapon == src->left_hand )
			src->left_hand = NULL;
	}

	else if ( off_result == RESULT_ADV )
		system_log("How could offence get RESULT_ADV?", TRUE);

	if ( def_result == RESULT_FUMBLE ) {
		if ( get_equip (tar, WEAR_PRIM) == defense_weapon && !IS_SET (tar->flags, FLAG_COMPETE) ){
			temp_obj = unequip_char (tar, WEAR_PRIM);
			obj_to_room (temp_obj, tar->in_room);
		}
		
		else if ( get_equip (tar, WEAR_SEC) == defense_weapon && !IS_SET (tar->flags, FLAG_COMPETE) ){
			temp_obj = unequip_char (tar, WEAR_SEC);
			obj_to_room (temp_obj, tar->in_room);
		}
		
		else if ( get_equip (tar, WEAR_BOTH) == defense_weapon && !IS_SET (tar->flags, FLAG_COMPETE) ){
			temp_obj = unequip_char (tar, WEAR_BOTH);
			obj_to_room (temp_obj, tar->in_room);
		}
		
		else if ( get_equip (tar, WEAR_SHIELD) == defense_weapon && !IS_SET (tar->flags, FLAG_COMPETE) ){
			temp_obj = unequip_char (tar, WEAR_SHIELD);
			obj_to_room (temp_obj, tar->in_room);
		}
		
		else if ( !IS_SET (tar->flags, FLAG_COMPETE) ){
			system_log("Disarm, but couldn't find weapons's hand. (defender)", TRUE);
		}
		
		if ( !IS_SET (tar->flags, FLAG_COMPETE) ) {
			if ( defense_weapon == tar->right_hand )
				tar->right_hand = NULL;
			else if ( defense_weapon == tar->left_hand )
				tar->left_hand = NULL;
			add_second_affect (SPA_GET_OBJ, 6, tar, defense_weapon, "", 0);
			add_second_affect (SPA_WEAR_OBJ, 10, tar, defense_weapon, "", 0);
			SET_BIT (defense_weapon->tmp_flags, SPA_DROPPED);
		}
	}

	else if ( def_result == RESULT_WEAPON_BREAK ||
			  def_result == RESULT_SHIELD_BREAK ) {
		if ( get_equip (tar, WEAR_PRIM) == defense_weapon ){
			temp_obj = unequip_char (tar, WEAR_PRIM);
			extract_obj (temp_obj);
		}
		
		else if ( get_equip (tar, WEAR_SEC) == defense_weapon ){
			temp_obj = unequip_char (tar, WEAR_SEC);
			extract_obj (temp_obj);
		}
		
		else if ( get_equip (tar, WEAR_BOTH) == defense_weapon ){
			temp_obj = unequip_char (tar, WEAR_BOTH);
			extract_obj (temp_obj);
		}
		
		else if ( get_equip (tar, WEAR_SHIELD) == defense_weapon ){
			temp_obj = unequip_char (tar, WEAR_SHIELD);
			extract_obj (temp_obj);
		}
		
		else{
			system_log("BREAK, but couldn't find weapons's hand. (defender)", TRUE);
		}

		if ( defense_weapon == tar->right_hand )
			tar->right_hand = NULL;
		else if ( defense_weapon == tar->left_hand )
			tar->left_hand = NULL;
	}

	else if ( def_result == RESULT_STUMBLE ) {
		if ( GET_POS (tar) == FIGHT || GET_POS (tar) == STAND ) {
			GET_POS (tar) = SIT;
			add_second_affect (SPA_STAND, 8, tar, NULL, NULL, 0);
		} else
			def_result = RESULT_NONE;
	}

	if ( attack_weapon )
		hit_type = attack_weapon->o.weapon.hit_type;
	else {
		if ( src->nat_attack_type == 0 )
			hit_type = 9;
		else if ( src->nat_attack_type == 1 || src->nat_attack_type == 3 )
			hit_type = 7;
		else if ( src->nat_attack_type == 2 )
			hit_type = 8;
	}

	if ( broken_eq ) {
		temp_arg = obj_short_desc(broken_eq);
		snprintf (buf, MAX_STRING_LENGTH,  "#2%s#0 is destroyed by the blow.", temp_arg);
		buf[2] = toupper(buf[2]);
		act (buf, FALSE, tar, 0, 0, TO_CHAR | TO_ACT_FORMAT | TO_ACT_COMBAT);
		act (buf, FALSE, tar, 0, 0, TO_ROOM | TO_ACT_FORMAT | TO_ACT_COMBAT);
		extract_obj (broken_eq);
	}

	tar->delay_ch = src;
	if ( attack_weapon )
		tar->delay_info1 = attack_weapon->virtual;

	if ( !invulnerability && damage && wound_to_char (tar, location, damage, hit_type, 0, 0, 0) ) {
		def_result = RESULT_DEAD;
	}

	else {

		if ( tar->fighting && IS_SET (tar->act, ACT_VEHICLE) )
			stop_fighting (tar);

		if ( !tar->fighting && !IS_SET (tar->act, ACT_VEHICLE) ) {
			set_fighting (tar, src);
			if ( !AWAKE (tar) && GET_POS(tar) != POSITION_UNCONSCIOUS )
				do_wake (tar, "", 0);
			add_second_affect (SPA_STAND, 8, tar, NULL, NULL, 0);
		}

		if ( !src->fighting )
			set_fighting (src, tar);

		if ( (GET_POS(tar) == POSITION_STUNNED || GET_POS(tar) == POSITION_UNCONSCIOUS)
			 && !IS_SET (src->flags, FLAG_KILL) ) {

			if ( src->fighting )
				stop_fighting (src);

			for ( tch = src->room->people; tch; tch = tch->next_in_room )
				if ( tch->fighting == src && tch != src && GET_HIT (tch) > 0 ) {
					set_fighting (src, tch);
					break;
				}
		}
	}

	tar->delay_ch = NULL;
	tar->delay_info1 = 0;


	if ( def_result == RESULT_PARRY || def_result == RESULT_BLOCK ) {
		if ( get_equip (tar, WEAR_PRIM) == defense_weapon ||
			 get_equip (tar, WEAR_BOTH) == defense_weapon )
			tar->primary_delay++;
		else if ( get_equip (tar, WEAR_SEC) == defense_weapon )
			tar->secondary_delay++;
	}

	else if ( def_result == RESULT_ADV ) {
		tar->primary_delay = 0;
		tar->secondary_delay = 0;
	}

	attack_delay = 0;

				/* Weapon delay / natural delay / calculated delay */

	if ( attack_weapon ) {
		attack_delay += use_table [attack_weapon->o.weapon.use_skill].delay +
						attack_weapon->o.weapon.delay;
		attack_delay += attack_weapon->o.od.value[5];
		if ( (attack_weapon->o.od.value[3] == SKILL_MEDIUM_EDGE || attack_weapon->o.od.value[3] == SKILL_MEDIUM_BLUNT ||
			attack_weapon->o.od.value[3] == SKILL_MEDIUM_PIERCE) && attack_weapon->location == WEAR_BOTH ) 
			attack_delay += 8;
	}

	else if ( IS_NPC (src) )
		attack_delay += src->natural_delay;
	else
		attack_delay += 20 - GET_DEX (src) + use_table [SKILL_BRAWLING].delay;

	snprintf (AD, MAX_STRING_LENGTH, "AttDel %d ", attack_delay);

				/* str+dex delay adjustment */

	delay_modifier = 100;

	delay_modifier = delay_modifier -
					 (GET_STR (src) + GET_DEX (src) - 15);

	snprintf (AD, MAX_STRING_LENGTH, "STRDEXadj %d%% ", delay_modifier);

	attack_delay = attack_delay * delay_modifier / 100;

				/* Fatigue adjustment */

	if ( GET_MAX_MOVE (src) > 0 )
		j = GET_MOVE (src) * 100 / GET_MAX_MOVE (src);
	else
		j = 0;

	if ( j > 100 )
		j = 100;

	for ( i = 0; j > fatigue [i].percent; i++ )
		;

	if ( i == 0 )
		attack_delay += 8;		/* Completely Exhausted */
	else if ( i == 1 )
		attack_delay += 4;		/* Exhausted */

	snprintf (AD, MAX_STRING_LENGTH, "Fatigue %d ", attack_delay);

				/* Fightmode delay adjustment */

	attack_delay += fight_tab [src->fight_mode].delay;

	snprintf (AD, MAX_STRING_LENGTH, "FM %d = %d [%d] (2)=%d\n", attack_delay, attack_delay,
				attack_num, src->secondary_delay);

	if ( attack_num == 1 )
		src->primary_delay = attack_delay;
	else
		src->secondary_delay = attack_delay;
}

void figure_damage (CHAR_DATA *src, CHAR_DATA *tar, OBJ_DATA *attack_weapon,
					int off_result, int *damage, int *location)
{
	OBJ_DATA		*eq;
	char			buf [MAX_STRING_LENGTH] = {'\0'};
	int			body_type;
	int			wear_loc1;
	int			wear_loc2;
	int			i;
	float			dam = 0;
	AFFECTED_TYPE	*shock = NULL;
	AFFECTED_TYPE	*af;

	*damage = 0;

			/* Determine hit location */

	body_type = 0;

	i = number (1, 100);
	*location = -1;

	while ( i > 0 )
		i = i - body_tab [body_type] [++(*location)].percent;

	wear_loc1 = body_tab [body_type] [*location].wear_loc1;
	wear_loc2 = body_tab [body_type] [*location].wear_loc2;


			/* Assess automatic damage by NPCs */

	if ( IS_NPC (src) )
		dam += src->mob->damroll;

			/* For weapons, add weapon damage roll and affects */

	if ( attack_weapon ) {
		if ( attack_weapon->o.weapon.dice && attack_weapon->o.weapon.sides ) {
			if ( (attack_weapon->o.od.value[3] == SKILL_MEDIUM_EDGE || attack_weapon->o.od.value[3] == SKILL_MEDIUM_BLUNT ||
				attack_weapon->o.od.value[3] == SKILL_MEDIUM_PIERCE) && attack_weapon->location == WEAR_BOTH ) 
            			dam += dice (attack_weapon->o.weapon.dice, attack_weapon->o.weapon.sides+2);
            		else dam += dice (attack_weapon->o.weapon.dice, attack_weapon->o.weapon.sides);
		} else {
	            snprintf (buf, MAX_STRING_LENGTH,  "Ineffective weapon, vnum %d on mob %d room %d\n",
        	        attack_weapon->virtual, src->mob ? src->mob->virtual : -1, src->in_room);
			system_log (buf, TRUE);
		}

		for ( af = attack_weapon->xaffected; af; af = af->next ) {
			if ( af->a.spell.location == APPLY_DAMROLL )
				dam += af->a.spell.modifier;
		}
	}

			/* For NPCs with no weapons, add natural attack */

	else if ( IS_NPC (src) ) {

		if ( src->mob->damnodice * src->mob->damsizedice < 8 && shock )
			dam += dice (2, 4);
		else
			dam += dice (src->mob->damnodice, src->mob->damsizedice);
	}

			/* For bare handed PCs */

	else if ( shock )
		dam += dice (2, 4);
	else
		dam += number (0, 2);

			/* Subtract the armor protection at the hit location */

	eq = get_equip (tar, wear_loc1);

	if ( eq && eq->obj_flags.type_flag == ITEM_ARMOR )
		if ( attack_weapon || !shock )
			dam -= eq->o.armor.armor_value;

			/* Mobs will have marmor, which is natural armor */

	if ( attack_weapon || !shock )
		dam -= (tar->armor);

			/* Weapon vs armor */

	eq = get_equip (tar, wear_loc2);

	if ( attack_weapon && eq )
		dam += weapon_armor_table [attack_weapon->o.weapon.hit_type]
								  [eq->o.armor.armor_type];
	else if ( !attack_weapon && eq )
		dam += weapon_nat_attack_table [src->nat_attack_type]
								  [eq->o.armor.armor_type];

			/* Multiply by hit location multiplier */

	dam *= (body_tab [body_type] [*location].damage_mult*1.0) /
			    (body_tab [body_type] [*location].damage_div*1.0);

	/* Multiply in critical strike bonus */

	if ( off_result == RESULT_HIT || (off_result == RESULT_HIT && (!attack_weapon && src->nat_attack_type == 0)) )
		dam *= 1;
	else if ( off_result == RESULT_HIT1 )
		dam *= 1.3;
	else if ( off_result == RESULT_HIT2 )
		dam *= 1.5;
	else if ( off_result == RESULT_HIT3 || (off_result == RESULT_HIT && !attack_weapon) ) {
		dam += 2;
		dam *= 1.7;
	}
	else if ( off_result == RESULT_HIT4 ) {
		dam += 3;
		dam *= 2;
	}
	else {
		*damage = 0;
		return;
	}

			/* Subtract/add spell offsets */

	if ( (af = get_affect (tar, MAGIC_AFFECT_ARMOR)) )
		if ( attack_weapon || !shock )
			dam -= af->a.spell.modifier;

		/* Reduce damage by SANCTUARY or BLESS.  Note:  Not cumulative */

	if ( get_affect (tar, MAGIC_AFFECT_CURSE) && !get_affect (tar, MAGIC_AFFECT_BLESS) )
		dam += dam / 4 + 1;

	else if ( get_affect (tar, MAGIC_AFFECT_BLESS) &&
			  !get_affect (tar, MAGIC_AFFECT_CURSE) )
		dam = dam * 3 / 4;

	if ( attack_weapon || src->nat_attack_type > 0 )
		(float) (dam *= COMBAT_BRUTALITY);

	dam = (int)dam;

	if ( dam <= 0 )
		dam = number (0, 1);

	*damage = dam;
}

int weaken (CHAR_DATA *victim, int hits, int moves, char *log_msg)
{
	char		buf [MAX_STRING_LENGTH] = {'\0'};

	if ( hits == 0 && moves == 0 )
		return 0;

	if ( log_msg ) {
		snprintf (buf, MAX_STRING_LENGTH,  "%s (%dh/%dm)", log_msg, hits, moves);
		add_combat_log(victim, buf);
	}

	if ( !IS_MORTAL (victim) && !IS_NPC (victim) )
		return 0;

		/* If moves is negative, then we subtract excess moves from hits */

	moves = -moves;

	if ( GET_MOVE (victim) > moves )
		GET_MOVE (victim) -= moves;
	else
		GET_MOVE (victim) = 0;

	if ( GET_POS (victim) == POSITION_DEAD ) {

		if ( moves ) {
			act ("$n dies of exhaustion!", FALSE, victim, 0, 0, TO_ROOM);
			add_combat_log(victim, "Death by exhaustion");
		}

		die (victim);

		return 1;
	}

	return 0;
}

void subdue_resync (CHAR_DATA *ch)
{
	CHAR_DATA		*tch;

		/* ch needs someone else to subdue */

	if ( ch->fighting )
		stop_fighting (ch);

	for ( tch = ch->room->people; tch; tch = tch->next_in_room ) {

		if ( tch->fighting == ch ) {
			set_fighting (ch, tch);

			act ("You turn to confront $N.", FALSE, ch, 0, tch, TO_CHAR);
			act ("$n turns to confront $N.", FALSE, ch, 0, tch, TO_ROOM);
			act ("$N turns to confront you.", FALSE, tch, 0, ch, TO_CHAR);

			if ( !IS_SET (tch->flags, FLAG_SUBDUING) )
				REMOVE_BIT (ch->flags, FLAG_SUBDUING);
			break;
		}
	}

	if ( !ch->fighting )
		send_to_char ("You stop fighting.\n\r", ch);
}

void remove_subduer (CHAR_DATA *ch)
{
	CHAR_DATA		*tch;
	int				was_in_room;

	for ( tch = ch->room->people; tch == ch; )
		tch = tch->next_in_room;

	was_in_room = ch->in_room;

	char_from_room (ch);

	for ( ; tch; tch = tch->next_in_room )
		if ( tch->fighting == ch )
			subdue_resync (tch);

	char_to_room (ch, was_in_room);
}

void subdue_char (CHAR_DATA *ch, CHAR_DATA *victim)
{
	int				victim_was_room = 0;
	OBJ_DATA		*obj = NULL;
	OBJ_DATA		*temp_obj = NULL;
	AFFECTED_TYPE	*af = NULL;

	if ( ch->fighting )
		stop_fighting (ch);

	if ( victim->fighting )
		stop_fighting (victim);

	REMOVE_BIT (ch->flags, FLAG_SUBDUING);
	REMOVE_BIT (ch->flags, FLAG_SUBDUEE);
	REMOVE_BIT (victim->flags, FLAG_SUBDUING);
	REMOVE_BIT (victim->flags, FLAG_SUBDUER);

	SET_BIT (ch->flags, FLAG_SUBDUER);
	SET_BIT (victim->flags, FLAG_SUBDUEE);

	clear_moves (victim);
	clear_current_move (victim);

	ch->subdue = victim;
	victim->subdue = ch;

    if ( GET_POS(victim) < POSITION_STANDING ) {
	    act ("You fall upon your foe and get $M into a firm headlock.", FALSE, ch, 0, victim, TO_CHAR);
	    act ("$N falls upon you and gets you into a firm headlock.", FALSE, victim, 0, ch, TO_CHAR);
	    act ("$n falls upon $N.", FALSE, ch, 0, victim, TO_NOTVICT);
	    act ("You haul $N to $S feet.", FALSE, ch, 0, victim, TO_CHAR);
	    act ("$N hauls you to your feet.", FALSE, victim, 0, ch, TO_CHAR);
	    act ("$e hauls $M to $S feet in a firm headlock.", FALSE, ch, 0, victim, TO_NOTVICT);
        GET_POS(victim) = POSITION_STANDING;
    } else {
	    act ("You grapple $N and lock $M firmly in your grasp.", FALSE, ch, 0, victim, TO_CHAR);
	    act ("$N grapples you and locks you firmly in $S grasp!", FALSE, victim, 0, ch, TO_CHAR);
	    act ("$n grapples $N and locks $M firmly in $s grasp.", FALSE, ch, 0, victim, TO_NOTVICT);
    }
		/* Nobody is trying to subdue ch.  Lets stop or redirect subdue
           attempts against victim */

	victim_was_room = victim->in_room;

	char_from_room (victim);

	remove_subduer (ch);

	char_to_room (victim, victim_was_room);

	remove_subduer (victim);

	if ( ch->mob &&
		 IS_SET (ch->act, ACT_ENFORCER) &&
		 is_hooded (victim) ) {

		obj = get_equip (victim, WEAR_ABOUT);
		if ( obj ) {
			temp_obj = unequip_char (victim, WEAR_ABOUT);
			obj_to_char (temp_obj, victim);
			act ("$n removes your $p.", FALSE, ch, obj, victim, TO_VICT);
			act ("$n removes $N's $p.", FALSE, ch, obj, victim, TO_NOTVICT);
			act ("You remove $N's $p.", FALSE, ch, obj, victim, TO_CHAR);
		}
		
		obj = get_equip (victim, WEAR_HEAD);
		if ( obj ) {
			temp_obj = unequip_char (victim, WEAR_HEAD);
			obj_to_char (temp_obj, victim);
			act ("$n removes your $p.", FALSE, ch, obj, victim, TO_VICT);
			act ("$n removes $N's $p.", FALSE, ch, obj, victim, TO_NOTVICT);
			act ("You remove $N's $p.", FALSE, ch, obj, victim, TO_CHAR);
		}

		if ( (af = get_affect (victim, MAGIC_CRIM_HOODED + ch->room->zone)) )
			add_criminal_time (victim, ch->room->zone, af->a.spell.modifier);
	}
}


void perform_violence (void)
{
	CHAR_DATA	*ch;
	CHAR_DATA	*new_combat_list = NULL;

	for ( ch = combat_list; ch; ch = combat_next_dude ) {

		if ( ch->next_fighting && (!ch->next_fighting->fighting || !ch->next_fighting->room) )
			ch->next_fighting = ch->next_fighting->next_fighting;

		combat_next_dude = ch->next_fighting;

		if ( !ch->fighting || !ch->fighting->room )
			continue;

		if ( get_affect (ch, MAGIC_HIDDEN) ) {
			remove_affect_type (ch, MAGIC_HIDDEN);
			act ("$n reveals $mself.", TRUE, ch, 0, 0, TO_ROOM);
		}

	        if ( IS_NPC (ch) && !IS_SET (ch->flags, FLAG_FLEE) && (IS_SET (ch->flags, FLAG_AUTOFLEE) || morale_broken (ch))) {
			ch->speed = 4;
                	do_flee (ch, "", 0);
                	add_threat (ch, ch->fighting, 5);
			continue;
        	}

		if ( !ch->fighting ) {
			sigsegv(SIGSEGV);
		}

			/* Remove delays from both hands */

		ch->primary_delay -= pulse_violence;
		ch->secondary_delay -= pulse_violence;

		if ( ch->primary_delay < 0 )
			ch->primary_delay = 0;

		if ( ch->secondary_delay < 0 )
			ch->secondary_delay = 0;

			/* Stop fighting if player is physically incapable */

		if ( !AWAKE (ch) ||
			 ch->in_room != ch->fighting->in_room ||
			 get_affect (ch, MAGIC_AFFECT_PARALYSIS) ) {
			stop_fighting (ch);
			continue;
		}

			/* No combat if there are delays */

		if ( ch->primary_delay && ch->secondary_delay )
			continue;

		if ( GET_POS (ch) == STAND )
			GET_POS (ch) = FIGHT;

		if ( GET_POS (ch) != FIGHT )
			continue;

		if ( ch->mount && !ch->mount->fighting )
			set_fighting (ch->mount, ch->fighting);

		hit_char (ch, ch->fighting, 0);

		if ( combat_next_dude && combat_next_dude->deleted )
			system_log("Loss of combat_next_dude in fight.c: perform_violence.", TRUE);
	}

		/* Reverse the combat list */

	new_combat_list = combat_list;

	if ( combat_list ) {
		combat_list = combat_list->next_fighting;
		new_combat_list->next_fighting = NULL;
	}

	while ( combat_list ) {

		ch = combat_list;
		combat_list = combat_list->next_fighting;

		ch->next_fighting = new_combat_list;
		new_combat_list = ch;
	}

	combat_list = new_combat_list;
}

void do_stop (CHAR_DATA *ch, char *argument, int cmd)
{
	CHAR_DATA		*tch;
	AFFECTED_TYPE	*af;

	if ( is_mounted (ch) && ch->mount->moves )
		ch = ch->mount;

	if ( ch->moves ) {

		clear_moves (ch);
		clear_current_move (ch);

		send_to_char ("Movement commands cancelled.\n", ch);

		if ( is_mounted (ch) )
			send_to_char ("Movement commands cancelled.\n", ch->mount);

		return;
	}
  
	if ( (af = is_crafting(ch)) ) {
        	act ("$n stops doing $s craft.", FALSE, ch, 0, 0, TO_ROOM);
                send_to_char ("You stop doing your craft.\n", ch);
                af->a.craft->timer = 0;
                return;
	}

	if ( (af = get_affect (ch, MAGIC_TOLL)) ) {

		if ( af->a.toll.room_num == ch->in_room ) {
			stop_tolls (ch);
			return;
		}

			/* Toll affect should have been there...continue with stop */

		stop_tolls (ch);
	}

	if ( clear_current_move (ch) )
		return;

	if ( ch->delay || ch->aim ) {
		break_delay (ch);
		return;
	}

	if ( GET_TRUST (ch) ) {
		for ( tch = ch->room->people; tch; tch = tch->next_in_room ) {
			if ( tch->fighting ) {
				if ( tch != ch ) {
					act ("You immediately obey $N's command to stop fighting!",
						  TRUE, tch, 0, ch, TO_CHAR);
					act ("$N obeys.", FALSE, ch, 0, tch, TO_CHAR);
				}
				forget (tch, tch->fighting);
				stop_fighting (tch);
			}
			if ( IS_NPC (tch) ) {
				tch->attackers = NULL;
				tch->threats = NULL;
			}
		}
		send_to_char ("All combat in the room has been stopped.\n", ch);
		return;
	}
	
	if ( !ch->fighting ) {
		send_to_char ("You're not fighting anyone.\n\r", ch);
		return;
	}

	if ( ch->fighting->fighting != ch || GET_FLAG (ch->fighting, FLAG_FLEE) ) {
		send_to_char ("You stop fighting.\n\r", ch);
		stop_fighting (ch);
		return;
	}

	SET_BIT (ch->act, PLR_STOP);		/* Same as ACT_STOP */

	if ( IS_SET (ch->fighting->act, PLR_STOP) ) {

		send_to_char ("Your opponent agrees.\n\r", ch);

		act ("Both you and $N stop fighting.\n\r",
			FALSE, ch->fighting, 0, ch, TO_CHAR);

		if ( IS_NPC (ch->fighting) ) {
			remove_threat (ch->fighting, ch);
			remove_attacker (ch->fighting, ch);
		}
		if ( IS_NPC (ch) ) {
			remove_threat (ch, ch->fighting);
			remove_attacker (ch, ch->fighting);
		}

		REMOVE_BIT (ch->act, PLR_STOP);
		REMOVE_BIT (ch->fighting->act, PLR_STOP);

		if ( ch->fighting->fighting )
			stop_fighting (ch->fighting);

		if ( ch->fighting )
			stop_fighting (ch);

		return;
	}

	send_to_char ("You motion for a truce to your opponent.\n\r", ch);
	act ("$N motions for a truce.", FALSE, ch->fighting, 0, ch, TO_CHAR);
	act ("$N motions for a truce with $n.",
			FALSE, ch->fighting, 0, ch, TO_ROOM);
}

void do_release (CHAR_DATA *ch, char *argument, int cmd)
{
	char		buf [MAX_STRING_LENGTH] = {'\0'};
	CHAR_DATA	*target;

	if ( !IS_SUBDUER (ch) ) {

		if ( !IS_SET (ch->flags, FLAG_SUBDUER) ) {
			send_to_char ("You have no prisoner in tow.", ch);
			return;
		}

		REMOVE_BIT (ch->flags, FLAG_SUBDUER);

		if ( ch->subdue &&
			 is_he_somewhere (ch->subdue) &&
			 ch->subdue->subdue == ch ) {
			REMOVE_BIT (ch->subdue->flags, FLAG_SUBDUER);
			REMOVE_BIT (ch->subdue->flags, FLAG_SUBDUEE);
			send_to_char ("You are no longer a prisoner.\n\r", ch->subdue);
			send_to_char ("Ok.\n\r", ch);
			ch->subdue->subdue = NULL;
			return;
		}

		ch->subdue = NULL;
		send_to_char ("Alright.\n\r", ch);
		return;
	}

	argument = one_argument (argument, buf);

	if ( *buf && name_is (buf, GET_NAMES (ch->subdue)) )
		argument = one_argument (argument, buf);

	if ( !*buf ) {
		release_prisoner (ch, NULL);
		return;
	}

	if ( !str_cmp (buf, "to") ) {

		argument = one_argument (argument, buf);

		if ( !*buf ) {
			send_to_char ("Who do you want to release your prisoner to?\n\r", ch);
			return;
		}
	}

	if ( !(target = get_char_room_vis (ch, buf)) ) {
		send_to_char ("There is no such person here to receive your prisoner.\n\r", ch);
		return;
	}

	release_prisoner (ch, target);
}

int release_prisoner (CHAR_DATA *ch, CHAR_DATA *target)
{
	int		quiet = 0;

	if ( !target ) {

		if ( !IS_SUBDUER (ch) ) {
			REMOVE_BIT (ch->flags, FLAG_SUBDUER);
			act ("You have no prisoner.", FALSE, ch, 0, 0, TO_CHAR);
			return 0;
		}

		act ("$N releases you.", FALSE, ch->subdue, 0, ch, TO_CHAR);
		act ("You release $N.", FALSE, ch, 0, ch->subdue, TO_CHAR);
		act ("$n releases $N.", FALSE, ch, 0, ch->subdue, TO_NOTVICT);

		REMOVE_BIT (ch->flags, FLAG_SUBDUER);
		REMOVE_BIT (ch->subdue->flags, FLAG_SUBDUEE);

		ch->subdue->subdue = NULL;
		ch->subdue = NULL;

		return 1;
	}

	if ( IS_SUBDUER (target) ) {
		act ("$N has $S arms full with another prisoner.",
						FALSE, ch, 0, target, TO_CHAR);
		return 0;
	}

	if ( IS_SUBDUEE (target) ) {
		act ("$N is a prisoner himself!", FALSE, ch, 0, target, TO_CHAR);
		return 0;
	}

	if ( GET_POS (target) != STAND ) {
		act ("$N cannot accept your prisoner at the moment.",
						FALSE, ch, 0, target, TO_CHAR);
		return 0;
	}

	if ( !real_skill (target, SKILL_SUBDUE) ) {
		act ("$N isn't able to take care of your prisoner.",
						FALSE, ch, 0, target, TO_CHAR);
		return 0;
	}

	target->subdue = ch->subdue;
	target->subdue->subdue = target;
	ch->subdue = NULL;

	SET_BIT (target->flags, FLAG_SUBDUER);
	REMOVE_BIT (ch->flags, FLAG_SUBDUER);

	act ("You release your prisoner to $N.", FALSE, ch, 0, target, TO_CHAR);
	act ("$N releases his prisoner to you.", FALSE, target, 0, ch, TO_CHAR);

	if ( IS_SET (target->subdue->act, PLR_QUIET) )
		quiet = 1;
	else
		SET_BIT (target->subdue->act, PLR_QUIET);

	act ("$n releases his prisoner to $N.", FALSE, ch, 0, target, TO_NOTVICT);

	if ( !quiet )
		REMOVE_BIT (target->subdue->act, PLR_QUIET);

	act ("You are tossed into the arms of $N.", FALSE, target->subdue, 0, target, TO_CHAR);

	trigger (ch, "", TRIG_PRISONER);

	return 1;
}

/*int retaliate (CHAR_DATA *ch, CHAR_DATA *subject)
{
	if (!IS_NPC(ch))
        return;

    if (IS_SET(ch->act, ACT_WIMPY)) {
        s
	    return 0;

    ;
}*/

int flee_room (CHAR_DATA *ch)
{
	ROOM_DATA		*room_exit;
	ROOM_DATA		*room;
	int				room_exit_virt;
	int				exit_tab [6];
	int				zone;
	int				num_exits = 0;
	int				to_exit;
	int				i;
	char			log_msg [MAX_STRING_LENGTH] = {'\0'};

	room = vtor (ch->in_room);
	zone = room->zone;

    if ( GET_POS (ch) == POSITION_FIGHTING ) {
        do_flee (ch,"",0);
        return 0;
    }

    if ( GET_POS (ch) < POSITION_RESTING )
        return 0;

    if ( GET_POS (ch) < POSITION_STANDING )
        do_stand (ch,"",0);

  	if ( ch->desc && ch->desc->original )
    	return 0;

	for ( i = 0; i < 6; i++ ) {

		if ( !CAN_GO (ch, i) )
			continue;

		room_exit = vtor (PASSAGE (ch, i)->to_room);

		if ( !room_exit ) {
			snprintf (log_msg, MAX_STRING_LENGTH, "ERROR:  Room %d, dir %d doesn't go to %d",
				ch->in_room, i, PASSAGE (ch, i)->to_room);

			system_log(log_msg, TRUE);
			continue;
		}
        exit_tab [num_exits++] = i;
	}

	if ( num_exits == 0 )
		return 0;

	to_exit = number (1, num_exits) - 1;

	if ( vtor (PASSAGE (ch, exit_tab [to_exit])->to_room)->virtual ==
				ch->last_room )
		to_exit = (to_exit + 1) % num_exits;

	room_exit_virt = vtor (PASSAGE (ch, exit_tab [to_exit])->to_room)->virtual;

	ch->last_room = room_exit_virt;

	do_move (ch, "", exit_tab [to_exit]);

	return 1;
}

void do_subdue (CHAR_DATA *ch, char *argument, int cmd)
{
	char			buf [MAX_STRING_LENGTH] = {'\0'};
	CHAR_DATA		*target = NULL;
	char			*temp_arg = NULL;
	
	if ( IS_SET (ch->room->room_flags, OOC) && IS_MORTAL(ch) ) {
		send_to_char ("You can't do that in an OOC area.\n", ch);
		return;
	}

	if ( !db_race_table [ch->race].can_subdue ) {
		snprintf (buf, MAX_STRING_LENGTH,  "A %s cannot subdue.\n",
						db_race_table [ch->race].name);
		send_to_char (buf, ch);
		return;
	}

    	argument = one_argument (argument, buf);

    	if (!*buf && !ch->fighting) {
        	send_to_char ("Subdue whom?\n\r",ch);
        	return;
    	}

	if ( ch->subdue && !is_he_here (ch, ch->subdue, 0) )
		ch->subdue = NULL;

	if ( ch->fighting && !is_he_here (ch, ch->fighting, 0) )
		stop_fighting (ch);

    	if ( ch->fighting && (!*buf || !name_is (buf, GET_NAMES(ch->fighting))))
        	target = ch->fighting;

	else if ( !(target = get_char_room_vis (ch, buf)) ) {
		send_to_char ("You don't see them here.\n\r", ch);
		return;
	}

    	else if (ch == target) {
        	send_to_char("Be serious.\n\r",ch);
        	return;
    	}
/*
    	else if ( !db_race_table [target->race].can_subdue ) {
		act ("$N cannot be subdued.", FALSE, ch, 0, target, TO_CHAR);
		return;
	}
*/
    	else if (ch->subdue && name_is (buf, GET_NAMES(ch->subdue))) {
        	send_to_char("You already have them subdued!\n\r",ch);
        	return;
    	}

    	else if ( IS_SUBDUEE (target) ) {
    		temp_arg = char_short (target->subdue);
		snprintf (buf, MAX_STRING_LENGTH,  "$N has already been subdued by %s.\n", temp_arg);
        	act (buf, FALSE, ch, 0, target, TO_CHAR);
		return;
	}

    	else if ( ch->subdue ) {
		send_to_char ("Release your current prisoner, first.\n",
					  ch);
		return;
	}

	if ( GET_POS (target) != UNCON && GET_POS (target) != SLEEP ) {
		send_to_char ("They must be unconscious or asleep, first.\n", ch);
		return;
	}

    	if ( IS_NPC(ch) && !ch->desc ) {
        	do_sheathe (ch,"",0);
		do_wear (ch, "shield", 0);
        	do_sheathe (ch,"",0);
		if ( ch->right_hand ) {
			(void)one_argument (ch->right_hand->name, buf);
			do_wear (ch, buf, 0);
		}
		if ( ch->left_hand ) {
			(void)one_argument (ch->left_hand->name, buf);
			do_wear (ch, buf, 0);
		}
    	}

	if ( ch->right_hand || ch->left_hand ) {
		send_to_char ("You'll need both hands free to subdue.\n", ch);
		return;
	}

	if ( GET_POS (target) == SLEEP ) {
		GET_POS (target) = STAND;
		if ( number(1,100) <= target->skills [SKILL_LISTEN] ) {
			do_wake (target, "", 0);
			act ("You are startled awake as $N unsuccessfully attempts to grab you!", FALSE, target, 0, ch, TO_CHAR | TO_ACT_FORMAT);
			act ("$n is startled awake as you unsuccessfully attempt to grab $m!", TRUE, target, 0, ch, TO_VICT | TO_ACT_FORMAT);
			return;
		}
		else {
			act ("You are awakened abruptly!", FALSE, target, 0, ch, TO_CHAR | TO_ACT_FORMAT);
		}			
	}

	else if ( ch->fighting ) {
        send_to_char("You abandon your opponent.\n\r",ch);
	    act("$N turns away from you suddenly.",FALSE,ch->fighting,0,ch,TO_CHAR);
		act("$n turns away from $N.",FALSE,ch,0,target,TO_NOTVICT);
	}

	if ( IS_SUBDUER (target) )
		release_prisoner (target, NULL);

	subdue_char (ch, target);
}

void do_escape (CHAR_DATA *ch, char *argument, int cmd)
{
	int			chance;
	int			pressure;
	char		log_message [MAX_STRING_LENGTH] = {'\0'};

	if ( !IS_SUBDUEE (ch) ) {

		if ( ch->fighting )
			do_flee (ch, "", 0);
		else
			send_to_char ("You are not currently subdued.\n", ch);

		return;
	}

	if ( get_second_affect (ch, SPA_ESCAPE, NULL) ) {
		act ("$N is still holding you very tightly.",
				FALSE, ch, 0, ch->subdue, TO_CHAR);
		return;
	}

	chance = 20 + 2 * (GET_STR (ch) + GET_AGI (ch) - GET_STR (ch->subdue)
					- GET_DEX (ch->subdue));

	if ( chance > number (0, 100) ) {
		act ("You manage to wriggle free of $N's grasp!",
				FALSE, ch, 0, ch->subdue, TO_CHAR);
		act ("$N wriggles free of your grasp!",
				FALSE, ch->subdue, 0, ch, TO_CHAR);
		act ("$n escapes from $N's grasp.",
				TRUE, ch, 0, ch->subdue, TO_NOTVICT);

		REMOVE_BIT (ch->subdue->flags, FLAG_SUBDUER);
		REMOVE_BIT (ch->flags, FLAG_SUBDUEE);

		ch->subdue->subdue = NULL;
		ch->subdue = NULL;

		return;
	}

	act ("$N chokes you when you attempt to escape.",
				FALSE, ch, 0, ch->subdue, TO_CHAR);
	act ("You choke $N to prevent $M from escaping.",
				FALSE, ch->subdue, 0, ch, TO_CHAR);
	act ("$n tries and fails to escape $N.",
				TRUE, ch, 0, ch->subdue, TO_NOTVICT);

	pressure = GET_STR (ch->subdue) - 10;

	if ( pressure > 0 ) {

		snprintf (log_message, MAX_STRING_LENGTH, "Choked by %s while escaping", ch->tname);

		if ( wound_to_char (ch, "neck", number(1,pressure),9, 0, 0, 0) ) {
			act ("$n crumples to the ground dead!",
				 FALSE, ch->subdue, 0, ch, TO_CHAR);
			act ("$n chokes $N to death!",
				 FALSE, ch, 0, ch->subdue, TO_NOTVICT);
			return;
		}
	}

	add_second_affect (SPA_ESCAPE, 10, ch, NULL, NULL, 0);
}

void do_choke (CHAR_DATA *ch, char *argument, int cmd)
{
	int		pressure;

	send_to_char ("This command is disabled.\n", ch);
	return;

	if ( !IS_SUBDUER (ch) ) {
		send_to_char ("You can only choke someone you have subdued.\n", ch);
		return;
	}

	pressure = GET_STR (ch) - 10;

	if ( pressure <= 0 ) {
		act ("You are not strong enough to choke $N.",
				FALSE, ch, 0, ch->subdue, TO_CHAR);
		act ("$N applies pressure to your neck, but doesn't hurt you.",
				FALSE, ch->subdue, 0, ch, TO_CHAR);
		return;
	}

	act ("You choke $N.", FALSE, ch, 0, ch->subdue, TO_CHAR);
	act ("$N chokes you!", TRUE, ch->subdue, 0, ch, TO_CHAR);
	act ("$n chokes $N.", FALSE, ch, 0, ch->subdue, TO_NOTVICT);

	if ( wound_to_char (ch, "neck", 2 * pressure, 9, 0, 0, 0) ) {
		act ("$n crumples to the ground dead!",
			 FALSE, ch->subdue, 0, ch, TO_CHAR);
		act ("$n chokes $N to death!", FALSE, ch, 0, ch->subdue, TO_NOTVICT);
	}
}

void fix_offense (CHAR_DATA *ch)
{
	int		i;
	int		best_skill = SKILL_BRAWLING;

	for ( i = SKILL_BRAWLING; i <= SKILL_CROSSBOW; i++ )
		if ( ch->skills [i] > ch->skills [best_skill] )
			best_skill = i;

	ch->offense = ch->skills [best_skill] / 2;
}

void do_compete (CHAR_DATA *ch, char *argument, int cmd)
{
	char		buf [MAX_STRING_LENGTH] = {'\0'};
	CHAR_DATA	*src;
	CHAR_DATA	*tar;
	int			iterations = 100;
	char		*temp_arg = NULL;


	argument = one_argument (argument, buf);

	if ( str_cmp (ch->tname, IMPLEMENTOR_ACCOUNT) ) {
		send_to_char ("This command is for the implementor only.\n", ch);
		return;
	}

	if ( !(src = get_char_room_vis (ch, buf)) ) {
		send_to_char ("First combatant isn't here.\n\r", ch);
		free(argument);
		return;
	}
	if(temp_arg)
		free(temp_arg);
	temp_arg = argument;
	argument = one_argument (temp_arg, buf);
	
	
	if ( !(tar = get_char_room_vis (ch, buf)) ) {
		send_to_char ("Second combatant isn't here.\n\r", ch);
		return;
	}

	disable_timer_abort = TRUE;
	
	argument = one_argument (argument, buf);
	
	if ( strtol(buf, NULL, 10))
		iterations = strtol(buf, NULL, 10);

	compete (src, tar, iterations);

	disable_timer_abort = FALSE;
	
	return;
}

struct stats_data {
	int		kills;
	int		hits_given;
	int		hits_given_2;
	int		swipes;
	int		swipes_2;
	int		smites;
	int		smites_2;
	int		breaks;
} src_stats, tar_stats;

int compete_smite (CHAR_DATA *src, CHAR_DATA *tar, struct stats_data *stats)
{
	int		old_hits;
	int		killed = 0;

	old_hits = GET_DAM (tar);

	if ( !src->primary_delay &&
		 (get_equip (src, WEAR_PRIM) ||
		  get_equip (src, WEAR_BOTH) ||
		  (!get_equip (src, WEAR_PRIM) &&
		   !get_equip (src, WEAR_BOTH) &&
		   !get_equip (src, WEAR_SEC))) ) {
		stats->swipes++;
		killed = smite (src, tar, 1);
	}

	if ( old_hits != GET_DAM (tar) ) {
		stats->smites++;
		stats->hits_given += GET_DAM (tar) - old_hits;
	}

	if ( killed ) {
		stats->kills++;
		heal_all_wounds (src);
		heal_all_wounds (tar);
		return 1;
	}

	old_hits = GET_DAM (tar);

	if ( !src->secondary_delay &&
		 get_equip (src, WEAR_SEC) ) {
		stats->swipes_2++;
		killed = smite (src, tar, 2);
	}

	if ( old_hits != GET_DAM (tar) ) {
		stats->smites_2++;
		stats->hits_given_2 += GET_DAM (tar) - old_hits;
	}

	if ( killed ) {
		stats->kills++;
		heal_all_wounds (src);
		heal_all_wounds (tar);
		return 1;
	}

	return 0;
}

/** Debug function to test weapons and defense values in close to real-game conditions ***/
void compete (CHAR_DATA *src, CHAR_DATA *tar, int iterations)
{
	int			tick = 0;
	int			i;
	OBJ_DATA	*src_prim		= NULL;
	OBJ_DATA	*tar_prim		= NULL;
	OBJ_DATA	*src_sec		= NULL;
	OBJ_DATA	*tar_sec		= NULL;
	OBJ_DATA	*src_both		= NULL;
	OBJ_DATA	*tar_both		= NULL;
	OBJ_DATA	*src_shield		= NULL;
	OBJ_DATA	*tar_shield		= NULL;
	OBJ_DATA	*obj, *next_obj;
	char		buf [MAX_STRING_LENGTH] = {'\0'};
	char		name [MAX_STRING_LENGTH] = {'\0'};


	if ( get_equip (src, WEAR_PRIM) )
		src_prim = vtoo (get_equip (src, WEAR_PRIM)->virtual);

	if ( get_equip (tar, WEAR_PRIM) )
		tar_prim = vtoo (get_equip (tar, WEAR_PRIM)->virtual);

	if ( get_equip (src, WEAR_SEC) )
		src_sec = vtoo (get_equip (src, WEAR_SEC)->virtual);

	if ( get_equip (tar, WEAR_SEC) )
		tar_sec = vtoo (get_equip (tar, WEAR_SEC)->virtual);

	if ( get_equip (src, WEAR_BOTH) )
		src_both = vtoo (get_equip (src, WEAR_BOTH)->virtual);

	if ( get_equip (tar, WEAR_BOTH) )
		tar_both = vtoo (get_equip (tar, WEAR_BOTH)->virtual);

	if ( get_equip (src, WEAR_SHIELD) )
		src_shield = vtoo (get_equip (src, WEAR_SHIELD)->virtual);

	if ( get_equip (tar, WEAR_SHIELD) )
		tar_shield = vtoo (get_equip (tar, WEAR_SHIELD)->virtual);

	SET_BIT (src->flags, FLAG_COMPETE);
	SET_BIT (tar->flags, FLAG_COMPETE);

	src->primary_delay = 0;
	src->secondary_delay = 0;

	src_stats.kills = 0;
	src_stats.hits_given = 0;
	src_stats.hits_given_2 = 0;
	src_stats.swipes = 0;
	src_stats.swipes_2 = 0;
	src_stats.smites = 0;
	src_stats.smites_2 = 0;
	src_stats.breaks = 0;

	tar->primary_delay = 0;
	tar->secondary_delay = 0;

	tar_stats.kills = 0;
	tar_stats.hits_given = 0;
	tar_stats.hits_given_2 = 0;
	tar_stats.swipes = 0;
	tar_stats.swipes_2 = 0;
	tar_stats.smites = 0;
	tar_stats.smites_2 = 0;
	tar_stats.breaks = 0;

	GET_MOVE (src) = GET_MAX_MOVE (src);
	GET_MOVE (tar) = GET_MAX_MOVE (tar);

	GET_HIT (src) = GET_MAX_HIT (src);
	GET_HIT (tar) = GET_MAX_HIT (tar);

	REMOVE_BIT (src->flags, FLAG_KILL);
	REMOVE_BIT (tar->flags, FLAG_KILL);

	for ( i = 0; i < iterations; i++ ) {

		while ( 1 ) {

			if ( !(tick % 4) )
				second_affect_update ();
			
			if ( tick & 1 ) {
				if ( compete_smite (src, tar, &src_stats) )
					break;

				if ( compete_smite (tar, src, &tar_stats) )
					break;
			} else {
				if ( compete_smite (tar, src, &tar_stats) )
					break;

				if ( compete_smite (src, tar, &src_stats) )
					break;
			}

			if ( src->primary_delay )
				src->primary_delay--;

			if ( src->secondary_delay )
				src->secondary_delay--;

			if ( tar->primary_delay )
				tar->primary_delay--;

			if ( tar->secondary_delay )
				tar->secondary_delay--;

			tick++;
		}

		GET_MOVE (src) = GET_MAX_MOVE (src);
		GET_MOVE (tar) = GET_MAX_MOVE (tar);

		second_affect_update ();
		second_affect_update ();
		second_affect_update ();
		second_affect_update ();
		second_affect_update ();
		second_affect_update ();
		second_affect_update ();
		second_affect_update ();
		second_affect_update ();
		second_affect_update ();

		if ( src_prim && !get_equip (src, WEAR_PRIM) ) {
			src_stats.breaks++;
			obj = load_object (src_prim->virtual);
			obj_to_char (obj, src);
			equip_char (src, obj, WEAR_PRIM);
		}

		if ( tar_prim && !get_equip (tar, WEAR_PRIM) ) {
			tar_stats.breaks++;
			obj = load_object (tar_prim->virtual);
			obj_to_char (obj, tar);
			equip_char (tar, obj, WEAR_PRIM);
		}

		if ( src_sec && !get_equip (src, WEAR_SEC) ) {
			src_stats.breaks++;
			obj = load_object (src_sec->virtual);
			obj_to_char (obj, src);
			equip_char (src, obj, WEAR_SEC);
		}

		if ( tar_sec && !get_equip (tar, WEAR_SEC) ) {
			tar_stats.breaks++;
			obj = load_object (tar_sec->virtual);
			obj_to_char (obj, tar);
			equip_char (tar, obj, WEAR_SEC);
		}

		if ( src_both && !get_equip (src, WEAR_BOTH) ) {
			src_stats.breaks++;
			obj = load_object (src_both->virtual);
			obj_to_char (obj, src);
			equip_char (src, obj, WEAR_BOTH);
		}

		if ( tar_both && !get_equip (tar, WEAR_BOTH) ) {
			tar_stats.breaks++;
			obj = load_object (tar_both->virtual);
			obj_to_char (obj, tar);
			equip_char (tar, obj, WEAR_BOTH);
		}

		if ( src_shield && !get_equip (src, WEAR_SHIELD) ) {
			src_stats.breaks++;
			obj = load_object (src_shield->virtual);
			obj_to_char (obj, src);
		}

		if ( tar_shield && !get_equip (tar, WEAR_SHIELD) ) {
			tar_stats.breaks++;
			obj = load_object (tar_shield->virtual);
			obj_to_char (obj, src);
		}

		tics++;
	}

	snprintf (buf, MAX_STRING_LENGTH,  "Name              Kills    DamP    DamS   StrkP   StrkS   MissP   MissS   Breaks\n\r");
	send_to_room_unf (buf, src->in_room);
	snprintf (buf, MAX_STRING_LENGTH,  "===============   ======   =====   =====  ======  ======  ======  ======  ======\n\r");
	send_to_room_unf (buf, src->in_room);

	strncpy (name, src->name, 15);

	name [15] = '\0';

	while ( strlen (name) < 15 )
		strcat (name, " ");

	snprintf (buf, MAX_STRING_LENGTH,  "%15s   %-6d   %-5d   %-5d  %-6d  %-6d  %-6d  %-6d  %-6d\n\r",
		name,
		src_stats.kills,
		tar_stats.hits_given,
		tar_stats.hits_given_2,
		src_stats.smites,
		src_stats.smites_2,
		src_stats.swipes,
		src_stats.swipes_2,
		src_stats.breaks);
	send_to_room_unf (buf, src->in_room);

	strncpy (name, tar->name, 15);

	name [15] = '\0';

	while ( strlen (name) < 15 )
		strcat (name, " ");

	snprintf (buf, MAX_STRING_LENGTH,  "%15s   %-6d   %-5d   %-5d  %-6d  %-6d  %-6d  %-6d  %-6d\n\r",
		name,
		tar_stats.kills,
		src_stats.hits_given,
		src_stats.hits_given_2,
		tar_stats.smites,
		tar_stats.smites_2,
		tar_stats.swipes,
		tar_stats.swipes_2,
		tar_stats.breaks);
	send_to_room_unf (buf, src->in_room);

	REMOVE_BIT (src->flags, FLAG_COMPETE);
	REMOVE_BIT (tar->flags, FLAG_COMPETE);

	for ( obj = src->room->contents; obj; obj = next_obj ) {
		next_obj = obj->next_content;
		extract_obj (obj);
	}
}

void sa_rescue (SECOND_AFFECT *sa)
{
	int			result;
	CHAR_DATA	*tch,*rescuee;

	if ( !is_he_somewhere (sa->ch) )
		return;

	rescuee = (CHAR_DATA *) sa->obj;
	result = rescue_attempt (sa->ch, rescuee);
	

	if ( result == 2 )		/* can't rescue...stop trying */
		return;

	else if ( result == 0 ) {	/* Failed, try again */

		act ("$n makes another failed attempt at rescuing $N.",
				FALSE, sa->ch, 0, rescuee, TO_NOTVICT);
		act ("$N tries again, but fails to rescue you.",
				FALSE, rescuee, 0, sa->ch, TO_CHAR);
		act ("You try again, but fail to rescue $n.",
				FALSE, rescuee, 0, sa->ch, TO_VICT);

		add_second_affect (SPA_RESCUE, 3, sa->ch, sa->obj, NULL, 0);

		return;
	}

	else if ( result == 1 )		/* Couldn't try...try asap */
		add_second_affect (SPA_RESCUE, 1, sa->ch, sa->obj, NULL, 0);

	else if ( result == 3 ) {

		for ( tch = sa->ch->room->people; tch; tch = tch->next_in_room )
			if ( tch->fighting == rescuee )
				break;

		if ( !tch )
			return;

		if ( !sa->ch->fighting )
			set_fighting (sa->ch, tch);
		else
			sa->ch->fighting = tch;

		if ( tch->fighting ) {
			stop_fighting (tch);
			if (rescuee->fighting)
				stop_fighting (rescuee);
		}
		set_fighting (tch, sa->ch);

		act ("You draw $N's attention.", FALSE, sa->ch, 0, tch, TO_CHAR);
		act ("$N draws your attention.", FALSE, tch, 0, sa->ch, TO_CHAR);
		act ("$N draws $n's attention.", FALSE, tch, 0, sa->ch, TO_NOTVICT);
		act ("You stop fighting $N.", FALSE, rescuee, 0, tch, TO_CHAR);

	}
}

	/* Rescue results:
		0 = failed to rescue (3 sec pause)
			 Normal failure...try again
		1 = no rescue attempt, not possible yet (1 sec pause)
             Not in FIGHT or STAND mode
             Being subdued
		2 = can't rescue (delete sa)
			 Fighting friend, or friend fighting us
             Friend not here
             Friend begin fought
		3 = success
	*/

int rescue_attempt (CHAR_DATA *ch, CHAR_DATA *friend)
{
	CHAR_DATA		*tch;
	int				agi_diff;

	if ( GET_POS (ch) < FIGHT )
		return 1;

	if ( IS_SET (ch->flags, FLAG_SUBDUING) )
		return 1;

	if ( !is_he_here (ch, friend, TRUE) )
		return 2;

	if ( IS_SET (friend->flags, FLAG_SUBDUING) )
		return 1;

	if ( ch->fighting == friend || friend->fighting == ch )
		return 2;

	for ( tch = ch->room->people; tch; tch = tch->next_in_room )
		if ( tch->fighting == friend )
			break;

	if ( !tch )
		return 2;

	agi_diff = (GET_AGI (ch) - GET_AGI (tch)) + 
		
		/*
		 * easier to rescue if you are fighting your friend's enemy
		 * harder to rescue if you are fighting someone else
		 * otherwise rescue as normal
		*/
		
		(ch->fighting == tch)?8:(ch->fighting)?2:5;
	
	if ( agi_diff >= number (1, 10) )
		return 3;
	else if ( number (0, 19) == 0 )
		return 3;
	else
		return 0;
}

void do_rescue (CHAR_DATA *ch, char *argument, int cmd)
{
	int			result;
	CHAR_DATA		*friend;
	CHAR_DATA		*tch;
	SECOND_AFFECT	*sa;
	char			buf [MAX_STRING_LENGTH] = {'\0'};

	argument = one_argument (argument, buf);

	sa = get_second_affect (ch, SPA_RESCUE, NULL);

	if ( !*buf ) {

		if ( sa ) {
			send_to_char ("You stop trying to rescue.\n", ch);
			remove_second_affect (sa);
			return;
		}

		send_to_char ("Rescue whom?\n", ch);
		return;
	}

	if ( !(friend = get_char_room_vis (ch, buf)) ) {
		send_to_char ("You don't see them here.\n", ch);
		return;
	}

	if ( friend == ch ) {
		send_to_char ("Rescue yourself?\n", ch);
		return;
	}

	if ( friend == ch->fighting ) {
		send_to_char ("You can't rescue your opponent?\n", ch);
		return;
	}

	for ( tch = ch->room->people; tch; tch = tch->next_in_room )
		if ( tch->fighting == friend )
			break;

	if ( !tch ) {
		act ("$N doesn't need rescuing.", FALSE, ch, 0, friend, TO_CHAR);
		return;
	}

	if ( sa ) {

		if ( (CHAR_DATA *) sa->obj == friend ) {
			act ("You're still trying your best to rescue $N.",
					FALSE, ch, 0, friend, TO_CHAR);
			return;
		}

		sa->obj = (OBJ_DATA *) friend;
		act ("You will try to rescue $N now.", FALSE, ch, 0, friend, TO_CHAR);
		return;
	}

	result = rescue_attempt (ch, friend);

	if ( result == 0 ) {
		act ("You try to draw $N's attention.", FALSE, ch, 0, tch, TO_CHAR);
		act ("$N tries to draw your attention.", FALSE, tch, 0, ch, TO_CHAR);
		act ("$n tries to draw $N's attention.", FALSE, ch, 0, tch, TO_NOTVICT);

		add_second_affect (SPA_RESCUE, 3, ch, (OBJ_DATA *) friend, NULL, 0);
	}

	else if ( result == 3 ) {
		act ("You draw $N's attention.", FALSE, ch, 0, tch, TO_CHAR);
		act ("$N draws your attention.", FALSE, tch, 0, ch, TO_CHAR);
		act ("$N draws $n's attention.", FALSE, tch, 0, ch, TO_NOTVICT);

		if ( GET_POS (ch) != POSITION_DEAD && GET_POS (tch) != POSITION_DEAD )
			criminalize (ch, tch, ch->room->zone, CRIME_KILL);

		if ( !tch->fighting )
			set_fighting (tch, ch);
		else
			tch->fighting = ch;
	}

	else if ( result == 1 ) {
		act ("You will try to rescue $N when you can.",
				FALSE, ch, 0, friend, TO_CHAR);

		add_second_affect (SPA_RESCUE, 1, ch, (OBJ_DATA *) friend, NULL, 0);
	}

	else {		/* better be result == 2, shouldn't be possible */
		printf ("Rescue attempt, result = 2\n");
	}
	return;
}

void do_surrender (CHAR_DATA *ch, char *argument, int cmd)
{
	CHAR_DATA	*tch;
	char		buf [MAX_STRING_LENGTH] = {'\0'};

	argument = one_argument (argument, buf);

    if ( IS_SWIMMING (ch) ) {
    	send_to_char ("You can't do that while swimming!\n", ch);
        return;
	}

	if ( IS_SET (ch->flags, FLAG_SUBDUER) ) {
		send_to_char ("Release your prisoner, first.\n", ch);
		return;
	}

	if ( IS_SET (ch->room->room_flags, OOC) ) {
		send_to_char ("Sorry, but this command is disabled in OOC areas.\n", ch);
		return;
	}

	if ( !*buf && ch->fighting )
		tch = ch->fighting;
	else if ( !(tch = get_char_room_vis (ch, buf)) ) {
		send_to_char ("Surrender to whom?\n", ch);
		return;
	}

	if ( ch == tch ) {
		send_to_char ("Surrender to yourself? Hmm...\n", ch);
		return;
	}

	if ( tch->fighting && tch->fighting != ch ) {
		send_to_char ("They're a little too busy to take prisoners, right now...\n", ch);
		return;
	}

	if ( tch->subdue ) {
		send_to_char ("They are unable to take another prisoner.\n", ch);
		return;
	}

	if ( IS_SET (tch->flags, FLAG_KILL) ) {
		send_to_char ("They don't look particularly interested in taking prisoners...\n", ch);
		return;
	}

	act ("You surrender yourself into $N's custody.", FALSE, ch, 0, tch, TO_CHAR | TO_ACT_FORMAT);
	act ("$n surrenders $mself into your custody.", TRUE, ch, 0, tch, TO_VICT | TO_ACT_FORMAT);
	act ("$n surrenders $mself into $N's custody.", TRUE, ch, 0, tch, TO_NOTVICT | TO_ACT_FORMAT);

	subdue_char (tch, ch);
	return;
}

void do_study (CHAR_DATA *ch, char *argument, int cmd)
{
	CHAR_DATA	*crim;
	char		buf [MAX_STRING_LENGTH] = {'\0'};

	argument = one_argument (argument, buf);

	if ( IS_SET (ch->room->room_flags, OOC) ) {
		send_to_char ("That command is disabled in OOC areas.\n", ch);
		return;
	}

	if ( !*buf ) {
		send_to_char ("Study is used to identify those who are masked.\n", ch);
		return;
	}

	if ( !(crim = get_char_room_vis (ch, buf)) ) {
		send_to_char ("Study whom?\n", ch);
		return;
	}

	if ( crim == ch ) {
		send_to_char ("You like the way you look.\n", ch);
		return;
	}

	do_look (ch, buf, 0);

	act ("You stare at $N.", FALSE, ch, 0, crim, TO_CHAR);
	act ("$n is staring at $N.", FALSE, ch, 0, crim, TO_NOTVICT);
	act ("$n stares at you.", FALSE, ch, 0, crim, TO_VICT);

	if ( !is_hooded (crim) )
		return;
	
	ch->delay_ch = crim;
	ch->delay_type = DEL_STARE;
	ch->delay = 5;
	return;
}

void delayed_study (CHAR_DATA *ch)
{
	AFFECTED_TYPE	*af = NULL;
	char			buf [MAX_STRING_LENGTH] = {'\0'};

	if ( !is_he_here (ch, ch->delay_ch, TRUE) )
		return;

	if ( !is_hooded (ch->delay_ch) )
		return;

	if ( !skill_use (ch, SKILL_SCAN, 0) ) {
		act ("The identity of $N remains a mystery.",
				FALSE, ch, 0, ch->delay_ch, TO_CHAR);
		return;
	}

	snprintf (buf, MAX_STRING_LENGTH,  "You discover that $N is %s.", ch->delay_ch->short_descr);
	act (buf, FALSE, ch, 0, ch->delay_ch, TO_CHAR);

	if ( ch->mob && IS_SET (ch->act, ACT_ENFORCER) ) {
		magic_add_affect (ch->delay_ch, MAGIC_STARED, 90, 0, 0, 0, 0);
	        if ( (is_area_enforcer(ch) && (ch->race == 0) )
       	      		&& (ch->in_room / 1000 == 1 || ch->in_room / 1000 == 2 || ch->in_room / 1000 == 3) ) {
                	if ( ch->delay_ch->race >= 1 && CAN_SEE (ch, ch->delay_ch) )  {	/* Beasts in Gondor? Uh oh... */
				criminalize (ch->delay_ch, ch, ch->room->zone, 6);
                	}
        	}
	}

	if ( !get_affect (ch->delay_ch, MAGIC_CRIM_BASE + ch->room->zone) )
		return;

	if ( is_area_enforcer (ch) )
		act ("$E is a criminal!", FALSE, ch, 0, ch->delay_ch, TO_CHAR);

		/* Make criminal hot */

	if ( !(af = get_affect (ch->delay_ch, MAGIC_CRIM_HOODED)) )
		magic_add_affect (ch->delay_ch, MAGIC_CRIM_HOODED + ch->room->zone,
						  400, 0, 0, 0, 0);
	else
		af->a.spell.duration = 400;
		
		/* Probably should check to see if this is an enforcer of the zone */

	if ( ch->mob && is_area_enforcer(ch) )
		enforcer (ch, ch->delay_ch, 1, 1);
}