R2b5/deity/
R2b5/gods/
R2b5/log/
R2b5/player/
/***************************************************************************
*   Original Diku Mud copyright (C) 1990, 1991 by Sebastian Hammer,        *
*   Michael Seifert, Hans Henrik St{rfeldt, Tom Madsen, and Katja Nyboe.   *
*                                                                          *
*   Merc Diku Mud improvments copyright (C) 1992, 1993 by Michael          *
*   Chastain, Michael Quan, and Mitchell Tse.                              *
*                                                                          *
*   In order to use any part of this Merc Diku Mud, you must comply with   *
*   both the original Diku license in 'license.doc' as well the Merc       *
*   license in 'license.txt'.  In particular, you may not remove either of *
*   these copyright notices.                                               *
*                                                                          *
*   Much time and thought has gone into this software and you are          *
*   benefitting.  We hope that you share your changes too.  What goes      *
*   around, comes around.                                                  *
***************************************************************************/
/***************************************************************************
*       ROM 2.4 is copyright 1993-1995 Russ Taylor                         *
*       ROM has been brought to you by the ROM consortium                  *
*           Russ Taylor (rtaylor@pacinfo.com)                              *
*           Gabrielle Taylor (gtaylor@pacinfo.com)                         *
*           Brian Moore (rom@rom.efn.org)                                  *
*       By using this code, you have agreed to follow the terms of the     *
*       ROM license, in the file 'rom.license'                             *
***************************************************************************/
/***************************************************************************
*       ROT 2.0 is copyright 1996-1999 by Russ Walsh                       *
*       By using this code, you have agreed to follow the terms of the     *
*       ROT license, in the file 'rot.license'                             *
***************************************************************************/

#if defined(macintosh)
#include <types.h>
#else
#include <sys/types.h>
#endif
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <stdlib.h>
#include <ctype.h>
#include "merc.h"
#include "tables.h"
#include "interp.h"

float cpo_stat, vpo_stat;	//actual pay-off ratio for arena

const int vam_str[] = {
    6, 5, 4, 3, 2, 1, 0, 1, 2, 3, 4, 5,
    6, 5, 4, 3, 2, 1, 0, 1, 2, 3, 4, 5
};

/*
 * Local functions.
 */
void    check_assist    args ( ( CHAR_DATA * ch, CHAR_DATA * victim ) );
bool    check_dodge     args ( ( CHAR_DATA * ch, CHAR_DATA * victim ) );
bool    check_parry     args ( ( CHAR_DATA * ch, CHAR_DATA * victim ) );
bool    check_shield_block     args ( ( CHAR_DATA * ch, CHAR_DATA * victim ) );
void    dam_message   args ( ( CHAR_DATA * ch, CHAR_DATA * victim, int dam, int dt, bool immune ) );
void    death_cry     args ( ( CHAR_DATA * ch, CHAR_DATA * killer ) );
void    group_gain    args ( ( CHAR_DATA * ch, CHAR_DATA * victim ) );
int     xp_compute    args ( ( CHAR_DATA * gch, CHAR_DATA * victim, int total_levels ) );
bool    can_bypass    args ( ( CHAR_DATA * ch, CHAR_DATA * victim ) );
int     dambonus      args ( ( CHAR_DATA * ch, CHAR_DATA * victim, int dam, int stance ) );
void    special_move  args ( ( CHAR_DATA * ch, CHAR_DATA * victim ) );
bool    can_counter   args ( ( CHAR_DATA * ch ) );
bool    is_safe       args ( ( CHAR_DATA * ch, CHAR_DATA * victim ) );
bool    is_safe_mock  args ( ( CHAR_DATA * ch, CHAR_DATA * victim ) );
bool    is_voodood    args ( ( CHAR_DATA * ch, CHAR_DATA * victim ) );
void    make_corpse   args ( ( CHAR_DATA * ch, CHAR_DATA * killer ) );
void    one_hit       args ( ( CHAR_DATA * ch, CHAR_DATA * victim, int dt, bool secondary ) );
void    one_hit_mock  args ( ( CHAR_DATA * ch, CHAR_DATA * victim, int dt, bool secondary ) );
void    mob_hit       args ( ( CHAR_DATA * ch, CHAR_DATA * victim, int dt ) );
void    raw_kill      args ( ( CHAR_DATA * victim, CHAR_DATA * killer ) );
void    set_fighting  args ( ( CHAR_DATA * ch, CHAR_DATA * victim ) );
void    disarm        args ( ( CHAR_DATA * ch, CHAR_DATA * victim ) );
bool    check_fade    args ( ( CHAR_DATA *ch, CHAR_DATA *victim ) );

void check_arena args((CHAR_DATA * ch, CHAR_DATA * victim));

/*
 * Control the fights going on.
 * Called periodically by update_handler.
 */
void violence_update(void)
{
    CHAR_DATA *ch;
    CHAR_DATA *ch_next;
    CHAR_DATA *victim;

    for (ch = char_list; ch != NULL; ch = ch->next) {
	ch_next = ch->next;

	if ((victim = ch->fighting) == NULL || ch->in_room == NULL)
	    continue;

	if (IS_AWAKE(ch) && ch->in_room == victim->in_room)
	    multi_hit(ch, victim, TYPE_UNDEFINED);
	else
	    stop_fighting(ch, FALSE);

	if ((victim = ch->fighting) == NULL)
	    continue;

	/*
	 * Fun for the whole family!
	 */
	check_assist(ch, victim);

 	if ( IS_NPC( ch ) )
 	{
 	    if ( HAS_TRIGGER( ch, TRIG_FIGHT ) )
 		mp_percent_trigger( ch, victim, NULL, NULL, TRIG_FIGHT );
 	    if ( HAS_TRIGGER( ch, TRIG_HPCNT ) )
 		mp_hprct_trigger( ch, victim );
 	}
    }

    return;
}

/* for auto assisting */
void check_assist(CHAR_DATA * ch, CHAR_DATA * victim)
{
    CHAR_DATA *rch, *rch_next;

    for (rch = ch->in_room->people; rch != NULL; rch = rch_next) {
	rch_next = rch->next_in_room;

	if (IS_AWAKE(rch) && rch->fighting == NULL) {

	    /* quick check for ASSIST_PLAYER */
	    if (!IS_NPC(ch) && IS_NPC(rch)
		&& IS_SET(rch->off_flags, ASSIST_PLAYERS)
		&& rch->level + 6 > victim->level) {
		do_emote(rch, "{Rscreams and attacks!{x");
		multi_hit(rch, victim, TYPE_UNDEFINED);
		continue;
	    }

	    /* PCs next */
	    if (!IS_NPC(ch) || IS_AFFECTED(ch, AFF_CHARM)) {
		if (!IS_NPC(rch) && !IS_NPC(victim)
		    && (!is_pkill(rch) || !is_pkill(victim))
		    && !IS_SET(victim->act, PLR_TWIT))
		    continue;

		if (((!IS_NPC(rch) && IS_SET(rch->act, PLR_AUTOASSIST))
		     || IS_AFFECTED(rch, AFF_CHARM))
		    && is_same_group(ch, rch)
		    && !is_safe(rch, victim))
		    multi_hit(rch, victim, TYPE_UNDEFINED);

		continue;
	    }

	    /* now check the NPC cases */

	    if (IS_NPC(ch) && !IS_AFFECTED(ch, AFF_CHARM))
	     {
		if ((IS_NPC(rch) && IS_SET(rch->off_flags, ASSIST_ALL))

		    || (IS_NPC(rch) && rch->group
			&& rch->group == ch->group)

		    || (IS_NPC(rch) && rch->race == ch->race
			&& IS_SET(rch->off_flags, ASSIST_RACE))

		    || (IS_NPC(rch) && IS_SET(rch->off_flags, ASSIST_ALIGN)
			&& ((IS_GOOD(rch) && IS_GOOD(ch))
			    || (IS_EVIL(rch) && IS_EVIL(ch))
			    || (IS_NEUTRAL(rch) && IS_NEUTRAL(ch))))

		    || (rch->pIndexData == ch->pIndexData
			&& IS_SET(rch->off_flags, ASSIST_VNUM)))
		 {
		    CHAR_DATA *vch;
		    CHAR_DATA *target;
		    int number;

		    if (number_bits(1) == 0)
			continue;

		    target = NULL;
		    number = 0;
		    for (vch = ch->in_room->people; vch; vch = vch->next) {
			if (can_see(rch, vch)
			    && is_same_group(vch, victim)
			    && number_range(0, number) == 0) {
			    target = vch;
			    number++;
			}
		    }

		    if (target != NULL) {
			do_emote(rch, "{Rscreams and attacks!{x");
			multi_hit(rch, target, TYPE_UNDEFINED);
		    }
		}
	    }
	}
    }
}


/*
 * Do one group of attacks.
 */
void multi_hit(CHAR_DATA * ch, CHAR_DATA * victim, int dt)
{
    int chance;
    int count = 1;		// DB
    /* decrement the wait */
    if (ch->desc == NULL)
	ch->wait = UMAX(0, ch->wait - PULSE_VIOLENCE);

    if (ch->desc == NULL)
	ch->daze = UMAX(0, ch->daze - PULSE_VIOLENCE);


    /* no attacks for stunnies -- just a check */
    if (ch->position < POS_RESTING)
	return;

    if (ch->shadow) {
	ch->shadowing->shadowed = FALSE;
	ch->shadowing->shadower = NULL;
	ch->shadowing = NULL;
	ch->shadow = FALSE;
    }
    if (ch->stunned) {
	ch->stunned--;
	if (!ch->stunned) {
	    send_to_char("You regain your equilibrium.\n\r", ch);
	    act("$n regains $s equilibrium.", ch, NULL, NULL, TO_ROOM);
	}
	return;
    }

    if (IS_NPC(ch)) {
	mob_hit(ch, victim, dt);
	return;
    }

    one_hit(ch, victim, dt, FALSE);

    if (get_eq_char(ch, WEAR_SECONDARY)) {
	chance = (get_skill(ch, gsn_dual_wield) / 3) * 2;
	chance += 33;
	if (number_percent() < chance) {
	    one_hit(ch, victim, dt, TRUE);
	    if (get_skill(ch, gsn_dual_wield) != 0 && (!IS_NPC(ch)
						       && ch->level >=
						       skill_table
						       [gsn_dual_wield].
						       skill_level[ch->
								   class]))
	    {
		check_improve(ch, gsn_dual_wield, TRUE, 1);
	    } else if (!IS_NPC(ch) && (ch->pcdata->tier == 2)) {
		if (get_skill(ch, gsn_dual_wield) != 0 && (!IS_NPC(ch)
							   && ch->level >=
							   skill_table
							   [gsn_dual_wield].
							   skill_level[ch->
								       clasb]))
		{
		    check_improve(ch, gsn_dual_wield, TRUE, 1);
		}
	    }
	}
	if (ch->fighting != victim)
	    return;
    }

    if (ch->fighting != victim)
	return;

    if (IS_AFFECTED(ch, AFF_HASTE))
	one_hit(ch, victim, dt, FALSE);

    if (IS_STANCE(ch, STANCE_SERPENT) && number_percent() >
	ch->stance[STANCE_SERPENT] * 0.5)
	count += 1;
    else if (IS_STANCE(ch, STANCE_MANTIS) && number_percent() >
	     ch->stance[STANCE_MANTIS] * 0.5)
	count += 1;
    else if (IS_STANCE(ch, STANCE_TIGER) && number_percent() >
	     ch->stance[STANCE_TIGER] * 0.5)
	count += 3;
    if (ch->fighting != victim || dt == gsn_backstab || dt == gsn_circle)
	return;

    chance = get_skill(ch, gsn_second_attack) / 2;

    if (IS_AFFECTED(ch, AFF_SLOW))
	chance /= 2;

    if (number_percent() < chance) {
	one_hit(ch, victim, dt, FALSE);
	check_improve(ch, gsn_second_attack, TRUE, 5);
	if (ch->fighting != victim)
	    return;
    } else {
	return;
    }

    chance = get_skill(ch, gsn_third_attack) / 2;

    if (IS_AFFECTED(ch, AFF_SLOW))
	chance /= 2;

    if (number_percent() < chance) {
	one_hit(ch, victim, dt, FALSE);
	check_improve(ch, gsn_third_attack, TRUE, 6);
	if (ch->fighting != victim)
	    return;
    } else {
	return;
    }

    chance = get_skill(ch, gsn_fourth_attack) / 2;

    if (IS_AFFECTED(ch, AFF_SLOW))
	chance /= 3;

    if (number_percent() < chance) {
	one_hit(ch, victim, dt, FALSE);
	check_improve(ch, gsn_fourth_attack, TRUE, 6);
	if (ch->fighting != victim)
	    return;
    } else {
	return;
    }

    chance = get_skill(ch, gsn_fifth_attack) / 2;

    if (IS_AFFECTED(ch, AFF_SLOW))
	chance = 0;

    if (ch->stance[0] > 0 && number_percent() == 1) {
	int stance = ch->stance[0];
	if (ch->stance[stance] >= 200) {
	    special_move(ch, victim);
	    return;
	}
    }
    if (number_percent() < chance) {
	one_hit(ch, victim, dt, FALSE);
	check_improve(ch, gsn_fifth_attack, TRUE, 6);
	if (ch->fighting != victim)
	    return;
    }

    return;
}

/* procedure for all mobile attacks */
void mob_hit(CHAR_DATA * ch, CHAR_DATA * victim, int dt)
{
    int chance, number;
    CHAR_DATA *vch, *vch_next;

    one_hit(ch, victim, dt, FALSE);

    if (ch->fighting != victim)
	return;

    if (ch->stunned)
	return;

    /* Area attack -- BALLS nasty! */

    if (IS_SET(ch->off_flags, OFF_AREA_ATTACK)) {
	for (vch = ch->in_room->people; vch != NULL; vch = vch_next) {
	    vch_next = vch->next;
	    if ((vch != victim && vch->fighting == ch))
		one_hit(ch, vch, dt, FALSE);
	}
    }

    if (ch->fighting != victim)
	return;

    if (get_eq_char(ch, WEAR_SECONDARY)) {
	chance = (get_skill(ch, gsn_dual_wield) / 3) * 2;
	chance += 33;
	if (number_percent() < chance) {
	    one_hit(ch, victim, dt, TRUE);
	}
	if (ch->fighting != victim)
	    return;
    }

    if (IS_AFFECTED(ch, AFF_HASTE)
	|| (IS_SET(ch->off_flags, OFF_FAST) && !IS_AFFECTED(ch, AFF_SLOW)))
	one_hit(ch, victim, dt, FALSE);

    if (ch->fighting != victim || dt == gsn_backstab || dt == gsn_circle)
	return;

    chance = get_skill(ch, gsn_second_attack) / 2;

    if (IS_AFFECTED(ch, AFF_SLOW) && !IS_SET(ch->off_flags, OFF_FAST))
	chance /= 2;

    if (number_percent() < chance) {
	one_hit(ch, victim, dt, FALSE);
	if (ch->fighting != victim)
	    return;
	chance = get_skill(ch, gsn_third_attack) / 2;

	if (IS_AFFECTED(ch, AFF_SLOW) && !IS_SET(ch->off_flags, OFF_FAST))
	    chance /= 2;

	if (number_percent() < chance) {
	    one_hit(ch, victim, dt, FALSE);
	    if (ch->fighting != victim)
		return;

	    chance = get_skill(ch, gsn_fourth_attack) / 2;

	    if (IS_AFFECTED(ch, AFF_SLOW)
		&& !IS_SET(ch->off_flags, OFF_FAST)) chance /= 3;

	    if (number_percent() < chance) {
		one_hit(ch, victim, dt, FALSE);
		if (ch->fighting != victim)
		    return;

		chance = get_skill(ch, gsn_fifth_attack) / 2;

		if (IS_AFFECTED(ch, AFF_SLOW)
		    && !IS_SET(ch->off_flags, OFF_FAST)) chance = 0;

		if (number_percent() < chance) {
		    one_hit(ch, victim, dt, FALSE);
		    if (ch->fighting != victim)
			return;
		}
	    }
	}
    }

    /* oh boy!  Fun stuff! */

    if (ch->wait > 0)
	return;

    number = number_range(0, 2);

    if (number == 1 && IS_SET(ch->act, ACT_MAGE)) {
	/*  { mob_cast_mage(ch,victim); return; } */ ;
    }

    if (number == 2 && IS_SET(ch->act, ACT_CLERIC)) {
	/* { mob_cast_cleric(ch,victim); return; } */ ;
    }

    /* now for the skills */

    number = number_range(0, 8);

    switch (number) {
    case (0):
	if (IS_SET(ch->off_flags, OFF_BASH))
	    do_bash(ch, "");
	break;

    case (1):
	if (IS_SET(ch->off_flags, OFF_BERSERK)
	    && !IS_AFFECTED(ch, AFF_BERSERK)) do_berserk(ch, "");
	break;


    case (2):
	if (IS_SET(ch->off_flags, OFF_DISARM)
	    || (get_weapon_sn(ch) != gsn_hand_to_hand
		&& (IS_SET(ch->act, ACT_WARRIOR)
		    || IS_SET(ch->act, ACT_VAMPIRE)
		    || IS_SET(ch->act, ACT_THIEF)))) do_disarm(ch, "");
	break;

    case (3):
	if (IS_SET(ch->off_flags, OFF_KICK))
	    do_kick(ch, "");
	break;

    case (4):
	if (IS_SET(ch->off_flags, OFF_KICK_DIRT))
	    do_dirt(ch, "");
	break;

    case (5):
	if (IS_SET(ch->off_flags, OFF_TAIL)) {
	    do_tail(ch,"");
	}
	break;

    case (6):
	if (IS_SET(ch->off_flags, OFF_TRIP))
	    do_trip(ch, "");
	break;

    case (7):
	if (IS_SET(ch->off_flags, OFF_CRUSH)) {
	    do_crush(ch,"");
	}
	break;
    case (8):
	if (IS_SET(ch->off_flags, OFF_BACKSTAB)) {
	    do_backstab(ch, "");
	}
    }
}


/*
 * Hit one guy once.
 */
void one_hit(CHAR_DATA * ch, CHAR_DATA * victim, int dt, bool secondary)
{
    OBJ_DATA *wield;
    int victim_ac;
    int thac0;
    int thac0_00;
    int thac0_32;
    int dam;
    int stance;
    int diceroll;
    int sn, skill;
    int dam_type;
    bool result;

    sn = -1;


    /* just in case */
    if (victim == ch || ch == NULL || victim == NULL)
	return;

    /*
     * Can't beat a dead char!
     * Guard against weird room-leavings.
     */
    if (victim->position == POS_DEAD || ch->in_room != victim->in_room
	|| victim->spirit) return;

    /*
     * Figure out the type of damage message.
     * if secondary == true, use the second weapon.
     */
    if (!secondary)
	wield = get_eq_char(ch, WEAR_WIELD);
    else
	wield = get_eq_char(ch, WEAR_SECONDARY);
    if (dt == TYPE_UNDEFINED) {
	dt = TYPE_HIT;
	if (wield != NULL && wield->item_type == ITEM_WEAPON)
	    dt += wield->value[3];
	else
	    dt += ch->dam_type;
    }

    if (dt < TYPE_HIT)
	if (wield != NULL)
	    dam_type = attack_table[wield->value[3]].damage;
	else
	    dam_type = attack_table[ch->dam_type].damage;
    else
	dam_type = attack_table[dt - TYPE_HIT].damage;

    if (dam_type == -1)
	dam_type = DAM_BASH;

    /* get the weapon skill */
    sn = get_weapon_sn(ch);
    skill = 20 + get_weapon_skill(ch, sn);

    /*
     * Calculate to-hit-armor-class-0 versus armor.
     */
    if (IS_NPC(ch)) {
	thac0_00 = 20;
	thac0_32 = -4;		/* as good as a thief */
	if (IS_SET(ch->act, ACT_VAMPIRE))
	    thac0_32 = -30;
	else if (IS_SET(ch->act, ACT_DRUID))
	    thac0_32 = 0;
	else if (IS_SET(ch->act, ACT_RANGER))
	    thac0_32 = -4;
	else if (IS_SET(ch->act, ACT_WARRIOR))
	    thac0_32 = -10;
	else if (IS_SET(ch->act, ACT_THIEF))
	    thac0_32 = -4;
	else if (IS_SET(ch->act, ACT_CLERIC))
	    thac0_32 = 2;
	else if (IS_SET(ch->act, ACT_MAGE))
	    thac0_32 = 6;
    } else {
	thac0_00 = class_table[ch->class].thac0_00;
	thac0_32 = class_table[ch->class].thac0_32;
	if (ch->pcdata->tier == 2) {
	    thac0_00 = UMIN(class_table[ch->class].thac0_00,
			    class_table[ch->clasb].thac0_00);
	    thac0_32 = UMIN(class_table[ch->class].thac0_32,
			    class_table[ch->clasb].thac0_32);
	}
    }
    thac0 = interpolate(ch->level, thac0_00, thac0_32);

    if (thac0 < 0)
	thac0 = thac0 / 2;

    if (thac0 < -5)
	thac0 = -5 + (thac0 + 5) / 2;

    thac0 -= GET_HITROLL(ch) * skill / 100;
    thac0 += 5 * (100 - skill) / 100;

    if (dt == gsn_backstab)
	thac0 -= 10 * (100 - get_skill(ch, gsn_backstab));

    switch (dam_type) {
    case (DAM_PIERCE):
	victim_ac = GET_AC(victim, AC_PIERCE) / 10;
	break;
    case (DAM_BASH):
	victim_ac = GET_AC(victim, AC_BASH) / 10;
	break;
    case (DAM_SLASH):
	victim_ac = GET_AC(victim, AC_SLASH) / 10;
	break;
    default:
	victim_ac = GET_AC(victim, AC_EXOTIC) / 10;
	break;
    };

    if (((!strcmp(class_table[victim->class].name, "vampire"))
	 || (!strcmp(class_table[victim->class].name, "lich")))
	&& (IS_OUTSIDE(victim))
	&& (vam_str[time_info.hour] != 0)) {
	if ((time_info.hour > 6) && (time_info.hour < 18)) {
	    victim_ac += (victim_ac * (vam_str[time_info.hour] / 100));
	} else {
	    victim_ac -= (victim_ac * (vam_str[time_info.hour] / 100));
	}
    } else if (!IS_NPC(victim) && (victim->pcdata->tier == 2)) {
	if ((!strcmp(class_table[victim->clasb].name, "vampire"))
	    && (IS_OUTSIDE(victim))
	    && (vam_str[time_info.hour] != 0)) {
	    if ((time_info.hour > 6) && (time_info.hour < 18)) {
		victim_ac += (victim_ac * (vam_str[time_info.hour] / 100));
	    } else {
		victim_ac -= (victim_ac * (vam_str[time_info.hour] / 100));
	    }
	}

    }

    if (victim_ac < -15)
	victim_ac = (victim_ac + 15) / 5 - 15;

    if (!can_see(ch, victim))
	victim_ac -= 4;

    if (victim->position < POS_FIGHTING)
	victim_ac += 4;

    if (victim->position < POS_RESTING)
	victim_ac += 6;

    /*
     * The moment of excitement!
     */
    while ((diceroll = number_bits(5)) >= 20);

    if (diceroll == 0 || (diceroll != 19 && diceroll < thac0 - victim_ac)) {
	/* Miss. */
	damage(ch, victim, 0, dt, dam_type, TRUE);
	tail_chain();
	return;
    }

    /*
     * Hit.
     * Calc damage.
     */
    if (IS_NPC(ch) && (!ch->pIndexData->new_format || wield == NULL))
	if (!ch->pIndexData->new_format) {
	    dam = number_range(ch->level / 2, ch->level * 3 / 2);
	    if (wield != NULL)
		dam += dam / 2;
		if (global_damq){ dam = dam*2; }
	} else
	    dam = dice(ch->damage[DICE_NUMBER], ch->damage[DICE_TYPE]);

    else {
	if (sn != -1)
	    check_improve(ch, sn, TRUE, 5);
	if (wield != NULL) {
	    if (wield->clan) {
		float adlev, inclev;
		int cntr;

		adlev = 8;
		inclev = .01;
		for (cntr = 0; cntr <= ch->level; cntr++) {
		    adlev += .57;
		    adlev += inclev;
		    inclev += .005;
		}
		cntr = (int) adlev;
		dam = dice(cntr / 3, 3) * skill / 100;
		if (global_damq){ dam = dam*2; }
	    } else {
		if (wield->pIndexData->new_format)
		    dam =
			dice(wield->value[1],
			     wield->value[2]) * skill / 100;
		else
		    dam =
			number_range(wield->value[1] * skill / 100,
				     wield->value[2] * skill / 100);
		if (global_damq){ dam = dam*2; }
	    }

	    if (get_eq_char(ch, WEAR_SHIELD) == NULL)	/* no shield = more */
		dam = dam * 11 / 10;
		if (global_damq){ dam = dam*2; }

	    /* sharpness! */
	    if (IS_WEAPON_STAT(wield, WEAPON_SHARP)) {
		int percent;

		if ((percent = number_percent()) <= (skill / 8))
		    dam = 2 * dam + (dam * 2 * percent / 100);
		if (global_damq){ dam = dam*2; }
	    }
	} else
	    dam =
		number_range(1 + 4 * skill / 100,
			     2 * ch->level / 3 * skill / 100);
		if (global_damq){ dam = dam*2; }
    }

    /*
     * Bonuses.
     */

    if (((!strcmp(class_table[ch->class].name, "vampire"))
	 || (!strcmp(class_table[ch->class].name, "lich")))
	&& (IS_OUTSIDE(ch))
	&& (vam_str[time_info.hour] != 0)) {
	if ((time_info.hour > 6) && (time_info.hour < 18)) {
	    dam -= (dam * (vam_str[time_info.hour] / 100));
		if (global_damq){ dam = dam*2; }
	} else {
	    dam += (dam * (vam_str[time_info.hour] / 100));
		if (global_damq){ dam = dam*2; }
	}
    } else if (!IS_NPC(ch) && (ch->pcdata->tier == 2)) {
	if ((!strcmp(class_table[ch->clasb].name, "vampire"))
	    && (IS_OUTSIDE(ch))
	    && (vam_str[time_info.hour] != 0)) {
	    if ((time_info.hour > 6) && (time_info.hour < 18)) {
		dam -= (dam * (vam_str[time_info.hour] / 100));
	    } else {
		dam += (dam * (vam_str[time_info.hour] / 100));
	    }
	}
		if (global_damq){ dam = dam*2; }
    }

    if (get_skill(ch, gsn_enhanced_damage) > 0) {
	diceroll = number_percent();
	if (diceroll <= get_skill(ch, gsn_enhanced_damage)) {
	    check_improve(ch, gsn_enhanced_damage, TRUE, 6);
	    if (str_cmp(class_table[ch->class].name, "gladiator"))
		dam += 2 * (dam * diceroll / 300);
	    else
		dam += 2 * (dam * diceroll / 200);
	}
		if (global_damq){ dam = dam*2; }
    }

    if (!IS_AWAKE(victim))
	dam *= 2;
    else if (victim->position < POS_FIGHTING)
	dam = dam * 3 / 2;

    if (dt == gsn_backstab && wield != NULL) {
	if (wield->value[0] != 2)
	    dam *= 2 + (ch->level / 10);
	else
	    dam *= 2 + (ch->level / 8);
    }
    if (dt == gsn_circle && wield != NULL) {
	if (wield->value[0] != 2)
	    dam *= 1.5 + (ch->level / 15);
	else
	    dam *= 1.5 + (ch->level / 12);
    }
    dam += GET_DAMROLL(ch) * UMIN(100, skill) / 100;
		if (global_damq){ dam = dam*2; }

    if (dam <= 0)
	dam = 1;

    result = damage(ch, victim, dam, dt, dam_type, TRUE);

    /* but do we have a funky weapon? */
    if (result && wield != NULL) {
	int dam;

	if (ch->fighting == victim && IS_WEAPON_STAT(wield, WEAPON_POISON)) {
	    int level;
	    AFFECT_DATA *poison, af;

	    if ((poison = affect_find(wield->affected, gsn_poison)) ==
		NULL) level = wield->level;
	    else
		level = poison->level;

	    if (!saves_spell(level / 2, victim, DAM_POISON)) {
		send_to_char
		    ("{cYou feel {ypoison{c coursing through your veins.\n{x",
		     victim);
		act("$n is {ypoisoned{x by the venom on $p.", victim,
		    wield, NULL, TO_ROOM);

		af.where = TO_AFFECTS;
		af.type = gsn_poison;
		af.level = level * 3 / 4;
		af.duration = level / 2;
		af.location = APPLY_STR;
		af.modifier = -1;
		af.bitvector = AFF_POISON;
		affect_join(victim, &af);
	    }

	    /* weaken the poison if it's temporary */
	    if (poison != NULL) {
		poison->level = UMAX(0, poison->level - 2);
		poison->duration = UMAX(0, poison->duration - 1);

		if (poison->level == 0 || poison->duration == 0)
		    act("The {ypoison{x on $p has worn off.", ch, wield,
			NULL, TO_CHAR);
	    }
	}


	if (ch->fighting == victim
	    && IS_WEAPON_STAT(wield, WEAPON_VAMPIRIC)) {
	    dam = number_range(1, wield->level / 5 + 1);
	    act("$p draws life from $n.{x", victim, wield, NULL,
		TO_ROOM);
	    act("You feel $p drawing your life away.{x", victim, wield,
		NULL, TO_CHAR);
	    damage(ch, victim, dam, 0, DAM_NEGATIVE, FALSE);
	    ch->alignment = UMAX(-1000, ch->alignment - 1);
	    if (ch->pet != NULL)
		ch->pet->alignment = ch->alignment;
	    ch->hit += dam / 2;
	}

	if (ch->fighting == victim
	    && IS_WEAPON_STAT(wield, WEAPON_FLAMING)) {
	    dam = number_range(1, wield->level / 4 + 1);
	    act("$n is {rburned by $p.{x", victim, wield, NULL,
		TO_ROOM);
	    act("$p {rsears your flesh.{x", victim, wield, NULL,
		TO_CHAR);
	    fire_effect((void *) victim, wield->level / 2, dam,
			TARGET_CHAR);
	    damage(ch, victim, dam, 0, DAM_FIRE, FALSE);
	}

	if (ch->fighting == victim && IS_WEAPON_STAT(wield, WEAPON_FROST)) {
	    dam = number_range(1, wield->level / 6 + 2);
	    act("$p {cfreezes $n.{x", victim, wield, NULL, TO_ROOM);
	    act("The {Ccold touch of $p surrounds you with {Cice.{x",
		victim, wield, NULL, TO_CHAR);
	    cold_effect(victim, wield->level / 2, dam, TARGET_CHAR);
	    damage(ch, victim, dam, 0, DAM_COLD, FALSE);
	}

	if (ch->fighting == victim
	    && IS_WEAPON_STAT(wield, WEAPON_SHOCKING)) {
	    dam = number_range(1, wield->level / 5 + 2);
	    act("$n is struck by {Ylightning from $p.{x", victim,
		wield, NULL, TO_ROOM);
	    act("You are {Yshocked by $p.{x", victim, wield, NULL,
		TO_CHAR);
	    shock_effect(victim, wield->level / 2, dam, TARGET_CHAR);
	    damage(ch, victim, dam, 0, DAM_LIGHTNING, FALSE);
	}
		if (global_damq){ dam = dam*2; }
    }
    if (ch->fighting == victim);
    {
	if (result) {
	    if (IS_SHIELDED(victim, SHD_ICE)) {
		if (!IS_SHIELDED(ch, SHD_ICE)) {
		    dt = skill_lookup("iceshield");
		    dam = number_range(5, 15);
		    damage(victim, ch, dam, dt, DAM_COLD, TRUE);
		}
	    }
	    if (IS_SHIELDED(victim, SHD_FIRE)) {
		if (!IS_SHIELDED(ch, SHD_FIRE)) {
		    dt = skill_lookup("fireshield");
		    dam = number_range(10, 20);
		    damage(victim, ch, dam, dt, DAM_FIRE, TRUE);
		}
	    }

	    if (!IS_NPC(ch)) {
		stance = ch->stance[0];
		if (IS_STANCE(ch, STANCE_NORMAL))
		    dam *= 1.75;
		else
		    dam = dambonus(ch, victim, dam, stance);
		dambonus(ch, victim, dam, stance);
		improve_stance(ch);
	    }

	    if (IS_NPC(ch)) {
		stance = ch->stance[0];
		if (IS_STANCE(ch, STANCE_NORMAL))
		    dam *= 1.95;
		else
		    dam = dambonus(ch, victim, dam, stance);
		dambonus(ch, victim, dam, stance);
		improve_stance(ch);
		improve_stance(ch);
	    }
	    if (IS_SHIELDED(victim, SHD_SHOCK)) {
		if (!IS_SHIELDED(ch, SHD_SHOCK)) {
		    dt = skill_lookup("shockshield");
		    dam = number_range(15, 25);
		    damage(victim, ch, dam, dt, DAM_LIGHTNING, TRUE);
		}
	    }
	}
		if (global_damq){ dam = dam*2; }
    }

    tail_chain();
    return;
}

/*
 * Mock hit one guy once.
 */
void one_hit_mock(CHAR_DATA * ch, CHAR_DATA * victim, int dt,
		  bool secondary)
{
    OBJ_DATA *wield;
    int victim_ac;
    int thac0;
    int thac0_00;
    int thac0_32;
    int dam;
    int diceroll;
    int sn, skill;
    int dam_type;
    bool result;

    sn = -1;


    /* just in case */
    if (ch == NULL || victim == NULL)
	return;

    /*
     * Can't beat a dead char!
     * Guard against weird room-leavings.
     */
    if (victim->position == POS_DEAD || ch->in_room != victim->in_room)
	return;

    /*
     * Figure out the type of damage message.
     * if secondary == true, use the second weapon.
     */
    if (!secondary)
	wield = get_eq_char(ch, WEAR_WIELD);
    else
	wield = get_eq_char(ch, WEAR_SECONDARY);
    if (dt == TYPE_UNDEFINED) {
	dt = TYPE_HIT;
	if (wield != NULL && wield->item_type == ITEM_WEAPON)
	    dt += wield->value[3];
	else
	    dt += ch->dam_type;
    }

    if (dt < TYPE_HIT)
	if (wield != NULL)
	    dam_type = attack_table[wield->value[3]].damage;
	else
	    dam_type = attack_table[ch->dam_type].damage;
    else
	dam_type = attack_table[dt - TYPE_HIT].damage;

    if (dam_type == -1)
	dam_type = DAM_BASH;

    /* get the weapon skill */
    sn = get_weapon_sn(ch);
    skill = 20 + get_weapon_skill(ch, sn);

    /*
     * Calculate to-hit-armor-class-0 versus armor.
     */
    if (IS_NPC(ch)) {
	thac0_00 = 20;
	thac0_32 = -4;		/* as good as a thief */
	if (IS_SET(ch->act, ACT_VAMPIRE))
	    thac0_32 = -30;
	else if (IS_SET(ch->act, ACT_DRUID))
	    thac0_32 = 0;
	else if (IS_SET(ch->act, ACT_RANGER))
	    thac0_32 = -4;
	else if (IS_SET(ch->act, ACT_WARRIOR))
	    thac0_32 = -10;
	else if (IS_SET(ch->act, ACT_THIEF))
	    thac0_32 = -4;
	else if (IS_SET(ch->act, ACT_CLERIC))
	    thac0_32 = 2;
	else if (IS_SET(ch->act, ACT_MAGE))
	    thac0_32 = 6;
    } else {
	thac0_00 = class_table[ch->class].thac0_00;
	thac0_32 = class_table[ch->class].thac0_32;
	if (ch->pcdata->tier == 2) {
	    thac0_00 = UMIN(class_table[ch->class].thac0_00,
			    class_table[ch->clasb].thac0_00);
	    thac0_32 = UMIN(class_table[ch->class].thac0_32,
			    class_table[ch->clasb].thac0_32);
	}
    }
    thac0 = interpolate(ch->level, thac0_00, thac0_32);

    if (thac0 < 0)
	thac0 = thac0 / 2;

    if (thac0 < -5)
	thac0 = -5 + (thac0 + 5) / 2;

    thac0 -= GET_HITROLL(ch) * skill / 100;
    thac0 += 5 * (100 - skill) / 100;

    if (dt == gsn_backstab)
	thac0 -= 10 * (100 - get_skill(ch, gsn_backstab));

    switch (dam_type) {
    case (DAM_PIERCE):
	victim_ac = GET_AC(victim, AC_PIERCE) / 10;
	break;
    case (DAM_BASH):
	victim_ac = GET_AC(victim, AC_BASH) / 10;
	break;
    case (DAM_SLASH):
	victim_ac = GET_AC(victim, AC_SLASH) / 10;
	break;
    default:
	victim_ac = GET_AC(victim, AC_EXOTIC) / 10;
	break;
    };

    if (victim_ac < -15)
	victim_ac = (victim_ac + 15) / 5 - 15;

    if (!can_see(ch, victim))
	victim_ac -= 4;

    if (victim->position < POS_FIGHTING)
	victim_ac += 4;

    if (victim->position < POS_RESTING)
	victim_ac += 6;

    /*
     * The moment of excitement!
     */
    while ((diceroll = number_bits(5)) >= 20);

    if (diceroll == 0 || (diceroll != 19 && diceroll < thac0 - victim_ac)) {
	/* Miss. */
	damage_mock(ch, victim, 0, dt, dam_type, TRUE);
	tail_chain();
	return;
    }

    /*
     * Hit.
     * Calc damage.
     */
    if (IS_NPC(ch) && (!ch->pIndexData->new_format || wield == NULL))
	if (!ch->pIndexData->new_format) {
	    dam = number_range(ch->level / 2, ch->level * 3 / 2);
	    if (wield != NULL)
		dam += dam / 2;
	} else
	    dam = dice(ch->damage[DICE_NUMBER], ch->damage[DICE_TYPE]);

    else {
	if (sn != -1)
	    check_improve(ch, sn, TRUE, 5);
	if (wield != NULL) {
	    if (wield->clan) {
		float adlev, inclev;
		int cntr;

		adlev = 8;
		inclev = .01;
		for (cntr = 0; cntr <= ch->level; cntr++) {
		    adlev += .57;
		    adlev += inclev;
		    inclev += .005;
		}
		cntr = (int) adlev;
		dam = dice(cntr / 3, 3) * skill / 100;
	    } else {
		if (wield->pIndexData->new_format)
		    dam =
			dice(wield->value[1],
			     wield->value[2]) * skill / 100;
		else
		    dam =
			number_range(wield->value[1] * skill / 100,
				     wield->value[2] * skill / 100);
	    }

	    if (get_eq_char(ch, WEAR_SHIELD) == NULL)	/* no shield = more */
		dam = dam * 11 / 10;

	    /* sharpness! */
	    if (IS_WEAPON_STAT(wield, WEAPON_SHARP)) {
		int percent;

		if ((percent = number_percent()) <= (skill / 8))
		    dam = 2 * dam + (dam * 2 * percent / 100);
	    }
	} else
	    dam =
		number_range(1 + 4 * skill / 100,
			     2 * ch->level / 3 * skill / 100);
    }

    /*
     * Bonuses.
     */
    if (get_skill(ch, gsn_enhanced_damage) > 0) {
	diceroll = number_percent();
	if (diceroll <= get_skill(ch, gsn_enhanced_damage)) {
	    check_improve(ch, gsn_enhanced_damage, TRUE, 6);
	    if (str_cmp(class_table[ch->class].name, "gladiator"))
		dam += 2 * (dam * diceroll / 300);
	    else
		dam += 2 * (dam * diceroll / 200);
	}
    }

    if (!IS_AWAKE(victim))
	dam *= 2;
    else if (victim->position < POS_FIGHTING)
	dam = dam * 3 / 2;

    if (dt == gsn_backstab && wield != NULL) {
	if (wield->value[0] != 2)
	    dam *= 2 + (ch->level / 10);
	else
	    dam *= 2 + (ch->level / 8);
    }
    if (dt == gsn_circle && wield != NULL) {
	if (wield->value[0] != 2)
	    dam *= 1.5 + (ch->level / 15);
	else
	    dam *= 1.5 + (ch->level / 12);
    }
    dam += GET_DAMROLL(ch) * UMIN(100, skill) / 100;

    if (dam <= 0)
	dam = 1;

    result = damage_mock(ch, victim, dam, dt, dam_type, TRUE);

    tail_chain();
    return;
}

/*
 * Inflict damage from a hit.
 */
bool damage(CHAR_DATA * ch, CHAR_DATA * victim, int dam, int dt,
	    int dam_type, bool show)
{
    OBJ_DATA *corpse;
    bool immune;
    int stance;

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

    if (ch->spirit || victim->spirit)
	return FALSE;

    /*
     * Stop up any residual loopholes.
     */

    if (IS_NPC(ch)) {
	stance = ch->stance[0];
	if (IS_STANCE(ch, STANCE_NORMAL))
	    dam *= 1.75;
	else
	    dam = dambonus(ch, victim, dam, stance);
	dambonus(ch, victim, dam, stance);
	improve_stance(ch);
    }
    if (!IS_NPC(ch)) {
	stance = ch->stance[0];
	if (IS_STANCE(ch, STANCE_NORMAL))
	    dam *= 1.95;
	else
	    dam = dambonus(ch, victim, dam, stance);
	dambonus(ch, victim, dam, stance);
	improve_stance(ch);
    }
/*
    if (dam > 25000 && dt >= TYPE_HIT && !IS_IMMORTAL(ch)) {
	bug("Damage: %d: more than 25000 points!", dam);
	dam = 5200;
	if (!IS_IMMORTAL(ch)) {
	    OBJ_DATA *obj;
	    obj = get_eq_char(ch, WEAR_WIELD);
	send_to_char("Damage more than 25000 points!", ch);
	// send_to_char("{cYou {z{Breally{x{c shouldn't cheat.{x\n\r", ch);
	    if (obj != NULL)
		extract_obj(obj);
	    obj = get_eq_char(ch, WEAR_SECONDARY);
	    if (obj != NULL)
		extract_obj(obj);
	}

    }
 */

    /* damage reduction */
    if (dam > 35)
	dam = (dam - 35) / 2 + 35;
    if (dam > 80)
	dam = (dam - 80) / 2 + 80;

    if (victim != ch) {
	/*
	 * Certain attacks are forbidden.
	 * Most other attacks are returned.
	 */
	if (is_safe(ch, victim))
	    return FALSE;

	if (ch->spirit || victim->spirit)
	    return FALSE;
	if (victim->position > POS_STUNNED) {
  	    if ( victim->fighting == NULL )
 	    {
  		set_fighting( victim, ch );
 		if ( IS_NPC( victim ) && HAS_TRIGGER( victim, TRIG_KILL ) )
 		    mp_percent_trigger( victim, ch, NULL, NULL, TRIG_KILL );
	    }
	    if (victim->timer <= 4)
		victim->position = POS_FIGHTING;
	}

	if (victim->position > POS_STUNNED) {
	    if (ch->fighting == NULL)
		set_fighting(ch, victim);
	}

	/*
	 * More charm stuff.
	 */
	if (victim->master == ch)
	    stop_follower(victim);
    }

    /*
     * Inviso attacks ... not.
     */
    if (IS_SHIELDED(ch, SHD_INVISIBLE)) {
	affect_strip(ch, gsn_invis);
	affect_strip(ch, gsn_mass_invis);
	REMOVE_BIT(ch->shielded_by, SHD_INVISIBLE);
	act("$n fades into existence.", ch, NULL, NULL, TO_ROOM);
    }

    /*
     * Damage modifiers.
     */

    if (dam > 1 && !IS_NPC(victim)
	&& victim->pcdata->condition[COND_DRUNK] > 10)
	dam = 9 * dam / 10;

    if (dam > 1 && IS_SHIELDED(victim, SHD_SANCTUARY))
	dam /= 2;

    if (dam > 1 && ((IS_SHIELDED(victim, SHD_PROTECT_EVIL) && IS_EVIL(ch))
		    || (IS_SHIELDED(victim, SHD_PROTECT_GOOD)
			&& IS_GOOD(ch)))) dam -= dam / 4;

    immune = FALSE;


    /*
     * Check for parry, and dodge.
     */
    if (dt >= TYPE_HIT && ch != victim) {
	if (check_parry(ch, victim))
	    return FALSE;
	if (check_dodge(ch, victim))
	    return FALSE;
	if (check_shield_block(ch, victim))
	    return FALSE;
	if ( check_fade( ch, victim ))
	    return FALSE;

	if (IS_STANCE(victim, STANCE_CRANE) &&
	    victim->stance[STANCE_CRANE] > 100 && !can_counter(ch)
	    && !can_bypass(ch, victim))
	    return FALSE;
	if (IS_STANCE(victim, STANCE_MANTIS) &&
	    victim->stance[STANCE_MANTIS] > 100 && !can_counter(ch)
	    && !can_bypass(ch, victim))
	    return FALSE;
	if (IS_STANCE(victim, STANCE_MONGOOSE) &&
	    victim->stance[STANCE_MONGOOSE] > 100 && !can_counter(ch)
	    && !can_bypass(ch, victim))
	    return FALSE;
	if (IS_STANCE(victim, STANCE_SWALLOW) &&
	    victim->stance[STANCE_SWALLOW] > 100 && !can_counter(ch)
	    && !can_bypass(ch, victim))
	    return FALSE;


    }

    switch (check_immune(victim, dam_type)) {
    case (IS_IMMUNE):
	immune = TRUE;
	dam = 0;
	break;
    case (IS_RESISTANT):
	dam -= dam / 3;
	break;
    case (IS_VULNERABLE):
	dam += dam / 2;
	break;
    }

    if (ch->spirit || victim->spirit)
	return FALSE;

    if (show)
	dam_message(ch, victim, dam, dt, immune);

    if (dam == 0)
	return FALSE;

    /*
     * Hurt the victim.
     * Inform the victim of his new state.
     */
    victim->hit -= dam;
    if (!IS_NPC(victim)
	&& victim->level >= LEVEL_IMMORTAL && victim->hit < 1)
	victim->hit = 1;
    update_pos(victim);
    if (dt == gsn_feed && !victim->spirit) {
	ch->hit = UMIN(ch->hit + ((dam / 4) * 3), ch->max_hit);
	update_pos(ch);
    }

    switch (victim->position) {
    case POS_MORTAL:
	act("{c$n is mortally wounded, and will die soon, if not aided.{x",
	    victim, NULL, NULL, TO_ROOM);
	send_to_char
	    ("{cYou are mortally wounded, and will die soon, if not aided.{x\n\r",
	     victim);
	break;

    case POS_INCAP:
	act("{c$n is incapacitated and will slowly die, if not aided.{x",
	    victim, NULL, NULL, TO_ROOM);
	send_to_char
	    ("{cYou are incapacitated and will slowly {z{Rdie{x{c, if not aided.{x\n\r",
	     victim);
	break;

    case POS_STUNNED:
	act("{c$n is stunned, but will probably recover.{x",
	    victim, NULL, NULL, TO_ROOM);
	send_to_char("{cYou are stunned, but will probably recover.{x\n\r",
		     victim);
	break;

    case POS_DEAD:
	if ((IS_NPC(victim)) && (victim->die_descr[0] != '\0')) {
	    act("{c$n $T{x", victim, 0, victim->die_descr, TO_ROOM);
	} else {
	    act("{c$n is {CDEAD!!{x", victim, 0, 0, TO_ROOM);
	}
	send_to_char("{cYou have been {RKILLED!!{x\n\r\n\r", victim);

	break;

    default:
	if (dam > victim->max_hit / 4)
	    send_to_char("{cThat really did {RHURT!{x\n\r", victim);
	if (victim->hit < victim->max_hit / 4)
	    send_to_char("{cYou sure are {z{RBLEEDING!{x\n\r", victim);
	break;
    }

    /*
     * Sleep spells and extremely wounded folks.
     */
    if (!IS_AWAKE(victim))
	stop_fighting(victim, FALSE);

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

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

	    /*
	     * Dying penalty:
	     * 5/6 way back to previous level.
	     */
	    if (victim->exp > exp_per_level(victim, victim->pcdata->points)
		* victim->level)
		if (!IS_SET(victim->act, PLR_LQUEST))
		    gain_exp(victim, (5 *
				      (exp_per_level
				       (victim,
					victim->pcdata->points) *
				       victim->level - victim->exp) / 6) +
			     50);
	}

	sprintf(log_buf, "%s got toasted by %s at %s [room %d]",
		(IS_NPC(victim) ? victim->short_descr : victim->name),
		(IS_NPC(ch) ? ch->short_descr : ch->name),
		ch->in_room->name, ch->in_room->vnum);

	if (IS_NPC(victim))
	    wiznet(log_buf, NULL, NULL, WIZ_MOBDEATHS, 0, 0);
	else
	    wiznet(log_buf, NULL, NULL, WIZ_DEATHS, 0, 0);

         /*
          * Death trigger
          */
         if ( IS_NPC( victim ) && HAS_TRIGGER( victim, TRIG_DEATH) )
         {
             victim->position = POS_STANDING;
             mp_percent_trigger( victim, ch, NULL, NULL, TRIG_DEATH );
         }
 
	raw_kill(victim, ch);
	/* dump the flags */
	if (IS_SET(victim->exbit1_flags, RECRUIT)) {
	    REMOVE_BIT(victim->exbit1_flags, RECRUIT);
	}
	if (IS_SET(victim->exbit1_flags, PK_KILLER)) {
	    REMOVE_BIT(victim->exbit1_flags, PK_KILLER);
	    SET_BIT(ch->exbit1_flags, PK_LAWFUL);
	}
	if (ch != victim && !IS_NPC(ch) && (!is_same_clan(ch, victim)
					    || clan_table[victim->clan].
					    independent)) {
	    if (IS_SET(victim->act, PLR_TWIT))
		REMOVE_BIT(victim->act, PLR_TWIT);
	}

	if (!IS_NPC(ch) && !IS_NPC(victim)
	    && IS_SET(ch->in_room->room_flags, ROOM_ARENA)
	    && IS_SET(victim->in_room->room_flags, ROOM_ARENA)) {
	    check_arena(ch, victim);
	    return TRUE;
	}

	/* RT new auto commands */

	if (!IS_NPC(ch) && IS_NPC(victim)) {
	    OBJ_DATA *coins;

	    corpse = get_obj_list(ch, "corpse", ch->in_room->contents);

	    if (IS_SET(ch->act, PLR_AUTOLOOT) && corpse && corpse->contains)	/* exists and not empty */
		do_get(ch, "all corpse");

	    if (IS_SET(ch->act, PLR_AUTOGOLD) && corpse && corpse->contains &&	/* exists and not empty */
		!IS_SET(ch->act, PLR_AUTOLOOT))
		if ((coins = get_obj_list(ch, "gcash", corpse->contains))
		    != NULL)
		    do_get(ch, "all.gcash corpse");

	    if (IS_SET(ch->act, PLR_AUTOSAC)) {
		if (IS_SET(ch->act, PLR_AUTOLOOT) && corpse
		    && corpse->contains) return TRUE;	/* leave if corpse has treasure */
		else
		    do_sacrifice(ch, "corpse");
	    }
	}

	return TRUE;
    }

    if (victim == ch)
	return TRUE;

    /*
     * Take care of link dead people.
     */
    if (!IS_NPC(victim) && victim->desc == NULL) {
	if (number_range(0, victim->wait) == 0) {
	    do_recall(victim, "");
	    return TRUE;
	}
    }

    /*
     * Wimp out?
     */
    if (IS_NPC(victim) && dam > 0 && victim->wait < PULSE_VIOLENCE / 2) {
	if ((IS_SET(victim->act, ACT_WIMPY) && number_bits(2) == 0
	     && victim->hit < victim->max_hit / 5)
	    || (IS_AFFECTED(victim, AFF_CHARM) && victim->master != NULL
		&& victim->master->in_room != victim->in_room))
	    do_flee(victim, "");
    }

    if (!IS_NPC(victim)
	&& victim->hit > 0
	&& victim->hit <= victim->wimpy
	&& victim->wait < PULSE_VIOLENCE / 2) do_flee(victim, "");

    tail_chain();
    return TRUE;
}

/*
 * Show damage from a mock hit.
 */
bool damage_mock(CHAR_DATA * ch, CHAR_DATA * victim, int dam, int dt,
		 int dam_type, bool show)
{
    long immdam;
    bool immune;
    char buf1[256], buf2[256], buf3[256];
    const char *attack;

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

    if (dam > 35)
	dam = (dam - 35) / 2 + 35;
    if (dam > 80)
	dam = (dam - 80) / 2 + 80;
    if (is_safe_mock(ch, victim))
	return FALSE;
    /*
     * Damage modifiers.
     */

    if (dam > 1 && !IS_NPC(victim)
	&& victim->pcdata->condition[COND_DRUNK] > 10)
	dam = 9 * dam / 10;

    if (dam > 1 && IS_SHIELDED(victim, SHD_SANCTUARY))
	dam /= 2;

    if (dam > 1 && ((IS_SHIELDED(victim, SHD_PROTECT_EVIL) && IS_EVIL(ch))
		    || (IS_SHIELDED(victim, SHD_PROTECT_GOOD)
			&& IS_GOOD(ch)))) dam -= dam / 4;

    immune = FALSE;


    switch (check_immune(victim, dam_type)) {
    case (IS_IMMUNE):
	immune = TRUE;
	dam = 0;
	break;
    case (IS_RESISTANT):
	dam -= dam / 3;
	break;
    case (IS_VULNERABLE):
	dam += dam / 2;
	break;
    }

    if (dt >= 0 && dt < MAX_SKILL)
	attack = skill_table[dt].noun_damage;
    else if (dt >= TYPE_HIT && dt <= TYPE_HIT + MAX_DAMAGE_MESSAGE)
	attack = attack_table[dt - TYPE_HIT].noun;
    else {
	bug("Dam_message: bad dt %d.", dt);
	dt = TYPE_HIT;
	attack = attack_table[0].name;
    }
    immdam = 0;
    if (ch->level == MAX_LEVEL) {
	immdam = dam * 63;
    }
    if (ch == victim) {
	sprintf(buf1,
		"{y$n's {gmock {B%s{g would have done {R%d hp{g damage to {y$mself{g.{x",
		attack, dam);
	sprintf(buf2,
		"{yYour {gmock {B%s{g would have done {R%d hp{g damage to {yyourself{g.{x",
		attack, dam);
	act(buf1, ch, NULL, NULL, TO_ROOM);
	act(buf2, ch, NULL, NULL, TO_CHAR);
    } else if (ch->level < MAX_LEVEL) {
	sprintf(buf1,
		"{y$n's {gmock {B%s{g would have done {R%d hp{g damage to {y$N{g.{x",
		attack, dam);
	sprintf(buf2,
		"{yYour {gmock {B%s{g would have done {R%d hp{g damage to {y$N{g.{x",
		attack, dam);
	sprintf(buf3,
		"{y$n's {gmock {B%s{g would have done {R%d hp{g damage to {yyou{g.{x",
		attack, dam);
	act(buf1, ch, NULL, victim, TO_NOTVICT);
	act(buf2, ch, NULL, victim, TO_CHAR);
	act(buf3, ch, NULL, victim, TO_VICT);
    } else {
	sprintf(buf1,
		"{y$n's {gmock {B%s{g would have done {R%lu hp{g damage to {y$N{g.{x",
		attack, immdam);
	sprintf(buf2,
		"{yYour {gmock {B%s{g would have done {R%lu hp{g damage to {y$N{g.{x",
		attack, immdam);
	sprintf(buf3,
		"{y$n's {gmock {B%s{g would have done {R%lu hp{g damage to {yyou{g.{x",
		attack, immdam);
	act(buf1, ch, NULL, victim, TO_NOTVICT);
	act(buf2, ch, NULL, victim, TO_CHAR);
	act(buf3, ch, NULL, victim, TO_VICT);
    }

    tail_chain();
    return TRUE;
}

bool is_safe(CHAR_DATA * ch, CHAR_DATA * victim)
{
    if (victim->in_room == NULL || ch->in_room == NULL)
	return TRUE;

    if (victim->fighting == ch || victim == ch)
	return FALSE;

    if (!IS_NPC(ch) && IS_IMMORTAL(ch))
	return FALSE;

    if (ch->spirit) {
	send_to_char("You need a body for that!\n\r", ch);
	return TRUE;
    }
    if (victim->spirit) {
	send_to_char("Spirits are difficult to harm.\n\r", ch);
	return TRUE;
    }
    /* killing mobiles */
    if (IS_NPC(victim)) {

	/* safe room? */
	if (IS_SET(victim->in_room->room_flags, ROOM_SAFE)) {
	    send_to_char("Not in this room.\n\r", ch);
	    return TRUE;
	}

	if (IS_SET(victim->exbit1_flags, RECRUIT)
	    || IS_SET(victim->exbit1_flags, PK_VETERAN)
	    || IS_SET(victim->exbit1_flags, PK_LAWFUL)
	    || IS_SET(victim->exbit1_flags, PK_KILLER)
	    || IS_SET(victim->exbit1_flags, PK_KILLER2)) {
	    return FALSE;
	}

	if (IS_SET(victim->in_room->room_flags, ROOM_ARENA))
	    return FALSE;
	if (IS_SET(victim->in_room->room_flags, ROOM_ARENA))
	    return FALSE;
	if (!IS_NPC(ch)
	    && IS_SET(victim->in_room->room_flags, ROOM_CLAN_ENT)) {
	    send_to_char("Not in this room.\n\r", ch);
	    return TRUE;
	}

	if (victim->pIndexData->pShop != NULL) {
	    send_to_char("The shopkeeper wouldn't like that.\n\r", ch);
	    return TRUE;
	}

	/* no killing healers, trainers, etc */
	if (IS_SET(victim->act, ACT_TRAIN)
	    || IS_SET(victim->act, ACT_PRACTICE)
	    || IS_SET(victim->act, ACT_IS_HEALER)
	    || IS_SET(victim->act, ACT_IS_BANKER)
	    || IS_SET(victim->act, ACT_IS_SATAN)
	    || IS_SET(victim->act, ACT_IS_PRIEST)) {
	    act("I don't think $g would approve.", ch, NULL, NULL,
		TO_CHAR);
	    return TRUE;
	}

	if (!IS_NPC(ch)) {
	    /* no pets */
	    if (IS_SET(victim->act, ACT_PET)) {
		act("But $N looks so cute and cuddly...",
		    ch, NULL, victim, TO_CHAR);
		return TRUE;
	    }

	    /* no charmed creatures unless owner */
	    if (IS_AFFECTED(victim, AFF_CHARM) && ch != victim->master) {
		send_to_char("You don't own that monster.\n\r", ch);
		return TRUE;
	    }
	}
    }
    /* killing players */
    else {
	/* NPC doing the killing */
	if (IS_NPC(ch)) {
	    /* safe room check */
	    if (IS_SET(victim->in_room->room_flags, ROOM_SAFE)) {
		send_to_char("Not in this room.\n\r", ch);
		return TRUE;
	    }

	    /* charmed mobs and pets cannot attack players while owned */
	    if (IS_AFFECTED(ch, AFF_CHARM) && ch->master != NULL
		&& ch->master->fighting != victim) {
		send_to_char("Players are your friends!\n\r", ch);
		return TRUE;
	    }
	}
	/* player doing the killing */
	else {
	    if (IS_SET(victim->in_room->room_flags, ROOM_ARENA))
		return FALSE;

	    if (IS_SET(victim->act, PLR_TWIT))
		return FALSE;

	    if (((victim->level > 19)
		 || ((victim->class >= MCLT_1)
		     && (victim->level > 14)))
		&& (is_voodood(ch, victim)))
		return FALSE;

	    if (IS_SET(victim->in_room->room_flags, ROOM_SAFE)) {
		send_to_char("Not in this room.\n\r", ch);
		return TRUE;
	    }
	    if (ch->on_gquest) {
		send_to_char("Not while you are on a quest.\n\r", ch);
		return TRUE;
	    }
	    if (victim->on_gquest) {
		send_to_char("They are on a quest, leave them alone.\n\r",
			     ch);
		return TRUE;
	    }
	    if (!is_clan(ch)) {
		send_to_char
		    ("Join a clan if you want to fight players.\n\r", ch);
		return TRUE;
	    }

	    if (!is_pkill(ch)) {
		send_to_char
		    ("Your clan does not allow player fighting.\n\r", ch);
		return TRUE;
	    }

	    if (!is_clan(victim)) {
		send_to_char
		    ("They aren't in a clan, leave them alone.\n\r", ch);
		return TRUE;
	    }

	    if (!is_pkill(victim)) {
		send_to_char
		    ("They are in a no pkill clan, leave them alone.\n\r",
		     ch);
		return TRUE;
	    }

	    if (is_same_clan(ch, victim)) {
		send_to_char("You can't fight your own clan members.\n\r",
			     ch);
		return TRUE;
	    }

	    if (((ch->pcdata->tier == 2)
		 && (victim->pcdata->tier == 2))
		|| ((ch->pcdata->tier == 1)
		    && (victim->pcdata->tier == 1))
		|| ((ch->pcdata->tier == 0)
		    && (victim->pcdata->tier == 0))) {
		if (ch->level > victim->level + 10) {
		    send_to_char("Pick on someone your own size.\n\r", ch);
		    return TRUE;
		}
		if (ch->level < victim->level - 20) {
		    send_to_char
			("If you wish to die, there are less painful methods.\n\r",
			 ch);
		    return TRUE;
		}
	    }

	    if ((ch->pcdata->tier == 2)
		&& (victim->pcdata->tier == 0)) {
		send_to_char("Pick on someone your own size.\n\r", ch);
		return TRUE;
	    }

	    if ((ch->pcdata->tier == 0)
		&& (victim->pcdata->tier == 2)) {
		send_to_char
		    ("If you wish to die, there are less painful methods.\n\r",
		     ch);
		return TRUE;
	    }

	    if (((ch->pcdata->tier == 1)
		 && (victim->pcdata->tier == 0))
		|| ((ch->pcdata->tier == 2)
		    && (victim->pcdata->tier == 1))) {
		if (ch->level < (victim->level - 30)) {
		    send_to_char
			("If you wish to die, there are less painful methods.\n\r",
			 ch);
		    return TRUE;
		}
		if (ch->level > victim->level) {
		    send_to_char("Pick on someone your own size.\n\r", ch);
		    return TRUE;
		}
	    }

	    if (((ch->pcdata->tier == 0)
		 && (victim->pcdata->tier == 1))
		|| ((ch->pcdata->tier == 1)
		    && (victim->pcdata->tier == 2))) {
		if (ch->level < (victim->level - 10)) {
		    send_to_char
			("If you wish to die, there are less painful methods.\n\r",
			 ch);
		    return TRUE;
		}
		if (ch->level > (victim->level + 20)) {
		    send_to_char("Pick on someone your own size.\n\r", ch);
		    return TRUE;
		}
	    }
	}
    }
    return FALSE;
}

bool is_safe_mock(CHAR_DATA * ch, CHAR_DATA * victim)
{
    if (victim->in_room == NULL || ch->in_room == NULL)
	return TRUE;
    if (!IS_NPC(ch) && IS_IMMORTAL(ch))
	return FALSE;
    if (ch->spirit) {
	send_to_char("You need a body for that!\n\r", ch);
	return TRUE;
    }
    if (victim->spirit) {
	send_to_char("Spirits are difficult to harm.\n\r", ch);
	return TRUE;
    }
    if (IS_SET(victim->in_room->room_flags, ROOM_SAFE)) {
	send_to_char("Not in this room.\n\r", ch);
	return TRUE;
    }
    if (IS_NPC(victim)) {
	send_to_char("{RYou can only use this on a player.{x\n\r", ch);
	return TRUE;
    }
    return FALSE;
}

/*=======================================================================*
 * function: do_challenge                                                *
 * purpose: sends initial arena match query                              *
 * written by: Doug Araya (whiplash@tft.nacs.net) 6-10-96                *
 *=======================================================================*/
// DB
void do_challenge(CHAR_DATA * ch, char *argument)
{
    CHAR_DATA *victim;
    char buf[MSL];
    DESCRIPTOR_DATA *d;


/* == First make all invalid checks == */
    if (IS_NPC(ch))
	return;

    if ((ch->in_room->vnum == ROOM_VNUM_CORNER)
	&& (!IS_IMMORTAL(ch))) {
	send_to_char
	    ("Just keep your nose in the corner like a good little player.\n\r",
	     ch);
	return;
    }
    if (arena == FIGHT_START) {
	send_to_char
	    ("Sorry, some one else has already started a challenge, please try later.\n\r",
	     ch);
	return;
    }

    if (arena == FIGHT_BUSY) {
	send_to_char
	    ("Sorry, there is a fight in progress, please wait a few moments.\n\r",
	     ch);
	return;
    }

    if (arena == FIGHT_LOCK) {
	send_to_char("Sorry, the arena is currently locked from use.\n\r",
		     ch);
	return;
    }

    if (IS_SET(ch->exbit1_flags, EXBIT1_CHALLENGED)) {
	send_to_char
	    ("You have already been challenged, either ACCEPT or DECLINE first.\n\r",
	     ch);
	return;
    }
    if (ch->hit < ch->max_hit) {
	send_to_char("You must be fully healed to fight in the arena.\n\r",
		     ch);
	return;
    }


    if (IS_AFFECTED(ch, SHD_INVISIBLE) || IS_AFFECTED(ch, AFF_SNEAK)
	|| IS_AFFECTED(ch, AFF_HIDE)) {
	send_to_char
	    ("You can't challenge while invis, sneaking, or hidden.\n\r",
	     ch);
	return;
    }

    if (argument[0] == '\0') {
	send_to_char("You must specify whom you wish to challenge.\n\r",
		     ch);
	return;
    }

    if ((victim = get_char_world(ch, argument)) == NULL) {
	send_to_char("They are not playing.\n\r", ch);
	return;
    }

    if ((victim->in_room->vnum == ROOM_VNUM_CORNER)) {
	send_to_char("They are in the corner, leave them alone.\n\r", ch);
	return;
    }
/*
 if( IS_IMMORTAL(ch) )
  {
  send_to_char("Immortals are not allowed to battle in the arena.\n\r",ch);
  return;
  }
 */
    if (IS_NPC(victim) || victim == ch) {
	send_to_char("You cannot challenge NPC's, or yourself.\n\r", ch);
	return;
    }

    if (IS_AFFECTED(victim, AFF_BLIND)) {
	send_to_char("That person is blind right now.\n\r", ch);
	return;
    }

    if (IS_SET(victim->exbit1_flags, EXBIT1_CHALLENGER)) {
	send_to_char("They have already challenged someone else.\n\r", ch);
	return;
    }
    if (victim->fighting != NULL) {
	send_to_char("That person is engaged in battle right now.\n\r",
		     ch);
	return;
    }

    if (victim->hit < victim->max_hit) {
	send_to_char
	    ("That player is not healthy enough to fight right now.\n\r",
	     ch);
	return;
    }


    if (IS_SET(victim->comm, COMM_AFK)) {
	send_to_char
	    ("That player is AFK at the moment, try them later.\n\r", ch);
	return;
    }

    if (victim->desc == NULL) {
	send_to_char
	    ("That player is linkdead at the moment, try them later.\n\r",
	     ch);
	return;
    }

    if (IS_SET(ch->comm, COMM_NOARENA)) {
	send_to_char
	    ("Why should you be allowed to challenge if no one can challenge you?\n\r",
	     ch);
	return;
    }

    if (IS_SET(victim->comm, COMM_NOARENA)) {
	send_to_char("That player is blocking all challenges.\n\r", ch);
	return;
    }

    if (victim->level <= 10) {
	send_to_char("That player is just a newbie!\n\r", ch);
	return;
    }
    if (ch->level > (victim->level + 50)) {
	send_to_char("That player would be no challenge at all!\r", ch);
	return;
    }
    if (ch->level < (victim->level - 50)) {
	act("{bThey laugh at you mercilessly!{x\r.",
	    ch, NULL, victim, TO_VICT);
	return;
    }

/* == Now for the challenge == */
    ch->challenged = victim;
    SET_BIT(ch->exbit1_flags, EXBIT1_CHALLENGER);
    victim->challenger = ch;
    SET_BIT(victim->exbit1_flags, EXBIT1_CHALLENGED);
    arena = FIGHT_START;
    send_to_char("Challenge has been sent\n\r", ch);
    act("{b$n{x has {ychallenged{x you to a {rdeath match{x.",
	ch, NULL, victim, TO_VICT);
    sprintf(buf,
	    "{W^{x{gArena{x{W^{x {R%s{x has {rchallenged{x {B%s{x to a duel.\n\r",
	    ch->name, victim->name);
    for (d = descriptor_list; d; d = d->next) {
	if (d->connected == CON_PLAYING &&
	    (d->character != victim && d->character != ch)
	    && !IS_SET(d->character->comm, COMM_NOARENA)) {
	    send_to_char(buf, d->character);
	}
    }
    sprintf(buf, "type: {gACCEPT{x {b%s{x to meet the challenge.\n\r",
	    ch->name);
    send_to_char(buf, victim);
    sprintf(buf, "type: {gDECLINE{x {b%s{x to chicken out.\n\r", ch->name);
    send_to_char(buf, victim);
    return;
}

/*=======================================================================*
 * function: do_accept                                                   *
 * purpose: to accept the arena match, and move the players to the arena *
 * written by: Doug Araya (whiplash@tft.nacs.net) 6-10-96                *
 *=======================================================================*/
void do_accept(CHAR_DATA * ch, char *argument)
{
    float vafl, vdfl, cafl, cdfl, vpd, vpk, cpd, cpk;
    float clvl, vlvl, cw, vw, clo, vlo;

// the preceding variables before this point can be redefined to use less space.
// all variables following need to be set at what they are.
    float cha_stat, vha_stat;	//base odds from arena wins
    float chl_stat, vhl_stat;	//base odds from level diff
    float chpk_stat, vhpk_stat;	//base odds from pk/pd ratio
    float cht_stat, vht_stat;	//Average odds of winning based
    //      off previous statistics


    DESCRIPTOR_DATA *d;
    CHAR_DATA *victim;

    char buf1[MSL];
    char buf2[MSL];
    char buf3[MSL];
    int char_room;
    int vict_room;
    char_room = number_range(27001, 27032);
    vict_room = number_range(27001, 27032);

    if (IS_NPC(ch))
	return;

    if (!IS_SET(ch->exbit1_flags, EXBIT1_CHALLENGED)) {
	send_to_char("You have not been challenged.\n\r", ch);
	return;
    }

    if (arena == FIGHT_BUSY) {
	send_to_char
	    ("Sorry, there is a fight in progress, please wait a few moments.\n\r",
	     ch);
	return;
    }

    if (arena == FIGHT_LOCK) {
	send_to_char("Sorry, the arena is currently locked from use.\n\r",
		     ch);
	return;
    }

    if (argument[0] == '\0') {
	send_to_char
	    ("You must specify whose challenge you wish to accept.\n\r",
	     ch);
	return;
    }

    if ((victim = get_char_world(ch, argument)) == NULL) {
	send_to_char("They aren't logged in!\n\r", ch);
	return;
    }

    if (victim == ch) {
	send_to_char("You haven't challenged yourself!\n\r", ch);
	return;
    }

    if (!IS_SET(victim->exbit1_flags, EXBIT1_CHALLENGER)
	|| victim != ch->challenger) {
	send_to_char("That player hasn't challenged you!\n\r", ch);
	return;
    }

    send_to_char("You have accepted the challenge!\n\r", ch);
    act("$n accepts your challenge!", ch, NULL, victim, TO_VICT);

    cw = ch->pcdata->awins;
    vw = victim->pcdata->awins;
    clo = ch->pcdata->alosses;
    vlo = victim->pcdata->alosses;
    clvl = ch->level;
    vlvl = victim->level;
    vafl = victim->pcdata->aflee;
    vdfl = victim->pcdata->dflee;
    cafl = ch->pcdata->aflee;
    cdfl = ch->pcdata->dflee;
    vpd = victim->pcdata->pdeath;
    vpk = victim->pcdata->pkills;
    cpd = ch->pcdata->pdeath;
    cpk = ch->pcdata->pkills;
    /* flee record is currently not taken into account  */
    /* until a fair adjustment can be decided using it. *
       vafl =  victim->pcdata->aflee; 
       vdfl =  victim->pcdata->dflee;
       cafl =  ch->pcdata->aflee;
       cdfl =  ch->pcdata->dflee;
       * can add later
     */

/* This sets base odds of winning to 1.  Needed to maintain accurate ratio's */
/* and to also keep this function from having 'division by zero' errors      */

    if (cw == 0) {
	cw = 1;
    }
    if (clo == 0) {
	clo = 1;
    }
    if (cpd == 0) {
	cpd = 1;
    }
    if (cpk == 0) {
	cpk = 1;
    }
    if (vw == 0) {
	vw = 1;
    }
    if (vlo == 0) {
	vlo = 1;
    }
    if (vpd == 0) {
	vpd = 1;
    }
    if (vpk == 0) {
	vpk = 1;
    }

    /* Sample odds from a test fight are commented in to the right
       Please take a look at these and notice how much of an extreme
       in odds you get by having each base stat use both peoples stats */

    /* Base odds from previous arena wins/loss ratio  */

    cha_stat = ((cw / clo) / (vw / vlo));
    /*  (1/4) / (100/10) = 0.025 */
    vha_stat = ((vw / vlo) / (cw / clo));
    /*  (100/10) / (1/4) = 40.00 */

    /* Base odds from pk/pdeath ratio */

    chpk_stat = ((cpk / cpd) / (vpk / vpd));
    /*  (1/5) / (2/20)  =  2.0  */
    vhpk_stat = ((vpk / vpd) / (cpk / cpd));
    /*  (2/20) / (1/5)  =  0.5  */

    /* Base odds from level differences               */
    chl_stat = ((clvl / vlvl));	//  20/40 = 0.5
    vhl_stat = ((vlvl / clvl));	//  40/20 = 2.0


    /* Calculate winning odds = AVG of other ratio's  */
    /* Does NOT always equal payoff ratio             */
    cht_stat = ((cha_stat + chpk_stat + chl_stat) / 3);	//  2.0 + 0.5 + .025 = 2.25/3 = .750
    vht_stat = ((vha_stat + vhpk_stat + vhl_stat) / 3);	//  0.5 + 2.0 + 40.0 = 42.5/3 = 14.x

    /* Enforce payoff ratio limits
       Max payoff is 300% profit
       Min payoff is 20%  profit */
    if (cha_stat > 3) {
	cha_stat = 3;
    }
    if (chl_stat > 3) {
	chl_stat = 3;
    }
    if (chpk_stat > 3) {
	chpk_stat = 3;
    }
    if (vha_stat > 3) {
	vha_stat = 3;
    }
    if (vhl_stat > 3) {
	vhl_stat = 3;
    }
    if (vhpk_stat > 3) {
	vhpk_stat = 3;
    }
    if (cha_stat < .2) {
	cha_stat = .2;
    }
    if (chl_stat < .2) {
	chl_stat = .2;
    }
    if (chpk_stat < .2) {
	chpk_stat = .2;
    }
    if (vha_stat < .2) {
	vha_stat = .2;
    }
    if (vhl_stat < .2) {
	vhl_stat = .2;
    }
    if (vhpk_stat < .2) {
	vhpk_stat = .2;
    }
    /*  the aditional +1 is set here to make sure the original bet 
       is also returned with the profits */
    /*bet is not deducted in the first place, so +1 removed */
    cpo_stat = ((cha_stat + chpk_stat + chl_stat) / 3);
    vpo_stat = ((vha_stat + vhpk_stat + vhl_stat) / 3);

    if (cpo_stat > 10) {
	cpo_stat = 10;
    }
    if (vpo_stat > 10) {
	vpo_stat = 10;
    }




    sprintf(buf1,
	    "^{gArena{x^ {b%s{x {m({y%d {gwins{m) ({y%d {rlosses{m){x Payoff odds %f\n\r",
	    victim->name, victim->pcdata->awins, victim->pcdata->alosses,
	    vht_stat);
    sprintf(buf2,
	    "^{gArena{x^ {b%s{x {m({y%d {gwins{m) ({y%d {rlosses{m){x Payoff odds %f\n\r",
	    ch->name, ch->pcdata->awins, ch->pcdata->alosses, cht_stat);
    strcpy(buf3,
	   "{x^{gArena{x^ To wager on the fight, type: {gbet{x ({yamount{x) ({bplayer name{x)\n\r");
    for (d = descriptor_list; d; d = d->next) {
	if (d->connected == CON_PLAYING &&
	    (d->character != victim && d->character != ch)
	    && !IS_SET(d->character->comm, COMM_NOARENA)) {
	    send_to_char(buf1, d->character);
	    send_to_char(buf2, d->character);
	    send_to_char(buf3, d->character);
	    d->character->gladiator = NULL;
	}
    }
/* == now move them both to an arena for the fun == */
    send_to_char("You make your way into the arena.\n\r", ch);
    char_from_room(ch);
    char_to_room(ch, get_room_index(char_room));
    do_look(ch, "auto");
    SET_BIT(ch->comm, COMM_NOCHANNELS);
    SET_BIT(ch->act, PLR_NORESTORE);
    send_to_char("You make your way to the arena.\n\r", victim);
    char_from_room(victim);
    char_to_room(victim, get_room_index(vict_room));
    do_look(victim, "auto");
    SET_BIT(victim->comm, COMM_NOCHANNELS);
    SET_BIT(victim->act, PLR_NORESTORE);
    arena = FIGHT_BUSY;
    return;
}

/*=======================================================================*

 if( !IS_SET(fighter->in_room->room_flags,ROOM_ARENA) )

 * function: do_decline                                                  *
 * purpose: to chicken out from a sent arena challenge                   *
 * written by: Doug Araya (whiplash@tft.nacs.net) 6-10-96                *
 *=======================================================================*/
void do_decline(CHAR_DATA * ch, char *argument)
{
    CHAR_DATA *victim;
    char buf[MSL];
    DESCRIPTOR_DATA *d;


/*== make all invalid checks == */
    if (IS_NPC(ch))
	return;

    if (!IS_SET(ch->exbit1_flags, EXBIT1_CHALLENGED)) {
	send_to_char
	    ("You have niether given a challenge or been challenged.\n\r",
	     ch);
	return;
    }

    if (argument[0] == '\0') {
	send_to_char
	    ("You must specify whose challenge you wish to decline.\n\r",
	     ch);
	return;
    }

    if ((victim = get_char_world(ch, argument)) == NULL) {
	send_to_char("They aren't logged in!\n\r", ch);
	return;
    }

    if (!IS_SET(victim->exbit1_flags, EXBIT1_CHALLENGER)
	|| victim != ch->challenger) {
	send_to_char("That player hasn't challenged you.\n\r", ch);
	return;
    }


/*== now actually decline == */
    victim->challenged = NULL;
    REMOVE_BIT(victim->exbit1_flags, EXBIT1_CHALLENGER);
    ch->challenger = NULL;
    REMOVE_BIT(ch->exbit1_flags, EXBIT1_CHALLENGED);



    arena = FIGHT_OPEN;
    send_to_char("Challenge declined!\n\r", ch);
    act("$n has withdrawn from the challenge.", ch, NULL, victim, TO_VICT);
    sprintf(buf,
	    "^{gArena{x^ {b%s{x {bhas withdrawn from the challenge{x.\n\r",
	    ch->name);
    for (d = descriptor_list; d; d = d->next) {
	if (d->connected == CON_PLAYING &&
	    (d->character != victim && d->character != ch)
	    && !IS_SET(d->character->comm, COMM_NOARENA)) {
	    send_to_char(buf, d->character);
	}
    }

    return;
}

void do_dismiss(CHAR_DATA * ch, char *argument)
{
    CHAR_DATA *victim;
    char buf[MSL];
    DESCRIPTOR_DATA *d;


/*== make all invalid checks == */
    if (IS_NPC(ch))
	return;

    if (!IS_SET(ch->exbit1_flags, EXBIT1_CHALLENGER)) {
	send_to_char
	    ("You have niether given a challenge or been challenged.\n\r",
	     ch);
	return;
    }

    if (argument[0] == '\0') {
	send_to_char
	    ("You must specify whose challenge you wish to decline.\n\r",
	     ch);
	return;
    }

    if ((victim = get_char_world(ch, argument)) == NULL) {
	send_to_char("They aren't logged in!\n\r", ch);
	return;
    }

    if (!IS_SET(victim->exbit1_flags, EXBIT1_CHALLENGER)
	|| victim != ch->challenger) {
	send_to_char("That player hasn't challenged you.\n\r", ch);
	return;
    }


/*== now actually decline == */
    victim->challenged = NULL;
    REMOVE_BIT(victim->exbit1_flags, EXBIT1_CHALLENGER);
    ch->challenger = NULL;
    REMOVE_BIT(ch->exbit1_flags, EXBIT1_CHALLENGED);



    arena = FIGHT_OPEN;
    send_to_char("Challenge declined!\n\r", ch);
    act("$n has withdrawn from the challenge.", ch, NULL, victim, TO_VICT);
    sprintf(buf,
	    "^{gArena{x^ {b%s{x {bhas withdrawn from the challenge{x.\n\r",
	    ch->name);
    for (d = descriptor_list; d; d = d->next) {
	if (d->connected == CON_PLAYING &&
	    (d->character != victim && d->character != ch)
	    && !IS_SET(d->character->comm, COMM_NOARENA)) {
	    send_to_char(buf, d->character);
	}
    }

    return;
}

void do_arec(CHAR_DATA * ch, char *argument)
{
    CHAR_DATA *victim;
    char buf[MSL];
    DESCRIPTOR_DATA *d;


/* == First make all invalid checks == */
    if (IS_NPC(ch)) {
	send_to_char("Arec will not recover mobs in the arena!\n\r", ch);
	return;
    }

    if (argument[0] == '\0') {
	send_to_char
	    ("Syntax: Arec <player-name> to recover somebody stuck in the Arena.\n\r",
	     ch);
	return;
    }

    if ((victim = get_char_world(ch, argument)) == NULL) {
	send_to_char("They are not playing.\n\r", ch);
	return;
    }


/* == Removing the flags  == */

    stop_fighting(victim, TRUE);
    char_from_room(victim);
    victim->hit = victim->max_hit;
    victim->mana = victim->max_mana;
    victim->move = victim->max_move;
    update_pos(victim);
    do_look(victim, "auto");
    char_to_room(victim, get_room_index(ROOM_VNUM_AWINNER));

    if (IS_SET(ch->exbit1_flags, EXBIT1_CHALLENGER))
	REMOVE_BIT(ch->exbit1_flags, EXBIT1_CHALLENGER);
    if (IS_SET(victim->exbit1_flags, EXBIT1_CHALLENGER))
	REMOVE_BIT(victim->exbit1_flags, EXBIT1_CHALLENGER);
    if (IS_SET(victim->exbit1_flags, EXBIT1_CHALLENGED))
	REMOVE_BIT(victim->exbit1_flags, EXBIT1_CHALLENGED);
    if (IS_SET(ch->exbit1_flags, EXBIT1_CHALLENGED))
	REMOVE_BIT(ch->exbit1_flags, EXBIT1_CHALLENGED);

    victim->challenger = NULL;
    victim->challenged = NULL;
    REMOVE_BIT(victim->comm, COMM_NOCHANNELS);
    REMOVE_BIT(victim->act, PLR_NORESTORE);
    arena = FIGHT_OPEN;

    for (d = descriptor_list; d; d = d->next) {
	if (d->connected == CON_PLAYING &&
	    (d->character != victim && d->character != ch)) {
	    send_to_char(buf, d->character);
	}
    }
    send_to_char("Player recovered from the arena.\n\r", ch);
    return;
}

/*======================================================================*
 * function: do_bet                                                     *
 * purpose: to allow players to wager on the outcome of arena battles   *
 * written by: Doug Araya (whiplash@tft.nacs.net) 6-10-96               *
 *======================================================================*/
void do_bet(CHAR_DATA * ch, char *argument)
{
    char arg[MIL];
    char buf[MSL];
    CHAR_DATA *fighter;
    int wager;

    argument = one_argument(argument, arg);

    if (argument[0] == '\0' || !is_number(arg)) {
	send_to_char("Syntax: BET [amount] [player]\n\r", ch);
	return;
    }

    if (ch->gladiator != NULL) {
	send_to_char("You have already placed a bet on this fight.\n\r",
		     ch);
	return;
    }

/*== disable the actual fighters from betting ==*/
    if (IS_SET(ch->exbit1_flags, EXBIT1_CHALLENGER)
	|| IS_SET(ch->exbit1_flags, EXBIT1_CHALLENGED)) {
	send_to_char("You can't bet on this battle.\n\r", ch);
	return;
    }

    fighter = get_char_world(ch, argument);

/*== make sure the choice is valid ==*/

    if (fighter == NULL) {
	send_to_char("That player is not logged in.\n\r", ch);
	return;
    }

    if (IS_NPC(ch)) {
	send_to_char("Why bet on a mob? They aren't fighting...\n\r", ch);
	return;
    }

    if (!IS_SET(fighter->in_room->room_flags, ROOM_ARENA)) {
	send_to_char("That player is not in the arena.\n\r", ch);
	return;
    }

/*== do away with the negative number trickery ==*/
    if (!str_prefix("-", arg)) {
	send_to_char("Error: Invalid argument!\n\r", ch);
	return;
    }

    wager = atoi(arg);

    if (wager > 10001 || wager < 1) {
	send_to_char("Wager range is between 1 and 10000\n\r", ch);
	return;
    }

/*== make sure they have the cash ==*/
    if (wager > ch->gold + (ch->platinum * 100)) {
	send_to_char("You don't have that much gold to wager!\n\r", ch);
	return;
    }

/*== now set the info ==*/
    ch->gladiator = fighter;
    ch->pcdata->plr_wager = wager;
    sprintf(buf, "You have placed a {y%d{x gold wager on {b%s{x\n\r",
	    wager, fighter->name);
    send_to_char(buf, ch);
    return;
}

bool is_voodood(CHAR_DATA * ch, CHAR_DATA * victim)
{
    OBJ_DATA *object;
    bool found;

    if (ch->level > HERO)
	return FALSE;

    found = FALSE;
    for (object = victim->carrying; object != NULL;
	 object = object->next_content) {
	if (object->pIndexData->vnum == OBJ_VNUM_VOODOO) {
	    char arg[MIL];

	    one_argument(object->name, arg);
	    if (!str_cmp(arg, ch->name)) {
		return TRUE;
	    }
	}
    }
    return FALSE;
}

bool is_safe_spell(CHAR_DATA * ch, CHAR_DATA * victim, bool area)
{
    if (victim->in_room == NULL || ch->in_room == NULL)
	return TRUE;

    if (victim == ch && area)
	return TRUE;

    if (victim->fighting == ch || victim == ch)
	return FALSE;

    if (!IS_NPC(ch) && IS_IMMORTAL(ch))
	return FALSE;

    if (ch->spirit)
	return TRUE;

    if (victim->spirit)
	return TRUE;

    /* killing mobiles */
    if (IS_NPC(victim)) {
	/* safe room? */
	if (IS_SET(victim->in_room->room_flags, ROOM_SAFE))
	    return TRUE;

	if (!IS_NPC(ch)
	    && IS_SET(victim->in_room->room_flags,
		      ROOM_CLAN_ENT)) return TRUE;

	if (victim->pIndexData->pShop != NULL)
	    return TRUE;

	/* no killing healers, trainers, etc */
	if (IS_SET(victim->act, ACT_TRAIN)
	    || IS_SET(victim->act, ACT_PRACTICE)
	    || IS_SET(victim->act, ACT_IS_HEALER)
	    || IS_SET(victim->act, ACT_IS_BANKER)
	    || IS_SET(victim->act, ACT_IS_SATAN)
	    || IS_SET(victim->act, ACT_IS_PRIEST))
	    return TRUE;

	if (!IS_NPC(ch)) {
	    /* no pets */
	    if (IS_SET(victim->act, ACT_PET))
		return TRUE;

	    /* no charmed creatures unless owner */
	    if (IS_AFFECTED(victim, AFF_CHARM)
		&& (area || ch != victim->master)) return TRUE;

	    /* legal kill? -- cannot hit mob fighting non-group member */
	    if (victim->fighting != NULL
		&& !is_same_group(ch, victim->fighting)) return TRUE;
	} else {
	    /* area effect spells do not hit other mobs */
	    if (area && !is_same_group(victim, ch->fighting))
		return TRUE;
	}
    }
    /* killing players */
    else {
	if (area && IS_IMMORTAL(victim) && victim->level > LEVEL_IMMORTAL)
	    return TRUE;

	/* NPC doing the killing */
	if (IS_NPC(ch)) {
	    /* charmed mobs and pets cannot attack players while owned */
	    if (((IS_AFFECTED(ch, AFF_CHARM)) & (ch->master != NULL))
		&& (ch->master->fighting != victim))
		return TRUE;

	    /* safe room? */
	    if (IS_SET(victim->in_room->room_flags, ROOM_SAFE))
		return TRUE;

	    /* legal kill? -- mobs only hit players grouped with opponent */
	    if (ch->fighting != NULL
		&& !is_same_group(ch->fighting, victim)) return TRUE;
	}

	/* player doing the killing */
	else {
	    if (IS_SET(victim->in_room->room_flags, ROOM_ARENA))
		return FALSE;

	    if (IS_SET(victim->act, PLR_TWIT))
		return FALSE;

	    if (((victim->level > 19)
		 || ((victim->class >= MCLT_1)
		     && (victim->level > 14)))
		&& (is_voodood(ch, victim)))
		return FALSE;

	    if (!is_clan(ch))
		return TRUE;

	    if (!is_pkill(ch))
		return TRUE;

	    if (IS_SET(victim->in_room->room_flags, ROOM_SAFE))
		return TRUE;

	    if (ch->on_gquest)
		return TRUE;

	    if (victim->on_gquest)
		return TRUE;

	    if (!is_clan(victim))
		return TRUE;

	    if (!is_pkill(victim))
		return TRUE;

	    if (is_same_clan(ch, victim))
		return TRUE;

	    if (((ch->pcdata->tier == 2)
		 && (victim->pcdata->tier == 2))
		|| ((ch->pcdata->tier == 1)
		    && (victim->pcdata->tier == 1))
		|| ((ch->pcdata->tier == 0)
		    && (victim->pcdata->tier == 0))) {
		if (ch->level > victim->level + 10) {
		    return TRUE;
		}
		if (ch->level < victim->level - 20) {
		    return TRUE;
		}
	    }

	    if ((ch->pcdata->tier == 2)
		&& (victim->pcdata->tier == 0)) {
		return TRUE;
	    }

	    if ((ch->pcdata->tier == 0)
		&& (victim->pcdata->tier == 2)) {
		return TRUE;
	    }

	    if (((ch->pcdata->tier == 1)
		 && (victim->pcdata->tier == 0))
		|| ((ch->pcdata->tier == 2)
		    && (victim->pcdata->tier == 1))) {
		if (ch->level < (victim->level - 30)) {
		    return TRUE;
		}
		if (ch->level > victim->level) {
		    return TRUE;
		}
	    }

	    if (((ch->pcdata->tier == 0)
		 && (victim->pcdata->tier == 1))
		|| ((ch->pcdata->tier == 1)
		    && (victim->pcdata->tier == 2))) {
		if (ch->level < (victim->level - 10)) {
		    return TRUE;
		}
		if (ch->level > (victim->level + 20)) {
		    return TRUE;
		}
	    }
	}
    }
    return FALSE;
}

/*
 * Check for parry.
 */
bool check_parry(CHAR_DATA * ch, CHAR_DATA * victim)
{
    int chance;
    int bill;

    if (!IS_AWAKE(victim))
	return FALSE;

    chance = get_skill(victim, gsn_parry) / 2;

    if (get_eq_char(victim, WEAR_WIELD) == NULL) {
	if (IS_NPC(victim))
	    chance /= 2;
	else
	    return FALSE;
    }

    if (victim->stunned)
	return FALSE;

    if (!can_see(ch, victim))
	chance /= 2;

    if (number_percent() >= chance + victim->level - ch->level)
	return FALSE;


    if (IS_STANCE(victim, STANCE_CRANE) &&
	victim->stance[STANCE_CRANE] > 0 && !can_counter(ch) &&
	!can_bypass(ch, victim))
	chance += (victim->stance[STANCE_CRANE] * 0.25);
    else if (IS_STANCE(victim, STANCE_MANTIS) &&
	     victim->stance[STANCE_MANTIS] > 0 && !can_counter(ch) &&
	     !can_bypass(ch, victim))
	chance += (victim->stance[STANCE_MANTIS] * 0.25);
/* fuk */
    bill = number_range(1, 24);
    if (bill == 1) {
	act("With cat like speed you parry $n's attack.", ch, NULL, victim,
	    TO_VICT);
	act("With cat like speed $N parries your attack.", ch, NULL,
	    victim, TO_CHAR);
	act("With cat like speed $n parries $N's attack.", ch, NULL,
	    victim, TO_NOTVICT);
	check_improve(victim, gsn_parry, TRUE, 6);
    } else if (bill == 2) {
	act("You move your weapon up parrying $n's attack.", ch, NULL,
	    victim, TO_VICT);
	act("$N moves $s weapon up parrying your blow.", ch, NULL, victim,
	    TO_CHAR);
	act("$n moves $s weapon up parrying $N's blow.", ch, NULL, victim,
	    TO_NOTVICT);
	check_improve(victim, gsn_parry, TRUE, 6);
    } else if (bill == 3) {
	act("You move your weapon to the side parrying $n's blow.", ch,
	    NULL, victim, TO_VICT);
	act("$N moves $s weapon to the side parrying your blow.", ch, NULL,
	    victim, TO_CHAR);
	act("$n moves $s weapon to the side parring $N's blow.", ch, NULL,
	    victim, TO_NOTVICT);
	check_improve(victim, gsn_parry, TRUE, 6);
    } else if (bill == 4) {
	act("You deftly move your weapon between $n's attack.", ch, NULL,
	    victim, TO_VICT);
	act("$N deftly moves $s weapon between your attack", ch, NULL,
	    victim, TO_CHAR);
	act("$n deftly moves $s weapon between $N's attack.", ch, NULL,
	    victim, TO_NOTVICT);

    } else if (bill == 5) {
	act("You spin your weapon in a defensive move parrying $n's blow.",
	    ch, get_eq_char(ch, WEAR_WIELD), victim, TO_VICT);
	act("$N spins $s weapon in a defensive move parrying your blow.",
	    ch, get_eq_char(ch, WEAR_WIELD), victim, TO_CHAR);
	act("$n spins $s weapon in a defensive move parrying $N's blow.",
	    ch, get_eq_char(ch, WEAR_WIELD), victim, TO_NOTVICT);
	check_improve(victim, gsn_parry, TRUE, 6);
    } else if (bill == 6) {
	act("With a bone-jarring skill you parry $n's blow.", ch, NULL,
	    victim, TO_VICT);
	act("With a bone-jarring skill $N parries your blow.", ch, NULL,
	    victim, TO_CHAR);
	act("With a bone-jarring skill $n parries $N's blow.", ch, NULL,
	    victim, TO_NOTVICT);
	check_improve(victim, gsn_parry, TRUE, 6);
    } else if (bill == 7) {
	act("You swiftly parry $n's attack.", ch, NULL, victim, TO_VICT);
	act("$N swiftly parries your attack.", ch, NULL, victim, TO_CHAR);
	act("$n swiftly parries $N's attack.", ch, NULL, victim,
	    TO_NOTVICT);
	check_improve(victim, gsn_parry, TRUE, 6);
    } else if (bill == 8) {
	act("Moving like a panther you parry $n's attack.", ch, NULL,
	    victim, TO_VICT);
	act("$N moves like a panther parrying your attack.", ch, NULL,
	    victim, TO_CHAR);
	act("$n moves like a panther parrying $N's attack.", ch, NULL,
	    victim, TO_NOTVICT);
	check_improve(victim, gsn_parry, TRUE, 6);
    }
    return TRUE;
}

/*
 * Check for shield block.
 */
bool check_shield_block(CHAR_DATA * ch, CHAR_DATA * victim)
{
    int chance;

    if (!IS_AWAKE(victim))
	return FALSE;


    chance = get_skill(victim, gsn_shield_block) / 5 + 3;


    if (get_eq_char(victim, WEAR_SHIELD) == NULL)
	return FALSE;

    if (number_percent() >= chance + victim->level - ch->level)
	return FALSE;

    if (victim->stunned)
	return FALSE;

    act("You block $n's attack with your shield.{x", ch, NULL, victim,
	TO_VICT);
    act("{h$N blocks your attack with a shield.{x", ch, NULL, victim,
	TO_CHAR);
    check_improve(victim, gsn_shield_block, TRUE, 6);
    return TRUE;
}


/*
 * Check for dodge.
 */
bool check_dodge(CHAR_DATA * ch, CHAR_DATA * victim)
{
    int chance;
    int bill;

    if (!IS_AWAKE(victim))
	return FALSE;

    chance = get_skill(victim, gsn_dodge) / 2;

    if (!can_see(victim, ch))
	chance /= 2;

    if (number_percent() >= chance + victim->level - ch->level)
	return FALSE;

    if (victim->stunned)
	return FALSE;


    if (IS_STANCE(victim, STANCE_MONGOOSE) &&
	victim->stance[STANCE_MONGOOSE] > 0 && !can_counter(ch) &&
	!can_bypass(ch, victim))
	(chance += victim->stance[STANCE_MONGOOSE] * 0.25);
    if (IS_STANCE(victim, STANCE_SWALLOW) &&
	victim->stance[STANCE_SWALLOW] > 0 && !can_counter(ch) &&
	!can_bypass(ch, victim))
	(chance += victim->stance[STANCE_SWALLOW] * 0.25);

    bill = number_range(1, 27);
    if (bill == 1) {
	act("You feint to the right dodging $n's blow.", ch, NULL, victim,
	    TO_VICT);
	act("$N feints to the right dodging your blow.", ch, NULL, victim,
	    TO_CHAR);
	act("$n feints to the right dodging $N's blow.", ch, NULL, victim,
	    TO_NOTVICT);
	check_improve(victim, gsn_dodge, TRUE, 6);
    } else if (bill == 2) {
	act("You quickly duck dodging $n's attack.", ch, NULL, victim,
	    TO_VICT);
	act("$N ducks quickly dodging your attack.", ch, NULL, victim,
	    TO_CHAR);
	act("$n ducks quickly dodging $N's attack.", ch, NULL, victim,
	    TO_NOTVICT);
	check_improve(victim, gsn_dodge, TRUE, 6);
    } else if (bill == 3) {
	act("You roll to the ground dodging $n's blow.", ch, NULL, victim,
	    TO_VICT);
	act("$N rolls to the ground dodging your blow.", ch, NULL, victim,
	    TO_CHAR);
	act("$n rolls to the ground dodging  $N's blow.", ch, NULL, victim,
	    TO_NOTVICT);
	act("$n leaps back up!", ch, NULL, victim, TO_NOTVICT);
	act("You leap back up!", ch, NULL, victim, TO_VICT);
	act("$N leaps back up!", ch, NULL, victim, TO_CHAR);
	check_improve(victim, gsn_dodge, TRUE, 6);
    } else if (bill == 4) {
	act("You dodge $n's useless attack.", ch, NULL, victim, TO_VICT);
	act("$N dodges your useless attack.", ch, NULL, victim, TO_CHAR);
	act("$n dodges $N's useless attack.", ch, NULL, victim,
	    TO_NOTVICT);
	check_improve(victim, gsn_dodge, TRUE, 6);
    } else if (bill == 5) {
	act("You bob and weave dodging $n's blow.", ch, NULL, victim,
	    TO_VICT);
	act("$N bobs and weaves dodging your blow.", ch, NULL, victim,
	    TO_CHAR);
	act("$n bobs and weaves dodging $N's blow.", ch, NULL, victim,
	    TO_NOTVICT);
	check_improve(victim, gsn_dodge, TRUE, 6);
    } else if (bill == 6) {
	act("You roll with the blow dodging $n's attack.", ch, NULL,
	    victim, TO_VICT);
	act("$N rolls with the blow dodging your attack.", ch, NULL,
	    victim, TO_CHAR);
	act("$n rolls with the blow dodging $N's attack.", ch, NULL,
	    victim, TO_NOTVICT);
    } else if (bill == 7) {
	act("You twist right dodging $n.", ch, NULL, victim, TO_VICT);
	act("$N twists right dodging your blow.", ch, NULL, victim,
	    TO_CHAR);
	act("$n twists right dodging $N's blow.", ch, NULL, victim,
	    TO_NOTVICT);
	check_improve(victim, gsn_dodge, TRUE, 6);
    } else if (bill == 8) {
	act("You twist left dodging $n.", ch, NULL, victim, TO_VICT);
	act("$N twists left dodging your blow.", ch, NULL, victim,
	    TO_CHAR);
	act("$n twists left dodging $N's blow.", ch, NULL, victim,
	    TO_NOTVICT);
	check_improve(victim, gsn_dodge, TRUE, 6);
    } else if (bill == 9) {
	act("You roll to the ground dodging $n's blow.", ch, NULL, victim,
	    TO_VICT);
	act("$N rolls to the ground dodging your blow.", ch, NULL, victim,
	    TO_CHAR);
	act("$n rolls to the ground dodging  $N's blow.", ch, NULL, victim,
	    TO_NOTVICT);
	act("$n deftly springs to their feet!", ch, NULL, victim,
	    TO_NOTVICT);
	act("deftly... you spring to your feet!", ch, NULL, victim,
	    TO_VICT);
	act("$N deftly springs to their feet!", ch, NULL, victim, TO_CHAR);
	check_improve(victim, gsn_dodge, TRUE, 6);
    }
    return TRUE;
}



/*
 * Set position of a victim.
 */
void update_pos(CHAR_DATA * victim)
{
    if (victim->hit > 0) {
	if (victim->position <= POS_STUNNED)
	    victim->position = POS_STANDING;
	return;
    }

    if (IS_NPC(victim) && victim->hit < 1) {
	victim->position = POS_DEAD;
	return;
    }

    if (victim->hit <= -11) {

	if (IS_SET(victim->exbit1_flags, RECRUIT)
	    && (victim->pcdata->pdeath >= 5
		|| victim->pcdata->pkills >= 5)) {
	    send_to_char("Your skill at PK has improved.\n\r", victim);
	    REMOVE_BIT(victim->exbit1_flags, RECRUIT);
	    SET_BIT(victim->exbit1_flags, PK_VETERAN);
	}
	victim->position = POS_DEAD;
	victim->spirit = 1;
	return;
    }

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

    return;
}



/*
 * Start fights.
 */
void set_fighting(CHAR_DATA * ch, CHAR_DATA * victim)
{
    if (ch->fighting != NULL) {
	bug("Set_fighting: already fighting", 0);
	return;
    }

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

    if (ch->shadow) {
	ch->shadowing->shadowed = FALSE;
	ch->shadowing->shadower = NULL;
	ch->shadowing = NULL;
	ch->shadow = FALSE;
    }
    ch->fighting = victim;
    ch->position = POS_FIGHTING;
    ch->stunned = 0;

    return;
}



/*
 * Stop fights.
 */
void stop_fighting(CHAR_DATA * ch, bool fBoth)
{
    CHAR_DATA *fch;
    char buf[MSL];

    for (fch = char_list; fch != NULL; fch = fch->next) {
	if (fch == ch || (fBoth && fch->fighting == ch)) {
	    fch->fighting = NULL;
	    fch->position = IS_NPC(fch) ? fch->default_pos : POS_STANDING;
	    fch->stunned = 0;
	    update_pos(fch);
	    if (IS_SET(fch->comm, COMM_STORE))
		if (fch->tells) {
		    sprintf(buf, "You have {R%d{x tells waiting.\n\r",
			    fch->tells);
		    send_to_char(buf, fch);
		    send_to_char("Type 'replay' to see tells.\n\r", fch);
		}

	    if (IS_SET(ch->exbit1_flags, RECRUIT)
		&& (ch->pcdata->pdeath >= 5 || ch->pcdata->pkills >= 5)) {
		send_to_char("Your skill at PK has improved.\n\r", ch);
		REMOVE_BIT(ch->exbit1_flags, RECRUIT);
		SET_BIT(ch->exbit1_flags, PK_VETERAN);
	    }
	}
    }

    return;
}



/*
 * Make a corpse out of a character.
 */
void make_corpse(CHAR_DATA * ch, CHAR_DATA * killer)
{
    char buf[MSL];
    OBJ_DATA *corpse;
    OBJ_DATA *obj;
    OBJ_DATA *obj_next;
    char *name;
    int gold, silver, platinum;
    int wearloc;

    if (IS_NPC(ch)) {
	if (IS_SET(ch->act, ACT_NO_BODY)) {
	    if (IS_SET(ch->act, ACT_NB_DROP)) {
		for (obj = ch->carrying; obj != NULL; obj = obj_next) {
		    obj_next = obj->next_content;
		    obj_from_char(obj);
		    if (!IS_NPC(killer) && killer->pcdata->is_aquest) {
			obj->got_from = ch->pIndexData->vnum;
		    } else {
			obj->got_from = 0;
		    }
		    if (obj->item_type == ITEM_POTION)
			obj->timer = number_range(500, 1000);
		    if (obj->item_type == ITEM_SCROLL)
			obj->timer = number_range(1000, 2500);
		    if (IS_SET(obj->extra_flags, ITEM_ROT_DEATH)) {
			obj->timer = number_range(5, 10);
			REMOVE_BIT(obj->extra_flags, ITEM_ROT_DEATH);
		    }
		    REMOVE_BIT(obj->extra_flags, ITEM_VIS_DEATH);

		    if (IS_SET(obj->extra_flags, ITEM_INVENTORY))
			extract_obj(obj);
		    act("$p falls to the floor.", ch, obj, NULL, TO_ROOM);
		    obj_to_room(obj, ch->in_room);
		}
	    }
	    return;
	}
	name = ch->short_descr;
	corpse = create_object(get_obj_index(OBJ_VNUM_CORPSE_NPC), 0);
	corpse->timer = number_range(3, 6);
	if (ch->silver > 0 || ch->gold > 0 || ch->platinum > 0) {
	    obj_to_obj(create_money(ch->platinum, ch->gold, ch->silver),
		       corpse);
	    ch->platinum = 0;
	    ch->gold = 0;
	    ch->silver = 0;
	}
	corpse->cost = 0;
    } else {
	name = ch->name;
	corpse = create_object(get_obj_index(OBJ_VNUM_CORPSE_PC), 0);
	corpse->timer = number_range(25, 40);
	REMOVE_BIT(ch->act, PLR_CANLOOT);
	if (!is_clan(ch)) {
	    corpse->owner = str_dup(ch->name);
	    corpse->killer = NULL;
	} else {
	    corpse->owner = str_dup(ch->name);
	    corpse->killer = str_dup(killer->name);
	    if (ch->platinum > 1 || ch->gold > 1 || ch->silver > 1) {
		silver = number_range(0, ch->silver / 3);
		gold = number_range(0, ch->gold / 3);
		platinum = number_range(0, ch->platinum / 3);
		obj_to_obj(create_money
			   ((ch->platinum / 2) - platinum,
			    (ch->gold / 2) - gold,
			    (ch->silver / 2) - silver), corpse);
		ch->platinum -= ch->platinum / 2;
		ch->gold -= ch->gold / 2;
		ch->silver -= ch->silver / 2;
		obj_to_room(create_money(platinum, gold, silver),
			    ch->in_room);
		act("Some money spills across the floor.", ch, NULL, NULL,
		    TO_ROOM);
		act("Some of your money spills across the floor.", ch,
		    NULL, NULL, TO_CHAR);
	    }
	}

	corpse->cost = 0;

    }

    corpse->level = ch->level;

    sprintf(buf, corpse->short_descr, name);
    free_string(corpse->short_descr);
    corpse->short_descr = str_dup(buf);

    sprintf(buf, corpse->description, name);
    free_string(corpse->description);
    corpse->description = str_dup(buf);

    if (!IS_NPC(ch) && !IS_NPC(killer)) {
	wearloc = number_range(0, MAX_WEAR - 1);
	if ((obj = get_eq_char(ch, wearloc)) != NULL) {
	    if ((obj->wear_loc != WEAR_FLOAT)
		&& (obj->item_type != ITEM_PASSBOOK)
		&& (!obj->clan)
		&& (!obj->quest)) {
		obj_from_char(obj);
		obj_to_room(obj, ch->in_room);
		act("$p falls to the floor.", ch, obj, NULL, TO_ROOM);
		act("$p falls to the floor.", ch, obj, NULL, TO_CHAR);
	    }
	}
	wearloc = number_range(0, MAX_WEAR - 1);
	if ((obj = get_eq_char(ch, wearloc)) != NULL) {
	    if ((obj->wear_loc != WEAR_FLOAT)
		&& (obj->item_type != ITEM_PASSBOOK)
		&& (!obj->clan)
		&& (!obj->quest)) {
		obj_from_char(obj);
		obj_to_room(obj, ch->in_room);
		act("$p falls to the floor.", ch, obj, NULL, TO_ROOM);
		act("$p falls to the floor.", ch, obj, NULL, TO_CHAR);
	    }
	}
	wearloc = number_range(0, MAX_WEAR - 1);
	if ((obj = get_eq_char(ch, wearloc)) != NULL) {
	    if ((obj->wear_loc != WEAR_FLOAT)
		&& (obj->item_type != ITEM_PASSBOOK)
		&& (!obj->clan)
		&& (!obj->quest)) {
		obj_from_char(obj);
		obj_to_room(obj, ch->in_room);
		act("$p falls to the floor.", ch, obj, NULL, TO_ROOM);
		act("$p falls to the floor.", ch, obj, NULL, TO_CHAR);
	    }
	}
    }

    for (obj = ch->carrying; obj != NULL; obj = obj_next) {
	bool floating = FALSE;

	obj_next = obj->next_content;
	if (IS_OBJ_STAT(obj, ITEM_LQUEST))
	    continue;
	if (obj->pIndexData->vnum == OBJ_VNUM_QPOUCH)
	    continue;
	if (obj->wear_loc == WEAR_FLOAT)
	    floating = TRUE;

	obj_from_char(obj);
	if (IS_NPC(ch) && !IS_NPC(killer) && killer->pcdata->is_aquest) {
	    obj->got_from = ch->pIndexData->vnum;
	} else {
	    obj->got_from = 0;
	}
	if (obj->item_type == ITEM_POTION)
	    obj->timer = number_range(500, 1000);
	if (obj->item_type == ITEM_SCROLL)
	    obj->timer = number_range(1000, 2500);
	if (IS_SET(obj->extra_flags, ITEM_ROT_DEATH) && !floating) {
	    obj->timer = number_range(5, 10);
	    REMOVE_BIT(obj->extra_flags, ITEM_ROT_DEATH);
	}
	REMOVE_BIT(obj->extra_flags, ITEM_VIS_DEATH);

	if (obj->item_type == ITEM_PASSBOOK) {
	    change_banklist(ch, FALSE, obj->value[0], obj->value[1], 0,
			    obj->name);
	    extract_obj(obj);
	} else if (IS_SET(obj->extra_flags, ITEM_INVENTORY)) {
	    extract_obj(obj);
	} else if (floating) {
	    if (IS_OBJ_STAT(obj, ITEM_ROT_DEATH)) {	/* get rid of it! */
		if (obj->contains != NULL) {
		    OBJ_DATA *in, *in_next;

		    act("$p evaporates,scattering its contents.",
			ch, obj, NULL, TO_ROOM);
		    for (in = obj->contains; in != NULL; in = in_next) {
			in_next = in->next_content;
			obj_from_obj(in);
			obj_to_room(in, ch->in_room);
		    }
		} else
		    act("$p evaporates.", ch, obj, NULL, TO_ROOM);
		extract_obj(obj);
	    } else {
		act("$p falls to the floor.", ch, obj, NULL, TO_ROOM);
		obj_to_room(obj, ch->in_room);
	    }
	} else
	    obj_to_obj(obj, corpse);
    }

    if (!IS_NPC(ch)) {
	act("$p vanishes in a bright flash.", ch, corpse, NULL, TO_ROOM);
	act("Your corpse vanishes in a bright flash.", ch, corpse, NULL,
	    TO_CHAR);
	
	if (ch->level < 10 && ch->pcdata->tier < 1 )
	    obj_to_room(corpse, get_room_index(ROOM_VNUM_MORGUE_SCHOOL));
	else
	    obj_to_room(corpse,
			get_room_index(home_table[ch->home].morgue));
    } else {
	obj_to_room(corpse, ch->in_room);
    }
    return;
}



/*
 * Improved Death_cry contributed by Diavolo.
 * PK Token modifications added by  D. A. C.
 */

void death_cry(CHAR_DATA * ch, CHAR_DATA * killer) 
{
    ROOM_INDEX_DATA *was_in_room;
    char buf[MSL];
    OBJ_DATA *token2, *token3, *token4, *token5, *token6;
//    CHAR_DATA *victim;
    char *msg;
    int door;
    int vnum;

    vnum = 0;
    msg = "You hear $n's death cry.";
	if (!IS_SET(ch->act, ACT_NO_BODY)) {
	    switch (number_bits(4)) {
	    case 0:
		msg = "$n hits the ground ... DEAD.";
		vnum = OBJ_VNUM_BLOOD;
		break;
	    case 1:
		msg = "$n splatters blood on your armor.";
		vnum = OBJ_VNUM_BLOOD;
		break;
	    case 2:
		if (IS_SET(ch->parts, PART_GUTS)) {
		    msg = "$n spills $s guts all over the floor.";
		    vnum = OBJ_VNUM_GUTS;
		}
		break;
	    case 3:
		if (IS_SET(ch->parts, PART_HEAD)) {
		    msg = "$n's severed head plops on the ground.";
		    vnum = OBJ_VNUM_SEVERED_HEAD;
		}
		break;
	    case 4:
		if (IS_SET(ch->parts, PART_HEART)) {
		    msg = "$n's heart is torn from $s chest.";
		    vnum = OBJ_VNUM_TORN_HEART;
		}
		break;
	    case 5:
		if (IS_SET(ch->parts, PART_ARMS)) {
		    msg = "$n's arm is sliced from $s dead body.";
		    vnum = OBJ_VNUM_SLICED_ARM;
		}
		break;
	    case 6:
		if (IS_SET(ch->parts, PART_LEGS)) {
		    msg = "$n's leg is sliced from $s dead body.";
		    vnum = OBJ_VNUM_SLICED_LEG;
		}
		break;
	    case 7:
		if (IS_SET(ch->parts, PART_BRAINS)) {
		    msg =
			"$n's head is shattered, and $s brains splash all over you.";
		    vnum = OBJ_VNUM_BRAINS;
		}
		break;
	    case 8:
		msg = "$n hits the ground ... DEAD.";
		vnum = OBJ_VNUM_BLOOD;
		break;
	    case 9:
		msg = "$n hits the ground ... DEAD.";
		vnum = OBJ_VNUM_BLOOD;
	    }
	}

    else if (ch->level > 19) {
	switch (number_bits(4)) {
	case 0:
	    msg = "$n hits the ground ... DEAD.";
	    vnum = OBJ_VNUM_BLOOD;
	    break;
	case 1:
	    msg = "$n splatters blood on your armor.";
	    vnum = OBJ_VNUM_BLOOD;
	    break;
	case 2:
	    if (IS_SET(ch->parts, PART_GUTS)) {
		msg = "$n spills $s guts all over the floor.";
		vnum = OBJ_VNUM_GUTS;
	    }
	    break;
	case 3:
	    if (IS_SET(ch->parts, PART_HEAD)) {
		msg = "$n's severed head plops on the ground.";
		vnum = OBJ_VNUM_SEVERED_HEAD;
	    }
	    break;
	case 4:
	    if (IS_SET(ch->parts, PART_HEART)) {
		msg = "$n's heart is torn from $s chest.";
		vnum = OBJ_VNUM_TORN_HEART;
	    }
	    break;
	case 5:
	    if (IS_SET(ch->parts, PART_ARMS)) {
		msg = "$n's arm is sliced from $s dead body.";
		vnum = OBJ_VNUM_SLICED_ARM;
	    }
	    break;
	case 6:
	    if (IS_SET(ch->parts, PART_LEGS)) {
		msg = "$n's leg is sliced from $s dead body.";
		vnum = OBJ_VNUM_SLICED_LEG;
	    }
	    break;
	case 7:
	    if (IS_SET(ch->parts, PART_BRAINS)) {
		msg =
		    "$n's head is shattered, and $s brains splash all over you.";
		vnum = OBJ_VNUM_BRAINS;
	    }
	    break;
	case 8:
	    msg = "$n hits the ground ... DEAD.";
	    vnum = OBJ_VNUM_BLOOD;
	    break;
	case 9:
	    msg = "$n hits the ground ... DEAD.";
	    vnum = OBJ_VNUM_BLOOD;
	    break;
	case 10:
	    if (IS_SET(ch->parts, PART_HEAD)) {
		msg = "$n's severed head plops on the ground.";
		vnum = OBJ_VNUM_SEVERED_HEAD;
	    }
	    break;
	case 11:
	    if (IS_SET(ch->parts, PART_HEART)) {
		msg = "$n's heart is torn from $s chest.";
		vnum = OBJ_VNUM_TORN_HEART;
	    }
	    break;
	case 12:
	    if (IS_SET(ch->parts, PART_ARMS)) {
		msg = "$n's arm is sliced from $s dead body.";
		vnum = OBJ_VNUM_SLICED_ARM;
	    }
	    break;
	case 13:
	    if (IS_SET(ch->parts, PART_LEGS)) {
		msg = "$n's leg is sliced from $s dead body.";
		vnum = OBJ_VNUM_SLICED_LEG;
	    }
	    break;
	case 14:
	    if (IS_SET(ch->parts, PART_BRAINS)) {
		msg =
		    "$n's head is shattered, and $s brains splash all over you.";
		vnum = OBJ_VNUM_BRAINS;
	    }
	}
    }

    act(msg, ch, NULL, NULL, TO_ROOM);
    if ((vnum == 0) && !IS_SET(ch->act, ACT_NO_BODY) && (!IS_SET(ch->in_room->room_flags, ROOM_ARENA))) 
	{

	switch (number_bits(4)) {
	case 0:
	    if (killer == ch)  // This part here is where I want it to return if its a self kill
		return;
	    if ( !IS_NPC( ch ) ) {
		vnum = OVPKT1;
	    } else {
		; // vnum = vnum;
	    }
	    break;
	case 1:
	    if (killer == ch)
		return;
	    token2 = get_eq_char(killer, WEAR_HOLD);
	    token4 = create_object(get_obj_index(OVPKT4), 0);

	    if (!IS_NPC(ch)
		&& token2 != NULL && token2->pIndexData->vnum == OVPKT2) {
		sprintf(buf, token4->short_descr, killer->name, ch->name);
		free_string(token4->short_descr);
		token4->short_descr = str_dup(buf);
		sprintf(buf, token4->description, killer->name, ch->name);
		free_string(token4->description);
		token4->description = str_dup(buf);
		sprintf(buf, token4->name, killer->name, ch->name);
		free_string(token4->name);
		token4->name = str_dup(buf);
		obj_from_char(token2);
		extract_obj(token2);
		obj_to_char(token4, killer);
		DAZE_STATE(killer, 17 + (5 * PULSE_VIOLENCE));
	    } else if ( !IS_NPC( ch ) ) {
		vnum = OVPKT1;
	    } else {
		vnum = OBJ_VNUM_BLOOD;
	    }
	    break;
	case 2:
	    if (killer == ch)
		return;
		if ( !IS_NPC( ch ) ) {
		vnum = OVPKT1;
	    } else {
		vnum = OBJ_VNUM_BLOOD;
	    }
	    break;
	case 3:
	    if (killer == ch)
		return;

	    token2 = get_eq_char(killer, WEAR_HOLD);
	    token4 = create_object(get_obj_index(OVPKT4), 0);

	    if (!IS_NPC(ch)
		&& token2 != NULL && token2->pIndexData->vnum == OVPKT2) {
		sprintf(buf, token4->short_descr, killer->name, ch->name);
		free_string(token4->short_descr);
		token4->short_descr = str_dup(buf);
		sprintf(buf, token4->description, killer->name, ch->name);
		free_string(token4->description);
		token4->description = str_dup(buf);
		sprintf(buf, token4->name, killer->name, ch->name);
		free_string(token4->name);
		token4->name = str_dup(buf);
		obj_from_char(token2);
		extract_obj(token2);
		obj_to_char(token4, killer);
		DAZE_STATE(killer, 17 + (5 * PULSE_VIOLENCE));
	    } else if ( !IS_NPC( ch ) ) {
		vnum = OVPKT2;
	    } else {
		vnum = OBJ_VNUM_BLOOD;
	    }
	    break;
	case 4:
	    if (killer == ch)
		return;
	    token2 = get_eq_char(killer, WEAR_HOLD);
	    token4 = get_eq_char(killer, WEAR_NECK_1);
	    token5 = create_object(get_obj_index(OVPKT5), 0);
	    if (!IS_NPC(ch)
		&& token2 != NULL
		&& token2->pIndexData->vnum == OVPKT2
		&& token4 != NULL && token4->pIndexData->vnum == OVPKT4) {
		obj_from_char(token2);
		extract_obj(token2);
		obj_to_char(token5, killer);
		DAZE_STATE(killer, 24 + (5 * PULSE_VIOLENCE));
	    } else if ( !IS_NPC( ch ) ) {
		vnum = OVPKT1;
	    } else {
		vnum = OBJ_VNUM_BLOOD;
	    }
	    break;
	case 5:
	    if (killer == ch)
		return;
		if ( !IS_NPC( ch ) ) {
		vnum = OVPKT1;
	    } else {
		vnum = OBJ_VNUM_BLOOD;
	    }
	    break;
	case 6:
	    if (killer == ch)
		return;
	    token2 = get_eq_char(killer, WEAR_HOLD);
	    token4 = get_eq_char(killer, WEAR_NECK_1);
	    token5 = create_object(get_obj_index(OVPKT5), 0);
	    if (!IS_NPC(ch)
		&& token2 != NULL
		&& token2->pIndexData->vnum == OVPKT2
		&& token4 != NULL && token4->pIndexData->vnum == OVPKT4) {
		obj_from_char(token2);
		extract_obj(token2);
		obj_to_char(token5, killer);
		DAZE_STATE(killer, 24 + (5 * PULSE_VIOLENCE));
	    } else if ( !IS_NPC( ch ) ) {
		vnum = OVPKT2;
	    } else {
		vnum = OBJ_VNUM_BLOOD;
	    }
	    break;
	case 7:
	    if (killer == ch)
		return;
		if ( !IS_NPC( ch ) ) {
		vnum = OVPKT2;
	    } else {
		vnum = OBJ_VNUM_BLOOD;
	    }
	    break;
	case 8:
	    if (killer == ch)
		return;
	    token2 = get_eq_char(killer, WEAR_HOLD);
	    token4 = get_eq_char(killer, WEAR_NECK_1);
	    token5 = create_object(get_obj_index(OVPKT5), 0);
	    if (!IS_NPC(ch)
		&& token2 != NULL
		&& token2->pIndexData->vnum == OVPKT2
		&& token4 != NULL && token4->pIndexData->vnum == OVPKT4) {
		obj_from_char(token2);
		extract_obj(token2);
		obj_to_char(token5, killer);
		DAZE_STATE(killer, 24 + (5 * PULSE_VIOLENCE));
	    } else if ( !IS_NPC( ch ) ) {
		vnum = OVPKT2;
	    } else {
		vnum = OBJ_VNUM_BLOOD;
	    }
	    break;
	case 9:
	    if (killer == ch)
		return;
	    token2 = get_eq_char(killer, WEAR_HOLD);
	    token3 = create_object(get_obj_index(OVPKT3), 0);
	    if (!IS_NPC(ch)
		&& token2 != NULL && token2->pIndexData->vnum == OVPKT2) {
		obj_from_char(token2);
		extract_obj(token2);
		obj_to_char(token3, killer);
		do_wear(killer, "token");
		DAZE_STATE(killer, 12 + (5 * PULSE_VIOLENCE));
	    } else {
		vnum = OBJ_VNUM_BLOOD;
	    }
	    break;
	case 10:
	    if (killer == ch)
		return;
	    token2 = get_eq_char(killer, WEAR_HOLD);
	    token4 = create_object(get_obj_index(OVPKT4), 0);
	    if (!IS_NPC(ch)
		&& token2 != NULL && token2->pIndexData->vnum == OVPKT2) {
		sprintf(buf, token4->short_descr, killer->name, ch->name);
		free_string(token4->short_descr);
		token4->short_descr = str_dup(buf);
		sprintf(buf, token4->description, killer->name, ch->name);
		free_string(token4->description);
		token4->description = str_dup(buf);
		sprintf(buf, token4->name, killer->name, ch->name);
		free_string(token4->name);
		token4->name = str_dup(buf);
		obj_from_char(token2);
		extract_obj(token2);
		obj_to_char(token4, killer);
		DAZE_STATE(killer, 17 + (5 * PULSE_VIOLENCE));
	    } else if ( !IS_NPC( ch ) ) {
		vnum = OVPKT2;
	    } else {
		vnum = OBJ_VNUM_BLOOD;
	    }
	    break;
	case 11:
	    if (killer == ch)
		return;
	    token2 = get_eq_char(killer, WEAR_HOLD);
	    token4 = get_eq_char(killer, WEAR_NECK_1);
	    token5 = create_object(get_obj_index(OVPKT5), 0);
	    if (!IS_NPC(ch)
		&& token2 != NULL
		&& token2->pIndexData->vnum == OVPKT2
		&& token4 != NULL && token4->pIndexData->vnum == OVPKT4) {
		obj_from_char(token2);
		extract_obj(token2);
		obj_to_char(token5, killer);
		DAZE_STATE(killer, 24 + (5 * PULSE_VIOLENCE));
	    } else if ( !IS_NPC( ch ) ) {
		vnum = OVPKT2;
	    } else {
		vnum = OBJ_VNUM_BLOOD;
	    }
	    break;
	case 12:
	    if (killer == ch)
		return;
	    token2 = get_eq_char(killer, WEAR_HOLD);
	    token4 = get_eq_char(killer, WEAR_NECK_1);
	    token5 = get_eq_char(killer, WEAR_BODY);
	    token6 = create_object(get_obj_index(OVPKT6), 0);
	    if (!IS_NPC(ch)
		&& token2 != NULL
		&& token2->pIndexData->vnum == OVPKT2
		&& token4 != NULL
		&& token4->pIndexData->vnum == OVPKT4
		&& token5 != NULL && token5->pIndexData->vnum == OVPKT5) {
		obj_from_char(token2);
		extract_obj(token2);
		obj_to_char(token6, killer);
		DAZE_STATE(killer, 32 + (5 * PULSE_VIOLENCE));
	    } else if ( !IS_NPC( ch ) ) {
		vnum = OVPKT2;
	    } else {
		vnum = OBJ_VNUM_BLOOD;
	    }
	    break;
	}
    }
    if (vnum != 0) {
	char buf[MSL];
	OBJ_DATA *obj;
	char *name;

	name = IS_NPC(ch) ? ch->short_descr : ch->name;
	obj = create_object(get_obj_index(vnum), 0);
	obj->timer = number_range(4, 7);
	if (!IS_NPC(ch)) {
	    obj->timer = number_range(12, 18);
	}
	if (vnum == OBJ_VNUM_BLOOD) {
	    obj->timer = number_range(1, 4);
	}
	if (IS_NPC(killer) && vnum == OVPKT1 ) {
	    obj->timer = number_range(1, 4);
	} 
	if (IS_NPC(killer) && vnum == OVPKT2 ) {
	    obj->timer = number_range(1, 4);
	} 
	if (!IS_NPC(killer) && vnum == OVPKT1 ) {
	    obj->timer = number_range(100, 200);
	}
	if (!IS_NPC(killer) && vnum == OVPKT2 ) {
	    obj->timer = number_range(100, 200);
	}
	if (vnum == OVPKT3) {
	    obj->timer = number_range(50, 100 * PULSE_VIOLENCE);
	}

	sprintf(buf, obj->short_descr, name);
	free_string(obj->short_descr);
	obj->short_descr = str_dup(buf);

	sprintf(buf, obj->description, name);
	free_string(obj->description);
	obj->description = str_dup(buf);

	sprintf(buf, obj->name, name);
	free_string(obj->name);
	obj->name = str_dup(buf);

	if (obj->item_type == ITEM_FOOD) {
	    if (IS_SET(ch->form, FORM_POISON))
		obj->value[3] = 1;
	    else if (!IS_SET(ch->form, FORM_EDIBLE))
		obj->item_type = ITEM_TRASH;
	}

	if (IS_NPC(ch)) {
	    obj->value[4] = 0;
	} else {
	    obj->value[4] = 1;
	}

	obj_to_room(obj, ch->in_room);
    }

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

    was_in_room = ch->in_room;
    for (door = 0; door <= 5; door++) {
	EXIT_DATA *pexit;

	if ((pexit = was_in_room->exit[door]) != NULL
	    && pexit->u1.to_room != NULL
	    && pexit->u1.to_room != was_in_room) {
	    ch->in_room = pexit->u1.to_room;
	    act(msg, ch, NULL, NULL, TO_ROOM);
	}
    }
    ch->in_room = was_in_room;

    return;
}

void raw_kill(CHAR_DATA * victim, CHAR_DATA * killer)
{
    int i;

    death_cry( victim, killer );
    stop_fighting(victim, TRUE);
/*do not make corps if character is in arena*/
    if (!IS_SET(victim->in_room->room_flags, ROOM_ARENA)) {
	make_corpse(victim, killer);
    }

    if (IS_NPC(victim) && !IS_NPC(killer)) {
	if ((killer->can_aquest == 2)
	    && (victim->pIndexData->vnum == killer->pcdata->quest_mob)) {
	    bool found = FALSE;
	    OBJ_DATA *object;
	    int level_vnum;
	    level_vnum = ((killer->level / 10) + 56);

	    for (object = killer->carrying; object != NULL;
		 object = object->next_content) {
		if (IS_OBJ_STAT(object, ITEM_LQUEST)
		    && (object->pIndexData->vnum == level_vnum))
		    found = TRUE;
	    }
	    if (!found) {
		char buf[MIL];
		OBJ_DATA *obj;
		OBJ_DATA *obj_next;
		OBJ_DATA *pouch;
		sprintf(buf, "You quickly pick up the %s.\n\r",
			killer->pcdata->lquest_obj);
		send_to_char(buf, killer);
		object = create_object(get_obj_index(level_vnum), 0);
		sprintf(buf, "%s", killer->pcdata->lquest_obj);
		free_string(object->short_descr);
		object->short_descr = str_dup(buf);
		free_string(object->description);
		object->description = str_dup(buf);	// DB
		free_string(object->name);
		object->name = str_dup(buf);
		buf[0] = '\0';
		SET_BIT(object->extra_flags, ITEM_LQUEST);
		for (obj = killer->carrying; obj != NULL; obj = obj_next) {
		    obj_next = obj->next_content;
		    if (obj->pIndexData->vnum == OBJ_VNUM_QPOUCH) {
			obj_to_obj(object, obj);
			break;
		    } else {
			pouch = create_object(get_obj_index(OBJ_VNUM_QPOUCH), 0);
			obj_to_char(pouch, killer);
			send_to_char ("Your quest pouch returns to you.{x\n\r", killer);
			obj_to_obj(object, pouch);
			break;
		    }
		}
	    }
	}
    }
    if (IS_NPC(victim)) {
	victim->pIndexData->killed++;
	kill_table[URANGE(0, victim->level, MAX_LEVEL - 1)].killed++;
	extract_char(victim, TRUE);
	if ( !IS_SET(victim->form,FORM_UNDEAD))
	check_spirit(victim, killer);
	return;
    }

    do_mod_favor(victim, 4);

    if (killer->race == victim->race)
	do_mod_favor(killer, 9);

/*do no give pkills, etc, for arena*/
    if (!IS_SET(victim->in_room->room_flags, ROOM_ARENA)) {
	if (!IS_NPC(killer)) {
	    if (strcmp(killer->pcdata->socket, victim->pcdata->socket)) {
		do_mod_favor(killer, 5);
		killer->pcdata->pkills++;
	    }
	    victim->pcdata->pdeath++;
	    if (!is_banklist(victim)) {
		int bank;

		bank = number_range(0, MAX_BANKS - 1);
		if ((number_range(1, 100) < 50) && victim->balance[bank]) {
		    char buf[MSL];
		    int amount;
		    int pwd;
		    OBJ_DATA *pbook;
		    EXTRA_DESCR_DATA *ed;

		    amount =
			(number_range(1, 75) / 100) *
			victim->balance[bank];
		    pwd = number_range(1, 20000);
		    pbook =
			create_object(get_obj_index(OBJ_VNUM_PASSBOOK), 0);
		    sprintf(buf, "%s %s", capitalize(victim->name),
			    pbook->name);
		    free_string(pbook->name);
		    pbook->name = str_dup(buf);
		    sprintf(buf,
			    "The passbook is covered with strange magical symbols that prevent your eyes\n\rfrom focusing on the inscriptions.  Only the word {B%s{x is legible.\n\r",
			    capitalize(victim->name));
		    ed = alloc_perm(sizeof(*ed));
		    ed->keyword = str_dup("passbook");
		    ed->description = str_dup(buf);
		    ed->next = pbook->extra_descr;
		    pbook->extra_descr = ed;
		    pbook->value[0] = bank;
		    pbook->value[1] = pwd;
		    pbook->value[2] = amount;
		    obj_to_char(pbook, killer);
		    send_to_char
			("{RA passbook appears in your inventory!{x\n\r",
			 killer);
		    change_banklist(killer, TRUE, bank, amount, pwd,
				    victim->name);
		}
	    }
	}
	extract_char(victim, FALSE);
	while (victim->affected)
	    affect_remove(victim, victim->affected);
	victim->affected_by = race_table[victim->race].aff;
	victim->shielded_by = race_table[victim->race].shd;
	for (i = 0; i < 4; i++)
	    victim->armor[i] = 100;
	victim->position = POS_STANDING;
	victim->hit = UMAX(1, victim->hit);
	victim->mana = UMAX(1, victim->mana);
	victim->move = UMAX(1, victim->move);
	return;
    }
}


void group_gain(CHAR_DATA * ch, CHAR_DATA * victim)
{
    char buf[MSL];
    CHAR_DATA *gch;
    CHAR_DATA *lch;
    int xp;
    int members;
    int group_levels;

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

    members = 0;
    group_levels = 0;
    for (gch = ch->in_room->people; gch != NULL; gch = gch->next_in_room) {
	if (is_same_group(gch, ch)) {
	    members++;
	    group_levels += IS_NPC(gch) ? gch->level / 2 : gch->level;
	}
    }

    if (members == 0) {
	bug("Group_gain: members.", members);
	members = 1;
	group_levels = ch->level;
    }

    lch = (ch->leader != NULL) ? ch->leader : ch;

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

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

/*	Taken out, add it back if you want it
	if ( gch->level - lch->level >= 5 )
	{
	    send_to_char( "You are too high for this group.\n\r", gch );
	    continue;
	}

	if ( gch->level - lch->level <= -5 )
	{
	    send_to_char( "You are too low for this group.\n\r", gch );
	    continue;
	}
*/

	xp = xp_compute(gch, victim, group_levels);
	if (global_xpq){ xp = xp*2; }
	if (!IS_NPC(ch) && IS_SET(ch->act, PLR_LQUEST))
	    xp = 0;
	sprintf(buf, "{BYou receive {W%d{B experience points.{x\n\r", xp);
	send_to_char(buf, gch);
	gain_exp(gch, xp);

	for (obj = ch->carrying; obj != NULL; obj = obj_next) {
	    obj_next = obj->next_content;
	    if (obj->wear_loc == WEAR_NONE)
		continue;

	    if ((IS_OBJ_STAT(obj, ITEM_ANTI_EVIL) && IS_EVIL(ch))
		|| (IS_OBJ_STAT(obj, ITEM_ANTI_GOOD) && IS_GOOD(ch))
		|| (IS_OBJ_STAT(obj, ITEM_ANTI_NEUTRAL) && IS_NEUTRAL(ch))) {
		act("{cYou are {Wzapped{c by $p.{x", ch, obj, NULL,
		    TO_CHAR);
		act("$n is {Wzapped{x by $p.", ch, obj, NULL, TO_ROOM);
		obj_from_char(obj);
		obj_to_room(obj, ch->in_room);
	    }
	}

	if (IS_SET(ch->exbit1_flags, PLR_QUESTOR) && IS_NPC(victim)) {
	    if (ch->questmob == victim->pIndexData->vnum) {
		send_to_char
		    ("You have almost completed your ADVENTURE!\n\r", ch);
		send_to_char
		    ("Return to the questmaster before your time runs out!\n\r",
		     ch);
		ch->questmob = -1;
	    }
	}
    }

    return;
}



/*
 * Compute xp for a kill.
 * Also adjust alignment of killer.
 * Edit this function to change xp computations.
 */
int xp_compute(CHAR_DATA * gch, CHAR_DATA * victim, int total_levels)
{
    int xp, base_exp;
    int align, level_range;
    int change;
    int time_per_level;

    level_range = victim->level - gch->level;
    if (!IS_NPC(gch)) {
//	if (gch->class >= MCLT_1)
//	    level_range -= 4;
	if (gch->pcdata->tier == 3) { level_range -= 4; }
	if (gch->pcdata->tier == 2) { level_range -= 3; }
	if (gch->pcdata->tier == 1) { level_range -= 2; }
	if (gch->pcdata->tier == 0) { level_range -= 1; }
    }

    /* compute the base exp */
    switch (level_range) {
    default:
	base_exp = 0;
	break;
    case -9:
	base_exp = 1;
	break;
    case -8:
	base_exp = 3;
	break;
    case -7:
	base_exp = 8;
	break;
    case -6:
	base_exp = 14;
	break;
    case -5:
	base_exp = 22;
	break;
    case -4:
	base_exp = 35;
	break;
    case -3:
	base_exp = 49;
	break;
    case -2:
	base_exp = 61;
	break;
    case -1:
	base_exp = 77;
	break;
    case 0:
	base_exp = 95;
	break;
    case 1:
	base_exp = 115;
	break;
    case 2:
	base_exp = 135;
	break;
    case 3:
	base_exp = 157;
	break;
    case 4:
	base_exp = 181;
	break;
    }

    if (level_range > 4)
	base_exp = 181 + 29 * (level_range - 4);

    /* do alignment computations */

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

    if (IS_SET(victim->act, ACT_NOALIGN)) {
	/* no change */
    }

    else if (align > 500) {	/* monster is more good than slayer */
	change =
	    (align - 500) * base_exp / 500 * gch->level / total_levels;
	change = UMAX(1, change);
	gch->alignment = UMAX(-1000, gch->alignment - change);
	if (gch->pet != NULL)
	    gch->pet->alignment = gch->alignment;
    }

    else if (align < -500) {	/* monster is more evil than slayer */
	change =
	    (-1 * align -
	     500) * base_exp / 500 * gch->level / total_levels;
	change = UMAX(1, change);
	gch->alignment = UMIN(1000, gch->alignment + change);
	if (gch->pet != NULL)
	    gch->pet->alignment = gch->alignment;
    }

    else {			/* improve this someday */

	change =
	    gch->alignment * base_exp / 500 * gch->level / total_levels;
	gch->alignment -= change;
	if (gch->pet != NULL)
	    gch->pet->alignment = gch->alignment;
    }

    /* calculate exp multiplier */
    if (IS_SET(victim->act, ACT_NOALIGN))
	xp = base_exp;

    else if (gch->alignment > 500) {	
	if (victim->alignment <= -750) xp = (base_exp * 4) / 3;
	else if (victim->alignment <= -500 && victim->alignment > -750) xp = (base_exp * 5) / 4;
	else if (victim->alignment <= -250 && victim->alignment > -500) xp = (base_exp * 6) / 5;
	else if (victim->alignment <= 250 && victim->alignment > -250) xp = (base_exp * 7) / 6;
	else if (victim->alignment <= 500 && victim->alignment > 250) xp = (base_exp * 8) / 7;

	else
	    xp = base_exp;
    }

    else if (gch->alignment < -500) {

	if (victim->alignment >= 750) xp = (base_exp * 4) / 3;
	else if (victim->alignment >= 500 && victim->alignment < 750) xp = (base_exp * 5) / 4;
	else if (victim->alignment >= 250 && victim->alignment < 500) xp = (base_exp * 6) / 5;
	else if (victim->alignment >= -250 && victim->alignment < 250) xp = (base_exp * 7) / 6;
	else if (victim->alignment >= -500 && victim->alignment < -250) xp = (base_exp * 8) / 7;
	else if (victim->alignment > 500)
	    xp = (base_exp * 11) / 10;

	else if (victim->alignment < -750)
	    xp = base_exp / 2;

	else if (victim->alignment < -500)
	    xp = (base_exp * 3) / 4;

	else if (victim->alignment < -250)
	    xp = (base_exp * 9) / 10;

	else
	    xp = base_exp;
    }

    else if (gch->alignment > 200) {	/* a little good */

	if (victim->alignment < -500)
	    xp = (base_exp * 6) / 5;

	else if (victim->alignment > 750)
	    xp = base_exp / 2;

	else if (victim->alignment > 0)
	    xp = (base_exp * 3) / 4;

	else
	    xp = base_exp;
    }

    else if (gch->alignment < -200) {	/* a little bad */
	if (victim->alignment > 500)
	    xp = (base_exp * 6) / 5;

	else if (victim->alignment < -750)
	    xp = base_exp / 2;

	else if (victim->alignment < 0)
	    xp = (base_exp * 3) / 4;

	else
	    xp = base_exp;
    }

    else {			/* neutral */


	if (victim->alignment > 500 || victim->alignment < -500)
	    xp = (base_exp * 4) / 3;

	else if (victim->alignment < 200 && victim->alignment > -200)
	    xp = base_exp / 2;

	else
	    xp = base_exp;
    }

    /* more exp at the low levels */
    if (gch->level < 11)
	xp = 15 * xp / (gch->level + 4);

    /* less at high */
    if (gch->level > 60)
	xp = 15 * xp / (gch->level - 25);

    /* reduce for playing time */


    {
	/* compute quarter-hours per level */
	time_per_level = 4 *
	    (gch->played + (int) (current_time - gch->logon)) / 3600
	    / gch->level;

	time_per_level = URANGE(2, time_per_level, 12);
	if (gch->level < 25)	/* make it a curve */
	    time_per_level = UMAX(time_per_level, (25 - gch->level));
/*
 *	xp = xp * time_per_level / 12;
 */
    }
/*    xp = xp*.75;
 */
    /* randomize the rewards */
    xp = number_range(xp * 3 / 4, xp * 5 / 4);

    /* adjust for grouping */
    xp = xp * gch->level / (UMAX(1, total_levels - 1));

    if (!IS_NPC(gch) && !IS_NPC(victim))
	if (xp > 1)
	    xp = xp / 2;

    return xp;
}


void dam_message(CHAR_DATA * ch, CHAR_DATA * victim, int dam, int dt,
		 bool immune)
{
    char buf1[256], buf2[256], buf3[256];
    const char *vs;
    const char *vp;
    const char *attack;
    char punct;

    if (ch == NULL || victim == NULL)
	return;

    if (dam == 0) {
	vs = "miss";
	vp = "misses";
    } else if (dam <= 4) {
	vs = "scratch";
	vp = "scratches";
    } else if (dam <= 8) {
	vs = "graze";
	vp = "grazes";
    } else if (dam <= 12) {
	vs = "hit";
	vp = "hits";
    } else if (dam <= 16) {
	vs = "injure";
	vp = "injures";
    } else if (dam <= 20) {
	vs = "wound";
	vp = "wounds";
    } else if (dam <= 24) {
	vs = "maul";
	vp = "mauls";
    } else if (dam <= 28) {
	vs = "decimate";
	vp = "decimates";
    } else if (dam <= 32) {
	vs = "devastate";
	vp = "devastates";
    } else if (dam <= 36) {
	vs = "maim";
	vp = "maims";
    } else if (dam <= 40) {
	vs = "MUTILATE";
	vp = "MUTILATES";
    } else if (dam <= 44) {
	vs = "DISEMBOWEL";
	vp = "DISEMBOWELS";
    } else if (dam <= 48) {
	vs = "DISMEMBER";
	vp = "DISMEMBERS";
    } else if (dam <= 52) {
	vs = "MASSACRE";
	vp = "MASSACRES";
    } else if (dam <= 56) {
	vs = "MANGLE";
	vp = "MANGLES";
    } else if (dam <= 60) {
	vs = "*** DEMOLISH ***";
	vp = "*** DEMOLISHES ***";
    } else if (dam <= 75) {
	vs = "*** DEVASTATE ***";
	vp = "*** DEVASTATES ***";
    } else if (dam <= 100) {
	vs = "=== OBLITERATE ===";
	vp = "=== OBLITERATES ===";
    } else if (dam <= 125) {
	vs = ">>> ANNIHILATE <<<";
	vp = ">>> ANNIHILATES <<<";
    } else if (dam <= 150) {
	vs = "<<< ERADICATE >>>";
	vp = "<<< ERADICATES >>>";
    } else {
	vs = "do UNSPEAKABLE things to";
	vp = "does UNSPEAKABLE things to";
    }

    punct = (dam <= 24) ? '.' : '!';

    if (dt == TYPE_HIT) {
	if (ch == victim) {
	    sprintf(buf1, "$n %s $melf%c{x", vp, punct);
	    sprintf(buf2, "{hYou %s {hyourself%c{x", vs, punct);
	} else {
            sprintf(buf1, "{k$n %s {k$N%c {R[{k%d{R]{x", vp, punct, dam);
            sprintf(buf2, "{hYou %s {h$N%c {R[{h%d{R]{x", vs, punct, dam);
            sprintf(buf3, "{i$n %s {iyou%c {R[{i%d{R]{x", vp, punct, dam);
	}
    } else {
	if (dt >= 0 && dt < MAX_SKILL)
	    attack = skill_table[dt].noun_damage;
	else if (dt >= TYPE_HIT && dt < TYPE_HIT + MAX_DAMAGE_MESSAGE)
	    attack = attack_table[dt - TYPE_HIT].noun;
	else {
	    bug("Dam_message: bad dt %d.", dt);
	    dt = TYPE_HIT;
	    attack = attack_table[0].name;
	}

	if (immune) {
	    if (ch == victim) {
		sprintf(buf1, "$n is unaffected by $s own %s.{x",
			attack);
		sprintf(buf2, "{hLuckily, you are immune to that.{x");
	    } else {
		sprintf(buf1, "$N is unaffected by $n's %s!{x", attack);
		sprintf(buf2, "{h$N is unaffected by your %s!{x", attack);
		sprintf(buf3, "$n's %s is powerless against you.{x",
			attack);
	    }
	} else {
	    if (ch == victim) {
		sprintf(buf1, "$n's %s %s $m%c{x", attack, vp, punct);
		sprintf(buf2, "{hYour %s %s you%c{x", attack, vp, punct);
	    } else {
		sprintf(buf1, "$n's %s %s $N%c {R[%d{R]{x", attack,
			vp, punct, dam);
		sprintf(buf2, "{hYour %s %s {h$N%c {R[{h%d{R]{x", attack,
			vp, punct, dam);
		sprintf(buf3, "$n's %s %s you%c {R[%d{R]{x", attack,
			vp, punct, dam);
	    }
	}
    }

    if (ch == victim) {
	act(buf1, ch, NULL, NULL, TO_ROOM);
	act(buf2, ch, NULL, NULL, TO_CHAR);
    } else {
	act(buf1, ch, NULL, victim, TO_NOTVICT);
	act(buf2, ch, NULL, victim, TO_CHAR);
	act(buf3, ch, NULL, victim, TO_VICT);
    }

    return;
}

void do_surrender( CHAR_DATA *ch, char *argument )
{
    CHAR_DATA *mob;
    if ( (mob = ch->fighting) == NULL )
    {
	send_to_char( "But you're not fighting!\n\r", ch );
	return;
    }
    act( "You surrender to $N!", ch, NULL, mob, TO_CHAR );
    act( "$n surrenders to you!", ch, NULL, mob, TO_VICT );
    act( "$n tries to surrender to $N!", ch, NULL, mob, TO_NOTVICT );
    stop_fighting( ch, TRUE );

    if ( !IS_NPC( ch ) && IS_NPC( mob ) 
    &&   ( !HAS_TRIGGER( mob, TRIG_SURR ) 
        || !mp_percent_trigger( mob, ch, NULL, NULL, TRIG_SURR ) ) )
    {
	act( "$N seems to ignore your cowardly act!", ch, NULL, mob, TO_CHAR );
	multi_hit( mob, ch, TYPE_UNDEFINED );
    }
}

/*
 * Disarm a creature.
 * Caller must check for successful attack.
 */
void disarm(CHAR_DATA * ch, CHAR_DATA * victim)
{
    OBJ_DATA *obj;

    if ((obj = get_eq_char(victim, WEAR_WIELD)) == NULL)
	return;

    if (ch->shadow) {
	ch->shadowing->shadowed = FALSE;
	ch->shadowing->shadower = NULL;
	ch->shadowing = NULL;
	ch->shadow = FALSE;
    }
    if (IS_OBJ_STAT(obj, ITEM_NOREMOVE)) {
	act("{j$S weapon won't budge!{x", ch, NULL, victim, TO_CHAR);
	act("{j$n tries to disarm you, but your weapon won't budge!{x",
	    ch, NULL, victim, TO_VICT);
	act("$n tries to disarm $N, but fails.{x", ch, NULL, victim,
	    TO_NOTVICT);
	return;
    }

    act("{j$n DISARMS you and sends your weapon flying!{x",
	ch, NULL, victim, TO_VICT);
    act("{jYou disarm $N!{x", ch, NULL, victim, TO_CHAR);
    act("$n disarms $N!{x", ch, NULL, victim, TO_NOTVICT);

    obj_from_char(obj);
    if (IS_OBJ_STAT(obj, ITEM_NODROP) || IS_OBJ_STAT(obj, ITEM_INVENTORY))
	obj_to_char(obj, victim);
    else {
	obj_to_room(obj, victim->in_room);
	if (IS_NPC(victim) && victim->wait == 0
	    && can_see_obj(victim, obj)) get_obj(victim, obj, NULL);
    }

    return;
}

void do_berserk(CHAR_DATA * ch, char *argument)
{
    int chance, hp_percent;

    if ((chance = get_skill(ch, gsn_berserk)) == 0
	|| (IS_NPC(ch) && !IS_SET(ch->off_flags, OFF_BERSERK))
	|| (!IS_NPC(ch)
	    && ch->level <
	    skill_table[gsn_berserk].skill_level[ch->class])) {
	if (IS_NPC(ch)) {
	    send_to_char
		("{hYou turn {rred{h in the face, but nothing happens.{x\n\r",
		 ch);
	    return;
	}
	if (ch->pcdata->tier != 2) {
	    send_to_char
		("{hYou turn {rred{h in the face, but nothing happens.{x\n\r",
		 ch);
	    return;
	} else if (chance == 0
		   || (IS_NPC(ch) && !IS_SET(ch->off_flags, OFF_BERSERK))
		   || (!IS_NPC(ch)
		       && ch->level <
		       skill_table[gsn_berserk].skill_level[ch->clasb])) {
	    send_to_char
		("{hYou turn {rred{h in the face, but nothing happens.{x\n\r",
		 ch);
	    return;
	}
    }

    if (IS_AFFECTED(ch, AFF_BERSERK) || is_affected(ch, gsn_berserk)
	|| is_affected(ch, skill_lookup("frenzy"))) {
	send_to_char("{hYou get a little madder.{x\n\r", ch);
	return;
    }

    if (IS_AFFECTED(ch, AFF_CALM)) {
	send_to_char("{hYou're feeling to mellow to berserk.{x\n\r", ch);
	return;
    }

    if (ch->mana < 50) {
	send_to_char("{hYou can't get up enough energy.{x\n\r", ch);
	return;
    }

    /* modifiers */

    /* fighting */
    if (ch->position == POS_FIGHTING)
	chance += 10;

    /* damage -- below 50% of hp helps, above hurts */
    hp_percent = 100 * ch->hit / ch->max_hit;
    chance += 25 - hp_percent / 2;

    if (number_percent() < chance) {
	AFFECT_DATA af;

	WAIT_STATE(ch, PULSE_VIOLENCE);
	ch->mana -= 50;
	ch->move /= 2;

	/* heal a little damage */
	ch->hit += ch->level * 2;
	ch->hit = UMIN(ch->hit, ch->max_hit);

	if (ch->shadow) {
	    ch->shadowing->shadowed = FALSE;
	    ch->shadowing->shadower = NULL;
	    ch->shadowing = NULL;
	    ch->shadow = FALSE;
	}
	send_to_char
	    ("{hYour pulse races as you are consumed by {rrage!{x\n\r",
	     ch);
	act("$n gets a {cw{gi{rl{yd look in $s eyes.{x", ch, NULL,
	    NULL, TO_ROOM);
	check_improve(ch, gsn_berserk, TRUE, 2);

	af.where = TO_AFFECTS;
	af.type = gsn_berserk;
	af.level = ch->level;
	af.duration = number_fuzzy(ch->level / 8);
	af.modifier = UMAX(1, ch->level / 5);
	af.bitvector = AFF_BERSERK;

	af.location = APPLY_HITROLL;
	affect_to_char(ch, &af);

	af.location = APPLY_DAMROLL;
	affect_to_char(ch, &af);

	af.modifier = UMAX(10, 10 * (ch->level / 5));
	af.location = APPLY_AC;
	affect_to_char(ch, &af);
    }

    else {
	WAIT_STATE(ch, 3 * PULSE_VIOLENCE);
	ch->mana -= 25;
	ch->move /= 2;

	send_to_char("{hYour pulse speeds up, but nothing happens.{x\n\r",
		     ch);
	check_improve(ch, gsn_berserk, FALSE, 2);
    }
}

void do_voodoo(CHAR_DATA * ch, char *argument)
{
    char arg[MIL];
    OBJ_DATA *doll;

    if (IS_NPC(ch))
	return;

    doll = get_eq_char(ch, WEAR_HOLD);
    if (doll == NULL || (doll->pIndexData->vnum != OBJ_VNUM_VOODOO)) {
	send_to_char("You are not holding a voodoo doll.\n\r", ch);
	return;
    }

    one_argument(argument, arg);

    if (arg[0] == '\0') {
	send_to_char("Syntax: voodoo <action>\n\r", ch);
	send_to_char("Actions: pin trip throw\n\r", ch);
	return;
    }

    if (!str_cmp(arg, "pin")) {
	do_vdpi(ch, doll->name);
	return;
    }

    if (!str_cmp(arg, "trip")) {
	do_vdtr(ch, doll->name);
	return;
    }

    if (!str_cmp(arg, "throw")) {
	do_vdth(ch, doll->name);
	return;
    }

    do_voodoo(ch, "");
}

void do_vdpi(CHAR_DATA * ch, char *argument)
{
    char arg1[MIL];
    DESCRIPTOR_DATA *d;
    AFFECT_DATA af;
    bool found = FALSE;

    argument = one_argument(argument, arg1);

    for (d = descriptor_list; d != NULL; d = d->next) {
	CHAR_DATA *wch;

	if (d->connected != CON_PLAYING || !can_see(ch, d->character))
	    continue;

	wch = (d->original != NULL) ? d->original : d->character;

	if (!can_see(ch, wch))
	    continue;

	if (!str_cmp(arg1, wch->name) && !found) {
	    if (IS_NPC(wch))
		continue;

	    if (IS_IMMORTAL(wch) && (wch->level > ch->level)) {
		send_to_char("That's not a good idea.\n\r", ch);
		return;
	    }

	    if ((wch->level < 20) && !IS_IMMORTAL(ch)) {
		send_to_char("They are a little too young for that.\n\r",
			     ch);
		return;
	    }

	    if (IS_SHIELDED(wch, SHD_PROTECT_VOODOO)) {
		send_to_char
		    ("They are still realing from a previous voodoo.\n\r",
		     ch);
		return;
	    }

	    found = TRUE;

	    if (ch->shadow) {
		ch->shadowing->shadowed = FALSE;
		ch->shadowing->shadower = NULL;
		ch->shadowing = NULL;
		ch->shadow = FALSE;
	    }
	    send_to_char("You stick a pin into your voodoo doll.\n\r", ch);
	    act("$n sticks a pin into a voodoo doll.", ch, NULL, NULL,
		TO_ROOM);
	    send_to_char
		("{RYou double over with a sudden pain in your gut!{x\n\r",
		 wch);
	    act("$n suddenly doubles over with a look of extreme pain!",
		wch, NULL, NULL, TO_ROOM);
	    af.where = TO_SHIELDS;
	    af.type = skill_lookup("protection voodoo");
	    af.level = wch->level;
	    af.duration = 1;
	    af.location = APPLY_NONE;
	    af.modifier = 0;
	    af.bitvector = SHD_PROTECT_VOODOO;
	    affect_to_char(wch, &af);
	    return;
	}
    }
    send_to_char("Your victim doesn't seem to be in the realm.\n\r", ch);
    return;
}

void do_vdtr(CHAR_DATA * ch, char *argument)
{
    char arg1[MIL];
    DESCRIPTOR_DATA *d;
    AFFECT_DATA af;
    bool found = FALSE;

    argument = one_argument(argument, arg1);

    for (d = descriptor_list; d != NULL; d = d->next) {
	CHAR_DATA *wch;

	if (d->connected != CON_PLAYING || !can_see(ch, d->character))
	    continue;

	wch = (d->original != NULL) ? d->original : d->character;

	if (!can_see(ch, wch))
	    continue;

	if (!str_cmp(arg1, wch->name) && !found) {
	    if (IS_NPC(wch))
		continue;

	    if (IS_IMMORTAL(wch) && (wch->level > ch->level)) {
		send_to_char("That's not a good idea.\n\r", ch);
		return;
	    }

	    if ((wch->level < 20) && !IS_IMMORTAL(ch)) {
		send_to_char("They are a little too young for that.\n\r",
			     ch);
		return;
	    }

	    if (IS_SHIELDED(wch, SHD_PROTECT_VOODOO)) {
		send_to_char
		    ("They are still realing from a previous voodoo.\n\r",
		     ch);
		return;
	    }

	    found = TRUE;

	    if (ch->shadow) {
		ch->shadowing->shadowed = FALSE;
		ch->shadowing->shadower = NULL;
		ch->shadowing = NULL;
		ch->shadow = FALSE;
	    }
	    send_to_char
		("You slam your voodoo doll against the ground.\n\r", ch);
	    act("$n slams a voodoo doll against the ground.", ch, NULL,
		NULL, TO_ROOM);
	    send_to_char("{RYour feet slide out from under you!{x\n\r",
			 wch);
	    send_to_char("{RYou hit the ground face first!{x\n\r", wch);
	    act
		("$n trips over $s own feet, and does a nose dive into the ground!",
		 wch, NULL, NULL, TO_ROOM);
	    af.where = TO_SHIELDS;
	    af.type = skill_lookup("protection voodoo");
	    af.level = wch->level;
	    af.duration = 1;
	    af.location = APPLY_NONE;
	    af.modifier = 0;
	    af.bitvector = SHD_PROTECT_VOODOO;
	    affect_to_char(wch, &af);
	    return;
	}
    }
    send_to_char("Your victim doesn't seem to be in the realm.\n\r", ch);
    return;
}

void do_vdth(CHAR_DATA * ch, char *argument)
{
    char arg1[MIL];
    char buf[MSL];
    DESCRIPTOR_DATA *d;
    AFFECT_DATA af;
    ROOM_INDEX_DATA *was_in;
    ROOM_INDEX_DATA *now_in;
    bool found = FALSE;
    int attempt;

    argument = one_argument(argument, arg1);

    for (d = descriptor_list; d != NULL; d = d->next) {
	CHAR_DATA *wch;

	if (d->connected != CON_PLAYING || !can_see(ch, d->character))
	    continue;

	wch = (d->original != NULL) ? d->original : d->character;

	if (!can_see(ch, wch))
	    continue;

	if (!str_cmp(arg1, wch->name) && !found) {
	    if (IS_NPC(wch))
		continue;

	    if (IS_IMMORTAL(wch) && (wch->level > ch->level)) {
		send_to_char("That's not a good idea.\n\r", ch);
		return;
	    }

	    if ((wch->level < 20) && !IS_IMMORTAL(ch)) {
		send_to_char("They are a little too young for that.\n\r",
			     ch);
		return;
	    }

	    if (IS_SHIELDED(wch, SHD_PROTECT_VOODOO)) {
		send_to_char
		    ("They are still reeling from a previous voodoo.\n\r",
		     ch);
		return;
	    }

	    found = TRUE;

	    if (ch->shadow) {
		ch->shadowing->shadowed = FALSE;
		ch->shadowing->shadower = NULL;
		ch->shadowing = NULL;
		ch->shadow = FALSE;
	    }
	    send_to_char("You toss your voodoo doll into the air.\n\r",
			 ch);
	    act("$n tosses a voodoo doll into the air.", ch, NULL, NULL,
		TO_ROOM);
	    af.where = TO_SHIELDS;
	    af.type = skill_lookup("protection voodoo");
	    af.level = wch->level;
	    af.duration = 1;
	    af.location = APPLY_NONE;
	    af.modifier = 0;
	    af.bitvector = SHD_PROTECT_VOODOO;
	    affect_to_char(wch, &af);
	    if ((wch->fighting != NULL) || (number_percent() < 25)) {
		send_to_char
		    ("{RA sudden gust of wind throws you through the air!{x\n\r",
		     wch);
		send_to_char
		    ("{RYou slam face first into the nearest wall!{x\n\r",
		     wch);
		act
		    ("A sudden gust of wind picks up $n and throws $m into a wall!",
		     wch, NULL, NULL, TO_ROOM);
		return;
	    }
	    wch->position = POS_STANDING;
	    was_in = wch->in_room;
	    for (attempt = 0; attempt < 6; attempt++) {
		EXIT_DATA *pexit;
		int door;

		door = number_door();
		if ((pexit = was_in->exit[door]) == 0
		    || pexit->u1.to_room == NULL
		    || IS_SET(pexit->exit_info, EX_CLOSED)
		    || (IS_NPC(wch)
			&& IS_SET(pexit->u1.to_room->room_flags,
				  ROOM_NO_MOB))) continue;

		move_char(wch, door, FALSE, TRUE);
		if ((now_in = wch->in_room) == was_in)
		    continue;

		wch->in_room = was_in;
		sprintf(buf,
			"A sudden gust of wind picks up $n and throws $m to the %s.",
			dir_name[door]);
		act(buf, wch, NULL, NULL, TO_ROOM);
		send_to_char
		    ("{RA sudden gust of wind throws you through the air!{x\n\r",
		     wch);
		wch->in_room = now_in;
		act
		    ("$n sails into the room and slams face first into a wall!",
		     wch, NULL, NULL, TO_ROOM);
		do_look(wch, "auto");
		send_to_char
		    ("{RYou slam face first into the nearest wall!{x\n\r",
		     wch);
		return;
	    }
	    send_to_char
		("{RA sudden gust of wind throws you through the air!{x\n\r",
		 wch);
	    send_to_char
		("{RYou slam face first into the nearest wall!{x\n\r",
		 wch);
	    act
		("A sudden gust of wind picks up $n and throws $m into a wall!",
		 wch, NULL, NULL, TO_ROOM);
	    return;
	}
    }
    send_to_char("Your victim doesn't seem to be in the realm.\n\r", ch);
    return;
}

void do_bash(CHAR_DATA * ch, char *argument)
{
    char arg[MIL];
    CHAR_DATA *victim;
    int chance;

    one_argument(argument, arg);

    if ((chance = get_skill(ch, gsn_bash)) == 0
	|| (IS_NPC(ch) && !IS_SET(ch->off_flags, OFF_BASH))) {
	send_to_char("Bashing? What's that?\n\r", ch);
	return;
    }

    if (!IS_NPC(ch)) {
	if (ch->pcdata->tier != 2) {
	    if (ch->level < skill_table[gsn_bash].skill_level[ch->class]) {
		send_to_char("Bashing? What's that?\n\r", ch);
		return;
	    }
	} else
	    if ((ch->level < skill_table[gsn_bash].skill_level[ch->class])
		&& (ch->level <
		    skill_table[gsn_bash].skill_level[ch->clasb])) {
	    send_to_char("Bashing? What's that?\n\r", ch);
	    return;
	}
    }

    if (arg[0] == '\0') {
	victim = ch->fighting;
	if (victim == NULL) {
	    send_to_char("But you aren't fighting anyone!\n\r", ch);
	    return;
	}
    }

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

    if (victim->position < POS_FIGHTING) {
	act("You'll have to let $M get back up first.", ch, NULL, victim,
	    TO_CHAR);
	return;
    }

    if (victim == ch) {
	send_to_char("You try to bash your brains out, but fail.\n\r", ch);
	return;
    }

    if (is_safe(ch, victim))
	return;

    if (IS_NPC(victim) &&
	victim->fighting != NULL && !is_same_group(ch, victim->fighting)) {
	send_to_char("Kill stealing is not permitted.\n\r", ch);
	return;
    }

    if (IS_AFFECTED(ch, AFF_CHARM) && ch->master == victim) {
	act("But $N is your friend!", ch, NULL, victim, TO_CHAR);
	return;
    }

    if (ch->stunned) {
	send_to_char("You're still a little woozy.\n\r", ch);
	return;
    }

    if (!can_see(ch, victim)) {
	send_to_char
	    ("You get a running start, and slam right into a wall.\n\r",
	     ch);
	return;
    }

    if (ch->shadow) {
	ch->shadowing->shadowed = FALSE;
	ch->shadowing->shadower = NULL;
	ch->shadowing = NULL;
	ch->shadow = FALSE;
    }
    if ((ch->fighting == NULL)
	&& (!IS_NPC(ch))
	&& (!IS_NPC(victim))) {
	ch->attacker = TRUE;
	victim->attacker = FALSE;
    }

    /* modifiers */

    /* size  and weight */
    chance += ch->carry_weight / 250;
    chance -= victim->carry_weight / 200;

    if (ch->size < victim->size)
	chance += (ch->size - victim->size) * 15;
    else
	chance += (ch->size - victim->size) * 10;


    /* stats */
    chance += get_curr_stat(ch, STAT_STR);
    chance -= (get_curr_stat(victim, STAT_DEX) * 4) / 3;
    chance -= GET_AC(victim, AC_BASH) / 25;
    /* speed */
    if (IS_SET(ch->off_flags, OFF_FAST) || IS_AFFECTED(ch, AFF_HASTE))
	chance += 10;
    if (IS_SET(victim->off_flags, OFF_FAST)
	|| IS_AFFECTED(victim, AFF_HASTE)) chance -= 30;

    /* level */
    chance += (ch->level - victim->level);

    if (!IS_NPC(victim)
	&& chance < get_skill(victim, gsn_dodge)) {	/*
	act("$n tries to bash you, but you dodge it.{x",ch,NULL,victim,TO_VICT);
	act("{h$N dodges your bash, you fall flat on your face.{x",ch,NULL,victim,TO_CHAR);
	WAIT_STATE(ch,skill_table[gsn_bash].beats);
	return; */
	chance -= 3 * (get_skill(victim, gsn_dodge) - chance);
    }

    /* now the attack */
    if (number_percent() < chance) {
	int dam;

	dam = number_range(2, 2 + 2 * ch->size + chance / 20);
	act("$n sends you sprawling with a powerful bash!{x", ch, NULL,
	    victim, TO_VICT);
	act("{hYou slam into $N, and send $M flying!{x", ch, NULL, victim,
	    TO_CHAR);
	act("$n sends $N sprawling with a powerful bash.{x", ch, NULL,
	    victim, TO_NOTVICT);
	check_improve(ch, gsn_bash, TRUE, 1);

	DAZE_STATE(victim, 3 * PULSE_VIOLENCE);
	WAIT_STATE(ch, skill_table[gsn_bash].beats);
	victim->position = POS_RESTING;
	damage(ch, victim, dam, gsn_bash, DAM_BASH, TRUE);
	chance = (get_skill(ch, gsn_stun) / 5);
	if (number_percent() < chance) {
	    chance = (get_skill(ch, gsn_stun) / 5);
	    if (number_percent() < chance) {
		victim->stunned = 2;
	    } else {
		victim->stunned = 1;
	    }
	    act("You are stunned, and have trouble getting back up!{x",
		ch, NULL, victim, TO_VICT);
	    act("{h$N is stunned by your bash!{x", ch, NULL, victim,
		TO_CHAR);
	    act("$N is having trouble getting back up.{x", ch, NULL,
		victim, TO_NOTVICT);
	    check_improve(ch, gsn_stun, TRUE, 1);
	}
    } else {
	damage(ch, victim, 0, gsn_bash, DAM_BASH, FALSE);
	act("{hYou fall flat on your face!{x", ch, NULL, victim, TO_CHAR);
	act("$n falls flat on $s face.{x", ch, NULL, victim, TO_NOTVICT);
	act("You evade $n's bash, causing $m to fall flat on $s face.{x",
	    ch, NULL, victim, TO_VICT);
	check_improve(ch, gsn_bash, FALSE, 1);
	ch->position = POS_RESTING;
	WAIT_STATE(ch, skill_table[gsn_bash].beats * 3 / 2);
    }
}

void do_dirt(CHAR_DATA * ch, char *argument)
{
    char arg[MIL];
    CHAR_DATA *victim;
    int chance;

    one_argument(argument, arg);

    if ((chance = get_skill(ch, gsn_dirt)) == 0
	|| (IS_NPC(ch) && !IS_SET(ch->off_flags, OFF_KICK_DIRT))) {
	send_to_char("{hYou get your feet dirty.{x\n\r", ch);
	return;
    }

    if (!IS_NPC(ch)) {
	if (ch->pcdata->tier != 2) {
	    if (ch->level < skill_table[gsn_dirt].skill_level[ch->class]) {
		send_to_char("{hYou get your feet dirty.{x\n\r", ch);
		return;
	    }
	} else
	    if ((ch->level < skill_table[gsn_dirt].skill_level[ch->class])
		&& (ch->level <
		    skill_table[gsn_dirt].skill_level[ch->clasb])) {
	    send_to_char("{hYou get your feet dirty.{x\n\r", ch);
	    return;
	}
    }

    if (arg[0] == '\0') {
	victim = ch->fighting;
	if (victim == NULL) {
	    send_to_char("But you aren't in combat!\n\r", ch);
	    return;
	}
    }

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

    if (IS_AFFECTED(victim, AFF_BLIND)) {
	act("{h$E's already been blinded.{x", ch, NULL, victim, TO_CHAR);
	return;
    }

    if (victim == ch) {
	send_to_char("Very funny.\n\r", ch);
	return;
    }

    if (is_safe(ch, victim))
	return;

    if (IS_NPC(victim) &&
	victim->fighting != NULL && !is_same_group(ch, victim->fighting)) {
	send_to_char("Kill stealing is not permitted.\n\r", ch);
	return;
    }

    if (IS_AFFECTED(ch, AFF_CHARM) && ch->master == victim) {
	act("But $N is such a good friend!", ch, NULL, victim, TO_CHAR);
	return;
    }

    if (ch->stunned) {
	send_to_char("You're still a little woozy.\n\r", ch);
	return;
    }

    if (IS_SET(victim->exbit1_flags, RECRUIT)
	|| IS_SET(victim->exbit1_flags, PK_VETERAN)
	|| IS_SET(victim->exbit1_flags, PK_LAWFUL)
	|| IS_SET(victim->exbit1_flags, PK_KILLER)
	|| IS_SET(victim->exbit1_flags, PK_KILLER)
	|| IS_SET(ch->exbit1_flags, RECRUIT)
	|| IS_SET(ch->exbit1_flags, PK_VETERAN)
	|| IS_SET(ch->exbit1_flags, PK_LAWFUL)
	|| IS_SET(ch->exbit1_flags, PK_KILLER) ) {

	if (victim->fighting != NULL && IS_SET(ch->exbit1_flags, PK_LAWFUL) && !IS_NPC(victim)) {
	    send_to_char("So thats the way you like to play.\n\r", ch);
	    REMOVE_BIT(ch->exbit1_flags, PK_LAWFUL);
	    SET_BIT(ch->exbit1_flags, PK_KILLER);
	}
	    else if (victim->fighting != NULL && IS_SET(ch->exbit1_flags, PK_KILLER) && !IS_NPC(victim)) {
	    send_to_char("You really deserve this.\n\r", ch);
	    REMOVE_BIT(ch->exbit1_flags, PK_KILLER);
	    SET_BIT(ch->exbit1_flags, PK_KILLER2);
	}
	// send_to_char("Have mercy on them.\n\r", ch);
    }

    if ((ch->fighting == NULL)
	&& (!IS_NPC(ch))
	&& (!IS_NPC(victim))) {
	ch->attacker = TRUE;
	victim->attacker = FALSE;
    }

    /* modifiers */

    /* dexterity */
    chance += get_curr_stat(ch, STAT_DEX);
    chance -= 2 * get_curr_stat(victim, STAT_DEX);

    /* speed  */
    if (IS_SET(ch->off_flags, OFF_FAST) || IS_AFFECTED(ch, AFF_HASTE))
	chance += 10;
    if (IS_SET(victim->off_flags, OFF_FAST)
	|| IS_AFFECTED(victim, AFF_HASTE)) chance -= 25;

    /* level */
    chance += (ch->level - victim->level) * 2;

    /* sloppy hack to prevent false zeroes */
    if (chance % 5 == 0)
	chance += 1;

    /* terrain */

    switch (ch->in_room->sector_type) {
    case (SECT_INSIDE):
	chance -= 20;
	break;
    case (SECT_CITY):
	chance -= 10;
	break;
    case (SECT_FIELD):
	chance += 5;
	break;
    case (SECT_FOREST):
	break;
    case (SECT_HILLS):
	break;
    case (SECT_MOUNTAIN):
	chance -= 10;
	break;
    case (SECT_WATER_SWIM):
	chance = 0;
	break;
    case (SECT_WATER_NOSWIM):
	chance = 0;
	break;
    case (SECT_AIR):
	chance = 0;
	break;
    case (SECT_DESERT):
	chance += 10;
	break;
    }

    if (chance == 0) {
	send_to_char("{hThere isn't any dirt to kick.{x\n\r", ch);
	return;
    }

    if (ch->shadow) {
	ch->shadowing->shadowed = FALSE;
	ch->shadowing->shadower = NULL;
	ch->shadowing = NULL;
	ch->shadow = FALSE;
    }
    /* now the attack */
    if (number_percent() < chance) {
	AFFECT_DATA af;
	int dam;

	dam = number_range(2, 5);

	act("$n is blinded by the dirt in $s eyes!{x", victim, NULL,
	    NULL, TO_ROOM);
	act("$n kicks dirt in your eyes!{x", ch, NULL, victim, TO_VICT);
	damage(ch, victim, dam, gsn_dirt, DAM_NONE, TRUE);
	send_to_char("{DYou can't see a thing!{x\n\r", victim);
	check_improve(ch, gsn_dirt, TRUE, 2);
	WAIT_STATE(ch, skill_table[gsn_dirt].beats);

	af.where = TO_AFFECTS;
	af.type = gsn_dirt;
	af.level = ch->level;
	af.duration = 0;
	af.location = APPLY_HITROLL;
	af.modifier = -4;
	af.bitvector = AFF_BLIND;

	affect_to_char(victim, &af);
    } else {
	damage(ch, victim, 0, gsn_dirt, DAM_NONE, TRUE);
	check_improve(ch, gsn_dirt, FALSE, 2);
	WAIT_STATE(ch, skill_table[gsn_dirt].beats);
    }
}

void do_gouge(CHAR_DATA * ch, char *argument)
{
    char arg[MIL];
    CHAR_DATA *victim;
    int chance;

    one_argument(argument, arg);


    if ((chance = get_skill(ch, gsn_gouge)) == 0) {
	send_to_char("Gouge?  What's that?\n\r", ch);
	return;
    }

    if (!IS_NPC(ch)) {
	if (ch->pcdata->tier != 2) {
	    if (ch->level < skill_table[gsn_gouge].skill_level[ch->class]) {
		send_to_char("Gouge?  What's that?\n\r", ch);
		return;
	    }
	} else
	    if ((ch->level < skill_table[gsn_gouge].skill_level[ch->class])
		&& (ch->level <
		    skill_table[gsn_gouge].skill_level[ch->clasb])) {
	    send_to_char("Gouge?  What's that?\n\r", ch);
	    return;
	}
    }

    if (arg[0] == '\0') {
	victim = ch->fighting;
	if (victim == NULL) {
	    send_to_char("But you aren't in combat!\n\r", ch);
	    return;
	}
    }

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

    if (IS_AFFECTED(victim, AFF_BLIND)) {
	act("{h$E's already been blinded.{x", ch, NULL, victim, TO_CHAR);
	return;
    }

    if (victim == ch) {
	send_to_char("Very funny.\n\r", ch);
	return;
    }

    if (is_safe(ch, victim))
	return;

    if (IS_NPC(victim) &&
	victim->fighting != NULL && !is_same_group(ch, victim->fighting)) {
	send_to_char("Kill stealing is not permitted.\n\r", ch);
	return;
    }

    if (IS_AFFECTED(ch, AFF_CHARM) && ch->master == victim) {
	act("But $N is such a good friend!", ch, NULL, victim, TO_CHAR);
	return;
    }

    if (ch->stunned) {
	send_to_char("You're still a little woozy.\n\r", ch);
	return;
    }

    if (ch->shadow) {
	ch->shadowing->shadowed = FALSE;
	ch->shadowing->shadower = NULL;
	ch->shadowing = NULL;
	ch->shadow = FALSE;
    }
    if ((ch->fighting == NULL)
	&& (!IS_NPC(ch))
	&& (!IS_NPC(victim))) {
	ch->attacker = TRUE;
	victim->attacker = FALSE;
    }

    /* modifiers */

    /* dexterity */
    chance += get_curr_stat(ch, STAT_DEX);
    chance -= 2 * get_curr_stat(victim, STAT_DEX);

    /* speed  */
    if (IS_SET(ch->off_flags, OFF_FAST) || IS_AFFECTED(ch, AFF_HASTE))
	chance += 10;
    if (IS_SET(victim->off_flags, OFF_FAST)
	|| IS_AFFECTED(victim, AFF_HASTE)) chance -= 25;

    /* level */
    chance += (ch->level - victim->level) * 2;

    /* sloppy hack to prevent false zeroes */
    if (chance % 5 == 0)
	chance += 1;

    /* now the attack */
    if (number_percent() < chance) {
	AFFECT_DATA af;
	int dam;

	dam = number_range(2, 8);

	act("$n is blinded by a poke in the eyes!{x", victim, NULL, NULL,
	    TO_ROOM);
	act("$n gouges at your eyes!{x", ch, NULL, victim, TO_VICT);
	damage(ch, victim, dam, gsn_gouge, DAM_NONE, TRUE);
	send_to_char("{DYou see nothing but stars!{x\n\r", victim);
	check_improve(ch, gsn_gouge, TRUE, 2);
	WAIT_STATE(ch, skill_table[gsn_gouge].beats);

	af.where = TO_AFFECTS;
	af.type = gsn_gouge;
	af.level = ch->level;
	af.duration = 0;
	af.location = APPLY_HITROLL;
	af.modifier = -4;
	af.bitvector = AFF_BLIND;

	affect_to_char(victim, &af);
    } else {
	damage(ch, victim, 0, gsn_gouge, DAM_NONE, TRUE);
	check_improve(ch, gsn_gouge, FALSE, 2);
	WAIT_STATE(ch, skill_table[gsn_gouge].beats);
    }
}

void do_trip(CHAR_DATA * ch, char *argument)
{
    char arg[MIL];
    CHAR_DATA *victim;
    int chance;

    one_argument(argument, arg);

    if ((chance = get_skill(ch, gsn_trip)) == 0
	|| (IS_NPC(ch) && !IS_SET(ch->off_flags, OFF_TRIP))) {
	send_to_char("Tripping?  What's that?\n\r", ch);
	return;
    }

    if (!IS_NPC(ch)) {
	if (ch->pcdata->tier != 2) {
	    if (ch->level < skill_table[gsn_trip].skill_level[ch->class]) {
		send_to_char("Tripping?  What's that?\n\r", ch);
		return;
	    }
	} else
	    if ((ch->level < skill_table[gsn_trip].skill_level[ch->class])
		&& (ch->level <
		    skill_table[gsn_trip].skill_level[ch->clasb])) {
	    send_to_char("Tripping?  What's that?\n\r", ch);
	    return;
	}
    }

    if (arg[0] == '\0') {
	victim = ch->fighting;
	if (victim == NULL) {
	    send_to_char("But you aren't fighting anyone!\n\r", ch);
	    return;
	}
    }

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

    if (is_safe(ch, victim))
	return;

    if (IS_NPC(victim) &&
	victim->fighting != NULL && !is_same_group(ch, victim->fighting)) {
	send_to_char("Kill stealing is not permitted.\n\r", ch);
	return;
    }

    if (ch->stunned) {
	send_to_char("You're still a little woozy.\n\r", ch);
	return;
    }

    if (IS_AFFECTED(victim, AFF_FLYING)) {
	act("{h$S feet aren't on the ground.{x", ch, NULL, victim,
	    TO_CHAR);
	return;
    }

    if (victim->position < POS_FIGHTING) {
	act("{h$N is already down.{c", ch, NULL, victim, TO_CHAR);
	return;
    }

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

    if (ch->shadow) {
	ch->shadowing->shadowed = FALSE;
	ch->shadowing->shadower = NULL;
	ch->shadowing = NULL;
	ch->shadow = FALSE;
    }
    if (victim == ch) {
	send_to_char("{hYou fall flat on your face!{x\n\r", ch);
	WAIT_STATE(ch, 2 * skill_table[gsn_trip].beats);
	act("$n trips over $s own feet!{x", ch, NULL, NULL, TO_ROOM);
	return;
    }

    if ((ch->fighting == NULL)
	&& (!IS_NPC(ch))
	&& (!IS_NPC(victim))) {
	ch->attacker = TRUE;
	victim->attacker = FALSE;
    }

    /* modifiers */

    /* size */
    if (ch->size < victim->size)
	chance += (ch->size - victim->size) * 10;	/* bigger = harder to trip */

    /* dex */
    chance += get_curr_stat(ch, STAT_DEX);
    chance -= get_curr_stat(victim, STAT_DEX) * 3 / 2;

    /* speed */
    if (IS_SET(ch->off_flags, OFF_FAST) || IS_AFFECTED(ch, AFF_HASTE))
	chance += 10;
    if (IS_SET(victim->off_flags, OFF_FAST)
	|| IS_AFFECTED(victim, AFF_HASTE)) chance -= 20;

    /* level */
    chance += (ch->level - victim->level) * 2;


    /* now the attack */
    if (number_percent() < chance) {
	int dam;

	dam = number_range(2, 2 + 2 * victim->size);

	act("$n trips you and you go down!{x", ch, NULL, victim,
	    TO_VICT);
	act("{hYou trip $N and $N goes down!{x", ch, NULL, victim,
	    TO_CHAR);
	act("$n trips $N, sending $M to the ground.{x", ch, NULL, victim,
	    TO_NOTVICT);
	check_improve(ch, gsn_trip, TRUE, 1);

	DAZE_STATE(victim, 2 * PULSE_VIOLENCE);
	WAIT_STATE(ch, skill_table[gsn_trip].beats);
	victim->position = POS_RESTING;
	damage(ch, victim, dam, gsn_trip, DAM_BASH, TRUE);
    } else {
	damage(ch, victim, 0, gsn_trip, DAM_BASH, TRUE);
	WAIT_STATE(ch, skill_table[gsn_trip].beats * 2 / 3);
	check_improve(ch, gsn_trip, FALSE, 1);
    }
}



void do_kill(CHAR_DATA * ch, char *argument)
{
    char arg[MIL];
    CHAR_DATA *victim;

    one_argument(argument, arg);

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

    if ((victim = get_char_room(ch, arg)) == NULL) {
	send_to_char("They aren't here.\n\r", ch);
	return;
    }
    if (victim == ch) {
	send_to_char("{hYou hit yourself.  {z{COuch!{x\n\r", ch);
	multi_hit(ch, ch, TYPE_UNDEFINED);
	return;
    }

    if (is_safe(ch, victim))
	return;

    if (!IS_NPC(victim)) {
	/*
	   if ( !IS_SET(victim->act, PLR_TWIT) )
	   {
	   send_to_char( "You must MURDER a player.\n\r", ch );
	   return;
	   }
	 */
    }
    if (victim->fighting != NULL && !is_same_group(ch, victim->fighting)) {
	send_to_char("Kill stealing is not permitted.\n\r", ch);
	return;
    }

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

    if (ch->position == POS_FIGHTING) {
	send_to_char("You do the best you can!\n\r", ch);
	return;
    }

    if (ch->shadow) {
	ch->shadowing->shadowed = FALSE;
	ch->shadowing->shadower = NULL;
	ch->shadowing = NULL;
	ch->shadow = FALSE;
    }

/* Autostancing - Loki */
    if (IS_SET(victim->extra, dd)) {
	if (victim->stance[11] == STANCE_SERPENT)
	    do_stance(victim, "serpent");
	else if (victim->stance[11] == STANCE_CRANE)
	    do_stance(victim, "crane");
	else if (victim->stance[11] == STANCE_CRAB)
	    do_stance(victim, "crab");
	else if (victim->stance[11] == STANCE_MONGOOSE)
	    do_stance(victim, "mongoose");
	else if (victim->stance[11] == STANCE_BULL)
	    do_stance(victim, "bull");
	else if (victim->stance[11] == STANCE_MANTIS)
	    do_stance(victim, "mantis");
	else if (victim->stance[11] == STANCE_DRAGON)
	    do_stance(victim, "dragon");
	else if (victim->stance[11] == STANCE_TIGER)
	    do_stance(victim, "tiger");
	else if (victim->stance[11] == STANCE_MONKEY)
	    do_stance(victim, "monkey");
	else if (victim->stance[11] == STANCE_SWALLOW)
	    do_stance(victim, "swallow");
    }

/* Autostancing - Loki */
    if (IS_SET(ch->extra, dd)) {
	if (ch->stance[11] == STANCE_SERPENT)
	    do_stance(ch, "serpent");
	else if (ch->stance[11] == STANCE_CRANE)
	    do_stance(ch, "crane");
	else if (ch->stance[11] == STANCE_CRAB)
	    do_stance(ch, "crab");
	else if (ch->stance[11] == STANCE_MONGOOSE)
	    do_stance(ch, "mongoose");
	else if (ch->stance[11] == STANCE_BULL)
	    do_stance(ch, "bull");
	else if (ch->stance[11] == STANCE_MANTIS)
	    do_stance(ch, "mantis");
	else if (ch->stance[11] == STANCE_DRAGON)
	    do_stance(ch, "dragon");
	else if (ch->stance[11] == STANCE_TIGER)
	    do_stance(ch, "tiger");
	else if (ch->stance[11] == STANCE_MONKEY)
	    do_stance(ch, "monkey");
	else if (ch->stance[11] == STANCE_SWALLOW)
	    do_stance(ch, "swallow");
    }
    if ((ch->fighting == NULL)
	&& (!IS_NPC(ch))
	&& (!IS_NPC(victim))) {
	ch->attacker = TRUE;
	victim->attacker = FALSE;
    }

    WAIT_STATE(ch, 1 * PULSE_VIOLENCE);
    multi_hit(ch, victim, TYPE_UNDEFINED);
    return;
}

void do_mock(CHAR_DATA * ch, char *argument)
{
    char arg[MIL];
    CHAR_DATA *victim;

    one_argument(argument, arg);

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

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

    if (victim->fighting != NULL) {
	send_to_char("{gThis player is busy at the moment.{x\n\r", ch);
	return;
    }

    if (ch->position == POS_FIGHTING) {
	send_to_char("{gYou've already got your hands full!{x\n\r", ch);
	return;
    }

    if (ch->shadow) {
	ch->shadowing->shadowed = FALSE;
	ch->shadowing->shadower = NULL;
	ch->shadowing = NULL;
	ch->shadow = FALSE;
    }
    one_hit_mock(ch, victim, TYPE_UNDEFINED, FALSE);

    return;
}

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



void do_murder(CHAR_DATA * ch, char *argument)
{
    char buf[MSL];
    char arg[MIL];
    CHAR_DATA *victim;

    one_argument(argument, arg);

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

    if (IS_NPC(ch))
	return;

    if (IS_AFFECTED(ch, AFF_CHARM))
	return;

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

    if (victim == ch) {
	send_to_char("Suicide is a mortal sin.\n\r", ch);
	return;
    }

    if (is_safe(ch, victim))
	return;

    if (IS_NPC(victim) &&
	victim->fighting != NULL && !is_same_group(ch, victim->fighting)) {
	send_to_char("Kill stealing is not permitted.\n\r", ch);
	return;
    }

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

    if (ch->position == POS_FIGHTING) {
	send_to_char("You do the best you can!\n\r", ch);
	return;
    }

    if (ch->shadow) {
	ch->shadowing->shadowed = FALSE;
	ch->shadowing->shadower = NULL;
	ch->shadowing = NULL;
	ch->shadow = FALSE;
    }

    if (IS_SET(victim->exbit1_flags, RECRUIT)
	|| IS_SET(victim->exbit1_flags, PK_VETERAN)
	|| IS_SET(victim->exbit1_flags, PK_LAWFUL)
	|| IS_SET(victim->exbit1_flags, PK_KILLER)
	|| IS_SET(ch->exbit1_flags, RECRUIT)
	|| IS_SET(ch->exbit1_flags, PK_VETERAN)
	|| IS_SET(ch->exbit1_flags, PK_LAWFUL)
	|| IS_SET(ch->exbit1_flags, PK_KILLER) ) {

	if (victim->fighting != NULL
	    && IS_SET(ch->exbit1_flags, PK_LAWFUL)) {
	    send_to_char("So thats the way you like to play.\n\r", ch);
	    REMOVE_BIT(ch->exbit1_flags, PK_LAWFUL);
	    SET_BIT(ch->exbit1_flags, PK_KILLER);
	}
	    else if (victim->fighting != NULL
		     && IS_SET(ch->exbit1_flags, PK_KILLER)) {
	    send_to_char("You really deserve this.\n\r", ch);
	    REMOVE_BIT(ch->exbit1_flags, PK_KILLER);
	    SET_BIT(ch->exbit1_flags, PK_KILLER2);
	}
	// send_to_char("Have mercy on them.\n\r", ch);
    }

/* Autostancing - Loki */
    if (IS_SET(victim->extra, dd)) {
	if (victim->stance[11] == STANCE_SERPENT)
	    do_stance(victim, "serpent");
	else if (victim->stance[11] == STANCE_CRANE)
	    do_stance(victim, "crane");
	else if (victim->stance[11] == STANCE_CRAB)
	    do_stance(victim, "crab");
	else if (victim->stance[11] == STANCE_MONGOOSE)
	    do_stance(victim, "mongoose");
	else if (victim->stance[11] == STANCE_BULL)
	    do_stance(victim, "bull");
	else if (victim->stance[11] == STANCE_MANTIS)
	    do_stance(victim, "mantis");
	else if (victim->stance[11] == STANCE_DRAGON)
	    do_stance(victim, "dragon");
	else if (victim->stance[11] == STANCE_TIGER)
	    do_stance(victim, "tiger");
	else if (victim->stance[11] == STANCE_MONKEY)
	    do_stance(victim, "monkey");
	else if (victim->stance[11] == STANCE_SWALLOW)
	    do_stance(victim, "swallow");
    }

/* Autostancing - Loki */
    if (IS_SET(ch->extra, dd)) {
	if (ch->stance[11] == STANCE_SERPENT)
	    do_stance(ch, "serpent");
	else if (ch->stance[11] == STANCE_CRANE)
	    do_stance(ch, "crane");
	else if (ch->stance[11] == STANCE_CRAB)
	    do_stance(ch, "crab");
	else if (ch->stance[11] == STANCE_MONGOOSE)
	    do_stance(ch, "mongoose");
	else if (ch->stance[11] == STANCE_BULL)
	    do_stance(ch, "bull");
	else if (ch->stance[11] == STANCE_MANTIS)
	    do_stance(ch, "mantis");
	else if (ch->stance[11] == STANCE_DRAGON)
	    do_stance(ch, "dragon");
	else if (ch->stance[11] == STANCE_TIGER)
	    do_stance(ch, "tiger");
	else if (ch->stance[11] == STANCE_MONKEY)
	    do_stance(ch, "monkey");
	else if (ch->stance[11] == STANCE_SWALLOW)
	    do_stance(ch, "swallow");
    }
    if ((ch->fighting == NULL)
	&& (!IS_NPC(ch))
	&& (!IS_NPC(victim))) {
	ch->attacker = TRUE;
	victim->attacker = FALSE;
    }

    WAIT_STATE(ch, 1 * PULSE_VIOLENCE);
    if (IS_NPC(ch))
	sprintf(buf, "Help! I am being attacked by %s!", ch->short_descr);
    else
	sprintf(buf, "Help!  I am being attacked by %s!", ch->name);
    do_yell(victim, buf);
    multi_hit(ch, victim, TYPE_UNDEFINED);
    return;
}



void do_backstab(CHAR_DATA * ch, char *argument)
{
    char arg[MIL];
    CHAR_DATA *victim;
    OBJ_DATA *obj;

    one_argument(argument, arg);

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

    if (ch->fighting != NULL) {
	send_to_char("{hYou're facing the wrong end.{x\n\r", ch);
	return;
    }

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

    if (victim == ch) {
	send_to_char("How can you sneak up on yourself?\n\r", ch);
	return;
    }

    if (is_safe(ch, victim))
	return;

    if (IS_NPC(victim) &&
	victim->fighting != NULL && !is_same_group(ch, victim->fighting)) {
	send_to_char("Kill stealing is not permitted.\n\r", ch);
	return;
    }

    if ((obj = get_eq_char(ch, WEAR_WIELD)) == NULL) {
	send_to_char
	    ("{hYou need to wield a primary weapon to backstab.{x\n\r",
	     ch);
	return;
    }

    if (victim->hit < victim->max_hit / 3) {
	act("$N is hurt and suspicious ... you can't sneak up.",
	    ch, NULL, victim, TO_CHAR);
	return;
    }

    if (ch->shadow) {
	ch->shadowing->shadowed = FALSE;
	ch->shadowing->shadower = NULL;
	ch->shadowing = NULL;
	ch->shadow = FALSE;
    }

    if (IS_SET(victim->exbit1_flags, RECRUIT)
	|| IS_SET(victim->exbit1_flags, PK_VETERAN)
	|| IS_SET(victim->exbit1_flags, PK_LAWFUL)
	|| IS_SET(victim->exbit1_flags, PK_KILLER)
	|| IS_SET(ch->exbit1_flags, RECRUIT)
	|| IS_SET(ch->exbit1_flags, PK_VETERAN)
	|| IS_SET(ch->exbit1_flags, PK_LAWFUL)
	|| IS_SET(ch->exbit1_flags, PK_KILLER) ) {
	if (victim->fighting != NULL
	    && IS_SET(ch->exbit1_flags, PK_LAWFUL)) {
	    send_to_char("So thats the way you like to play.\n\r", ch);
	    REMOVE_BIT(ch->exbit1_flags, PK_LAWFUL);
	    SET_BIT(ch->exbit1_flags, PK_KILLER);
	}
	    else if (victim->fighting != NULL
		     && IS_SET(ch->exbit1_flags, PK_KILLER)) {
	    send_to_char("You really deserve this.\n\r", ch);
	    REMOVE_BIT(ch->exbit1_flags, PK_KILLER);
	    SET_BIT(ch->exbit1_flags, PK_KILLER2);
	}
	// send_to_char("Have mercy on them.\n\r", ch);
    }

/* Autostancing - Loki */
    if (IS_SET(victim->extra, dd)) {
	if (victim->stance[11] == STANCE_SERPENT)
	    do_stance(victim, "serpent");
	else if (victim->stance[11] == STANCE_CRANE)
	    do_stance(victim, "crane");
	else if (victim->stance[11] == STANCE_CRAB)
	    do_stance(victim, "crab");
	else if (victim->stance[11] == STANCE_MONGOOSE)
	    do_stance(victim, "mongoose");
	else if (victim->stance[11] == STANCE_BULL)
	    do_stance(victim, "bull");
	else if (victim->stance[11] == STANCE_MANTIS)
	    do_stance(victim, "mantis");
	else if (victim->stance[11] == STANCE_DRAGON)
	    do_stance(victim, "dragon");
	else if (victim->stance[11] == STANCE_TIGER)
	    do_stance(victim, "tiger");
	else if (victim->stance[11] == STANCE_MONKEY)
	    do_stance(victim, "monkey");
	else if (victim->stance[11] == STANCE_SWALLOW)
	    do_stance(victim, "swallow");
    }

/* Autostancing - Loki */
    if (IS_SET(ch->extra, dd)) {
	if (ch->stance[11] == STANCE_SERPENT)
	    do_stance(ch, "serpent");
	else if (ch->stance[11] == STANCE_CRANE)
	    do_stance(ch, "crane");
	else if (ch->stance[11] == STANCE_CRAB)
	    do_stance(ch, "crab");
	else if (ch->stance[11] == STANCE_MONGOOSE)
	    do_stance(ch, "mongoose");
	else if (ch->stance[11] == STANCE_BULL)
	    do_stance(ch, "bull");
	else if (ch->stance[11] == STANCE_MANTIS)
	    do_stance(ch, "mantis");
	else if (ch->stance[11] == STANCE_DRAGON)
	    do_stance(ch, "dragon");
	else if (ch->stance[11] == STANCE_TIGER)
	    do_stance(ch, "tiger");
	else if (ch->stance[11] == STANCE_MONKEY)
	    do_stance(ch, "monkey");
	else if (ch->stance[11] == STANCE_SWALLOW)
	    do_stance(ch, "swallow");
    }
    if ((ch->fighting == NULL)
	&& (!IS_NPC(ch))
	&& (!IS_NPC(victim))) {
	ch->attacker = TRUE;
	victim->attacker = FALSE;
    }

    if (get_skill(ch, gsn_backstab) == 0 && !IS_AWAKE(victim)) {
	WAIT_STATE(ch, skill_table[gsn_backstab].beats);
	multi_hit(ch, victim, gsn_backstab);
	if (!IS_NPC(ch))
	    do_mod_favor(ch, 1);
	return;
    }
    if (ch->shadow && (ch->shadowing == victim)) {
	WAIT_STATE(ch, skill_table[gsn_backstab].beats);
	multi_hit(ch, victim, gsn_backstab);
	if (!IS_NPC(ch))
	    do_mod_favor(ch, 1);
	return;
    }
    WAIT_STATE(ch, skill_table[gsn_backstab].beats);
    if (number_percent() < get_skill(ch, gsn_backstab)
	|| (get_skill(ch, gsn_backstab) >= 1 && !IS_AWAKE(victim))) {
	check_improve(ch, gsn_backstab, TRUE, 1);
	multi_hit(ch, victim, gsn_backstab);
	if (!IS_NPC(ch))
	    do_mod_favor(ch, 1);
    } else {
	check_improve(ch, gsn_backstab, FALSE, 1);
	damage(ch, victim, 0, gsn_backstab, DAM_NONE, TRUE);
    }

    return;
}

void do_circle(CHAR_DATA * ch, char *argument)
{
    CHAR_DATA *victim;
    OBJ_DATA *obj;
    int chance;

    if ((chance = get_skill(ch, gsn_circle)) == 0) {
	send_to_char("Circle?  What's that?\n\r", ch);
	return;
    }

    if (!IS_NPC(ch)) {
	if (ch->pcdata->tier != 2) {
	    if (ch->level < skill_table[gsn_circle].skill_level[ch->class]) {
		send_to_char("Circle?  What's that?\n\r", ch);
		return;
	    }
	} else
	    if (
		(ch->level <
		 skill_table[gsn_circle].skill_level[ch->class])
		&& (ch->level <
		    skill_table[gsn_circle].skill_level[ch->clasb])) {
	    send_to_char("Circle?  What's that?\n\r", ch);
	    return;
	}
    }

    if ((victim = ch->fighting) == NULL) {
	send_to_char("You aren't fighting anyone.\n\r", ch);
	return;
    }

    if ((obj = get_eq_char(ch, WEAR_WIELD)) == NULL) {
	send_to_char("You need to wield a primary weapon to circle.\n\r",
		     ch);
	return;
    }

    if (victim->hit < victim->max_hit / 6) {
	act("$N is hurt and suspicious ... you can't sneak around.",
	    ch, NULL, victim, TO_CHAR);
	return;
    }

    if (ch->stunned) {
	send_to_char("You're still a little woozy.\n\r", ch);
	return;
    }

    if (!can_see(ch, victim)) {
	send_to_char("You stumble blindly into a wall.\n\r", ch);
	return;
    }

    WAIT_STATE(ch, skill_table[gsn_circle].beats);
    if (number_percent() < get_skill(ch, gsn_circle)
	|| (get_skill(ch, gsn_circle) >= 2 && !IS_AWAKE(victim))) {
	check_improve(ch, gsn_circle, TRUE, 1);
	act("$n circles around behind you.{x", ch, NULL, victim,
	    TO_VICT);
	act("{hYou circle around $N.{x", ch, NULL, victim, TO_CHAR);
	act("$n circles around behind $N.{x", ch, NULL, victim,
	    TO_NOTVICT);
	multi_hit(ch, victim, gsn_circle);
	if (!IS_NPC(ch))
	    do_mod_favor(ch, 1);
    } else {
	check_improve(ch, gsn_circle, FALSE, 1);
	act("$n tries to circle around you.{x", ch, NULL, victim,
	    TO_VICT);
	act("{h$N circles with you.{x", ch, NULL, victim, TO_CHAR);
	act("$n tries to circle around $N.{x", ch, NULL, victim,
	    TO_NOTVICT);
	damage(ch, victim, 0, gsn_circle, DAM_NONE, TRUE);
    }

    return;
}

void do_feed(CHAR_DATA * ch, char *argument)
{
    CHAR_DATA *victim;
    int chance;

    if ((chance = get_skill(ch, gsn_feed)) == 0) {
	send_to_char("Feed?  What's that?\n\r", ch);
	return;
    }

    if (!IS_NPC(ch)) {
	if (ch->pcdata->tier != 2) {
	    if (ch->level < skill_table[gsn_feed].skill_level[ch->class]) {
		send_to_char("Feed?  What's that?\n\r", ch);
		return;
	    }
	} else
	    if ((ch->level < skill_table[gsn_feed].skill_level[ch->class])
		&& (ch->level <
		    skill_table[gsn_feed].skill_level[ch->clasb])) {
	    send_to_char("Feed?  What's that?\n\r", ch);
	    return;
	}
    }

    if ((victim = ch->fighting) == NULL) {
	send_to_char("You aren't fighting anyone.\n\r", ch);
	return;
    }

    if (victim->hit < victim->max_hit / 6) {
	act("$N is hurt and suspicious ... you can't get close enough.",
	    ch, NULL, victim, TO_CHAR);
	return;
    }

    if (ch->stunned) {
	send_to_char("You're still a little woozy.\n\r", ch);
	return;
    }

    WAIT_STATE(ch, skill_table[gsn_feed].beats);
    if (number_percent() < get_skill(ch, gsn_feed) / 3
	|| (get_skill(ch, gsn_feed) >= 2 && !IS_AWAKE(victim))) {
	int dam;

	dam = number_range((((ch->level / 2) + (victim->level / 2)) / 2.5), (((ch->level / 2) + (victim->level / 2)) / 2.5) * 2.5);

	check_improve(ch, gsn_feed, TRUE, 1);
	act("$n bites you.{x", ch, NULL, victim, TO_VICT);
	act("{hYou bite $N.{x", ch, NULL, victim, TO_CHAR);
	act("$n bites $N.{x", ch, NULL, victim, TO_NOTVICT);
	damage(ch, victim, dam, gsn_feed, DAM_NEGATIVE, TRUE);
    } else {
	check_improve(ch, gsn_feed, FALSE, 1);
	act("$n tries to bite you, but hits only air.{x", ch, NULL,
	    victim, TO_VICT);
	act("{hYou chomp a mouthfull of air.{x", ch, NULL, victim,
	    TO_CHAR);
	act("$n tries to bite $N.{x", ch, NULL, victim, TO_NOTVICT);
	damage(ch, victim, 0, gsn_feed, DAM_NEGATIVE, TRUE);
    }

    return;
}


void do_flee(CHAR_DATA * ch, char *argument)
{
    ROOM_INDEX_DATA *was_in;
    ROOM_INDEX_DATA *now_in;
    CHAR_DATA *victim;
    int attempt;

    if ((victim = ch->fighting) == NULL) {
	if (ch->position == POS_FIGHTING)
	    ch->position = POS_STANDING;
	send_to_char("You aren't fighting anyone.\n\r", ch);
	return;
    }

    was_in = ch->in_room;
    for (attempt = 0; attempt < 6; attempt++) {
	EXIT_DATA *pexit;
	int door;
	int gdoor;

	door = number_door();
	if (((pexit = was_in->exit[door + 6]) != NULL)
	    && (ch->alignment < 0))
	    gdoor = door + 6;
	else
	    gdoor = door;

	if (((pexit = was_in->exit[gdoor]) == NULL)
	    || (IS_SET(ch->in_room->room_flags, ROOM_CLAN_ENT))) {
	    OBJ_DATA *portal;

	    portal = get_obj_exit(dir_name[door], was_in->contents);
	    if (portal == NULL) {
		continue;
	    }
	} else if ((pexit = was_in->exit[gdoor]) == 0
		   || pexit->u1.to_room == NULL
		   || IS_SET(pexit->exit_info, EX_CLOSED)
		   || number_range(0, ch->daze) != 0 || (IS_NPC(ch)
							 && IS_SET(pexit->
								   u1.
								   to_room->
								   room_flags,
								   ROOM_NO_MOB)))
		continue;

	move_char(ch, door, FALSE, FALSE);
	if ((now_in = ch->in_room) == was_in) {
	    continue;
	}

	ch->in_room = was_in;
	act("$n has {Yfled{x!", ch, NULL, NULL, TO_ROOM);
	if (!IS_NPC(ch)) {
	    if (!IS_NPC(victim)) {
		if (ch->attacker == FALSE)
		    ch->pcdata->dflee++;
		else
		    ch->pcdata->aflee++;
	    }
	    send_to_char("{BYou {Yflee{B from combat!{x\n\r", ch);
	    if (((ch->class == 2) || (ch->class == (MCLT_1) + 1))
		&& (number_percent() < 3 * (ch->level / 2))) {
		if (IS_NPC(victim) || ch->attacker == FALSE) {
		    send_to_char("You {Ysnuck away{x safely.\n\r", ch);
		} else {
		    send_to_char
			("You feel something singe your butt on the way out.\n\r",
			 ch);
		    act
			("$n is nearly {Yzapped{x in the butt by a lightning bolt from above!",
			 ch, NULL, NULL, TO_ROOM);
		    ch->hit -= (ch->hit / 8);
		}
	    } else {
		if (!IS_NPC(victim) && ch->attacker == TRUE) {
		    send_to_char
			("The {RWrath of Thoth {YZAPS{x your butt on the way out!\n\r",
			 ch);
		    act
			("$n is {Yzapped{x in the butt by a lightning bolt from above!",
			 ch, NULL, NULL, TO_ROOM);
		    ch->hit -= (ch->hit / 4);
		}
		if (!IS_NPC(ch) && !IS_SET(ch->act, PLR_LQUEST)) {
		    send_to_char("You lost 10 exp.\n\r", ch);
		    gain_exp(ch, -10);
		}
	    }
	}
	ch->in_room = now_in;
	stop_fighting(ch, TRUE);
	do_mod_favor(ch, 2);
	return;
    }

    send_to_char("{z{CPANIC!{x{B You couldn't escape!{x\n\r", ch);
    return;
}



void do_rescue(CHAR_DATA * ch, char *argument)
{
    char arg[MIL];
    CHAR_DATA *victim;
    CHAR_DATA *fch;

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

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

    if (victim == ch) {
	send_to_char("What about {Yfleeing{x instead?\n\r", ch);
	return;
    }

    if (!IS_NPC(ch) && IS_NPC(victim)) {
	send_to_char("Doesn't need your help!\n\r", ch);
	return;
    }

    if (ch->fighting == victim) {
	send_to_char("Too late.\n\r", ch);
	return;
    }

    if ((fch = victim->fighting) == NULL) {
	send_to_char("That person is not fighting right now.\n\r", ch);
	return;
    }

    if (IS_NPC(fch) && !is_same_group(ch, victim)) {
	send_to_char("Kill stealing is not permitted.\n\r", ch);
	return;
    }

    if (ch->spirit) {
	send_to_char("That's tough to do without flesh.\n\r", ch);
	return;
    }

    WAIT_STATE(ch, skill_table[gsn_rescue].beats);
    if (number_percent() > get_skill(ch, gsn_rescue)) {
	send_to_char("You fail the rescue.\n\r", ch);
	check_improve(ch, gsn_rescue, FALSE, 1);
	return;
    }

    if (ch->shadow) {
	ch->shadowing->shadowed = FALSE;
	ch->shadowing->shadower = NULL;
	ch->shadowing = NULL;
	ch->shadow = FALSE;
    }
    act("{yYou rescue $N!{x", ch, NULL, victim, TO_CHAR);
    act("{y$n rescues you!{x", ch, NULL, victim, TO_VICT);
    act("{y$n rescues $N!{x", ch, NULL, victim, TO_NOTVICT);
    do_mod_favor(ch, 6);
    check_improve(ch, gsn_rescue, TRUE, 1);

    stop_fighting(fch, FALSE);
    stop_fighting(victim, FALSE);

    set_fighting(ch, fch);
    set_fighting(fch, ch);
    return;
}




void do_stance(CHAR_DATA * ch, char *argument)
{
    char arg[MIL];
    int selection;
    argument = one_argument(argument, arg);
    if (arg[0] == '\0') {
	if (ch->stance[0] == -1) {
	    ch->stance[0] = 0;
	    send_to_char("You drop into a street fighting stance.\n\r", ch);
	    act("$n drops into a street fighting stance.", ch, NULL, NULL,
		TO_ROOM);} else {
	    ch->stance[0] = -1;
	    send_to_char("You relax from your street fighting stance.\n\r",
			 ch);
	    act("$n relaxes from $s street fighting stance.", ch, NULL,
		NULL, TO_ROOM);
	}
	return;
    }
    if (!str_cmp(arg, "none")) {
	selection = STANCE_NONE;
	send_to_char("You drop into a boxing fighting stance.\n\r", ch);
	act("$n drops into a boxing fighting stance.", ch, NULL, NULL,
	    TO_ROOM);} else if (!str_cmp(arg, "serpent")) {
	selection = STANCE_SERPENT;
	send_to_char("You take up the serpent fighting stance.\n\r", ch);
	act("$n takes up the serpent fighting stance.", ch, NULL, NULL,
	    TO_ROOM);} else if (!str_cmp(arg, "crane")) {
	selection = STANCE_CRANE;
	send_to_char("You take up the crane fighting stance.\n\r", ch);
	act("$n takes up the crane fighting stance.", ch, NULL, NULL,
	    TO_ROOM);} else if (!str_cmp(arg, "crab")) {
	selection = STANCE_CRAB;
	send_to_char("You take up the crab fighting stance.\n\r", ch);
	act("$n takes up the crab fighting stance. ", ch, NULL, NULL,
	    TO_ROOM);} else if (!str_cmp(arg, "mongoose")) {
	selection = STANCE_MONGOOSE;
	send_to_char("You take up the mongoose fighting stance.\n\r", ch);
	act("$n takes up the mongoose fighting stance. ", ch, NULL, NULL,
	    TO_ROOM);} else if (!str_cmp(arg, "bull")) {
	selection = STANCE_BULL;
	send_to_char("You take up the bull fighting stance.\n\r", ch);
	act("$n takes up the bull fighting stance. ", ch, NULL, NULL,
	    TO_ROOM);} else {
	if (!str_cmp(arg, "mantis") && ch->stance[STANCE_CRANE] >= 200
	    && ch->stance[STANCE_SERPENT] >= 200) {
	    selection = STANCE_MANTIS;
	    send_to_char("You take up the mantis fighting stance.\n\r", ch);
	    act("$n takes up the mantis fighting stance.", ch, NULL, NULL,
		TO_ROOM);
	} else if (!str_cmp(arg, "dragon") && ch->stance[STANCE_BULL] >= 200
		   && ch->stance[STANCE_CRAB] >= 200) {
	    selection = STANCE_DRAGON;
	    send_to_char("You take up the dragon fighting stance.\n\r", ch);
	    act("$n takes up the dragon fighting stance.", ch, NULL, NULL,
		TO_ROOM);
	} else if (!str_cmp(arg, "tiger") && ch->stance[STANCE_BULL] >= 200
		   && ch->stance[STANCE_SERPENT] >= 200) {
	    selection = STANCE_TIGER;
	    send_to_char("You take up the tiger fighting stance.\n\r", ch);
	    act("$n takes up the tiger fighting stance.", ch, NULL, NULL,
		TO_ROOM);
	} else if (!str_cmp(arg, "monkey") && ch->stance[STANCE_CRANE] >= 200
		   && ch->stance[STANCE_MONGOOSE] >= 200) {
	    selection = STANCE_MONKEY;
	    send_to_char("You take up the monkey fighting stance.\n\r", ch);
	    act("$n takes up the monkey fighting stance.", ch, NULL, NULL,
		TO_ROOM);
	} else if (!str_cmp(arg, "swallow") && ch->stance[STANCE_CRAB] >= 200
		   && ch->stance[STANCE_MONGOOSE] >= 200) {
	    selection = STANCE_SWALLOW;
	    send_to_char("You take up the swallow fighting stance.\n\r",
			 ch);
	    act("$n takes up the swallow fighting stance.", ch, NULL, NULL,
		TO_ROOM);
	} else {
	    send_to_char("Syntax is: stance <stance>.\n\r", ch);
	    send_to_char
		("Stance being one of: None, Serpent, Crane, Crab, Mongoose, Bull.\n\r",
		 ch);
	    return;
	}
    }
    ch->stance[0] = selection;
    return;
}

void do_autostance(CHAR_DATA * ch, char *argument)
{
    char arg[MIL];
    int selection;

    one_argument(argument, arg);

    if (IS_NPC(ch))
	return;

    if (!str_cmp(arg, "none")) {
	selection = STANCE_NONE;
	send_to_char("You're autostance has been removed.\n\r", ch);
	REMOVE_BIT(ch->extra, dd);
    } else if (!str_cmp(arg, "serpent")) {
	selection = STANCE_SERPENT;
	send_to_char("Serpent stance set.\n\r", ch);
    } else if (!str_cmp(arg, "crane")) {
	selection = STANCE_CRANE;
	send_to_char("Crane stance set.\n\r", ch);
    } else if (!str_cmp(arg, "crab")) {
	selection = STANCE_CRAB;
	send_to_char("Crab stance set.\n\r", ch);
    } else if (!str_cmp(arg, "mongoose")) {
	selection = STANCE_MONGOOSE;
	send_to_char("Mongoose stance set.\n\r", ch);
    } else if (!str_cmp(arg, "bull")) {
	selection = STANCE_BULL;
	send_to_char("Bull stance set.\n\r", ch);
    } else {
	if (!str_cmp(arg, "mantis") && ch->stance[STANCE_CRANE] >= 200 &&
	    ch->stance[STANCE_SERPENT] >= 200) {
	    selection = STANCE_MANTIS;
	    send_to_char("Mantis stance set.\n\r", ch);
	}
	    else if (!str_cmp(arg, "dragon")
		     && ch->stance[STANCE_BULL] >= 200
		     && ch->stance[STANCE_CRAB] >= 200) {
	    selection = STANCE_DRAGON;
	    send_to_char("Dragon stance set.\n\r", ch);
	}
	    else if (!str_cmp(arg, "tiger") && ch->stance[STANCE_BULL] >= 200
		     && ch->stance[STANCE_SERPENT] >= 200) {
	    selection = STANCE_TIGER;
	    send_to_char("Tiger stance set.\n\r", ch);
	}
	    else if (!str_cmp(arg, "monkey")
		     && ch->stance[STANCE_CRANE] >= 200
		     && ch->stance[STANCE_MONGOOSE] >= 200) {
	    selection = STANCE_MONKEY;
	    send_to_char("Monkey stance set.\n\r", ch);
	}
	    else if (!str_cmp(arg, "swallow")
		     && ch->stance[STANCE_CRAB] >= 200
		     && ch->stance[STANCE_MONGOOSE] >= 200) {
	    selection = STANCE_SWALLOW;
	    send_to_char("Swallow  stance set.\n\r", ch);
	} else {
	    send_to_char("Syntax is: autostance <stance>.\n\r", ch);
	    send_to_char
		("Autotance being one of: None, Serpent, Crane, Crab, Mongoose, Bull.\n\r",
		 ch);
	    send_to_char
		("If you know them, they are:  Mantis, Dragon, Tiger, Monkey, Swallow.\n\r",
		 ch);
	    return;
	}
    }
    ch->stance[11] = selection;
    SET_BIT(ch->extra, dd);
    return;
}

int dambonus(CHAR_DATA * ch, CHAR_DATA * victim, int dam, int stance)
{
    if (dam < 1)
	return 0;
    if (stance < 1)
	return dam;
    if (!IS_NPC(ch) && !can_counter(victim)) {
	if (IS_STANCE(ch, STANCE_MONKEY)) {
	    int mindam = dam * 0.25;
	    dam *= (ch->stance[STANCE_MONKEY] + 1) / 200;
	    if (dam < mindam)
		dam = mindam;
	} else if (IS_STANCE(ch, STANCE_BULL) && ch->stance[STANCE_BULL] > 100)
	    dam += dam * (ch->stance[STANCE_BULL] / 100);
	else if (IS_STANCE(ch, STANCE_DRAGON)
		 && ch->stance[STANCE_DRAGON] > 100) dam +=
		dam * (ch->stance[STANCE_DRAGON] / 100);
	else if (IS_STANCE(ch, STANCE_TIGER) && ch->stance[STANCE_TIGER] > 100)
	    dam += dam * (ch->stance[STANCE_TIGER] / 100);
	else if (ch->stance[0] > 0 && ch->stance[stance] < 100)
	    dam *= 0.5;
    }
    if (!IS_NPC(victim) && !can_counter(ch)) {
	if (IS_STANCE(victim, STANCE_CRAB)
	    && victim->stance[STANCE_CRAB] >
	    100) dam /= victim->stance[STANCE_CRAB] / 100;
	else if (IS_STANCE(victim, STANCE_DRAGON)
		 && victim->stance[STANCE_DRAGON] > 100)
	    dam /= victim->stance[STANCE_DRAGON] / 100;
	else if (IS_STANCE(victim, STANCE_SWALLOW)
		 && victim->stance[STANCE_SWALLOW] > 100)
	    dam /= victim->stance[STANCE_SWALLOW] / 100;
    }
    return dam;
}

bool can_counter(CHAR_DATA * ch)
{
    if (IS_STANCE(ch, STANCE_MONKEY))
	return TRUE;
    return FALSE;
}

bool can_bypass(CHAR_DATA * ch, CHAR_DATA * victim)
{
    if (IS_STANCE(ch, STANCE_SERPENT))
	return TRUE;
    else if (IS_STANCE(ch, STANCE_MANTIS))
	return TRUE;
    else if (IS_STANCE(ch, STANCE_TIGER))
	return TRUE;
    return FALSE;
}

void improve_stance(CHAR_DATA * ch)
{
    char buf[MIL];
    char bufskill[25];
    char stancename[10];
    int dice1;
    int dice2;
    int stance;

    dice1 = number_percent();
    dice2 = number_percent();
    stance = ch->stance[0];
    if (stance < 1 || stance > 10)
	return;
    if (ch->stance[stance] >= 200) {
	ch->stance[stance] = 200;
	return;
    }
    if ((dice1 > ch->stance[stance] && dice2 > ch->stance[stance])
	|| (dice1 == 100 || dice2 == 100))
	ch->stance[stance] += 1;
    else
	return;
    if (stance == ch->stance[stance])
	return;
    if (ch->stance[stance] == 1)
	sprintf(bufskill, "an apprentice of");
    else if (ch->stance[stance] == 26)
	sprintf(bufskill, "a trainee of");
    else if (ch->stance[stance] == 51)
	sprintf(bufskill, "a student of");
    else if (ch->stance[stance] == 76)
	sprintf(bufskill, "fairly experienced in");
    else if (ch->stance[stance] == 101)
	sprintf(bufskill, "well trained in");
    else if (ch->stance[stance] == 126)
	sprintf(bufskill, "highly skilled in");
    else if (ch->stance[stance] == 151)
	sprintf(bufskill, "an expert of");
    else if (ch->stance[stance] == 176)
	sprintf(bufskill, "a master of");
    else if (ch->stance[stance] == 200)
	sprintf(bufskill, "a grand master of");
    else
	return;

    if (stance == STANCE_SERPENT)
	sprintf(stancename, "serpent");
    else if (stance == STANCE_CRANE)
	sprintf(stancename, "crane");
    else if (stance == STANCE_CRAB)
	sprintf(stancename, "crab");
    else if (stance == STANCE_MONGOOSE)
	sprintf(stancename, "mongoose");
    else if (stance == STANCE_BULL)
	sprintf(stancename, "bull");
    else if (stance == STANCE_MANTIS)
	sprintf(stancename, "mantis");
    else if (stance == STANCE_DRAGON)
	sprintf(stancename, "dragon");
    else if (stance == STANCE_TIGER)
	sprintf(stancename, "tiger");
    else if (stance == STANCE_MONKEY)
	sprintf(stancename, "monkey");
    else if (stance == STANCE_SWALLOW)
	sprintf(stancename, "swallow");

    else
	return;
    sprintf(buf, "You are now %s the %s stance.\n\r", bufskill, stancename);
    send_to_char(buf, ch);
    return;
}

void special_move(CHAR_DATA * ch, CHAR_DATA * victim)
{
    int dam = number_range(20, 40);

    if (dam < 20)
	dam = 20;

    switch (number_range(1, 7)) {
    default:
	return;
    case 1:
	act
	    ("You pull your hands into your waist then snap them into $N's stomach.",
	     ch, NULL, victim, TO_CHAR);
	act
	    ("$n pulls $s hands into $s waist then snaps them into your stomach.",
	     ch, NULL, victim, TO_VICT);
	act
	    ("$n pulls $s hands into $s waist then snaps them into $N's stomach.",
	     ch, NULL, victim, TO_NOTVICT);
	if (victim == NULL || victim->position == POS_DEAD)
	    return;
	act
	    ("You double over in agony, and fall to the ground gasping for breath.",
	     victim, NULL, NULL, TO_CHAR);
	act
	    ("$n doubles over in agony, and falls to the ground gasping for breath.",
	     victim, NULL, NULL, TO_ROOM);
	stop_fighting(victim, TRUE);
	victim->position = POS_STUNNED;
	break;
    case 2:
	act("You spin in a low circle, catching $N behind $S ankle.", ch,
	    NULL, victim, TO_CHAR);
	act("$n spins in a low circle, catching you behind your ankle.",
	    ch, NULL, victim, TO_VICT);
	act("$n spins in a low circle, catching $N behind $S ankle.", ch,
	    NULL, victim, TO_NOTVICT);
	if (victim == NULL || victim->position == POS_DEAD)
	    return;
	act("You crash to the ground, stunned.", victim, NULL, NULL,
	    TO_CHAR);
	act("$n crashes to the ground, stunned.", victim, NULL, NULL,
	    TO_ROOM);
	stop_fighting(victim, TRUE);
	victim->position = POS_STUNNED;
	break;
    case 3:
	act("You roll between $N's legs and flip to your feet.", ch, NULL,
	    victim, TO_CHAR);
	act("$n rolls between your legs and flips to $s feet.", ch, NULL,
	    victim, TO_VICT);
	act("$n rolls between $N's legs and flips to $s feet.", ch, NULL,
	    victim, TO_NOTVICT);
	act
	    ("You spin around and smash your elbow into the back of $N's head.",
	     ch, NULL, victim, TO_CHAR);
	act
	    ("$n spins around and smashes $s elbow into the back of your head.",
	     ch, NULL, victim, TO_VICT);
	act
	    ("$n spins around and smashes $s elbow into the back of $N's head.",
	     ch, NULL, victim, TO_NOTVICT);
	if (victim == NULL || victim->position == POS_DEAD)
	    return;
	act("You fall to the ground, stunned.", victim, NULL, NULL,
	    TO_CHAR);
	act("$n falls to the ground, stunned.", victim, NULL, NULL,
	    TO_ROOM);
	stop_fighting(victim, TRUE);
	victim->position = POS_STUNNED;
	break;
    case 4:
	act("You somersault over $N's head and land lightly on your toes.",
	    ch, NULL, victim, TO_CHAR);
	act("$n somersaults over your head and lands lightly on $s toes.",
	    ch, NULL, victim, TO_VICT);
	act("$n somersaults over $N's head and lands lightly on $s toes.",
	    ch, NULL, victim, TO_NOTVICT);
	act
	    ("You roll back onto your shoulders and kick both feet into $N's back.",
	     ch, NULL, victim, TO_CHAR);
	act
	    ("$n rolls back onto $s shoulders and kicks both feet into your back.",
	     ch, NULL, victim, TO_VICT);
	act
	    ("$n rolls back onto $s shoulders and kicks both feet into $N's back.",
	     ch, NULL, victim, TO_NOTVICT);
	act("You fall to the ground, stunned.", victim, NULL, NULL,
	    TO_CHAR);
	act("$n falls to the ground, stunned.", victim, NULL, NULL,
	    TO_ROOM);
	act("You flip back up to your feet.", ch, NULL, NULL, TO_CHAR);
	act("$n flips back up to $s feet.", ch, NULL, NULL, TO_ROOM);
	stop_fighting(victim, TRUE);
	victim->position = POS_STUNNED;
	break;
    case 5:
	act("You grab $N by the waist and hoist $M above your head.", ch,
	    NULL, victim, TO_CHAR);
	act("$n grabs $N by the waist and hoists $M above $s head.", ch,
	    NULL, victim, TO_NOTVICT);
	act("$n grabs you by the waist and hoists you above $s head.", ch,
	    NULL, victim, TO_VICT);
	if (victim == NULL || victim->position == POS_DEAD)
	    return;
	act("You crash to the ground, stunned.", victim, NULL, NULL,
	    TO_CHAR);
	act("$n crashes to the ground, stunned.", victim, NULL, NULL,
	    TO_ROOM);
	stop_fighting(victim, TRUE);
	victim->position = POS_STUNNED;
	break;
    case 6:
	act("You grab $N by the head and slam $S face into your knee.", ch,
	    NULL, victim, TO_CHAR);
	act("$n grabs you by the head and slams your face into $s knee.",
	    ch, NULL, victim, TO_VICT);
	act("$n grabs $N by the head and slams $S face into $s knee.", ch,
	    NULL, victim, TO_NOTVICT);
	if (victim == NULL || victim->position == POS_DEAD)
	    return;
	act("You crash to the ground, stunned.", victim, NULL, NULL,
	    TO_CHAR);
	act("$n crashes to the ground, stunned.", victim, NULL, NULL,
	    TO_ROOM);
	act("You flip back up to your feet.", ch, NULL, NULL, TO_CHAR);
	act("$n flips back up to $s feet.", ch, NULL, NULL, TO_ROOM);
	stop_fighting(victim, TRUE);
	victim->position = POS_STUNNED;
	break;
    case 7:
	act
	    ("You duck under $N's attack and pound your fist into $S stomach.",
	     ch, NULL, victim, TO_CHAR);
	act
	    ("$n ducks under your attack and pounds $s fist into your stomach.",
	     ch, NULL, victim, TO_VICT);
	act
	    ("$n ducks under $N's attack and pounds $s fist into $N's stomach.",
	     ch, NULL, victim, TO_NOTVICT);
	if (victim == NULL || victim->position == POS_DEAD)
	    return;
	act("You double over in agony.", victim, NULL, NULL, TO_CHAR);
	act("$n doubles over in agony.", victim, NULL, NULL, TO_ROOM);
	if (victim == NULL || victim->position == POS_DEAD)
	    return;
	stop_fighting(victim, TRUE);
	victim->position = POS_STUNNED;
	break;
    }
    return;
}

void do_left_hook(CHAR_DATA * ch, char *argument)
{

    CHAR_DATA *victim;
    int dam;

    if (!IS_NPC(ch)
	&& ch->level <
	skill_table[gsn_left_hook].skill_level[ch->
					       class])
    {send_to_char("You better leave that to the experts.\n\r", ch);
	return;
    }

    if ((victim = ch->fighting) == NULL) {
	send_to_char("You aren't fighting anyone.\n\r", ch);
	return;
    }
    if (ch->stunned) {
	send_to_char("You're still a little woozy.\n\r", ch);
	return;
    }
    dam = number_range(3, ch->level * 2);
    WAIT_STATE(ch, skill_table[gsn_left_hook].beats);
    if (get_skill(ch, gsn_left_hook) > number_percent()) {
	damage(ch, victim, number_range(dam, (ch->level * 2.2)),
	       gsn_left_hook, DAM_BASH, TRUE);
	SET_BIT(victim->position, POS_STUNNED);
	check_improve(ch, gsn_left_hook, TRUE, 1);
    } else {
	damage(ch, victim, 0, gsn_left_hook, DAM_BASH, TRUE);
	check_improve(ch, gsn_left_hook, FALSE, 1);
    }
    return;
}

void do_kidney_punch(CHAR_DATA * ch, char *argument)
{
    CHAR_DATA *victim;
    int dam;
    if (!IS_NPC(ch)
	&& ch->level <
	skill_table[gsn_kidney_punch].skill_level[ch->
						  class])
    {send_to_char("You better leave that to the experts.\n\r", ch);
	return;
    }
    if ((victim = ch->fighting) == NULL) {
	send_to_char("You aren't fighting anyone.\n\r", ch);
	return;
    }
    if (ch->stunned) {
	send_to_char("You're still a little woozy.\n\r", ch);
	return;
    }
    dam = number_range(3, ch->level * 1.9);
    WAIT_STATE(ch, skill_table[gsn_kidney_punch].beats);
    if (get_skill(ch, gsn_kidney_punch) > number_percent()) {
	damage(ch, victim, number_range(dam, (ch->level * 2.1)),
	       gsn_kidney_punch, DAM_BASH, TRUE);
	SET_BIT(victim->position, POS_STUNNED);
	check_improve(ch, gsn_kidney_punch, TRUE, 1);
    } else {
	damage(ch, victim, 0, gsn_kidney_punch, DAM_BASH, TRUE);
	check_improve(ch, gsn_kidney_punch, FALSE, 1);
    }
    return;
}
void do_right_cross(CHAR_DATA * ch, char *argument)
{
    CHAR_DATA *victim;
    int dam;
    if (!IS_NPC(ch)
	&& ch->level <
	skill_table[gsn_right_cross].skill_level[ch->
						 class])
    {send_to_char("You better leave that to the experts.\n\r", ch);
	return;
    }
    if ((victim = ch->fighting) == NULL) {
	send_to_char("You aren't fighting anyone.\n\r", ch);
	return;
    }
    if (ch->stunned) {
	send_to_char("You're still a little woozy.\n\r", ch);
	return;
    }
    dam = number_range(2, ch->level * 2.1);
    WAIT_STATE(ch, skill_table[gsn_right_cross].beats);
    if (get_skill(ch, gsn_right_cross) > number_percent()) {
	damage(ch, victim, number_range(dam, (ch->level * 2.3)),
	       gsn_right_cross, DAM_BASH, TRUE);
	check_improve(ch, gsn_right_cross, TRUE, 1);
    } else {
	damage(ch, victim, 0, gsn_right_cross, DAM_BASH, TRUE);
	check_improve(ch, gsn_right_cross, FALSE, 1);
    }
    return;
}

void do_critical_strike(CHAR_DATA * ch, char *argument)
{
    CHAR_DATA *victim;
    int dam;
    if (!IS_NPC(ch)
	&& ch->level <
	skill_table[gsn_critical_strike].skill_level[ch->
						     class])
    {send_to_char("You better leave that to the experts.\n\r", ch);
	return;
    }
    if ((victim = ch->fighting) == NULL) {
	send_to_char("You aren't fighting anyone.\n\r", ch);
	return;
    }
    if (ch->stunned) {
	send_to_char("You're still a little woozy.\n\r", ch);
	return;
    }
    dam = number_range(12, ch->level * 2.5);
    WAIT_STATE(ch, skill_table[gsn_critical_strike].beats);
    if (get_skill(ch, gsn_critical_strike) > number_percent()) {
	damage(ch, victim, number_range(dam, (ch->level * 3.7)),
	       gsn_critical_strike, DAM_BASH, TRUE);
	SET_BIT(victim->position, POS_MORTAL);
	check_improve(ch, gsn_critical_strike, TRUE, 1);
    } else {
	damage(ch, victim, 0, gsn_critical_strike, DAM_BASH, TRUE);
	check_improve(ch, gsn_critical_strike, FALSE, 1);
    }
    return;
}

void do_jab(CHAR_DATA * ch, char *argument)
{

    CHAR_DATA *victim;
    int dam;

    if (!IS_NPC(ch)
	&& ch->level <
	skill_table[gsn_jab].skill_level[ch->
					 class])
    {send_to_char("You better leave that to the experts.\n\r", ch);
	return;
    }

    if ((victim = ch->fighting) == NULL) {
	send_to_char("You aren't fighting anyone.\n\r", ch);
	return;
    }
    if (ch->stunned) {
	send_to_char("You're still a little woozy.\n\r", ch);
	return;
    }
    dam = number_range(3, ch->level * 1);
    WAIT_STATE(ch, skill_table[gsn_jab].beats);
    if (get_skill(ch, gsn_jab) > number_percent()) {
	damage(ch, victim, number_range(dam, (ch->level * 1.2)), gsn_jab,
	       DAM_BASH, TRUE);
	check_improve(ch, gsn_jab, TRUE, 1);
    } else {
	damage(ch, victim, 0, gsn_jab, DAM_BASH, TRUE);
	check_improve(ch, gsn_jab, FALSE, 1);
    }
    return;
}


void do_uppercut(CHAR_DATA * ch, char *argument)
{

    CHAR_DATA *victim;
    int dam;

    if (!IS_NPC(ch)
	&& ch->level <
	skill_table[gsn_uppercut].skill_level[ch->
					      class])
    {send_to_char("You better leave that to the experts.\n\r", ch);
	return;
    }

    if ((victim = ch->fighting) == NULL) {
	send_to_char("You aren't fighting anyone.\n\r", ch);
	return;
    }
    if (ch->stunned) {
	send_to_char("You're still a little woozy.\n\r", ch);
	return;
    }
    dam = number_range(3, ch->level * 2.3);
    WAIT_STATE(ch, skill_table[gsn_uppercut].beats);
    if (get_skill(ch, gsn_uppercut) > number_percent()) {
	damage(ch, victim, number_range(dam, (ch->level * 2.5)),
	       gsn_uppercut, DAM_BASH, TRUE);
	SET_BIT(victim->position, POS_STUNNED);
	check_improve(ch, gsn_uppercut, TRUE, 1);
    } else {
	damage(ch, victim, 0, gsn_uppercut, DAM_BASH, TRUE);
	check_improve(ch, gsn_uppercut, FALSE, 1);
    }
    return;
}

void check_arena(CHAR_DATA * ch, CHAR_DATA * victim)
{
    DESCRIPTOR_DATA *d;		/* needed for Arena bet checking */
    char buf[MSL];
    static int payoff;
    sprintf(buf, "^{gArena{x^ {b%s{x has {rdefeated{x {b%s{x!\n\r",
	    ch->name, victim->name);
    for (d = descriptor_list; d; d = d->next) {
	if (d->connected == CON_PLAYING &&
	    (d->character != victim && d->character != ch)
	    && !IS_SET(d->character->comm, COMM_NOARENA)) {
	    send_to_char(buf, d->character);
	}
    }

    ch->pcdata->awins += 1;
    victim->pcdata->alosses += 1;
    for (d = descriptor_list; d; d = d->next) {
	if (d->connected == CON_PLAYING) {
	    if (d->character->gladiator == ch) {

		if (IS_SET(ch->exbit1_flags, EXBIT1_CHALLENGER)) {
		    float odd1 = cpo_stat;
		    payoff = d->character->pcdata->plr_wager * (odd1);
		}
		if (IS_SET(ch->exbit1_flags, EXBIT1_CHALLENGED)) {
		    float odd2 = vpo_stat;
		    payoff = d->character->pcdata->plr_wager * (odd2);
		}
/*Since there is no ratio for a loss (you lose what you bet) this second part may be
  fubbing things up - going to comment it out for now*
*if (IS_SET(victim->exbit1_flags, EXBIT1_CHALLENGER))
	{ 
		float odd1=cpo_stat;
		payoff = d->character->pcdata->plr_wager * ( odd1 ); 
	}
if (IS_SET(victim->exbit1_flags, EXBIT1_CHALLENGED))
	{ 
		float odd2=vpo_stat;
		payoff = d->character->pcdata->plr_wager * ( odd2 ); 
	}*/

		sprintf(buf,
			"You {gwon{x! Your wager: {y%d{x, payoff: {y%d{x\n\r",
			d->character->pcdata->plr_wager, payoff);
		send_to_char(buf, d->character);
		d->character->gold += payoff;
/* reset the betting info */
		d->character->gladiator = NULL;
		d->character->pcdata->plr_wager = 0;
		payoff = 0;
	    }
	    if (d->character->gladiator != ch
		&& d->character->pcdata->plr_wager >= 1) {
		int tmp = 0;
		sprintf(buf, "You {rlost{x! Your wager: {y%d{x\n\r",
			d->character->pcdata->plr_wager);
		send_to_char(buf, d->character);
		if (d->character->pcdata->plr_wager > d->character->gold) {
		    tmp = d->character->pcdata->plr_wager / 100;
		    d->character->pcdata->plr_wager -= (tmp * 100);
		}
		if (tmp > 0)
		    d->character->platinum -= tmp;
		d->character->gold -= d->character->pcdata->plr_wager;
/* reset the betting info */
		d->character->gladiator = NULL;
		d->character->pcdata->plr_wager = 0;
	    }
	}
    }

/* now move both fighters out of arena and back
to the regular "world" be sure to define 
ROOM_VNUM_AWINNER and ROOM_VNUM_ALOSER */

    stop_fighting(victim, TRUE);
    char_from_room(victim);
    char_to_room(victim, get_room_index(ROOM_VNUM_ALOSER));
    victim->hit = victim->max_hit;
    victim->mana = victim->max_mana;
// affect_strip(victim,gsn_plague);
//    affect_strip(victim,gsn_poison);
//   affect_strip(victim,gsn_blindness);
//  affect_strip(victim,gsn_sleep);
// affect_strip(victim,gsn_curse);
    victim->move = victim->max_move;
    update_pos(victim);
    do_look(victim, "auto");
    stop_fighting(ch, TRUE);
    char_from_room(ch);
    char_to_room(ch, get_room_index(ROOM_VNUM_AWINNER));
    ch->hit = ch->max_hit;
    ch->mana = ch->max_mana;
//   affect_strip(ch,gsn_plague);
//  affect_strip(ch,gsn_poison); 
// affect_strip(ch,gsn_blindness);
//affect_strip(ch,gsn_sleep);
// affect_strip(ch,gsn_curse);
    ch->move = ch->max_move;
    update_pos(ch);
    do_look(ch, "auto");

    if (IS_SET(ch->exbit1_flags, EXBIT1_CHALLENGER))
	REMOVE_BIT(ch->exbit1_flags, EXBIT1_CHALLENGER);
    if (IS_SET(victim->exbit1_flags, EXBIT1_CHALLENGER))
	REMOVE_BIT(victim->exbit1_flags, EXBIT1_CHALLENGER);
    if (IS_SET(victim->exbit1_flags, EXBIT1_CHALLENGED))
	REMOVE_BIT(victim->exbit1_flags, EXBIT1_CHALLENGED);
    if (IS_SET(ch->exbit1_flags, EXBIT1_CHALLENGED))
	REMOVE_BIT(ch->exbit1_flags, EXBIT1_CHALLENGED);

    ch->challenger = NULL;
    ch->challenged = NULL;
    victim->challenger = NULL;
    victim->challenged = NULL;
    REMOVE_BIT(ch->comm, COMM_NOCHANNELS);
    REMOVE_BIT(ch->act, PLR_NORESTORE);
    REMOVE_BIT(victim->comm, COMM_NOCHANNELS);
    REMOVE_BIT(victim->act, PLR_NORESTORE);

    send_to_char("You have been restored.\n\r", ch);
    send_to_char("You have been restored.\n\r", victim);
    arena = FIGHT_OPEN;		/* clear the arena */
    return;
}

void do_kick(CHAR_DATA * ch, char *argument)
{
    CHAR_DATA *victim;

    if (!IS_NPC(ch)) {
	if ((ch->pcdata->tier != 2)
	    && (ch->level < skill_table[gsn_kick].skill_level[ch->class])) {
	    send_to_char
		("You better leave the martial arts to fighters.\n\r", ch);
	    return;
	}
	if ((ch->pcdata->tier == 2)
	    && (ch->level < skill_table[gsn_kick].skill_level[ch->class])
	    && (ch->level < skill_table[gsn_kick].skill_level[ch->clasb])) {
	    send_to_char
		("You better leave the martial arts to fighters.\n\r", ch);
	    return;
	}
    }

    if (IS_NPC(ch) && !IS_SET(ch->off_flags, OFF_KICK))
	return;

    if ((victim = ch->fighting) == NULL) {
	send_to_char("You aren't fighting anyone.\n\r", ch);
	return;
    }

    if (ch->stunned) {
	send_to_char("You're still a little woozy.\n\r", ch);
	return;
    }

    WAIT_STATE(ch, skill_table[gsn_kick].beats);
    if (get_skill(ch, gsn_kick) > number_percent()) {
	int dam;

	dam = number_range(1, ch->level);
	dam = number_range(dam, (ch->level * 1.5));

	damage(ch, victim, dam, gsn_kick, DAM_BASH, TRUE);
	check_improve(ch, gsn_kick, TRUE, 1);
    } else {
	damage(ch, victim, 0, gsn_kick, DAM_BASH, TRUE);
	check_improve(ch, gsn_kick, FALSE, 1);
    }
    return;
}




void do_disarm(CHAR_DATA * ch, char *argument)
{
    CHAR_DATA *victim;
    OBJ_DATA *obj;
    int chance, hth, ch_weapon, vict_weapon, ch_vict_weapon;

    hth = 0;

    if ((chance = get_skill(ch, gsn_disarm)) == 0) {
	send_to_char("You don't know how to disarm opponents.\n\r", ch);
	return;
    }

    if (get_eq_char(ch, WEAR_WIELD) == NULL
	&& ((hth = get_skill(ch, gsn_hand_to_hand)) == 0
	    || (IS_NPC(ch) && !IS_SET(ch->off_flags, OFF_DISARM)))) {
	send_to_char("You must wield a weapon to disarm.\n\r", ch);
	return;
    }

    if ((victim = ch->fighting) == NULL) {
	send_to_char("You aren't fighting anyone.\n\r", ch);
	return;
    }

    if (ch->stunned) {
	send_to_char("You're still a little woozy.\n\r", ch);
	return;
    }

    if ((obj = get_eq_char(victim, WEAR_WIELD)) == NULL) {
	send_to_char("{hYour opponent is not wielding a weapon.{x\n\r",
		     ch);
	return;
    }

    /* find weapon skills */
    ch_weapon = get_weapon_skill(ch, get_weapon_sn(ch));
    vict_weapon = get_weapon_skill(victim, get_weapon_sn(victim));
    ch_vict_weapon = get_weapon_skill(ch, get_weapon_sn(victim));

    /* modifiers */

    /* skill */
    if (get_eq_char(ch, WEAR_WIELD) == NULL)
	chance = chance * hth / 150;
    else
	chance = chance * ch_weapon / 100;

    chance += (ch_vict_weapon / 2 - vict_weapon) / 2;

    /* dex vs. strength */
    chance += get_curr_stat(ch, STAT_DEX);
    chance -= 2 * get_curr_stat(victim, STAT_STR);

    /* level */
    chance += (ch->level - victim->level) * 2;

    chance /= 2;

    /* and now the attack */
    if (number_percent() < chance) {
	if (((chance = get_skill(victim, gsn_grip)) == 0)
	    || (!IS_NPC(victim)
		&& victim->level <
		skill_table[gsn_grip].skill_level[victim->class])) {
	    if (chance == 0 || IS_NPC(victim)) {
		WAIT_STATE(ch, skill_table[gsn_disarm].beats);
		disarm(ch, victim);
		check_improve(ch, gsn_disarm, TRUE, 1);
		return;
	    }
	    if ((victim->pcdata->tier != 2)
		&& (victim->level <
		    skill_table[gsn_grip].skill_level[victim->class])) {
		WAIT_STATE(ch, skill_table[gsn_disarm].beats);
		disarm(ch, victim);
		check_improve(ch, gsn_disarm, TRUE, 1);
		return;
	    }
	    if ((victim->pcdata->tier == 2)
		&& (victim->level <
		    skill_table[gsn_grip].skill_level[victim->class])
		&& (victim->level <
		    skill_table[gsn_grip].skill_level[victim->clasb])) {
		WAIT_STATE(ch, skill_table[gsn_disarm].beats);
		disarm(ch, victim);
		check_improve(ch, gsn_disarm, TRUE, 1);
		return;
	    }
	}
	if (number_percent() > (chance / 5) * 4) {
	    WAIT_STATE(ch, skill_table[gsn_disarm].beats);
	    disarm(ch, victim);
	    check_improve(ch, gsn_disarm, TRUE, 1);
	    check_improve(victim, gsn_grip, FALSE, 1);
	    return;
	}
	check_improve(victim, gsn_grip, TRUE, 1);
    }
    WAIT_STATE(ch, skill_table[gsn_disarm].beats);
    act("{hYou fail to disarm $N.{x", ch, NULL, victim, TO_CHAR);
    act("$n tries to disarm you, but fails.{x", ch, NULL, victim,
	TO_VICT);
    act("$n tries to disarm $N, but fails.{x", ch, NULL, victim,
	TO_NOTVICT);
    check_improve(ch, gsn_disarm, FALSE, 1);
    return;
}



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



void do_slay(CHAR_DATA * ch, char *argument)
{
    CHAR_DATA *victim;
    char arg[MIL];

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

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

    if (ch == victim) {
	send_to_char("Suicide is a mortal sin.\n\r", ch);
	return;
    }

    if (!IS_NPC(victim) && victim->level >= get_trust(ch)) {
	send_to_char("{hYou failed.{c\n\r", ch);
	return;
    }

    if (ch->shadow) {
	ch->shadowing->shadowed = FALSE;
	ch->shadowing->shadower = NULL;
	ch->shadowing = NULL;
	ch->shadow = FALSE;
    }
    if (IS_NPC(victim) || get_trust(ch) >= CREATOR) {
	act("{hYou slay $M in cold blood!{x", ch, NULL, victim, TO_CHAR);
	act("$n slays you in cold blood!{x", ch, NULL, victim, TO_VICT);
	act("$n slays $N in cold blood!{x", ch, NULL, victim,
	    TO_NOTVICT);
	raw_kill(victim, ch);
    } else {
	act("$N wields a sword called '{z{RGodSlayer'!{x", ch, NULL,
	    victim, TO_CHAR);
	act("{hYou wield a sword called '{z{RGodSlayer{h'!{x", ch, NULL,
	    victim, TO_VICT);
	act("$N wields a sword called '{z{RGodSlayer'!{x", ch, NULL,
	    victim, TO_NOTVICT);
	act("$N's slice takes off your left arm!{x", ch, NULL, victim,
	    TO_CHAR);
	act("{hYour slice takes off $n's left arm!{x", ch, NULL, victim,
	    TO_VICT);
	act("$N's slice takes off $n's left arm!{x", ch, NULL, victim,
	    TO_NOTVICT);
	act("$N's slice takes off your right arm!{x", ch, NULL, victim,
	    TO_CHAR);
	act("{hYour slice takes off $n's right arm!{x", ch, NULL, victim,
	    TO_VICT);
	act("$N's slice takes off $n's right arm!{x", ch, NULL, victim,
	    TO_NOTVICT);
	act("$N's slice cuts off both of your legs!{x", ch, NULL, victim,
	    TO_CHAR);
	act("{hYour slice cuts off both of $n's legs!{x", ch, NULL, victim,
	    TO_VICT);
	act("$N's slice cuts off both of $n's legs!{x", ch, NULL, victim,
	    TO_NOTVICT);
	act("$N's slice beheads you!{x", ch, NULL, victim, TO_CHAR);
	act("{hYour slice beheads $n!{x", ch, NULL, victim, TO_VICT);
	act("$N's slice beheads $n!{x", ch, NULL, victim, TO_NOTVICT);
	act("You are DEAD!!!{x", ch, NULL, victim, TO_CHAR);
	act("{h$n is DEAD!!!{x", ch, NULL, victim, TO_VICT);
	act("$n is DEAD!!!{x", ch, NULL, victim, TO_NOTVICT);
	act("A sword called '{z{RGodSlayer{x' vanishes.", ch, NULL, victim,
	    TO_VICT);
	act("A sword called '{z{RGodSlayer{x' vanishes.", ch, NULL, victim,
	    TO_NOTVICT);
	raw_kill(ch, victim);
    }
    return;
}

void do_crush( CHAR_DATA *ch, char *argument )
{
    CHAR_DATA *victim;

    if ( !IS_NPC(ch)
    &&   ch->level < skill_table[gsn_tail].skill_level[ch->class] )
    {
	send_to_char( "Since when did you grow a tail?\n\r", ch );
      return;
    }

    if (IS_NPC(ch) && !IS_SET(ch->off_flags,OFF_TAIL))
	return;

    if ( ( victim = ch->fighting ) == NULL )
    {
	send_to_char( "You aren't fighting anyone.\n\r", ch );
	return;
    }

    WAIT_STATE( ch, skill_table[gsn_tail].beats );
    if ( get_skill(ch,gsn_tail) > number_percent())
    {
	damage(ch,victim,number_range( 1, ch->level ), gsn_tail,DAM_SLASH,TRUE);
	check_improve(ch,gsn_tail,TRUE,1);
    }
    else
    {
	damage( ch, victim, 0, gsn_tail,DAM_SLASH,TRUE);
	check_improve(ch,gsn_tail,FALSE,1);
    }
//	check_killer(ch,victim);
    return;
}

bool check_fade( CHAR_DATA *ch, CHAR_DATA *victim )
{
    int chance;

    if ( !IS_AWAKE(victim) )
	return FALSE;

    chance = get_skill(victim,gsn_fade) / 2;

    if (!can_see(victim,ch))
	chance /= 3;

    if ( number_percent( ) >= chance + victim->level - ch->level )
        return FALSE;
    act( "Your body fades from existence and avoids $n's attack.", ch, NULL, victim, TO_VICT );
    act( "$N's body fades from existence to avoid your attack.", ch, NULL, victim,  TO_CHAR );
    return TRUE;
}

void do_tail( CHAR_DATA *ch, char *argument )
{
    CHAR_DATA *victim;

    if ( !IS_NPC(ch)
    &&   ch->level < skill_table[gsn_tail].skill_level[ch->class] )
    {
	send_to_char( "Since when did you grow a tail?\n\r", ch );
      return;
    }

    if (IS_NPC(ch) && !IS_SET(ch->off_flags,OFF_TAIL))
	return;

    if ( ( victim = ch->fighting ) == NULL )
    {
	send_to_char( "You aren't fighting anyone.\n\r", ch );
	return;
    }

    WAIT_STATE( ch, skill_table[gsn_tail].beats );
    if ( get_skill(ch,gsn_tail) > number_percent())
    {
	damage(ch,victim,number_range( 1, ch->level ), gsn_tail,DAM_SLASH,TRUE);
	check_improve(ch,gsn_tail,TRUE,1);
    }
    else
    {
	damage( ch, victim, 0, gsn_tail,DAM_SLASH,TRUE);
	check_improve(ch,gsn_tail,FALSE,1);
    }
//	check_killer(ch,victim);
    return;
}