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 act.offensive.c
*	Offensive actions for players
*
*	This module provieds functionality for offensive activities, such as weapon
*	use, and archery, as well as guarding and fleeing. 
*
*	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 <stdlib.h>
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>

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

void do_throw (CHAR_DATA *ch, char *argument, int cmd)
{
	OBJ_DATA	*tobj = NULL;
	OBJ_DATA	*armor1 = NULL;
	OBJ_DATA	*armor2 = NULL;
	ROOM_DATA	*troom = NULL;
	ROOM_DIRECTION_DATA		*exit_room = NULL;
	CHAR_DATA	*tch = NULL;
	bool		can_lodge = FALSE;
	bool		ranged = FALSE;
	int			dir = 0;
	int			result = 0;
	int			location = 0;
	int			wear_loc1 = 0;
	int			wear_loc2 = 0;
	int			wound_type = 0;
	float		damage = 0;
	char		buf [MAX_STRING_LENGTH] = {'\0'};
	char		buf2 [MAX_STRING_LENGTH] = {'\0'};
	char		buf3 [MAX_STRING_LENGTH] = {'\0'};
	char		smite_location [MAX_STRING_LENGTH] = {'\0'};
	char		*temp_arg = NULL;
	char		*temp_arg1 = NULL;
	char		*temp_arg2 = NULL;
	OBJ_DATA	*temp_obj = NULL;
	
        if ( IS_SWIMMING (ch) ) {
                send_to_char ("You can't do that while swimming!\n", ch);
                return;
        }

        if ( IS_SET (ch->room->room_flags, OOC) && IS_MORTAL(ch) ) {
                send_to_char ("You cannot do this in an OOC area.\n", ch);
                return;
        }

	argument = one_argument (argument, buf);

	if ( !*buf ) {
		send_to_char ("What did you wish to throw?\n", ch);
		return;
	}

	if ( !(tobj = get_obj_in_list (buf, ch->right_hand)) &&
		!(tobj = get_obj_in_list (buf, ch->left_hand)) ) {
		send_to_char ("You aren't holding that in either hand.\n", ch);
		return;
	}

	argument = one_argument (argument, buf);

	if ( !*buf ) {
		send_to_char ("At what did you wish to throw?\n", ch);
		return;
	}

	if ( !(tch = get_char_room_vis (ch, buf)) ) {
		if ( (dir = is_direction (buf)) == -1 ) {
			send_to_char ("At what did you wish to throw?\n", ch);
			return;
		}
	}

	if ( ch->fighting ) {
		send_to_char ("You are currently engaged in melee combat and cannot throw.\n", ch);
		return;
	}

	if ( ch->balance <= -15 ) {
		send_to_char ("You're far too off-balance to attempt a throw.\n", ch);
		return;
	}

	if ( tobj->obj_flags.weight/100 > ch->str*2 ) {
		send_to_char ("That object is too heavy to throw effectively.\n", ch);
		return;
	}

	if ( tobj->count > 1 ) {
		send_to_char ("You may only throw one object at a time.\n", ch);
		return;
	}

	if ( !tch && dir != -1 ) {
		if ( (exit_room = PASSAGE (ch, dir)) )
			troom = vtor (PASSAGE (ch, dir)->to_room);

		if ( !troom ) {
			send_to_char ("There is no exit in that direction.\n", ch);
			return;
		}

		if ( exit_room && IS_SET (exit_room->exit_info, PASSAGE_CLOSED) ) {
			send_to_char ("Your view is blocked.\n", ch);
			return;
		}

		argument = one_argument (argument, buf);

		if ( *buf ) {
			tch = get_char_room_vis2 (ch, troom->virtual, buf);
			if ( !has_been_sighted (ch, tch) )
				tch = NULL;
			if ( !tch ) {
				send_to_char ("You do not see anyone like that in this direction.\n", ch);
				return;
			}
		}

		if ( !tch ) {
			snprintf (buf, MAX_STRING_LENGTH,  "You hurl #2%s#0 %sward.", tobj->short_description, dirs[dir]);
			act (buf, FALSE, ch, 0, 0, TO_CHAR | TO_ACT_FORMAT);

			snprintf (buf, MAX_STRING_LENGTH,  "$n hurls #2%s#0 %sward.", tobj->short_description, dirs[dir]);
			act (buf, TRUE, ch, 0, 0, TO_ROOM | TO_ACT_FORMAT);

			obj_from_char (&tobj, 0);

			obj_to_room (tobj, troom->virtual);

			snprintf (buf, MAX_STRING_LENGTH,  "#2%s#0 flies in, hurled from %s.", tobj->short_description, verbose_dirs[rev_dir[dir]]);
			buf[2] = toupper(buf[2]);
			send_to_room (buf, troom->virtual);

			return;
		}
	}

	if ( tch ) {
		if ( tch == ch ) {
			send_to_char ("That wouldn't require much of a throw...\n", ch);
			return;
		}

		if ( ch->room != tch->room && dir != -1 ) {
			if ( (exit_room = PASSAGE (ch, dir)) )
				troom = vtor (PASSAGE (ch, dir)->to_room);

			if ( !troom ) {
				send_to_char ("There is no exit in that direction.\n", ch);
				return;
			}

			if ( exit_room && IS_SET (exit_room->exit_info, PASSAGE_CLOSED) ) {
				send_to_char ("Your view is blocked.\n", ch);
				return;
			}
		}

		result = calculate_missile_result (ch, SKILL_THROWN, ch->balance*-10, tch, 0, NULL, tobj, NULL, &location, &damage);
		damage = (int)(damage);

	        wear_loc1 = body_tab [0] [location].wear_loc1;
        	wear_loc2 = body_tab [0] [location].wear_loc2;
 
	        if ( wear_loc1 ) {   
        	        armor1 = get_equip (tch, wear_loc1);
                	if ( armor1 && GET_ITEM_TYPE (armor1) != ITEM_ARMOR )  
                        	armor1 = NULL;
        	}
        	if ( wear_loc2 ) {
                	armor2 = get_equip (tch, wear_loc2);
                	if ( armor2 && GET_ITEM_TYPE (armor2) != ITEM_ARMOR )
                        	armor2 = NULL;
        	}

		if ( damage > 3 )
			criminalize (ch, tch, tch->room->zone, CRIME_KILL);

		if ( ch->room != tch->room ) {
			temp_arg1 = char_short(tch);
			temp_arg2 = char_short (ch);
			snprintf (buf, MAX_STRING_LENGTH,  "You hurl #2%s#0 %sward, toward #5%s#0.", tobj->short_description, verbose_dirs[dir], temp_arg1);
			snprintf (buf2, MAX_STRING_LENGTH,  "#5%s#0 hurls #2%s#0 %sward, toward #5%s#0.", temp_arg2, tobj->short_description, verbose_dirs[dir], temp_arg1);
			buf2[2] = toupper(buf2[2]);
			act (buf, FALSE, ch, 0, 0, TO_CHAR | TO_ACT_FORMAT);
			act (buf2, FALSE, ch, 0, 0, TO_ROOM | TO_ACT_FORMAT);
		}
		else {
			temp_arg1 = char_short(tch);
			temp_arg2 = char_short(ch);
			snprintf (buf, MAX_STRING_LENGTH,  "You hurl #2%s#0 forcefully at #5%s#0.", tobj->short_description, temp_arg1);
			snprintf (buf2, MAX_STRING_LENGTH,  "#5%s#0 hurls #2%s#0 forcefully at #5%s#0.", temp_arg2, tobj->short_description, temp_arg1);
			snprintf (buf3, MAX_STRING_LENGTH,  "#5%s#0 hurls #2%s#0 forcefully at you.", temp_arg2, tobj->short_description);
			act (buf, FALSE, ch, 0, tch, TO_CHAR | TO_ACT_FORMAT);
			act (buf2, FALSE, ch, 0, tch, TO_NOTVICT | TO_ACT_FORMAT);
			act (buf3, FALSE, ch, 0, tch, TO_VICT | TO_ACT_FORMAT);
		}

		if ( GET_ITEM_TYPE (tobj) == ITEM_WEAPON && (tobj->o.weapon.hit_type == 0 ||
			tobj->o.weapon.hit_type == 1 || tobj->o.weapon.hit_type == 2 || tobj->o.weapon.hit_type == 4) ) {
			if ( result != CRITICAL_HIT && armor1 && armor1->o.armor.armor_type >= 2 )
				can_lodge = FALSE;
			else if ( result != CRITICAL_HIT && armor2 && armor2->o.armor.armor_type >= 2 )
				can_lodge = FALSE;
			else if ( result != CRITICAL_HIT && tch->armor && tch->armor >= 4 )
				can_lodge = FALSE;
			else can_lodge = TRUE;
		}
		
		temp_arg = figure_location (tch, location);
		snprintf (smite_location, MAX_STRING_LENGTH, "%s", temp_arg);


		if ( result == MISS ) {
			snprintf (buf, MAX_STRING_LENGTH,  "It misses completely.");
			snprintf (buf2, MAX_STRING_LENGTH,  "It misses completely.");
		}
		else if ( result == CRITICAL_MISS ) {
			snprintf (buf, MAX_STRING_LENGTH,  "It flies far wide of any target.");
			snprintf (buf2, MAX_STRING_LENGTH,  "It flies far wide of any target.");
		}
		else if ( result == SHIELD_BLOCK ) {
			temp_obj = get_equip(tch, WEAR_SHIELD);
			temp_arg = obj_short_desc(temp_obj);
			snprintf (buf, MAX_STRING_LENGTH,  "It glances harmlessly off #2%s#0.", temp_arg);
			snprintf (buf2, MAX_STRING_LENGTH,  "It glances harmlessly off #2%s#0.", temp_arg);
		}
		else if ( result == GLANCING_HIT ) {
			temp_arg = expand_wound_loc (smite_location);
			snprintf (buf, MAX_STRING_LENGTH,  "It grazes %s on the %s.", HMHR(tch), temp_arg);
			snprintf (buf2, MAX_STRING_LENGTH,  "It grazes you on the %s.", temp_arg);
			
		}
		else if ( result == HIT ) {
			if ( can_lodge ) {
				temp_arg = expand_wound_loc(smite_location);
				snprintf (buf, MAX_STRING_LENGTH,  "It lodges in %s %s.", HSHR(tch), temp_arg);
				snprintf (buf2, MAX_STRING_LENGTH,  "It lodges in your %s.", temp_arg);
			}
			else {
				temp_arg = expand_wound_loc(smite_location);
				snprintf (buf, MAX_STRING_LENGTH,  "It strikes %s on the %s.", HMHR(tch), temp_arg);
				snprintf (buf2, MAX_STRING_LENGTH,  "It strikes you on the %s.", temp_arg);
			}
		}
		else if ( result == CRITICAL_HIT ) {
			if ( can_lodge ) {
				temp_arg = expand_wound_loc(smite_location);
				snprintf (buf, MAX_STRING_LENGTH,  "It lodges deeply in %s %s!", HSHR(tch), temp_arg);
				snprintf (buf2, MAX_STRING_LENGTH,  "It lodges deeply in your %s!", temp_arg);
			}
			else {
				temp_arg = expand_wound_loc(smite_location);
				snprintf (buf, MAX_STRING_LENGTH,  "It strikes %s solidly on the %s.", HMHR(tch), temp_arg);
				snprintf (buf2, MAX_STRING_LENGTH,  "It strikes you solidly on the %s.", temp_arg);
			}
		}

		if ( ch->room != tch->room ) {
			send_to_room ("\n", ch->in_room);
			act (buf, FALSE, ch, 0, 0, TO_CHAR | TO_ACT_FORMAT);
			act (buf, FALSE, ch, 0, 0, TO_ROOM | TO_ACT_FORMAT);
			send_to_room ("\n", tch->in_room);
			act (buf2, FALSE, tch, 0, 0, TO_CHAR | TO_ACT_FORMAT);
			act (buf, FALSE, tch, 0, 0, TO_ROOM | TO_ACT_FORMAT);
		}
		else {
			send_to_room ("\n", ch->in_room);
			act (buf, TRUE, ch, 0, tch, TO_CHAR | TO_ACT_FORMAT);
			act (buf2, TRUE, ch, 0, tch, TO_VICT | TO_ACT_FORMAT);
			act (buf, TRUE, ch, 0, tch, TO_NOTVICT | TO_ACT_FORMAT);
		}

		obj_from_char (&tobj, 0);

		if ( (result == HIT || result == CRITICAL_HIT) && can_lodge ) {
			lodge_missile (tch, tobj, smite_location);
		}
		else obj_to_room (tobj, tch->in_room);

		if (damage > 0) {
         	       if ( !IS_NPC (tch) ) {
                	        tch->delay_ch = ch;
                        	tch->delay_info1 = tobj->virtual;
                	}
			if ( ch->room != tch->room )
				ranged = TRUE;
			if ( GET_ITEM_TYPE (tobj) == ITEM_WEAPON )
				wound_type = tobj->o.weapon.hit_type;
			else wound_type = 3;
                	if ( wound_to_char (tch, smite_location, (int)(damage), wound_type, 0, 0, 0) ) {
                        	if ( ranged )
                                	send_to_char ("\nYour target collapses, dead.\n", ch);
                        	ch->ranged_enemy = NULL; 
                        	return;
                	}
                	if ( !IS_NPC (tch) ) {
                        	tch->delay_ch = NULL;
                        	tch->delay_info1 = 0;
                	}
        	}

		if ( ch->agi <= 9 )
			ch->balance += -20;
		else if ( ch->agi > 9 && ch->agi <= 13 )
			ch->balance += -17;
		else if ( ch->agi > 13 && ch->agi <= 15 )
			ch->balance += -15;
		else if ( ch->agi > 15 && ch->agi <= 18 )
			ch->balance += -12;
		else ch->balance += -10;

		ch->balance = MAX (ch->balance, -50);

		npc_archery_retaliation (tch, ch);

		return;
	}

	send_to_char ("There has been an error; please report your command syntax to the staff.\n", ch);
}

void do_whirl (CHAR_DATA *ch, char *argument, int cmd)
{
	OBJ_DATA	*sling = NULL;

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

	if ( ch->fighting ) {
		send_to_char ("You're fighting for your life!\n", ch);
		return;
	}

	if ( !get_equip (ch, WEAR_PRIM) ) {
		send_to_char ("You need to be wielding a loaded sling to use this command.\n", ch);
		return;
	}

	sling = get_equip (ch, WEAR_PRIM);

	if ( sling->o.weapon.use_skill != SKILL_SLING ) {
		send_to_char ("This command is for use with slings only.\n", ch);
		return;
	}

	if ( !sling->contains ) {
		send_to_char ("The sling needs to be loaded, first.\n", ch);
		return;
	}

	act ("You begin whirling $p, gathering momentum for a shot.", FALSE, ch, sling, 0, TO_CHAR | TO_ACT_FORMAT);
	act ("$n begins whirling $p, gathering momentum for a shot.", TRUE, ch, sling, 0, TO_ROOM | TO_ACT_FORMAT);

	ch->whirling = 1;
}

int projectile_shield_block (CHAR_DATA *ch, int result)
{
	OBJ_DATA	*shield_obj = NULL;
	int		roll = 0;

	if ( result == CRITICAL_HIT )
		return 0;

	if ( (shield_obj = get_equip (ch, WEAR_SHIELD)) && number(1,25) <= ch->dex ) {
		skill_use (ch, SKILL_BLOCK, 0);
		roll = number(1,85);
		if ( roll <= ch->skills [SKILL_BLOCK] ) {
			return 1;
		}
	}

	return 0;
}

int calculate_missile_result (CHAR_DATA *ch, int ch_skill, int att_modifier, CHAR_DATA *target, int def_modifier, OBJ_DATA *weapon, OBJ_DATA *missile, AFFECTED_TYPE *spell, int *location, float *damage)
{
	OBJ_DATA	*armor1 = NULL;
	OBJ_DATA	*armor2 = NULL;
	int			roll = 0;
	int			defense = 0;
	int			assault = 0;
	int			result = 0;
	int			wear_loc1 = 0;
	int			wear_loc2 = 0;
	int			body_type = 0;

	/* Determine result of hit attempt. */

	if ( !CAN_SEE (target, ch) )
		def_modifier -= number (15,30);

	skill_use (target, SKILL_DODGE, 0);

	roll = number(1,85);
	roll += def_modifier;
	roll = MIN (roll, 85);

	if ( roll > target->skills [SKILL_DODGE] ) {
		if ( roll % 5 == 0 || roll == 1 )
			defense = RESULT_CF;
		else
			defense = RESULT_MF;
	}
	else {
		if ( roll % 5 == 0 )
			defense = RESULT_CS;
		else
			defense = RESULT_MS;
	}

	skill_use (ch, ch_skill, 0);

        if ( weather_info[ch->room->zone].fog == THIN_FOG )   
                att_modifier += 5;
        if ( weather_info[ch->room->zone].fog == THICK_FOG )
                att_modifier += 10;
        if ( weather_info[ch->room->zone].state == STEADY_RAIN )
                att_modifier += 15;
        if ( weather_info[ch->room->zone].state == HEAVY_RAIN )
                att_modifier += 20;
        if ( weather_info[ch->room->zone].state == STEADY_SNOW )
                att_modifier += 25;

	roll = number(1,85);
	roll += att_modifier;
	roll = MIN (roll, 85);
 
	ch->aim = 0;

	if ( ch->skills [ch_skill] ) {
		if ( roll > ch->skills [ch_skill] ) {
			if ( roll % 5 == 0 || roll == 1 )
				assault = RESULT_CF;
			else
				assault = RESULT_MF;
		}
		else if ( roll <= ch->skills [ch_skill] ) {
			if ( roll % 5 == 0 )
				assault = RESULT_CS;
			else
				assault = RESULT_MS;
		}
	}
	else {
		if ( roll > ch->skills [SKILL_OFFENSE] ) {
			if ( roll % 5 == 0 || roll == 1 )
				assault = RESULT_CF;
			else
				assault = RESULT_MF;
		}
		else if ( roll <= ch->skills [SKILL_OFFENSE] ) {
			if ( roll % 5 == 0 )
				assault = RESULT_CS;
			else
				assault = RESULT_MS;
		}
	}

	if ( assault == defense ) {
		if ( number(1,10) > 5 )
			result = GLANCING_HIT;
		else
			result = MISS;
	}
	if ( assault == RESULT_CS ) {
		if ( defense == RESULT_MS )
			result = HIT;
		else if ( defense == RESULT_MF )
			result = HIT;
		else if ( defense == RESULT_CF )
			result = CRITICAL_HIT;
	}
	else if ( assault == RESULT_MS ) {
		if ( defense == RESULT_CS )
			result = MISS;
		else if ( defense == RESULT_MF )
			result = HIT;
		else if ( defense == RESULT_CF )
			result = CRITICAL_HIT;
	}
	else if ( assault == RESULT_MF ) {
		if ( defense == RESULT_CS )
			result = CRITICAL_MISS;
		else if ( defense == RESULT_MS )
			result = MISS;
		else if ( defense == RESULT_CF )
			result = GLANCING_HIT;
	}
	else if ( assault == RESULT_CF ) {
		if ( defense == RESULT_CS )
			result = CRITICAL_MISS;
		else if ( defense == RESULT_MS )
			result = CRITICAL_MISS;
		else if ( defense == RESULT_MF )
			result = MISS;
	}

        if ( !AWAKE (target) && assault != RESULT_CF )
                result = CRITICAL_HIT;
        
        if ( (result == HIT || result == GLANCING_HIT) && projectile_shield_block (target, result) )
                result = SHIELD_BLOCK;
 
	if ( result == MISS || result == CRITICAL_MISS || result == SHIELD_BLOCK )
		return result;

	/* Determine damage of hit, if applicable. */

	*damage = 0;

        body_type = 0;

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

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

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

	if ( wear_loc1 ) {
		armor1 = get_equip (target, wear_loc1);
		if ( armor1 && GET_ITEM_TYPE (armor1) != ITEM_ARMOR )
			armor1 = NULL;
	}
	if ( wear_loc2 ) {
		armor2 = get_equip (target, wear_loc2);
		if ( armor2 && GET_ITEM_TYPE (armor2) != ITEM_ARMOR )
			armor2 = NULL;
	}

	if ( missile ) {
		if ( GET_ITEM_TYPE (missile) == ITEM_MISSILE || GET_ITEM_TYPE (missile) == ITEM_BULLET )
			*damage = (float)dice(missile->o.od.value[0], missile->o.od.value[1]);
		else if ( GET_ITEM_TYPE (missile) == ITEM_WEAPON )
			*damage = (float)dice(missile->o.od.value[1], missile->o.od.value[2]);
		else *damage = (float)dice(1,3);

		if ( weapon ) 			/* Launched from a bow/sling */
			*damage += weapon->o.od.value[4];

		if ( weapon || IS_SET (missile->obj_flags.extra_flags, ITEM_THROWING) ) {
			if ( result == HIT ) {			/* Multiply in critical hits to raw damage amount. */
				*damage += number(3,5);
				*damage *= 1.75;
			}
			else if ( result == CRITICAL_HIT ) {
				*damage += number(4,6);
				*damage *= 2.75;
			}

		}

		if ( armor1 != NULL ) {
			*damage -= armor1->o.armor.armor_value;
			*damage += weapon_armor_table [1][armor1->o.armor.armor_type];
		}
		if ( armor2 != NULL ) {
			*damage -= armor2->o.armor.armor_value;
			*damage += weapon_armor_table [1][armor2->o.armor.armor_type];
		}
		if ( target->armor ) {
			*damage -= target->armor;
		}

		if ( weapon ) {
			if ( result != GLANCING_HIT) {		/* Shot lodged in target, piercing the armor. */
				if ( *location == 2 )
					*damage *= 1.75;
				else if ( *location == 3 )
					*damage *= 2.25;
				else if ( *location == 4 )
					*damage *= 3.00;
			}
		}

		if ( missile ) {
			if ( GET_ITEM_TYPE (missile) != ITEM_WEAPON && GET_ITEM_TYPE (missile) != ITEM_MISSILE && GET_ITEM_TYPE (missile) != ITEM_BULLET )
				*damage = 0;
		}
	}

	if ( weapon && weapon->o.weapon.use_skill == SKILL_SLING ) {
		if ( att_modifier < 0 )
			att_modifier *= -1;
		if ( att_modifier <= 1 )
			*damage *= 0.250;
		else if ( att_modifier > 1 && att_modifier <= 2 )
			*damage *= 0.500;
		else if ( att_modifier > 2 && att_modifier <= 3 )
			*damage *= 0.750;
		
	}

	return result;
}

void lodge_missile (CHAR_DATA *target, OBJ_DATA *ammo, char *smite_location)
{
	LODGED_OBJECT_INFO	*lodged = NULL;

	if ( !target->lodged ) {
		CREATE (target->lodged, LODGED_OBJECT_INFO, 1);
		target->lodged->vnum = ammo->virtual;
		target->lodged->location = add_hash (smite_location);
	}
	else for ( lodged = target->lodged; lodged; lodged = lodged->next ) {
		if ( !lodged->next ) {
			CREATE (lodged->next, LODGED_OBJECT_INFO, 1);
			lodged->next->vnum = ammo->virtual;
			lodged->next->location = add_hash (smite_location);
			break;
		}
		else continue;
	}
}

void fire_sling (CHAR_DATA *ch, OBJ_DATA *sling, char *argument)
{
	CHAR_DATA	*tch = NULL;
	ROOM_DATA	*troom = NULL;
	OBJ_DATA	*ammo = NULL;
	char		buf [MAX_STRING_LENGTH] = {'\0'};
	char		smite_location [MAX_STRING_LENGTH] = {'\0'};
	char		buf2 [MAX_STRING_LENGTH] = {'\0'};
	char		buf3 [MAX_STRING_LENGTH] = {'\0'};
	float		damage = 0;
	int			dir = 0;
	int			location = 0;
	int			result = 0;
	int			attack_mod = 0;
	int			wound_type = 0;
	bool		ranged = FALSE;
	char		*temp_arg = NULL;
	char		*temp_arg1 = NULL;
	char		*temp_arg2 = NULL;
	OBJ_DATA	*temp_obj = NULL;
	
	if ( !ch || !sling )
		return;

	if ( !*argument ) {
		send_to_char ("At what did you wish to fire your sling?\n", ch);
		return;
	}

	if ( !ch->whirling ) {
		send_to_char ("You'll need to begin whirling your sling before you can fire.\n", ch);
		return;
	}

	if ( !sling->contains ) {
		send_to_char ("You'll need to load your sling first.\n", ch);
		return;
	}

	argument = one_argument (argument, buf);

        if ( !(tch = get_char_room_vis (ch, buf)) ) {
                if ( (dir = is_direction (buf)) == -1 ) {
                        send_to_char ("At what did you wish to fire?\n", ch);
                        return;
                }
        }        
                                        
        if ( !tch && dir != -1 ) {
                if ( PASSAGE (ch, dir) )
                        troom = vtor (PASSAGE (ch, dir)->to_room);
                        
                if ( !troom ) {
                        send_to_char ("There is no exit in that direction.\n", ch);
                        return;
                }
                        
                argument = one_argument (argument, buf);
                 
                if ( *buf ) {
                        tch = get_char_room_vis2 (ch, troom->virtual, buf);
                        if ( !has_been_sighted (ch, tch) )
                                tch = NULL;
                        if ( !tch ) {
                                send_to_char ("You do not see anyone like that in this direction.\n", ch);
                                return;
                        }
                }
	}

	if ( !tch ) {
		send_to_char ("At whom did you wish to fire your sling?\n", ch);
		return;
	}

	if ( tch == ch ) {
		send_to_char ("Don't be silly.\n", ch);
		return;
	}

	attack_mod -= ch->whirling;
	ch->whirling = 0;

	result = calculate_missile_result (ch, sling->o.weapon.use_skill, attack_mod, tch, 0, sling, sling->contains, NULL, &location, &damage);
	damage = (int)(damage);

	temp_arg = figure_location (tch, location);
	snprintf (smite_location, MAX_STRING_LENGTH, "%s", temp_arg);


	if ( ch->room != tch->room ) {
		temp_arg1 = char_short(tch);
		temp_arg2 = char_short(ch);
		snprintf (buf, MAX_STRING_LENGTH,  "You sling #2%s#0 %sward, toward #5%s#0.", sling->contains->short_description, verbose_dirs[dir], temp_arg1);
		snprintf (buf2, MAX_STRING_LENGTH,  "#5%s#0 slings #2%s#0 %sward, toward #5%s#0.", temp_arg2, sling->contains->short_description, verbose_dirs[dir], temp_arg1);
		buf2[2] = toupper(buf2[2]);
		act (buf, FALSE, ch, 0, 0, TO_CHAR | TO_ACT_FORMAT);
		act (buf2, FALSE, ch, 0, 0, TO_ROOM | TO_ACT_FORMAT);
	}
	else {
		temp_arg1 = char_short(tch);
		temp_arg2 = char_short(ch);
		snprintf (buf, MAX_STRING_LENGTH,  "You sling #2%s#0 forcefully at #5%s#0.", sling->contains->short_description, temp_arg1);
		snprintf (buf2, MAX_STRING_LENGTH,  "#5%s#0 slings #2%s#0 forcefully at #5%s#0.", temp_arg2, sling->contains->short_description, temp_arg1);
		snprintf (buf3, MAX_STRING_LENGTH,  "#5%s#0 slings #2%s#0 forcefully at you.", temp_arg2, sling->contains->short_description);
		act (buf, FALSE, ch, 0, tch, TO_CHAR | TO_ACT_FORMAT);
		act (buf, FALSE, ch, 0, tch, TO_VICT | TO_ACT_FORMAT);
		act (buf2, FALSE, ch, 0, tch, TO_NOTVICT| TO_ACT_FORMAT);
	}

	if ( result == MISS ) {
		snprintf (buf, MAX_STRING_LENGTH,  "It misses completely.");
		snprintf (buf2, MAX_STRING_LENGTH,  "It misses completely.");
	}
	else if ( result == CRITICAL_MISS ) {
		snprintf (buf, MAX_STRING_LENGTH,  "It flies far wide of any target.");
		snprintf (buf2, MAX_STRING_LENGTH,  "It flies far wide of any target.");
	}
	else if ( result == SHIELD_BLOCK ) {
		temp_obj = get_equip(tch, WEAR_SHIELD);
		temp_arg = obj_short_desc(temp_obj);
		snprintf (buf, MAX_STRING_LENGTH,  "It glances harmlessly off #2%s#0.", temp_arg);
		snprintf (buf2, MAX_STRING_LENGTH,  "It glances harmlessly off #2%s#0.", temp_arg);
	}
	else if ( result == GLANCING_HIT ) {
		temp_arg = expand_wound_loc (smite_location);
		snprintf (buf, MAX_STRING_LENGTH,  "It grazes %s on the %s.", HMHR(tch), temp_arg);
		snprintf (buf2, MAX_STRING_LENGTH,  "It grazes you on the %s.", temp_arg);	
	}
	else if ( result == HIT ) {
		temp_arg = expand_wound_loc (smite_location);
		snprintf (buf, MAX_STRING_LENGTH,  "It strikes %s on the %s.", HMHR(tch), temp_arg);
		snprintf (buf2, MAX_STRING_LENGTH,  "It strikes you on the %s.", temp_arg);
	}
	else if ( result == CRITICAL_HIT ) {
		temp_arg = expand_wound_loc (smite_location);
		snprintf (buf, MAX_STRING_LENGTH,  "It strikes %s solidly on the %s.", HMHR(tch), temp_arg);
		snprintf (buf2, MAX_STRING_LENGTH,  "It strikes you solidly on the %s.", temp_arg);
	}

	ammo = sling->contains;

	obj_from_obj (&ammo, 0);
	obj_to_room (ammo, tch->in_room);

	if ( result == CRITICAL_MISS && !number(0,1) ) {
		snprintf (buf + strlen(buf), MAX_STRING_LENGTH,  "\n\nThe missile recedes hopelessly from sight.");
		snprintf (buf2 + strlen(buf2), MAX_STRING_LENGTH,  "\n\nThe missile recedes hopelessly from sight.");
		snprintf (buf3 + strlen(buf3), MAX_STRING_LENGTH, "\n\nThe missile recedes hopelessly from sight.");
		extract_obj(ammo);
	}

	if ( ch->room != tch->room ) {
		send_to_room ("\n", ch->in_room);
		act (buf, FALSE, ch, 0, 0, TO_CHAR | TO_ACT_FORMAT);
		act (buf, FALSE, ch, 0, 0, TO_ROOM | TO_ACT_FORMAT);
		send_to_room ("\n", tch->in_room);
		act (buf2, FALSE, tch, 0, 0, TO_CHAR | TO_ACT_FORMAT);
		act (buf, FALSE, tch, 0, 0, TO_ROOM | TO_ACT_FORMAT);
	}
	else {
		send_to_room ("\n", ch->in_room);
		act (buf, FALSE, ch, 0, tch, TO_CHAR | TO_ACT_FORMAT);
		act (buf2, FALSE, ch, 0, tch, TO_VICT | TO_ACT_FORMAT);
		act (buf, FALSE, ch, 0, tch, TO_NOTVICT | TO_ACT_FORMAT);
	}

	if (damage > 0) {
                if ( !IS_NPC (tch) ) {
              	        tch->delay_ch = ch;
                     	tch->delay_info1 = ammo->virtual;
               	}
		if ( ch->room != tch->room )
			ranged = TRUE;
		wound_type = 3;
               	if ( wound_to_char (tch, smite_location, (int)damage, wound_type, 0, 0, 0) ) {
                       	if ( ranged )
                               	send_to_char ("\nYour target collapses, dead.\n", ch);
                       	ch->ranged_enemy = NULL; 
                       	return;
               	}
               	if ( !IS_NPC (tch) ) {
                       	tch->delay_ch = NULL;
                       	tch->delay_info1 = 0;
               	}
		if ( damage > 3 )
			criminalize (ch, tch, tch->room->zone, CRIME_KILL);
        }

	npc_archery_retaliation (tch, ch);

}

void do_fire (CHAR_DATA *ch, char *argument, int cmd)
{
	CHAR_DATA	*target = NULL;
	CHAR_DATA	*tch = NULL;
	OBJ_DATA	*obj = NULL;
	OBJ_DATA	*ammo = NULL;
	OBJ_DATA	*bow = NULL;
	OBJ_DATA	*armor1 = NULL;
	OBJ_DATA	*armor2 = NULL;
	OBJ_DATA	*shield_obj = NULL;
	ROOM_DATA	*room = NULL;
	char		buf [MAX_STRING_LENGTH] = {'\0'};
	char		buf2 [MAX_STRING_LENGTH] = {'\0'};
	char		buf3 [MAX_STRING_LENGTH] = {'\0'};
	char		buffer [MAX_STRING_LENGTH] = {'\0'};
	char		smite_location [MAX_STRING_LENGTH] = {'\0'};
	char		*from_direction = NULL;
	char		*p = NULL;
	char		*temp_arg = NULL;
	char		*temp_arg1 = NULL;
	char		*temp_arg2 = NULL;
	int			roll = 0;
	int			ranged = 0;
	int			result = 0;
	int			location = 0;
	int			attack_mod = 0;
	float		damage = 0;
	int			dir = 0;
	bool		switched_target = FALSE;
	
    if ( IS_SWIMMING (ch) ) {
    	send_to_char ("You can't do that while swimming!\n", ch);
        return;
    }

	if ( IS_SET (ch->room->room_flags, OOC) && IS_MORTAL(ch) ) {
		send_to_char ("You cannot do this in an OOC area.\n", ch);
		return;
	}
	
	if ( ((bow = get_equip(ch, WEAR_PRIM)) && GET_ITEM_TYPE(bow) == ITEM_WEAPON && bow->o.weapon.use_skill == SKILL_SLING) ||
		((bow = get_equip (ch, WEAR_SEC)) && GET_ITEM_TYPE(bow) == ITEM_WEAPON && bow->o.weapon.use_skill == SKILL_SLING) ) {
		fire_sling (ch, bow, argument);
		return;
	}

	if ( !ch->aiming_at ) {
		send_to_char ("You aren't aiming at anything.\n", ch);
		return;
	}

	if ( !IS_NPC (ch->aiming_at) &&
		ch->aiming_at->pc->create_state == STATE_DIED ) {
		send_to_char ("You aren't aiming at anything alive.\n", ch);
		return;
	}

	if ( !(bow = get_equip (ch, WEAR_BOTH)) ) {
		send_to_char ("You aren't wielding a ranged weapon!\n", ch);
		ch->aiming_at->targeted_by = NULL;
		ch->aiming_at = NULL;
		ch->aim = 0;
		return;
	}

	if ( !bow->loaded ) {
		send_to_char ("Your weapon isn't loaded...\n", ch);
		ch->aiming_at->targeted_by = NULL;
		ch->aiming_at = NULL;
		ch->aim = 0;
		return;
	}

    if ( IS_SET (ch->plr_flags, NEW_PLAYER_TAG) &&
    	IS_SET (ch->room->room_flags, LAWFUL) &&
    	*argument != '!' ) {
        snprintf (buf, MAX_STRING_LENGTH,  "You are in a lawful area; you would likely be flagged wanted for assault. "
        	"To confirm, type \'#6fire !#0\', without the quotes.");
        act (buf, FALSE, ch, 0, 0, TO_CHAR | TO_ACT_FORMAT);
		return;
    }

	attack_mod -= ch->aim;
	target = ch->aiming_at;
	target->targeted_by = NULL;
	ch->aiming_at = NULL;
	ch->aim = 0;

	if ( !IS_NPC (target) &&
		(!str_cmp (target->tname, IMPLEMENTOR_ACCOUNT)) &&
		!IS_NPC (ch) ){
		target = ch;
	}

	if ( ch->in_room != target->in_room ){
		ranged = 1;
	}

	if ( ranged ) {
		if ( !ch->delay_who ) {
			send_to_char ("You seem to have lost sight of your quarry.\n", ch);
			return;
		}
        
        if ( !cmp_strn ("north", ch->delay_who, strlen(ch->delay_who)) )
        	dir = 0;
        else if ( !cmp_strn ("east", ch->delay_who, strlen(ch->delay_who)) )
        	dir = 1;
        else if ( !cmp_strn ("south", ch->delay_who, strlen(ch->delay_who)) )
        	dir = 2;
        else if ( !cmp_strn("west", ch->delay_who, strlen(ch->delay_who)) )
        	dir = 3;
        else if ( !cmp_strn ("up", ch->delay_who, strlen(ch->delay_who)) )
        	dir = 4;
        else if ( !cmp_strn ("down", ch->delay_who, strlen(ch->delay_who)) )
        	dir = 5;
	}

	/* ranged_projectile_echoes (ch, target, bow, ammo); */

	if ( bow->o.weapon.use_skill == SKILL_SHORTBOW ||
		bow->o.weapon.use_skill == SKILL_LONGBOW ) {
		
		if ( ranged ) {
			temp_arg = char_short (target);
			temp_arg1 = char_short(ch);
			snprintf (buf, MAX_STRING_LENGTH,  "You release the bowstring, launching #2%s#0 %sward through the air toward #5%s#0.", bow->loaded->short_description, ch->delay_who, temp_arg );	
			snprintf (buf2, MAX_STRING_LENGTH,  "%s#0 releases the bowstring, launching #2%s#0 %sward through the air toward #5%s#0.", temp_arg1, bow->loaded->short_description, ch->delay_who, temp_arg); 
			*buf2 = toupper (*buf2);
			snprintf (buffer, MAX_STRING_LENGTH,  "#5%s", buf2);
			snprintf (buf2, MAX_STRING_LENGTH,  "%s", buffer);
		}
		
		else {
			temp_arg = char_short(ch);
			temp_arg1 = char_short(target);
			snprintf (buf2, MAX_STRING_LENGTH,  "%s#0 releases the bowstring, launching #2%s#0 through the air toward #5%s#0.", temp_arg, bow->loaded->short_description, temp_arg1);
			*buf2 = toupper (*buf2);
			snprintf (buffer, MAX_STRING_LENGTH,  "#5%s", buf2);
			snprintf (buf2, MAX_STRING_LENGTH,  "%s", buffer);
			snprintf (buf3, MAX_STRING_LENGTH,  "%s#0 releases the bowstring, launching #2%s#0 through the air toward you!", temp_arg, bow->loaded->short_description);
			*buf3 = toupper (*buf3);
			snprintf (buffer, MAX_STRING_LENGTH,  "#5%s", buf3);
			snprintf (buf3, MAX_STRING_LENGTH,  "%s", buffer);
			snprintf (buf, MAX_STRING_LENGTH,  "You release the bowstring, launching #2%s#0 through the air toward #5%s#0!", bow->loaded->short_description, temp_arg1);
		}
	}
	
	else if ( bow->o.weapon.use_skill == SKILL_CROSSBOW ) {
		if ( ranged ) {
			temp_arg = char_short(ch);
			temp_arg1 = char_short(target);
			snprintf (buf, MAX_STRING_LENGTH,  "You squeeze the trigger, sending #2%s#0 whirring %sward through the air toward #5%s#0.", bow->loaded->short_description, ch->delay_who, temp_arg1);
			snprintf (buf2, MAX_STRING_LENGTH,  "%s#0 squeezes the trigger, sending #2%s#0 whirring %sward through the air toward #5%s#0.", temp_arg, bow->loaded->short_description, ch->delay_who, temp_arg1);
			snprintf (buffer, MAX_STRING_LENGTH,  "#5%s#0", CAP(buf2));
			snprintf (buf2, MAX_STRING_LENGTH,  "%s", buffer);
		}
		
		else {
			temp_arg = char_short(ch);
			temp_arg1 = char_short(target);
			snprintf (buf2, MAX_STRING_LENGTH,  "%s#0 squeezes the trigger, sending #2%s#0 whirring through the air toward #5%s#0.", temp_arg, bow->loaded->short_description, temp_arg1);
			snprintf (buffer, MAX_STRING_LENGTH,  "#5%s", CAP(buf2));
			snprintf (buf2, MAX_STRING_LENGTH,  "%s", buffer);
			snprintf (buf3, MAX_STRING_LENGTH,  "%s#0 squeezes the trigger, sending #2%s#0 whirring through the air toward you!", temp_arg, bow->loaded->short_description);
			snprintf (buffer, MAX_STRING_LENGTH,  "#5%s", CAP(buf3));
			snprintf (buf3, MAX_STRING_LENGTH,  "%s", buffer);
			snprintf (buf, MAX_STRING_LENGTH,  "You squeeze the trigger, sending #2%s#0 whirring through the air toward #5%s#0!", bow->loaded->short_description, temp_arg1);
		}
	}

	if ( ranged ) {
		act (buf, TRUE, ch, 0, 0, TO_CHAR | TO_ACT_FORMAT);
		act (buf2, TRUE, ch, 0, 0, TO_ROOM | TO_ACT_FORMAT);
		snprintf (buf3, MAX_STRING_LENGTH,  "You spy #2%s#0 as it arcs high overhead, streaking %sward.", bow->loaded->short_description, ch->delay_who);
		reformat_string (buf3, &p);
		
		if ( PASSAGE(ch,dir) )
			room = vtor (PASSAGE(ch,dir)->to_room);
		else
			room = NULL;
		
		if ( room && target->room != room ) {
			for ( tch = room->people; tch; tch = tch->next_in_room ){ 
				if ( skill_use (tch, SKILL_SCAN, 0) ){
					send_to_char (p, tch);
				}
			}
			
			if ( room->dir_option[dir] ){	
				room = vtor (room->dir_option[dir]->to_room);
			}
			else {
				room = NULL;
			}
			
			if ( room && target->room != room ) {
				for ( tch = room->people; tch; tch = tch->next_in_room ){ 
					if ( skill_use (tch, SKILL_SCAN, 0) ){
						send_to_char (p, tch);
					}
				}
				
				if ( room->dir_option[dir] ){	
					room = vtor (room->dir_option[dir]->to_room);
				}
				else{
					room = NULL;
				}
				
				if ( room && target->room != room ) {
					for ( tch = room->people; tch; tch = tch->next_in_room ){ 
						if ( skill_use (tch, SKILL_SCAN, 0) ){
							send_to_char (p, tch);
						}
					}
				}
			}
		}
		mem_free (p);
	}
	
	else if ( !ranged ) {
		act (buf, TRUE, ch, 0, target, TO_CHAR | TO_ACT_FORMAT);
		act (buf3, TRUE, ch, 0, target, TO_VICT | TO_ACT_FORMAT);
		act (buf2, TRUE, ch, 0, target, TO_NOTVICT | TO_ACT_FORMAT);
	}

	ammo = load_object(bow->loaded->virtual);
	ammo->count = 1;
	ammo->in_obj = NULL;
	ammo->carried_by = NULL;
	ammo->equiped_by = NULL;

	if ( ranged && ch->delay_who ) {
		if ( !str_cmp (ch->delay_who, "north") )
			from_direction = str_dup ("the south");
		else if ( !str_cmp (ch->delay_who, "east") )
			from_direction = str_dup ("the west");
		else if ( !str_cmp (ch->delay_who, "south") )
			from_direction = str_dup ("the north");
		else if ( !str_cmp (ch->delay_who, "west") )
			from_direction = str_dup ("the east");
		else if ( !str_cmp (ch->delay_who, "up") )
			from_direction = str_dup ("below");
		else if ( !str_cmp (ch->delay_who, "down") )
			from_direction = str_dup ("above");
		if ( ch->delay_who && strlen(ch->delay_who) > 1 )
			mem_free (ch->delay_who);
		ch->delay_who = NULL;
	}
	else{
		from_direction = add_hash ("an indeterminate direction");
	}
	
	attack_mod -= bow->o.od.value[2];

	if ( ch->fighting ) {
		if ( bow->o.weapon.use_skill == SKILL_LONGBOW ) 
			attack_mod += 30;
		else if ( bow->o.weapon.use_skill == SKILL_SHORTBOW )
			attack_mod += 20;
		else if ( bow->o.weapon.use_skill == SKILL_CROSSBOW )
			attack_mod += 10;
	}
	
	if ( !ch->delay_info1 ) {
		if ( bow->o.weapon.use_skill == SKILL_LONGBOW )
			attack_mod += 20;
		else if ( bow->o.weapon.use_skill == SKILL_SHORTBOW )
			attack_mod += 10;
	}
	
	else if ( ch->delay_info1 == 1 ) {
		if ( bow->o.weapon.use_skill == SKILL_LONGBOW )
			attack_mod += 10;
		else if ( bow->o.weapon.use_skill == SKILL_CROSSBOW )
			attack_mod += 10;
	}
	
	else if ( ch->delay_info1 == 2 ) {
		if ( bow->o.weapon.use_skill == SKILL_SHORTBOW )
			attack_mod += 10;
		else if ( bow->o.weapon.use_skill == SKILL_CROSSBOW )
			attack_mod += 15;
	}

	result = calculate_missile_result (ch, bow->o.weapon.use_skill, attack_mod, target, 0, bow, ammo, NULL, &location, &damage);
	damage = (int)(damage);

    if ( (result == CRITICAL_MISS || result == MISS) &&
    		target->fighting &&
    		target->fighting != ch &&
    		number(1,25) > ch->dex ) {
        target = target->fighting;
        result = calculate_missile_result (ch, bow->o.weapon.use_skill, roll, target, 0, bow, ammo, NULL, &location, &damage);
		switched_target = TRUE;
    }

	*buf = '\0';
	*buf2 = '\0';
	*buf3 = '\0';
	*buffer = '\0';

	
	if ( result == MISS ) {
		if ( ranged ) {
			temp_arg = char_short(target);
			snprintf (buf, MAX_STRING_LENGTH,  "%s#0 comes whirring through the air from %s, headed straight toward you!\n\nIt misses you completely.", ammo->short_description, from_direction);
			*buf = toupper(*buf);
			snprintf (buffer, MAX_STRING_LENGTH,  "#2%s", buf);
			snprintf (buf, MAX_STRING_LENGTH,  "\n%s", buffer);
			snprintf (buf2, MAX_STRING_LENGTH,  "%s#0 comes whirring through the air from %s, headed straight toward #5%s#0.\n\nIt misses %s completely.", ammo->short_description, from_direction, temp_arg, HMHR(target));
			*buf2 = toupper (*buf2);
			snprintf (buffer, MAX_STRING_LENGTH,  "#2%s", buf2);
			snprintf (buf2, MAX_STRING_LENGTH,  "\n%s", buffer);
			snprintf (buf3, MAX_STRING_LENGTH,  "It misses %s completely.", HMHR(target));
		}
		else {
			snprintf (buf, MAX_STRING_LENGTH,  "\nIt misses %s completely.", HMHR(target));
			snprintf (buf2, MAX_STRING_LENGTH,  "\nIt misses you completely.");
		}
	}  /* Miss. */

	else if ( result == CRITICAL_MISS ) {
		if ( ranged ) {
			snprintf (buf, MAX_STRING_LENGTH,  "%s#0 comes whirring through the air from %s, but it flies far wide of striking any target.", ammo->short_description, from_direction);
			*buf = toupper (*buf);
			snprintf (buffer, MAX_STRING_LENGTH,  "#2%s", buf);
			snprintf (buf, MAX_STRING_LENGTH,  "\n%s", buffer);
			snprintf (buf2, MAX_STRING_LENGTH,  "%s#0 comes whirring through the air from %s, but it flies far wide of striking any target.", ammo->short_description, from_direction);
			*buf2 = toupper(*buf2);
			snprintf (buffer, MAX_STRING_LENGTH,  "#2%s", buf2);
			snprintf (buf2, MAX_STRING_LENGTH,  "\n%s", buffer);
			snprintf (buf3, MAX_STRING_LENGTH,  "Your shot flies far wide of striking any target.");
		}
		else if ( !ranged ) {
			snprintf (buf, MAX_STRING_LENGTH,  "It streaks off to one side, far wide of any desired target.");
			snprintf (buf2, MAX_STRING_LENGTH,  "It streaks off to one side, far wide of any desired target.");
		}
	} /* Critical miss. */

	else if ( result == SHIELD_BLOCK ) {
		shield_obj = get_equip (target, WEAR_SHIELD);
		temp_arg = obj_short_desc(shield_obj);
		temp_arg1 = char_short(target);
		if ( ranged ) {
			snprintf (buf, MAX_STRING_LENGTH,  "%s#0 comes whirring through the air from %s, headed straight toward you!\n\nIt glances harmlessly off #2%s#0.", ammo->short_description, from_direction, temp_arg );
			snprintf (buf2, MAX_STRING_LENGTH,  "%s#0 comes whirring through the air from %s, headed straight toward #5%s#0.\n\nIt glances harmlessly off #2%s#0.", ammo->short_description, from_direction, temp_arg1, temp_arg);
			snprintf (buf3, MAX_STRING_LENGTH,  "It glances harmlessly off #2%s#0.", temp_arg);
		}
		else if ( !ranged ) {
			snprintf (buf, MAX_STRING_LENGTH,  "It glances harmlessly off #2%s#0.", temp_arg);
			snprintf (buf2, MAX_STRING_LENGTH,  "It glances harmlessly off #2%s#0.", temp_arg);
		}
	}

	else if ( result == HIT ||
				result == GLANCING_HIT ||
				result == CRITICAL_HIT ) {
		
		temp_arg = figure_location (target, location);
		snprintf (smite_location, MAX_STRING_LENGTH, "%s", temp_arg );

		if ( ranged ) {
			if ( result != CRITICAL_HIT && result != HIT ) {
				temp_arg = expand_wound_loc(smite_location);
				temp_arg1 = char_short(target);
				snprintf (buf, MAX_STRING_LENGTH,  "%s#0 comes whirring through the air from %s, headed straight toward you!\n\nIt grazes you on the %s.", ammo->short_description, from_direction, temp_arg);
				*buf = toupper(*buf);
				snprintf (buffer, MAX_STRING_LENGTH,  "#2%s", buf);
				snprintf (buf, MAX_STRING_LENGTH,  "\n%s", buffer);
				snprintf (buf2, MAX_STRING_LENGTH,  "%s#0 comes whirring through the air from %s, headed straight toward #5%s#0.\n\nIt grazes %s on the %s.", ammo->short_description, from_direction, temp_arg1, HMHR(target), temp_arg);
				*buf2 = toupper(*buf2);
				snprintf (buffer, MAX_STRING_LENGTH,  "#2%s", buf2);
				snprintf (buf2, MAX_STRING_LENGTH,  "\n%s", buffer);
                
                if ( switched_target ){
                	snprintf (buf3, MAX_STRING_LENGTH,  "It strays off-course, instead striking #5%s#0 on the %s!", temp_arg1, temp_arg);
                }
                else{
                   	snprintf (buf3, MAX_STRING_LENGTH,  "It grazes %s on the %s.", HMHR(target), temp_arg);
                }
			}
			else {
				if ( result == CRITICAL_HIT ){
					temp_arg = expand_wound_loc(smite_location);
					snprintf (buf, MAX_STRING_LENGTH,  "%s#0 comes whirring through the air from %s, headed straight toward you!\n\nThe missile lodges deeply in your %s!", ammo->short_description, from_direction, temp_arg);
				}
				else{
					temp_arg = expand_wound_loc(smite_location);
					snprintf (buf, MAX_STRING_LENGTH,  "%s#0 comes whirring through the air from %s, headed straight toward you!\n\nThe missile lodges in your %s!", ammo->short_description, from_direction, temp_arg);
				}
				
				*buf = toupper(*buf);
				snprintf (buffer, MAX_STRING_LENGTH,  "#2%s", buf);
				snprintf (buf, MAX_STRING_LENGTH,  "\n%s", buffer);
				if ( result == CRITICAL_HIT ){
					temp_arg = char_short(target);
					temp_arg1 = expand_wound_loc(smite_location);
					snprintf (buf2, MAX_STRING_LENGTH,  "%s#0 comes whirring through the air from %s, headed straight toward #5%s#0.\n\nThe missile lodges deeply in %s %s!", ammo->short_description, from_direction, temp_arg, HSHR(target), temp_arg1);
				}
				else{
					temp_arg = char_short(target);
					temp_arg1 = expand_wound_loc(smite_location);
					snprintf (buf2, MAX_STRING_LENGTH,  "%s#0 comes whirring through the air from %s, headed straight toward #5%s#0.\n\nThe missile lodges in %s %s!", ammo->short_description, from_direction, temp_arg, HSHR(target), temp_arg1);
				}
				*buf2 = toupper(*buf2);
				snprintf (buffer, MAX_STRING_LENGTH,  "#2%s", buf2);
				snprintf (buf2, MAX_STRING_LENGTH,  "\n%s", buffer);
				
				if ( switched_target ) {
					if ( result == CRITICAL_HIT ){
						temp_arg = char_short(target);
						temp_arg1 = expand_wound_loc(smite_location); 
						snprintf (buf3, MAX_STRING_LENGTH,  "It strays off-course, instead lodging deeply in #5%s#0's %s!", temp_arg, temp_arg1);
					}
					else{
						temp_arg = char_short(target);
						temp_arg1 = expand_wound_loc(smite_location); 
						snprintf (buf3, MAX_STRING_LENGTH,  "It strays off-course, instead lodging in #5%s#0's %s!", temp_arg, temp_arg1);
					}
				}   
			
				else {
					if ( result == CRITICAL_HIT ){
						temp_arg = expand_wound_loc(smite_location);
						snprintf (buf3, MAX_STRING_LENGTH,  "The missile lodges deeply in %s %s!", HSHR(target), temp_arg);
					}
					else {
						temp_arg = expand_wound_loc(smite_location);
						snprintf (buf3, MAX_STRING_LENGTH,  "The missile lodges in %s %s!", HSHR(target), temp_arg);
					}
				} 
			}
		}
		else if ( !ranged && result != CRITICAL_HIT && result != HIT ) {
			if ( switched_target ) {
				temp_arg = char_short (target);
				temp_arg1 = expand_wound_loc (smite_location);
				snprintf (buf, MAX_STRING_LENGTH,  "It strays off-course, grazing #5%s#0 on the %s.", temp_arg, temp_arg1 );
				snprintf (buf2, MAX_STRING_LENGTH,  "It strays off-course, grazing you on the %s.", temp_arg1);
			}
			else {
				temp_arg = expand_wound_loc (smite_location);
				snprintf (buf, MAX_STRING_LENGTH,  "It grazes %s on the %s.", HMHR (target), temp_arg);
				snprintf (buf2, MAX_STRING_LENGTH,  "It grazes you on the %s.", temp_arg);
			}
		}
		else if ( !ranged && (result == CRITICAL_HIT || result == HIT) ) {
			if ( switched_target ) {
				temp_arg1 = expand_wound_loc (smite_location);
				temp_arg2 = char_short(target);
				snprintf (buf, MAX_STRING_LENGTH,  "The missile strays off-course, striking #5%s#0 instead, and lodging deeply in %s %s!", temp_arg2, HSHR (target), temp_arg1 );
				snprintf (buf2, MAX_STRING_LENGTH,  "The missile strays off-course, striking you instead, and lodging deeply in your %s!", temp_arg1);
			}
			else {
				if ( result == CRITICAL_HIT ) {
					temp_arg = expand_wound_loc (smite_location);
					snprintf (buf, MAX_STRING_LENGTH,  "The missile lodges deeply in %s %s!", HSHR (target), temp_arg);
					snprintf (buf2, MAX_STRING_LENGTH,  "The missile lodges deeply in your %s!", temp_arg);
				}
				else {
					temp_arg = expand_wound_loc (smite_location);
					snprintf (buf, MAX_STRING_LENGTH,  "The missile lodges in %s %s!", HSHR (target), temp_arg);
					snprintf (buf2, MAX_STRING_LENGTH,  "The missile lodges in your %s!", temp_arg);
				}
			}
		}
	}

	if ( result == GLANCING_HIT ||
		result == MISS ||
		result == SHIELD_BLOCK ) {
		
		if ( !number(0,9) &&
			((armor1 || armor2 || target->armor) ||
			result == MISS ||
			result == SHIELD_BLOCK) ) {
			
			snprintf (buf + strlen(buf), MAX_STRING_LENGTH,  "\n\nThe missile shatters upon impact at its destination.");
			snprintf (buf2 + strlen(buf2), MAX_STRING_LENGTH,  "\n\nThe missile shatters upon impact at its destination.");
			snprintf (buf3 + strlen(buf3), MAX_STRING_LENGTH, "\n\nThe missile shatters upon impact at its destination.");
		}
		
		else {
			obj = load_object(ammo->virtual);
			obj->deleted = 0;
			obj->count = 1;
			obj->obj_timer = 8;			/* 2 RL hours. */
			obj->next_content = NULL;
			obj_to_room (obj, target->in_room);
		}
		extract_obj(bow->loaded);
		bow->loaded = NULL;
	}
	
	else if ( result == CRITICAL_HIT || result == HIT ) {
		lodge_missile (target, ammo, smite_location);
		bow->loaded = NULL;
	}

	if ( ranged ) {
		send_to_char ("\n", target);
		act (buf, TRUE, ch, 0, target, TO_VICT | TO_ACT_FORMAT);
		send_to_char ("\n", ch);
		act (buf3, TRUE, ch, 0, target, TO_CHAR | TO_ACT_FORMAT);
		
		for ( tch = target->room->people; tch; tch = tch->next_in_room ) {
			if ( tch != target && tch != ch ) {
				send_to_char ("\n", tch);
				act (buf2, TRUE, tch, 0, target, TO_CHAR | TO_ACT_FORMAT);
			}
		}
	}
	
	else if ( !ranged ) {
		act (buf2, TRUE, ch, 0, target, TO_VICT | TO_ACT_FORMAT);
		for ( tch = target->room->people; tch; tch = tch->next_in_room ) {
			if ( tch != target ) {
				send_to_char ("\n", tch);
				act (buf, TRUE, tch, 0, target, TO_CHAR | TO_ACT_FORMAT);
			}
		}
	}

	bow->loaded = NULL;

	criminalize (ch, target, target->room->zone, CRIME_KILL);

	ch->enemy_direction = NULL;

	if ( from_direction )
		mem_free (from_direction);
	
	if ( ch->delay_who ) {
		mem_free (ch->delay_who);
		ch->delay_who = NULL;
	}

	if (damage > 0) {
		if ( !IS_NPC (target) ) {
			target->delay_ch = ch;
			target->delay_info1 = ammo->virtual;
		}
		
		if ( wound_to_char (target, smite_location, (int)(damage), 0, 0, 0, 0) ) {
			if ( ranged ){
				send_to_char ("\nYour target collapses, dead.\n", ch);
			}
			ch->ranged_enemy = NULL;
			return;
		}
		
		if ( !IS_NPC (target) ) {
			target->delay_ch = NULL;
			target->delay_info1 = 0;
		}
	}

	for ( tch = target->room->people; tch; tch = tch->next_in_room ) {
		if ( !IS_NPC (tch) || !is_brother (target, tch) )
			continue;
		
		if ( morale_broken(tch) ||
			(!IS_SET (tch->act, ACT_ENFORCER) &&
			!IS_SET (tch->act, ACT_AGGRESSIVE)) )
			evade_attacker (tch, track (tch, ch->in_room));
	}

	npc_archery_retaliation (target, ch);

	return;

}

int has_been_sighted (CHAR_DATA *ch, CHAR_DATA *target)
{
	VIEWED_DATA		*sighted = NULL;

	if ( !ch || !target )
		return 0;

	if ( !IS_MORTAL (ch) )
		return 1;

	if ( IS_NPC (ch) && !ch->desc )
		return 1;		/* We know non-animated NPCs only acquire targets via SCANning; */
					/* don't need anti-twink code for them. */

	for ( sighted = ch->sighted; sighted; sighted = sighted->next ) {
		if ( sighted->target == target )
			return 1;
	}

	return 0;
}

void npc_archery_retaliation (CHAR_DATA *target, CHAR_DATA *ch)
{
	if ( IS_NPC (target) && !target->desc ) {
		add_threat (target, ch, 7);
		
		if ( IS_SET (target->act, ACT_MOUNT) && target->mount )
			add_threat (target->mount, ch, 7);
		
		if ( !target->fighting &&
			!IS_SET (target->flags, FLAG_ENTERING) &&
			!IS_SET (target->flags, FLAG_LEAVING) &&
			!IS_SET (target->flags, FLAG_FLEE) ) {
			do_stand (target, "", 0);
			target->speed = 4;
			
			if ( (track (target, ch->in_room) == -1 &&
				  target->in_room != ch->in_room) ||
				  (!IS_SET (ch->act, ACT_ENFORCER) &&
				  !IS_SET (ch->act, ACT_AGGRESSIVE)) ||
				 
				 	morale_broken (target) )
				evade_attacker (target, -1);
			else
				charge_archer (target, ch);
		}
		
		else if ( (IS_SET (target->act, ACT_MOUNT) &&
				target->mount) &&
				(IS_SET (target->mount->act, ACT_ENFORCER) ||
				IS_SET (target->mount->act, ACT_AGGRESSIVE)) &&
				!target->fighting &&
				!IS_SET (target->flags, FLAG_ENTERING) &&
				!IS_SET (target->flags, FLAG_LEAVING) &&
				!IS_SET (target->flags, FLAG_FLEE) ) {
					
				do_stand (target, "", 0);
				target->speed = 4;
			
				if ( (track (target, ch->in_room) == -1 &&
					target->in_room != ch->in_room) ||
					!(IS_SET (ch->act, ACT_ENFORCER) ||
					IS_SET (ch->act, ACT_AGGRESSIVE)) ||
					morale_broken (target) )
				
					evade_attacker (target, -1);
				else 
					charge_archer (target, ch);		
			}
		}
	return;
}

void do_aim (CHAR_DATA *ch, char *argument, int cmd)
{
	OBJ_DATA	*bow = NULL;
	CHAR_DATA	*target = NULL;
	CHAR_DATA	*tch = NULL;
	ROOM_DATA	*room = NULL;
	ROOM_DIRECTION_DATA	*exit_room = NULL;
	char		arg1 [MAX_STRING_LENGTH] = {'\0'};
	char		arg2 [MAX_STRING_LENGTH] = {'\0'};
	char		buf [MAX_STRING_LENGTH] = {'\0'};
	char		buffer [MAX_STRING_LENGTH] = {'\0'};
	int			ranged = 0;
	int			dir = 0;
	char		*temp_arg = NULL;
	char		*temp_arg1 = NULL;

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

	if ( IS_SET (ch->room->room_flags, OOC) && IS_MORTAL (ch) ) {
		send_to_char ("You cannot do this in an OOC area.\n", ch);
		return;
	}
	
	if ( ch->delay_type == DEL_LOAD_WEAPON ) {
		return;
	}

	argument = one_argument (argument, arg1);
	argument = one_argument (argument, arg2);

	if ( !*arg1 ) {
		send_to_char ("Usage: aim (<direction>) <target>\n", ch);
		return;
	}

	if ( !(bow = get_equip (ch, WEAR_BOTH)) || 
              (bow->o.weapon.use_skill != SKILL_SHORTBOW &&
	       bow->o.weapon.use_skill != SKILL_LONGBOW &&
               bow->o.weapon.use_skill != SKILL_CROSSBOW) ) {
		send_to_char ("You aren't wielding a ranged weapon.\n", ch);
		return;
	}

	if ( !bow->loaded ) {
		send_to_char ("Your weapon isn't loaded.\n", ch);
		return;
	}

	if ( (!cmp_strn ("east", arg1, strlen(arg1)) ||
             !cmp_strn ("west", arg1, strlen(arg1)) ||
             !cmp_strn ("north", arg1, strlen(arg1)) ||
             !cmp_strn ("south", arg1, strlen(arg1)) ||
             !cmp_strn ("up", arg1, strlen(arg1)) ||
             !cmp_strn ("down", arg1, strlen(arg1))) && *arg2 )
		ranged = 1;

	if ( !ranged ) {
		
		
		if ( !(target = get_char_room_vis (ch, arg1)) ) {
			send_to_char ("Who did you want to target?\n", ch);
			return;
		}
		
		if ( target == ch ) {
			send_to_char ("Now, now, now... things can't be THAT bad, can they?\n", ch);
			return;
		}
		
		temp_arg = char_short(target);
		snprintf (buf, MAX_STRING_LENGTH,  "You begin to carefully take aim at #5%s#0.", temp_arg);
		act (buf, FALSE, ch, 0, 0, TO_CHAR | TO_ACT_FORMAT);
		
		temp_arg = char_short(ch);
		temp_arg1 = char_short (target);
		snprintf (buf, MAX_STRING_LENGTH,  "%s#0 begins to carefully take aim at #5%s#0 with #2%s#0.", temp_arg, temp_arg1, bow->short_description);
		
		*buf = toupper(*buf);
		snprintf (buffer, MAX_STRING_LENGTH,  "#5%s", buf);
		
		for ( tch = ch->room->people; tch; tch = tch->next_in_room ) {
			if ( tch == ch )
				continue;
			if ( tch == target )
				continue;
			if ( CAN_SEE (tch, ch) )
				act (buffer, FALSE, ch, 0, tch, TO_VICT | TO_ACT_FORMAT);
		}

		temp_arg = char_short(ch);
		snprintf (buf, MAX_STRING_LENGTH,  "%s#0 begins to carefully take aim at you with #2%s#0!", temp_arg, bow->short_description);
		*buf = toupper(*buf);
		snprintf (buffer, MAX_STRING_LENGTH,  "#5%s", buf);
		
		if ( CAN_SEE (target, ch) )
			act (buffer, FALSE, ch, 0, target, TO_VICT | TO_ACT_FORMAT);
		
		else if ( real_skill (target, SKILL_DANGER_SENSE) ) {
			if ( skill_use (target, SKILL_DANGER_SENSE, 0) )
				send_to_char ("The back of your neck prickles, as if you are being watched closely.\n", target);
		}

		ch->aiming_at = target;
		target->targeted_by = ch;
		return;
	}

	else if ( ranged ) {
		if ( !cmp_strn ("north", arg1, strlen(arg1)) )
			dir = 0;
		else if ( !cmp_strn ("east", arg1, strlen(arg1)) )
			dir = 1;
		else if ( !cmp_strn ("south", arg1, strlen(arg1)) )
			dir = 2;
		else if ( !cmp_strn("west", arg1, strlen(arg1)) )
			dir = 3;
		else if ( !cmp_strn ("up", arg1, strlen(arg1)) )
			dir = 4;
		else if ( !cmp_strn ("down", arg1, strlen(arg1)) )
			dir = 5;

		if ( !PASSAGE(ch, dir)) { 
			send_to_char ("There isn't an exit in that direction.\n", ch);
			return;
		}

		ch->delay_who = str_dup (dirs[dir]);

		room = vtor(PASSAGE(ch,dir)->to_room);

		exit_room = PASSAGE(ch, dir);
		
		if ( exit_room && IS_SET (exit_room->exit_info, PASSAGE_CLOSED) ) {
			send_to_char ("Your view is blocked.\n", ch);
			return;
		}

		
	
		if ( IS_SET (room->room_flags, STIFLING_FOG) ) {
			send_to_char ("The stiflingly heavy fog in that area thwarts any such attempt.\n", ch);
			return;
		}

		if (!(target = get_char_room_vis2 (ch, room->virtual, arg2)) ||
			!has_been_sighted (ch, target) ) {
			exit_room = room->dir_option[dir];
			if ( !exit_room ) {
				send_to_char ("You don't see them within range.\n", ch);
				return;
			}
			
			if ( exit_room && IS_SET (exit_room->exit_info, PASSAGE_CLOSED) ) {
				send_to_char ("Your view is blocked.\n", ch);
				return;
			}
			
			if ( room->dir_option[dir] )
				room = vtor(room->dir_option[dir]->to_room);
			else
				room = NULL;
			
			if ( bow->o.od.value[1] == 3 || !room ) {	/* Sling, eventually. */
				send_to_char ("You don't see them within range.\n", ch);
				return;
			}
			
			
			
			if ( IS_SET (room->room_flags, STIFLING_FOG) ) {
				send_to_char ("The stiflingly heavy fog in that area thwarts any such attempt.\n", ch);
				return;
			}
			
			if (!(target = get_char_room_vis2 (ch, room->virtual, arg2)) ||
				 !has_been_sighted (ch, target) ) {
				exit_room = room->dir_option[dir];
				
				if ( !exit_room ) {
					send_to_char ("You don't see them within range.\n", ch);
					return;
				}
				
				if ( exit_room && IS_SET (exit_room->exit_info, PASSAGE_CLOSED) ) {
					send_to_char ("Your view is blocked.\n", ch);
					return;
				}
				
				if ( room->dir_option[dir] )
					room = vtor(room->dir_option[dir]->to_room);
				else 
					room = NULL;
				
				if ( bow->o.od.value[1] == 2 || !room ) {	/* Crossbows and shortbows; two-room range. */
					send_to_char ("You don't see them within range.\n", ch);
					return;
				}
				
				
				
				if ( IS_SET (room->room_flags, STIFLING_FOG) ) {
					send_to_char ("The stiflingly heavy fog in that area thwarts any such attempt.\n", ch);
					return;
				}
				
				if (!(target = get_char_room_vis2(ch, room->virtual, arg2)) ||
					!has_been_sighted (ch, target) ) {
					exit_room = room->dir_option[dir];
					if ( !exit_room ) {
						send_to_char ("You don't see them within range.\n", ch);
						return;
					}
					if ( IS_SET (exit_room->exit_info, PASSAGE_CLOSED) ) {
						send_to_char ("Your view is blocked.\n", ch);
						return;
					}
					send_to_char ("You don't see them within range.\n", ch);
					return;
				}
				else ch->delay_info1 = 3;
			}
			else ch->delay_info1 = 2;
		}
		
		if ( !target ||
			!CAN_SEE (ch, target) ||
			!has_been_sighted (ch, target) ) {
			send_to_char ("You don't see them within range.\n", ch);
			return;
		}
		
		if ( target == ch ) {
			send_to_char ("Now, now, now... things can't be THAT bad, can they?\n", ch);
			return;
		}
		
		temp_arg = char_short(target);
		snprintf (buf, MAX_STRING_LENGTH,  "You begin to carefully take aim at #5%s#0.", temp_arg);
		act (buf, FALSE, ch, 0, 0, TO_CHAR | TO_ACT_FORMAT);
		
		temp_arg = char_short(ch);
		snprintf (buf, MAX_STRING_LENGTH,  "%s#0 turns %sward, taking aim at a distant target with #2%s#0.", temp_arg, dirs[dir], bow->short_description);
		*buf = toupper(*buf);
		ch->ranged_enemy = target;
		snprintf (buffer, MAX_STRING_LENGTH,  "#5%s", buf);
		
		for ( tch = ch->room->people; tch; tch = tch->next_in_room ) {
			if ( tch == ch )
				continue;
			if ( tch == target )
				continue;
			if ( CAN_SEE (tch, ch) )
				act (buffer, FALSE, ch, 0, tch, TO_VICT | TO_ACT_FORMAT);
		}
		
		if ( real_skill (target, SKILL_DANGER_SENSE) ) {
			if ( skill_use (target, SKILL_DANGER_SENSE, 0) )
				send_to_char ("The back of your neck prickles, as if you are being watched closely.\n", target);
		}
		ch->aiming_at = target;
		target->targeted_by = ch;
		return;		
	}
	
	return;
}

void do_unload (CHAR_DATA *ch, char *argument, int cmd)
{
	OBJ_DATA	*bow = NULL;
	OBJ_DATA	*arrow = NULL;
	OBJ_DATA	*quiver = NULL;
	int			i = 0;
	char		*error = NULL;
	char		buf[MAX_STRING_LENGTH] = {'\0'};
	char		buffer[MAX_STRING_LENGTH] = {'\0'};
	char		*temp_arg1 = NULL;
	char		*temp_arg2 = NULL;
	char		*temp_arg3 = NULL;

	bow = get_bow (ch);

   if ( !bow ) {
        send_to_char ("What did you wish to unload?\n", ch);
    	return;
    }

	if ( !bow->loaded ) {
		send_to_char ("That isn't loaded.\n", ch);
		return;
	}

	if ( !(arrow = bow->loaded) ) {
		send_to_char ("That isn't loaded.\n", ch);
		return;
	}

	temp_arg1 = char_short (ch);
	snprintf (buf, MAX_STRING_LENGTH,  "%s#0 unloads #2%s#0.", temp_arg1, bow->short_description);
	
	*buf = toupper (*buf);
	snprintf (buffer, MAX_STRING_LENGTH,  "#5%s", buf);
	act (buffer, FALSE, ch, 0, 0, TO_ROOM | TO_ACT_FORMAT);

	arrow = load_object(bow->loaded->virtual);
	arrow->in_obj = NULL;
	arrow->carried_by = NULL;

    for ( i = 0; i < MAX_WEAR; i++ ) {
		if ( !(quiver = get_equip (ch, i)) )
        	continue;
        if ( GET_ITEM_TYPE (quiver) == ITEM_QUIVER &&
        	get_obj_in_list_num (arrow->virtual, quiver->contains) &&
            can_obj_to_container (arrow, quiver, &error, 1) )
			break;
    }

	if ( !quiver ) {
    	for ( i = 0; i < MAX_WEAR; i++ ) {
	       	if ( !(quiver = get_equip (ch, i)) )
               		continue;
        	if ( GET_ITEM_TYPE (quiver) == ITEM_QUIVER &&
        		can_obj_to_container (arrow, quiver, &error, 1) )
					break;
			else 
					quiver = NULL;
        }
	}
	
	if ( quiver ) {
		send_to_char ("\n", ch);
		temp_arg1 = obj_short_desc(bow);
		temp_arg2 = obj_short_desc(arrow);
		temp_arg3 = obj_short_desc(quiver);
		snprintf (buf, MAX_STRING_LENGTH,  "You unload #2%s#0, and slide #2%s#0 into #2%s#0.", temp_arg1, temp_arg2, temp_arg3);
		act (buf, FALSE, ch, 0, 0, TO_CHAR | TO_ACT_FORMAT);
		obj_to_obj (arrow, quiver);
        }
	else if ( !quiver ) {
		temp_arg1 = obj_short_desc(bow);
		snprintf (buf, MAX_STRING_LENGTH,  "You unload #2%s#0.\n", temp_arg1);
		send_to_char (buf, ch);
		obj_to_char (arrow, ch);
	}

	bow->loaded = NULL;
	
	return;
}

void delayed_load (CHAR_DATA *ch)
{
	OBJ_DATA	*bow = NULL;
	OBJ_DATA	*ammo = NULL;
	OBJ_DATA	*quiver = NULL;
	char		buf [MAX_STRING_LENGTH] = {'\0'};
	int			i = 0;

	if ( !(bow = get_equip (ch, WEAR_BOTH)) ) {
		ch->delay_who = NULL;
		ch->delay = 0;
		ch->delay_type = 0;
		ch->delay_info1 = 0;
		ch->delay_info2 = 0;
		return;
	}

	if ( bow->o.weapon.use_skill != SKILL_SHORTBOW &&
	     bow->o.weapon.use_skill != SKILL_LONGBOW &&
	     bow->o.weapon.use_skill != SKILL_CROSSBOW ) {
		ch->delay_who = NULL;
		ch->delay = 0;
		ch->delay_type = 0;
		ch->delay_info1 = 0;
		ch->delay_info2 = 0;
		return;
	}

	ammo = NULL;

    for ( i = 0; i < MAX_WEAR; i++ ) {
		if ( !(quiver = get_equip (ch, i)) )
			continue;
 		
 		if ( quiver->virtual != ch->delay_info1 ||
 			!get_obj_in_list_num (ch->delay_info2, quiver->contains) )
            continue;
            
        if ( GET_ITEM_TYPE (quiver) == ITEM_QUIVER ) {
        	for ( ammo = quiver->contains; ammo; ammo = ammo->next_content ){
            	if ( GET_ITEM_TYPE (ammo) == ITEM_MISSILE && ammo->virtual == ch->delay_info2 ){
                	break;
                }
                
				if ( ammo )
					break;
            }
        }	
	}
	
	if ( !ammo ) {
		send_to_char ("Having lost your ammunition, you cease loading your weapon.\n", ch);
		return;
	}

	snprintf (buf, MAX_STRING_LENGTH,  "You finish loading #2%s#0.\n", bow->short_description);
	send_to_char (buf, ch);

	snprintf (buf, MAX_STRING_LENGTH,  "$n finishes loading #2%s#0.", bow->short_description);
	act (buf, TRUE, ch, 0, 0, TO_ROOM | TO_ACT_FORMAT);

	bow->loaded = load_object(ammo->virtual);

	if ( IS_MORTAL(ch) )
		obj_from_obj (&ammo, 1);

	ch->delay_who = NULL;
	ch->delay = 0;
	ch->delay_info1 = 0;
	ch->delay_info2 = 0;
	ch->delay_type = 0;
	
	return;

}

void do_hit (CHAR_DATA *ch, char *argument, int cmd)
{
	CHAR_DATA	*victim= NULL;
	CHAR_DATA	*tch =  NULL;
	OBJ_DATA	*obj = NULL;
	int			i = 0;
	int			agi_diff=0;
	char		buf [MAX_STRING_LENGTH] = {'\0'};
	char		original [MAX_STRING_LENGTH] = {'\0'};

	snprintf (original, MAX_STRING_LENGTH, "%s", argument);

				/* cmd = 0 if hit,
				   cmd = 1 if kill */

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

	if ( IS_SET (ch->room->room_flags, OOC) && IS_MORTAL (ch) ) {
		send_to_char ("You cannot do this in an OOC area.\n", ch);
		return;
	}
	
	if ( is_room_affected (ch->room->affects, MAGIC_ROOM_CALM) ) {
		act ("Try as you might, you simply cannot muster the will to break "
			 "the peace that pervades the area.",
				FALSE, ch, 0, 0, TO_CHAR);
		return;
	}
	
	if ( IS_SET (ch->flags, FLAG_PACIFIST) ) {
		send_to_char ("Remove your pacifist flag, first...\n", ch);
		return;
	}

	argument = one_argument (argument, buf);

	if ( (obj = get_equip (ch, WEAR_BOTH)) ) {
		if ( obj->o.weapon.use_skill == SKILL_LONGBOW ||
		     obj->o.weapon.use_skill == SKILL_SHORTBOW ||
                     obj->o.weapon.use_skill == SKILL_CROSSBOW ||
		     obj->o.weapon.use_skill == SKILL_SLING ||
                     obj->o.weapon.use_skill == SKILL_THROWN ) {
				send_to_char ("You can't use that in melee combat!\n", ch);
				return;
		}
	}

	if ( get_affect (ch, MAGIC_AFFECT_PARALYSIS) ) {
		send_to_char ("You are paralyzed and unable to fight!\n\r", ch);
		return;
	}

	if ( get_affect (ch, MAGIC_AFFECT_FEAR) ) {
		send_to_char ("You are too afraid to fight!\n\r", ch);
		return;
	}

	if ( IS_SUBDUER (ch) ) {
		act ("You can't attack while you have $N subdued.",
				FALSE, ch, 0, ch->subdue, TO_CHAR);
		return;
	}

        if ( IS_SET (ch->plr_flags, NEW_PLAYER_TAG) && IS_SET (ch->room->room_flags, LAWFUL) && *argument != '!' ) {
                snprintf (buf, MAX_STRING_LENGTH,  "You are in a lawful area; you would likely be flagged wanted for assault. "
                              "To confirm, type \'#6hit %s !#0\', without the quotes.", original);
                act (buf, FALSE, ch, 0, 0, TO_CHAR | TO_ACT_FORMAT);
		return;
        }

	if ( !*buf ) {

		if ( IS_SET (ch->flags, FLAG_FLEE) ) {
			send_to_char ("You stop trying to flee.\n\r", ch);
			REMOVE_BIT (ch->flags, FLAG_FLEE);
			return;
		}

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

	if ( !(victim = get_char_room_vis (ch, buf)) ) {
		send_to_char ("They aren't here.\n\r", ch);
		return;
	}

	if ( victim == ch ) {
		send_to_char ("You affectionately pat yourself.\n\r", ch);
		act ("$n affectionately pats $mself.", FALSE, ch, 0, victim, TO_ROOM);
		return;
	}

	if ( IS_SET (victim->act, ACT_PREY) && AWAKE (victim) ) {
		if ( !get_affect (ch, MAGIC_HIDDEN) || !skill_use (ch, SKILL_SNEAK, 0) ) {
			act ("As you approach, $N spots you and darts away! Try using a ranged weapon or an ambush from hiding instead.", FALSE, ch, 0, victim, TO_CHAR | TO_ACT_FORMAT);
			act ("As $n approaches, $N spots $m and darts away.", FALSE, ch, 0, victim, TO_ROOM | TO_ACT_FORMAT);
			evade_attacker (victim, -1);
			add_threat (victim, ch, 7);
			return;
		}
		else act ("You successfully ambush $N, leaping from your cover to attack!", FALSE, ch, 0, victim, TO_CHAR | TO_ACT_FORMAT);
	}

	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_SET (victim->act, ACT_VEHICLE) ) {
		send_to_char ("How do you propose to kill an inanimate object, hmm?\n", ch);
		return;
	}

    for ( tch = vtor (ch->in_room)->people; tch; tch = tch->next_in_room ){
	   	if (tch->fighting == victim) {
			if (++i >= 4) {
	    		act ("You can't find an opening to attack $N.",
					FALSE, ch, 0, victim, TO_CHAR);
	    		return;
			}
    	}
	}
	
	REMOVE_BIT (ch->flags, FLAG_FLEE);
	REMOVE_BIT (ch->act, PLR_STOP);

	if ( GET_POS (ch) == POSITION_STANDING &&
		 !ch->fighting &&
		 victim != ch->fighting ) {

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

		ch->primary_delay = 0;
		ch->secondary_delay = 0;

		if ( cmd == 0 )
			REMOVE_BIT (ch->flags, FLAG_KILL);
		else
			SET_BIT (ch->flags, FLAG_KILL);

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

		hit_char (ch, victim, 0);

		WAIT_STATE(ch, 9); 		

		if ( victim->deleted )
			return;

		if ( IS_SET (victim->act, ACT_MEMORY) && IS_NPC (victim) ) 
			add_memory (ch, victim);

			/* Looks like a problem.  If you hit/kill in one hit, then
			   trigger isn't called. */

		trigger (ch, argument, TRIG_HIT);

		if ( ch->fighting == victim && IS_SUBDUEE (victim) )
			stop_fighting (ch);
	}

	else if ( ch->fighting == victim &&
			  !IS_SET (ch->flags, FLAG_KILL) &&
			  AWAKE (ch) && cmd == 1 ) {
		act ("You will try to kill $N.", FALSE, ch, 0, victim, TO_CHAR);
		SET_BIT (ch->flags, FLAG_KILL);
	}

	else if ( ch->fighting == victim &&
			  IS_SET (ch->flags, FLAG_KILL) &&
			  AWAKE (ch) && cmd == 0 ) {
		act ("You will try NOT to kill $N.", FALSE, ch, 0, victim, TO_CHAR);
		REMOVE_BIT (ch->flags, FLAG_KILL);
	}

	else if ( ch->fighting &&
			  (GET_POS (ch) == FIGHT ||
			   GET_POS (ch) == STAND) &&
			  victim != ch->fighting ) {
		
		if ( ch->agi <= 9 )
			ch->balance += -15;
		else if ( ch->agi > 9 && ch->agi <= 13 )
			ch->balance += -13;
		else if ( ch->agi > 13 && ch->agi <= 15 )
			ch->balance += -11;
		else if ( ch->agi > 15 && ch->agi <= 18 )
			ch->balance += -9;
		else ch->balance += -7;
		ch->balance = MAX (ch->balance, -50);

		if ( ch->balance < -15 ) {
			act ("You need more balance before you can try to attack $N!",FALSE,ch,0,victim,TO_CHAR | TO_ACT_FORMAT);
			return;
		}

		if ( ch->fighting ) {

			if ( ch->fighting->fighting == ch ) {

				agi_diff = GET_AGI (ch) - GET_AGI (ch->fighting);

				if ( agi_diff > number(-10,10) && ( number(0,19) != 0 ) ) {
				  
					act ("You fail to shift your attention away from $N.",FALSE,ch,0,ch->fighting,TO_CHAR | TO_ACT_FORMAT | TO_ACT_COMBAT);
					act ("$N fails to shift their attention away from you.",FALSE,ch->fighting,0,ch,TO_CHAR | TO_ACT_FORMAT | TO_ACT_COMBAT);
					act ("$N fails to shift their attention away from $n.", FALSE, ch->fighting, 0, ch, TO_NOTVICT | TO_ACT_FORMAT | TO_ACT_COMBAT);

					return;
				}
			}

			act ("You stop fighting $N.",
			     FALSE, ch, 0, ch->fighting, TO_CHAR);
			act ("You ready yourself for battle with $N.",
			     FALSE, ch, 0, victim, TO_CHAR);
			stop_fighting (ch);

		}

		if ( (is_area_enforcer (victim) || victim->race == RACE_WOLF) && IS_NPC (victim) )
			do_alert (victim, "", 0);

		set_fighting (ch, victim);

		act ("You notice $N's attention shift toward you!",
					FALSE, victim, 0, ch, TO_CHAR);

		if ( cmd == 0 )
			REMOVE_BIT (ch->flags, FLAG_KILL);
		else
			SET_BIT (ch->flags, FLAG_KILL);

		if ( IS_SET (victim->act, ACT_MEMORY) && IS_NPC (victim) ) 
			add_memory (ch, victim);

		trigger (ch, argument, TRIG_HIT);
	}

	else
		send_to_char ("You're doing the best you can!\n\r", ch);
	
	return;
}


void do_nokill (CHAR_DATA *ch, char *argument, int cmd)
{
	send_to_char ("Please spell out all of 'kill' to avoid any mistakes.\n",
				  ch);
	return;
}

void do_kill (CHAR_DATA *ch, char *argument, int cmd)
{
	char			arg [MAX_STRING_LENGTH] = {'\0'};
	char			buf [MAX_STRING_LENGTH] = {'\0'};
	char			verify [MAX_STRING_LENGTH] = {'\0'};
	char			original [MAX_STRING_LENGTH] = {'\0'};
	CHAR_DATA		*victim = NULL;
	CHAR_DATA		*tch = NULL;
	OBJ_DATA		*obj = NULL;
    int				i = 0;

	snprintf (original, MAX_STRING_LENGTH, "%s", argument);

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

	if ( IS_NPC (ch) ) {
		do_hit (ch, argument, 1);
    		return;
	}
	
	if ( IS_SET (ch->room->room_flags, OOC) && IS_MORTAL(ch) ) {
		send_to_char ("You cannot do this in an OOC area.\n", ch);
		return;
	}

	if ( IS_SET (ch->flags, FLAG_PACIFIST) ) {
		send_to_char ("Remove your pacifist flag, first...\n", ch);
		return;
	}

	if ( (obj = get_equip (ch, WEAR_BOTH)) ) {
		if ( obj->o.weapon.use_skill == SKILL_LONGBOW ||
		     obj->o.weapon.use_skill == SKILL_SHORTBOW ||
                     obj->o.weapon.use_skill == SKILL_CROSSBOW ||
		     obj->o.weapon.use_skill == SKILL_SLING ||
                     obj->o.weapon.use_skill == SKILL_THROWN ) {
				send_to_char ("You can't use that in melee combat!\n", ch);
				return;
		}
	}

	argument = one_argument (argument, arg);

	argument = one_argument (argument, verify);

	if ( !*arg ) {
		send_to_char ("Kill who?\n\r", ch);
		return;
	}

	if ( !(victim = get_char_room_vis (ch, arg)) ) {
		send_to_char ("They aren't here.\n\r", ch);
		return;
	}

	if ( ch == victim ) {
	   	send_to_char ("You slap yourself on the wrist.\n\r", ch);
		return;
	}

	if ( IS_SET (victim->act, ACT_PREY) && AWAKE (victim) ) {
		if ( !get_affect (ch, MAGIC_HIDDEN) || !skill_use (ch, SKILL_SNEAK, 0) ) {
			act ("As you approach, $N spots you and darts away! Try using a ranged weapon or an ambush from hiding instead.", FALSE, ch, 0, victim, TO_CHAR | TO_ACT_FORMAT);
			act ("As $n approaches, $N spots $m and darts away.", FALSE, ch, 0, victim, TO_ROOM | TO_ACT_FORMAT);
			evade_attacker (victim, -1);
			add_threat (victim, ch, 7);
			return;
		}
		else act ("You successfully ambush $N, leaping from your cover to attack!", FALSE, ch, 0, victim, TO_CHAR | TO_ACT_FORMAT);
	}

	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_SET (victim->act, ACT_VEHICLE) ) {
		send_to_char ("How do you propose to kill an inanimate object, hmm?\n", ch);
		return;
	}

        if ( IS_SET (ch->plr_flags, NEW_PLAYER_TAG) && IS_SET (ch->room->room_flags, LAWFUL) && *verify != '!' ) {
                snprintf (buf, MAX_STRING_LENGTH,  "You are in a lawful area; you would likely be flagged wanted for assault. "
                              "To confirm, type \'#6hit %s !#0\', without the quotes.", original);
                act (buf, FALSE, ch, 0, 0, TO_CHAR | TO_ACT_FORMAT);
		return;
        }

        i = 0;
        for ( tch = vtor (ch->in_room)->people; tch; tch = tch->next_in_room ){
            if(tch->fighting == victim) {
                if(++i >= 4) {
                    act ("You can't find an opening to attack $N.",
                        FALSE, ch, 0, victim, TO_CHAR);
                    return;
                }

            }
        }

	if ( (is_area_enforcer (victim) || victim->race == RACE_WOLF) && IS_NPC (victim) )
		do_alert (victim, "", 0);

	if ( ch->fighting ) {
		ch->fighting = victim;
		act ("You will fight $N until $E is dead.",
					FALSE, ch, 0, victim, TO_CHAR);
		return;
	}

	if ( IS_NPC (ch) || !GET_TRUST (ch) ) {

		SET_BIT (ch->flags, FLAG_KILL);

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

		hit_char (ch, victim, 0);
	}

   	else {
		if ( !IS_NPC (victim) && *verify != '!' ) {
			send_to_char ("Target is a player character.  Please use "
						  "'KILL <name> !' syntax if \n\ryou really mean it.'\n\r", ch);
			return;
		}

		if ( GET_TRUST (victim) > GET_TRUST (ch) ) {
			victim = ch;
		}

		act ("$n stares at you, narrowing $s eyes. Shortly thereafter, your heart obediently ceases to beat, and you feel death upon you...", FALSE, ch, 0, victim, TO_VICT | TO_ACT_FORMAT);

		act ("You narrow your eyes in concentration, and $N collapses, dead.", FALSE, ch, 0, victim, TO_CHAR | TO_ACT_FORMAT);

		act ("$n stares at $N, narrowing $s eyes. Suddenly, $N collapses, dead.", FALSE, ch, 0, victim, TO_NOTVICT | TO_ACT_FORMAT);

		die (victim);
	}
	return;
}

void do_order (CHAR_DATA *ch, char *argument, int cmd)
{
	int			everyone = 0;
	CHAR_DATA	*victim = NULL;
	CHAR_DATA	*next_in_room = NULL;
	CHAR_DATA	*tch = NULL;
	char		buf [MAX_STRING_LENGTH] = {'\0'};
	char		command [MAX_STRING_LENGTH] = {'\0'};
 	char		*temp_arg = NULL;
 	
	argument = one_argument (argument, buf);

	if ( !*buf ) {
		send_to_char ("Order whom?\n\r", ch);
		return;
	}

		/* We can order invis chars as well, why not :) */

	if ( !str_cmp (buf, "all") || !str_cmp (buf, "follower") ||
		 !str_cmp (buf, "followers") )
		everyone = 1;

	else if ( !(victim = get_char_room_vis (ch, buf)) &&
		 !(victim = get_char_room (buf, ch->in_room)) ) {
		send_to_char ("They aren't here.\n\r", ch);
		return;
	}

	while ( isspace (*argument) )
		argument++;

	if ( !*argument ) {
		send_to_char ("What is your order?\n\r", ch);
		return;
	}

	strcpy (command, argument);

	if ( victim == ch ) {
		send_to_char ("You don't have to give yourself orders.\n\r", ch);
		return;
	}

	if ( victim ) {

		if ( !is_leader (ch, victim) &&
			 victim->following != ch ) {
			act ("You do not have the authority to order $N.", FALSE, ch, 0, victim, TO_CHAR);
			return;
		}

		temp_arg = char_short (ch);
		snprintf (buf, MAX_STRING_LENGTH,  "#5%s#0 orders you to '%s'.\n", temp_arg, command);
		buf [2] = toupper (buf [2]);
		send_to_char (buf, victim);


		if ( victim->mob ) {
			send_to_char ("Ok.\n", ch);
			command_interpreter (victim, command);
		} 
		else {
			temp_arg = char_short (victim);
			snprintf (buf, MAX_STRING_LENGTH,  "You order #5%s#0 to '%s'.\n",
						temp_arg, command);
			send_to_char (buf, ch);
		}

		return;
	}

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

		next_in_room = tch->next_in_room;
		
		if ( !is_leader (ch, tch) &&
			 (tch->following != ch) )
			continue;
		
		temp_arg = char_short (ch);
		snprintf (buf, MAX_STRING_LENGTH,  "#5%s#0 orders you to '%s'.\n", temp_arg, command);
		buf [2] = toupper (buf [2]);
		send_to_char (buf, tch);

		if ( tch->mob )
			command_interpreter (tch, command);
	}

	send_to_char ("Ok.\n", ch);
	return;
}

void do_flee (CHAR_DATA *ch, char *argument, int cmd)
{
	int		dir;

	if ( !ch->fighting ) {
		send_to_char ("You're not fighting.\n\r", ch);
		return;
	} 

	if ( get_affect (ch, MAGIC_AFFECT_PARALYSIS) ) {
		send_to_char ("You are paralyzed and unable to flee!\n\r", ch);
		return;
	}

	if ( IS_SET (ch->flags, FLAG_FLEE) ) {
		send_to_char ("You are already trying to escape!\n\r", ch);
		return;
	}

	for ( dir = 0; dir < 6; dir++ )
		if ( CAN_GO (ch, dir) && !IsGuarded (ch->room, dir) )
			break;

	if ( dir == 6 ) {
		send_to_char ("THERE IS NOWHERE TO FLEE!!\n\r", ch);
		return;
	}

	SET_BIT (ch->flags, FLAG_FLEE);

	send_to_char ("You resolve to escape combat. . .\n\r", ch);

	act ("$n's eyes dart about looking for an escape path!",
				FALSE, ch, 0, 0, TO_ROOM);
	return;
}

int flee_attempt (CHAR_DATA *ch)
{
	int				dir = 0;
	int				enemies = 0;
	int				mobless_count = 0;
	int				mobbed_count = 0;
	int				mobless_dirs [6];
	int				mobbed_dirs [6];
	CHAR_DATA		*tch = NULL;
	char			buf [MAX_STRING_LENGTH] = {'\0'};
	ROOM_DATA		*troom = NULL;
/*
	if ( IS_SET (ch->flags, FLAG_SUBDUING) ) {
		REMOVE_BIT (ch->flags, FLAG_FLEE);
		return 0;
	}
*/
	if ( GET_POS (ch) < FIGHT )
		return 0;

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

		if ( tch->fighting != ch )
			continue;

		if ( GET_POS (tch) != FIGHT && GET_POS (tch) != STAND )
			continue;

		if ( !CAN_SEE (tch, ch) )
			continue;

		enemies++;
	}

        for ( dir = 0; dir < 6; dir++ ) {
        
                if ( !CAN_GO (ch, dir) )
                        continue;
        
                if ( vtor (PASSAGE (ch, dir)->to_room)->people )
                        mobbed_dirs [mobbed_count++] = dir;
                else
                        mobless_dirs [mobless_count++] = dir;
        }

	if ( !mobbed_count && !mobless_count ) {
		send_to_char ("There is nowhere to go!  You continue fighting!\n\r", ch);
		REMOVE_BIT (ch->flags, FLAG_FLEE);
		return 0;
	}

	if ( enemies && number (0, enemies) ) {
		switch (number (1, 3)) {
		case 1: send_to_char ("You attempt escape, but fail . . .\n\r", ch);
				break;
		case 2: send_to_char ("You nearly escape, but are blocked . . .\n\r", ch);
				break;
		case 3: send_to_char ("You continue seeking escape . . .\n\r", ch);
				break;
		}

		act ("$n nearly flees!", TRUE, ch, 0, 0, TO_ROOM);

		return 0;
	}

	if ( mobless_count )
		dir = mobless_dirs [number (0, mobless_count - 1)];
	else
		dir = mobbed_dirs [number (0, mobbed_count - 1)];

	troom = ch->room;

	/* stop_fighting_sounds (ch, troom); */

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

	do_move (ch, "", dir);

	act ("$n #3flees!#0", FALSE, ch, 0, 0, TO_ROOM);

	snprintf (buf, MAX_STRING_LENGTH,  "#3YOU FLEE %s!#0", dirs [dir]);
	act (buf, FALSE, ch, 0, 0, TO_CHAR);

	if ( !enemies )
		snprintf (buf, MAX_STRING_LENGTH,  "\nYou easily escaped to the %s.\n\r", dirs [dir]);
	else
		snprintf (buf, MAX_STRING_LENGTH,  "\nYou barely escaped to the %s.\n\r", dirs [dir]);

	if ( ch->room != troom )
		send_to_char (buf, ch);

	REMOVE_BIT (ch->flags, FLAG_FLEE);

	return 1;
}

	/* In case victim is being guarded, make sure rescue affects are active. */

void guard_check (CHAR_DATA *victim)
{
	CHAR_DATA		*tch;
	AFFECTED_TYPE	*af;

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

		if ( !(af = get_affect (tch, MAGIC_GUARD)) )
			continue;

		if ( (CHAR_DATA *) af->a.spell.t == victim &&
			 !get_second_affect (tch, SPA_RESCUE, NULL) )
			add_second_affect (SPA_RESCUE, 1, tch, (OBJ_DATA *) victim, NULL, 0);
	}
	
	return;
}

void do_guard (CHAR_DATA *ch, char *argument, int cmd)
{
	CHAR_DATA		*target = NULL;
	CHAR_DATA		*tch = NULL;
	AFFECTED_TYPE		*af;
	char			buf [MAX_STRING_LENGTH] = {'\0'};
	int			dir;

	if ( IS_SET (ch->room->room_flags, OOC) ) {
		send_to_char ("That command cannot be used in an OOC area.\n", ch);
		return;
	}

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

	argument = one_argument (argument, buf);

	if ( *buf && !(target = get_char_room_vis (ch, buf)) ) {
                if ( (dir = index_lookup (dirs, buf)) == -1 ) {
                        send_to_char ("Who or what did you want to guard?\n", ch);
                        return;
                }
                
		if ( !(af = get_affect (ch, AFFECT_GUARD_DIR)) )
               		magic_add_affect (ch, AFFECT_GUARD_DIR, -1, 0, 0, 0, 0);
        
                af = get_affect (ch, AFFECT_GUARD_DIR);
                
            	af->a.shadow.shadow = NULL;
                af->a.shadow.edge = dir;

		snprintf (buf, MAX_STRING_LENGTH,  "You will now guard the %s exit.\n", dirs[dir]);
		send_to_char (buf, ch);
		snprintf (buf, MAX_STRING_LENGTH,  "$n moves to block the %s exit.", dirs[dir]);
		act (buf, TRUE, ch, 0, 0, TO_ROOM | TO_ACT_FORMAT);
		return;

	}

	if ( (!*buf || target == ch) ) {
		if ( !(af = get_affect (ch, MAGIC_GUARD)) && !(af = get_affect (ch, AFFECT_GUARD_DIR)) ) {
			send_to_char ("You are not currently guarding anything.\n", ch);
			return;
		}
		else if ( (af = get_affect (ch, MAGIC_GUARD)) && (tch = (CHAR_DATA *)af->a.spell.t) != NULL ) {
			act ("You cease guarding $N.", TRUE, ch, 0, tch, TO_CHAR | TO_ACT_FORMAT);
			act ("$n ceases guarding you.", FALSE, ch, 0, tch, TO_VICT | TO_ACT_FORMAT);	
			act ("$n ceases guarding $N.", FALSE, ch, 0, tch, TO_NOTVICT | TO_ACT_FORMAT);
			remove_affect_type (ch, MAGIC_GUARD);
			return;
		}
		else if ( (af = get_affect (ch, AFFECT_GUARD_DIR)) ) {
			act ("You cease guarding the exit.", TRUE, ch, 0, 0, TO_CHAR);
			remove_affect_type (ch, AFFECT_GUARD_DIR);
			return;
		}
		else {
			send_to_char ("You cease guarding.\n", ch);
			remove_affect_type (ch, MAGIC_GUARD);
			remove_affect_type (ch, AFFECT_GUARD_DIR);
			return;
		}
	}

	if ( get_affect (target, MAGIC_GUARD) || get_affect (target, AFFECT_GUARD_DIR) ) {
		send_to_char ("They're already trying to guard something themselves!\n", ch);
		return;
	}

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

	magic_add_affect (ch, MAGIC_GUARD, -1, 0, 0, 0, 0);

	if ( !(af = get_affect (ch, MAGIC_GUARD)) ) {
		send_to_char ("There is a bug in guard.  Please let an admin "
					  "know.\n", ch);
		return;
	}

	af->a.spell.t = (int) target;

	act ("You will now guard $N.", FALSE, ch, 0, target, TO_CHAR | TO_ACT_FORMAT);
	act ("$n moves into position to guard you.", FALSE, ch, 0, target, TO_VICT | TO_ACT_FORMAT);
	act ("$n moves into position to guard $N.", FALSE, ch, 0, target, TO_NOTVICT | TO_ACT_FORMAT);
	
	return;
}