kbkmud/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-1996 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 Tartarus/doc/rom.license                  *
***************************************************************************/

/***************************************************************************
*       Tartarus code is copyright (C) 1997-1998 by Daniel Graham          *
*	In using this code you agree to comply with the Tartarus license   *
*       found in the file /Tartarus/doc/tartarus.doc                       *
***************************************************************************/
#include "include.h"

#define HITS (dt==gsn_kick||dt==gsn_lunge||dt==gsn_downstrike||dt==gsn_throw||dt==gsn_crush||dt==gsn_bash||dt==gsn_restrike)

/*
 * Local functions.
 */
void 	check_downstrike 	args( ( CHAR_DATA *ch, CHAR_DATA *victim) );
void 	check_assist 		args( ( CHAR_DATA *ch, CHAR_DATA *victim ) );
void	affect_join_obj		args(	(OBJ_DATA *obj, AFFECT_DATA *af)	);
bool 	check_dodge 		args( ( CHAR_DATA *ch, CHAR_DATA *victim, int dt ) );
bool 	check_questdodge 	args( ( CHAR_DATA *ch, CHAR_DATA *victim, int dt ) );
bool	check_fam		args( ( CHAR_DATA *ch, char *attack	)	);
bool 	check_block 		args( ( CHAR_DATA *ch, CHAR_DATA *victim, int dt ) );
void 	check_killer 		args( ( CHAR_DATA *ch, CHAR_DATA *victim ) );
bool 	check_parry 		args( ( CHAR_DATA *ch, CHAR_DATA *victim, int dt ) );
bool 	check_spin 		args( ( CHAR_DATA *ch, CHAR_DATA *victim, int dt ) );
bool 	check_displacement 	args( ( CHAR_DATA *ch, CHAR_DATA *victim) );
bool 	check_shield_block 	args( ( CHAR_DATA *ch, CHAR_DATA *victim, int dt ) );
void 	dam_message 		args( ( CHAR_DATA *ch, CHAR_DATA *victim, int dam,int dt, bool immune, char *dnoun, bool isPlural, bool showCharName) );
void    death_cry       	args( ( CHAR_DATA *ch ) );
void    group_gain      	args( ( CHAR_DATA *ch, CHAR_DATA *victim ) );
long	quest_credit_compute	args( ( CHAR_DATA *ch, CHAR_DATA *victim, int group_amount ) );
int     xp_compute      	args( ( CHAR_DATA *gch, CHAR_DATA *victim,int group_amount, int glevel ) );
bool    is_safe         	args( ( CHAR_DATA *ch, CHAR_DATA *victim ) );
void    make_corpse     	args( ( CHAR_DATA *killer, CHAR_DATA *ch ) );
void    one_hit         	args( ( CHAR_DATA *ch, CHAR_DATA *victim, int dt ));
void    mob_hit         	args( ( CHAR_DATA *ch, CHAR_DATA *victim, int dt ) );
void    raw_kill        	args( ( CHAR_DATA *ch, CHAR_DATA *victim ) );
void    raw_kill_new		args( ( CHAR_DATA *ch, CHAR_DATA *victim, bool deathCry, bool fLook ) );
void    set_fighting    	args( ( CHAR_DATA *ch, CHAR_DATA *victim ) );
void    disarm          	args( ( CHAR_DATA *ch, CHAR_DATA *victim ) );
void 	check_ground_control 	args( ( CHAR_DATA *ch,CHAR_DATA *victim,int chance,int dam) );
void 	check_follow_through	args( ( CHAR_DATA *ch, CHAR_DATA *victim,int dam) );
bool 	check_roll		args( ( CHAR_DATA *ch,CHAR_DATA *victim,int dt) );
void 	do_strap 		args( ( CHAR_DATA *victim,OBJ_DATA *strap));
bool 	check_unholy_bless 	args( ( CHAR_DATA *ch, CHAR_DATA *victim));
void 	check_cheap_shot 	args( ( CHAR_DATA *ch, CHAR_DATA *victim));
void 	check_parting_blow 	args( ( CHAR_DATA *ch, CHAR_DATA *victim));
bool 	arena;
bool 	check_distance  	args( ( CHAR_DATA *ch, CHAR_DATA *victim, int dt ));
bool 	check_ironhands 	args( ( CHAR_DATA *ch, CHAR_DATA *victim, int dt ));
bool 	check_unarmed_defense 	args( ( CHAR_DATA *ch, CHAR_DATA *victim, int dt ));
char 	*get_dam_message 	args( ( CHAR_DATA *ch, int dt));
char 	* get_attack_noun 	args( ( CHAR_DATA *ch, int dt));
int 	get_attack_number 	args( ( CHAR_DATA *ch, int dt));
bool 	check_dispel		( int dis_level, CHAR_DATA *victim, int sn);
bool 	check_cutoff		( CHAR_DATA *ch, CHAR_DATA *victim);
void 	do_arena_echo		( const char *txt);
int 	check_imperial_training	( CHAR_DATA *ch);
bool 	check_wall_thorns 	args( ( CHAR_DATA *ch));
void 	one_hit_new 		args( ( CHAR_DATA *ch, CHAR_DATA *victim, int dt, bool specials, bool blockable, int addition, int multiplier, char *dnoun));
bool 	damage_new 		args( ( CHAR_DATA *ch, CHAR_DATA *victim, int dam, int dt, int dam_type, bool show, bool blockable, int addition, int multiplier, char *dnoun));
char *  weapon_name_lookup    args( ( int type) );

int 	con_multiplier		args( (int con, int dam) );
//Customizable dnoun, isPlural for singular or plural dverbs, showCharName (i.e. Zornath's blah or The blah), dealtByAffect for DoTs, keep_invisible to avoid revealing the ch
bool    damage_newer		args( ( CHAR_DATA *ch, CHAR_DATA *victim, int dam, int dt, int dam_type, bool show, bool blockable, int addition, int multiplier, char *dnoun, bool isPlural, bool showCharName, AFFECT_DATA *dealtByAffect, bool keep_invisible ) );
int	damage_calculate	args( ( CHAR_DATA *ch, CHAR_DATA *victim, int dt, int dam_type, bool show, bool blockable, int addition, int multiplier) );
bool    check_blademaster     	args( ( CHAR_DATA *ch, CHAR_DATA *victim, int dt ) );
void 	check_restrike 		args( ( CHAR_DATA *ch, CHAR_DATA *victim));
bool 	check_ward_diminution	args( (CHAR_DATA *mage, CHAR_DATA *attacker, int dam, int type, int dt) );
bool	check_unholy_new	args( (CHAR_DATA *ch, CHAR_DATA *victim, OBJ_DATA *obj)	);
bool	is_affected_obj		args( (OBJ_DATA *obj, int sn)			);
void	check_paladin_combo	args( (CHAR_DATA *ch, CHAR_DATA *victim) );
float hitroll_multiplier	args( (CHAR_DATA *ch, CHAR_DATA *victim, float max_multiplier) );
bool check_shield_magnetism	args( ( CHAR_DATA *ch, CHAR_DATA *victim, int dt ));

 /*
 * Control the fights going on.
 * Called periodically by update_handler.
 */
void violence_update( void )
{
    CHAR_DATA *ch;
    CHAR_DATA *ch_next;
    CHAR_DATA *victim;
    int regen, to_heal;
    OBJ_DATA *obj;

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

	/* regen */
	if (!IS_NPC(ch))
	{
	    regen = get_skill(ch,gsn_regeneration);
	    to_heal = (ch->max_hit - ch->hit);

	    if (number_percent() <=  ch->level*2)
	    {
		if ((ch->hit < ch->max_hit) && ch->noregen_dam < to_heal && number_percent() < regen)
		{
		    if (number_percent() < 3)
			check_improve(ch,gsn_regeneration,TRUE,4);
		    ch->hit += number_range(1,3);
		}
	    }
	}

	//////// Begin Lich Quaff Potion Time Interval Messages ////////
	if (is_affected(ch,skill_lookup("lich elixir affect")))
	{
		AFFECT_DATA *lichAffect = affect_find(ch->affected,skill_lookup("lich elixir affect"));
		char buf[MSL];

		if (lichAffect->level == 59)
		{
			if (lichAffect->modifier == 8)
			{
				act("{BYou feel the elixir eating at your internal organs.{x",ch,0,0,TO_CHAR);
				lichAffect->modifier--;
			}
			else if (lichAffect->modifier == 6)
			{
				act("{BThin stripes of blackened energy play around you.{x",ch,0,0,TO_CHAR);
				lichAffect->modifier--;
			}
			else if (lichAffect->modifier == 4)
			{
				act("{BYour limbs, muscles, and bones seem to grow, the pain of transformation crippling you.{x",ch,0,0,TO_CHAR);
				lichAffect->modifier--;
			}
			else if (lichAffect->modifier == 2)
			{
				act("{BChunks of skin fall from your body, and suddenly the pain is gone.",ch,0,0,TO_CHAR);
				affect_strip(ch,skill_lookup("lich elixir affect"));
				ch->pcdata->learned[skill_lookup("minion tactics")] = 1;
     				ch->pcdata->learned[skill_lookup("minion sanc")] =1;
     				ch->pcdata->learned[skill_lookup("minion flight")] =1;
     				ch->pcdata->learned[skill_lookup("minion sneak")] =1;
     				ch->pcdata->learned[skill_lookup("minion recall")] =1;
     				ch->pcdata->learned[skill_lookup("minion haste")] =1;
     				ch->pcdata->learned[skill_lookup("minion trans")] =1;
				ch->pcdata->learned[skill_lookup("ritual of abominations")] = 1;
				ch->pcdata->learned[skill_lookup("vampiric touch")] = 1;
    
     				ch->race = race_lookup("lich");

    				ch->perm_stat[STAT_STR]=pc_race_table[ch->race].max_stats[STAT_STR];
        			ch->perm_stat[STAT_INT]=pc_race_table[ch->race].max_stats[STAT_INT];
       				ch->perm_stat[STAT_WIS]=pc_race_table[ch->race].max_stats[STAT_WIS];
        			ch->perm_stat[STAT_DEX]=pc_race_table[ch->race].max_stats[STAT_DEX];
        			ch->perm_stat[STAT_CON]=pc_race_table[ch->race].max_stats[STAT_CON];
    				ch->mod_stat[STAT_STR]=0;
    				ch->mod_stat[STAT_INT]=0;
    				ch->mod_stat[STAT_WIS]=0;
    				ch->mod_stat[STAT_DEX]=0;
    				ch->mod_stat[STAT_CON]=0;
    				sprintf(buf, "{RThe power of the undead courses through your veins as your soul becomes one with the Prime Negative Plane.{x\n\r");
				send_to_char(buf,ch);
				ch->ghost += 10;
			}
			else
				lichAffect->modifier--;
		}

		else if (lichAffect->level == 60)
		{
			if (lichAffect->modifier == 8)
			{
				act("{BYou feel the elixir eating at your internal organs.{x",ch,0,0,TO_CHAR);
				lichAffect->modifier--;
			}
			else if (lichAffect->modifier == 6)
			{
				act("{BThin stripes of blackened energy play around you.{x",ch,0,0,TO_CHAR);
				lichAffect->modifier--;
			}
			else if (lichAffect->modifier == 4)
			{
				act("{BYour limbs, muscles, and bones seem to grow, the pain of transformation crippling you.{x",ch,0,0,TO_CHAR);
				lichAffect->modifier--;
			}
			else if (lichAffect->modifier == 2)
			{

				act("{RJust as quickly, your body falls to the ground, the power leaving you.{x",ch,0,0,TO_CHAR);
				affect_strip(ch,skill_lookup("lich elixir affect"));
				if (!IS_IMMORTAL(ch))
					age_death(ch);
			}
			else
				lichAffect->modifier--;
		}
	}
	//////// End Lich Quaff Potion Time Interval Messages ////////

	if (ch->regen_rate != 0)
	{
	    if (ch->regen_rate > 0)
	  	regen = number_range(1,ch->regen_rate);
	    else
		regen = number_range(ch->regen_rate, -1);
	
		if (ch->regen_rate > 0) {
		    ch->hit = UMIN(ch->hit + regen,ch->max_hit);
			ch->mana = UMIN(ch->mana + regen / 2, ch->max_mana);
			ch->move = UMIN(ch->move + regen / 2, ch->max_move);
		}
		else {
		    ch->hit = UMAX(ch->hit + regen,0);
			ch->mana = UMAX(ch->mana + regen / 2, 0);
			ch->move = UMAX(ch->move + regen / 2, 0);
	    }
	}

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

	if (IS_NPC(ch) && (!IS_NPC(ch->fighting))
	&& !IS_SET(ch->act,ACT_NO_TRACK)
	&& !IS_AFFECTED(ch,AFF_CHARM)
	&& !IS_SET(ch->act,ACT_IS_HEALER)
	&& !IS_SET(ch->act,ACT_BANKER))
		ch->last_fought = ch->fighting;

	update_pc_last_fight(ch,ch->fighting);

        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;

	for (obj = ch->carrying;obj != NULL; obj = obj->next_content)
 	   if (IS_SET(obj->progtypes,IPROG_FIGHT))
		(obj->pIndexData->iprogs->fight_prog) (obj,ch);

	if (IS_SET(ch->progtypes,MPROG_FIGHT) && (ch->wait <= 0))
	   	(ch->pIndexData->mprogs->fight_prog) (ch,victim);

        /*
         * Fun for the whole family!
         */
        check_assist(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_NPC(rch) && rch->ghost > 0)
		continue;

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

	    if (IS_NPC(rch) && (IS_AFFECTED(rch,AFF_CHARM)) && is_same_group(rch,ch) )
 	    {
		multi_hit(rch,victim,TYPE_UNDEFINED);
		continue;
	    }


            /* 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,"screams and attacks!");
            	multi_hit(rch,victim,TYPE_UNDEFINED);
            	continue;
            }

	    /* PCs next */
            if ( !IS_NPC(ch) || IS_AFFECTED(ch,AFF_CHARM))
            {

            	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,"screams and attacks!");
                    	multi_hit(rch,target,TYPE_UNDEFINED);
                    }
            	}
            }
  	}
    }
}


/*
 * Do one group of attacks.
 */
void multi_hit( CHAR_DATA *ch, CHAR_DATA *victim, int dt )
{
    int chance, dual_chance;
    char buf[MAX_STRING_LENGTH];

    if (is_affected(ch,gsn_timestop))
    {
	if (ch->fighting != NULL)
		ch->fighting = NULL;
	return;
    }

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

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

    if (ch->level == MAX_LEVEL)
	ch->daze = 0;

    if(ch->in_room!=victim->in_room)
    {
	ch->fighting		= NULL;
	victim->fighting	= NULL;
	ch->position		= POS_STANDING;
	victim->position	= POS_STANDING;
	update_pos(ch);
	update_pos(victim);
	return;
    }

    if(is_affected(victim,gsn_snare) && number_percent()<80 && victim->fighting!=NULL)
    {
	act("In the chaos of combat, the snare holding $n comes loose.",victim,0,0,TO_ROOM);
	act("In the chaos of combat, the snare holding you comes loose.",victim,0,0,TO_CHAR);
	affect_strip(victim,gsn_snare);
    }


    if (ch->position < POS_RESTING)
        return;

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

    if (IS_NPC(victim) && IS_CABAL_GUARD(victim) && !IS_NPC(ch) && (ch->pcdata->newbie==TRUE || ch->ghost > 0))
    {
		int attempt, door;
    		for ( attempt = 0; attempt < 6; attempt++ )
    		{
			EXIT_DATA *pexit;
    			ROOM_INDEX_DATA *was_in;
			door = number_door( );
			was_in = ch->in_room;
			if ( ( pexit = was_in->exit[door] ) == 0 || pexit->u1.to_room == NULL || pexit->u1.to_room->cabal>0)
	    			continue;
			act("$N growls with rage and throws you out of the room!",ch,0,victim,TO_CHAR);
			act("$N growls with rage and throws $n out of the room!",ch,0,victim,TO_ROOM);
        		char_from_room(ch);
        		char_to_room(ch, pexit->u1.to_room);
			do_look(ch,"auto");
			ch->ghost = 1;
			stop_fighting( victim, TRUE );
			return;
		}
    }

    if (IS_NPC(victim) && IS_CABAL_GUARD(victim) && !IS_NPC(ch) && ch->cabal==victim->cabal)
    {
	sprintf(buf,"How DARE you attack me, %s!",ch->name);
	do_cb(victim,buf);
    }

    // First hit.
    one_hit( ch, victim, dt );

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

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

    if (IS_AFFECTED(ch,AFF_HASTE) && (IS_NPC(ch) || get_skill(ch,gsn_third_attack)>5))
        one_hit(ch,victim,dt);

    chance = get_skill(ch,gsn_second_attack)/2 + GET_HITROLL(ch) / 5;
    dual_chance = get_skill(ch,gsn_dual_wield)/2 + GET_HITROLL(ch) / 5;

    if (is_affected(ch,gsn_maehslin) && number_percent() < 20)
    {
	act("The amber aura around $n intenses and their movements become more fluid!",ch,0,victim,TO_VICT);
    	act("$n's amber aura intenses and their movements become more fluid!" ,ch,0,0,TO_NOTVICT);
    	act("Your amber aura intenses and your movements become more fluid!",ch,0,0,TO_CHAR);
	one_hit_new(ch,victim,dt,HIT_NOSPECIALS,HIT_UNBLOCKABLE,HIT_NOADD,HIT_NOMULT,NULL);
    }

//////////////////////////// Begin Critical Strike Check /////////////////////////////////
	if (number_percent() < ch->pcdata->learned[skill_lookup("critical strike")] / 6)
	{
		if (is_wielded(ch,WEAPON_SWORD,WIELD_PRIMARY) || is_wielded(ch,WEAPON_AXE,WIELD_PRIMARY) || is_wielded(ch,WEAPON_DAGGER,WIELD_PRIMARY) || is_wielded(ch,WEAPON_SPEAR,WIELD_PRIMARY) || is_wielded(ch,WEAPON_POLEARM,WIELD_PRIMARY) || is_wielded(ch,WEAPON_EXOTIC,WIELD_PRIMARY))
		{	
			act("You deliver a critical strike!",ch,0,0,TO_CHAR);
			act("$n delivers a critical strike!",ch,0,0,TO_ROOM);
			one_hit_new(ch,victim,dt,HIT_NOSPECIALS,HIT_UNBLOCKABLE,HIT_NOADD,175,"critical strike");
			if (!is_affected(victim,skill_lookup("critical strike")))
			{
				act("$n's critical strike tears open an immense gash in your body!",ch,0,victim,TO_VICT);
				act("$n's critical strike tears open an immense gash in $N's body!",ch,0,victim,TO_NOTVICT);
				act("Your critical strike tears open an immense gash in $N's body!",ch,0,victim,TO_CHAR);
				AFFECT_DATA bleeding;
				init_affect(&bleeding);
				bleeding.aftype = AFT_SKILL;
				bleeding.type = skill_lookup("critical strike");
				bleeding.affect_list_msg = str_dup("induces major bleeding");
				bleeding.owner_name = str_dup(ch->original_name);
				bleeding.duration = 3;
				if (is_wielded(ch,WEAPON_SWORD,WIELD_PRIMARY))
					bleeding.level = 3;
				else if (is_wielded(ch,WEAPON_AXE,WIELD_PRIMARY))
					bleeding.level = 4;
				else if (is_wielded(ch,WEAPON_DAGGER,WIELD_PRIMARY))
					bleeding.level = 2;
				else if (is_wielded(ch,WEAPON_POLEARM,WIELD_PRIMARY))
					bleeding.level = 5;
				else if (is_wielded(ch,WEAPON_SPEAR,WIELD_PRIMARY))
					bleeding.level = 6;
				else
					bleeding.level = 10;
				affect_to_char(victim,&bleeding);
			}
		}	
		else if (is_wielded(ch,WEAPON_FLAIL,WIELD_PRIMARY) || is_wielded(ch,WEAPON_MACE,WIELD_PRIMARY) || is_wielded(ch,WEAPON_STAFF,WIELD_PRIMARY) || is_wielded(ch,WEAPON_WHIP,WIELD_PRIMARY))
		{	
			act("You deliver a critical strike!",ch,0,0,TO_CHAR);
			act("$n delivers a critical strike!",ch,0,0,TO_ROOM);
			one_hit_new(ch,victim,dt,HIT_NOSPECIALS,HIT_UNBLOCKABLE,HIT_NOADD,175,"critical strike");
			if (!is_affected(victim,skill_lookup("critical strike")))
			{
				act("You feel your bones shatter under the force of $n's critical strike!",ch,0,victim,TO_VICT);
				act("$n's critical strike shatters $N's bones!",ch,0,victim,TO_NOTVICT);
				act("Your critical strike shatters $N's bones!",ch,0,victim,TO_CHAR);
				AFFECT_DATA boneshatter;
				init_affect(&boneshatter);
				boneshatter.aftype = AFT_SKILL;
				boneshatter.type = skill_lookup("critical strike");
				boneshatter.duration = 3;
				boneshatter.level = 1;
				boneshatter.owner_name = str_dup(ch->original_name);
				boneshatter.location = APPLY_STR;
				if (is_wielded(ch,WEAPON_FLAIL,WIELD_PRIMARY))
					boneshatter.modifier = -3;
				else if (is_wielded(ch,WEAPON_MACE,WIELD_PRIMARY))
					boneshatter.modifier = -4;
				else if (is_wielded(ch,WEAPON_STAFF,WIELD_PRIMARY))
					boneshatter.modifier = -3;
				else if (is_wielded(ch,WEAPON_WHIP,WIELD_PRIMARY))
					boneshatter.modifier = -2;
				else
					boneshatter.modifier = -1;
				affect_to_char(victim,&boneshatter);
				
				boneshatter.location = APPLY_DEX;
				if (is_wielded(ch,WEAPON_FLAIL,WIELD_PRIMARY))
					boneshatter.modifier = -3;
				else if (is_wielded(ch,WEAPON_MACE,WIELD_PRIMARY))
					boneshatter.modifier = -4;
				else if (is_wielded(ch,WEAPON_STAFF,WIELD_PRIMARY))
					boneshatter.modifier = -3;
				else if (is_wielded(ch,WEAPON_WHIP,WIELD_PRIMARY))
					boneshatter.modifier = -2;
				else
					boneshatter.modifier = -1;
				affect_to_char(victim,&boneshatter);
			}
		}
	}
//////////////////////////// End Critical Strike Check /////////////////////////////////			
			
//////////////////////////// Begin Anaconda Stance Fight Check /////////////////////////////////
    AFFECT_DATA *anacondaCheck = affect_find(ch->affected,gsn_stance), 
                *poisonCheck = affect_find(victim->affected,gsn_poison), 
		anacondaPoison;

    int poisonLevel = 51, poisonDuration = 3, strLoss = -1;

    if (anacondaCheck != NULL)
    {
	if (anacondaCheck->level == 5)
	{
		if (number_percent() < 15)
		{
				act("$n strikes forward suddenly, piercing through your defenses!",ch,0,victim,TO_VICT);
				act("$n strikes forward suddenly, piercing through $N's defenses!",ch,0,victim,TO_NOTVICT);
				act("With the speed of an Anaconda, you penetrate $N's defenses!",ch,0,victim,TO_CHAR);
				one_hit_new(ch,victim,TYPE_UNDEFINED,HIT_NOSPECIALS,HIT_UNBLOCKABLE,HIT_NOADD,150,"serpent strike");
				if (poisonCheck != NULL)
				{
					if (!str_cmp(poisonCheck->name,"anaconda venom"))
					{
						poisonLevel = poisonCheck->level + 2;
						if (poisonCheck->duration < 20)
							poisonDuration = poisonCheck->duration + 3;
						else poisonDuration = poisonCheck->duration;
						strLoss = poisonCheck->modifier - 1;
						if (poisonLevel > 100)
							poisonLevel = 100;
						if (poisonDuration > 100)
							poisonDuration = 100;
						if (strLoss > 100)
							strLoss = 100;
						act("You feel your body tingle as poison seeps into your veins.",ch,0,victim,TO_VICT);
						act("$N looks very sick.",ch,0,victim,TO_NOTVICT);
						act("You release poison into $N's veins!",ch,0,victim,TO_CHAR);
						affect_remove(victim,poisonCheck);
						init_affect(&anacondaPoison);
						anacondaPoison.where 		= TO_AFFECTS;
						anacondaPoison.aftype		= AFT_SKILL;
						anacondaPoison.type		= gsn_poison;
						anacondaPoison.level		= poisonLevel;
						anacondaPoison.duration		= poisonDuration;
						anacondaPoison.name		= str_dup("anaconda venom");
						anacondaPoison.location		= APPLY_STR;
						anacondaPoison.modifier		= strLoss;
						anacondaPoison.owner_name		= str_dup(ch->original_name);
						anacondaPoison.bitvector	= AFF_POISON;
						affect_to_char(victim,&anacondaPoison);
					
					}
				}
				else if (poisonCheck == NULL)
				{
					act("You feel your body tingle as poison seeps into your veins.",ch,0,victim,TO_VICT);
					act("$N looks very sick.",ch,0,victim,TO_ROOM);
					act("You release poison into $N's veins!",ch,0,victim,TO_CHAR);
					init_affect(&anacondaPoison);
					anacondaPoison.where 		= TO_AFFECTS;
					anacondaPoison.aftype		= AFT_SKILL;
					anacondaPoison.type		= gsn_poison;
					anacondaPoison.level		= poisonLevel;
					anacondaPoison.duration		= poisonDuration;
					anacondaPoison.name		= str_dup("anaconda venom");
					anacondaPoison.modifier		= strLoss;
					anacondaPoison.owner_name		= str_dup(ch->original_name);
					affect_to_char(victim,&anacondaPoison);
				}
		}
	}
    }
//////////////////////////// End Anaconda Stance Fight Check /////////////////////////////////

    if (check_darkshout(ch) == DARKSHOUT_MEPHISTOPHELES && number_percent() < 40)
    {
        damage_new(ch, victim, 250, TYPE_UNDEFINED, DAM_FIRE, TRUE, HIT_UNBLOCKABLE, HIT_NOADD, HIT_NOMULT, "infernal wrath");
    }

    if (is_affected(ch,gsn_shield_of_truth) && get_eq_char(ch,WEAR_SHIELD) != NULL)
    {
	int healingCheck = number_percent();
	
	if (healingCheck <= 65)
	{
		act("The power of your god flows through your body, revitalizing you.",ch,0,0,TO_CHAR);
		act("$n looks more at peace as his wounds seem to heal.",ch,0,0,TO_ROOM);
	}
	if (healingCheck < 45)
		(*skill_table[skill_lookup("cure serious")].spell_fun) (skill_lookup("cure serious"), 51, ch, ch, TAR_CHAR_DEFENSIVE);
	if (healingCheck >= 45 && healingCheck < 57)
		(*skill_table[skill_lookup("cure critical")].spell_fun) (skill_lookup("cure serious"), 51, ch, ch, TAR_CHAR_DEFENSIVE);
	if (healingCheck >= 57 && healingCheck <= 65)
		(*skill_table[skill_lookup("heal")].spell_fun) (skill_lookup("heal"), 51, ch, ch, TAR_CHAR_DEFENSIVE);
    }

    if (IS_AFFECTED(ch,AFF_HASTE))
    {
	chance*=1.25;
	dual_chance*=1.25;
    }

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

    if (check_imperial_training(ch) == IMPERIAL_DEFENSE)
    {
	chance /= 2.5;
	dual_chance /= 2.5;
    }

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

    if (get_eq_char(ch,WEAR_DUAL_WIELD) != NULL && ch->pcdata->learned[gsn_second_attack] > 10)
    {
	if (number_percent( ) < dual_chance)
	{
	    one_hit(ch,victim,gsn_dual_wield);
	    check_improve(ch,gsn_dual_wield,TRUE,3);
	    if (ch->fighting != victim)
		return;
	} else {
	    check_improve(ch,gsn_dual_wield,FALSE,3);
	}
    }

    chance = get_skill(ch,gsn_third_attack)/4 + GET_HITROLL(ch) / 10;

    if (IS_AFFECTED(ch,AFF_SLOW))
        chance = 0;
    if (IS_AFFECTED(ch,AFF_HASTE))
        chance*=1.3;
    if ( number_percent( ) < chance )
    {
        one_hit( ch, victim, dt );
        check_improve(ch,gsn_third_attack,TRUE,6);
        if ( ch->fighting != victim )
            return;
    }

    dual_chance = get_skill(ch,gsn_dual_wield)/4 + GET_HITROLL(ch) / 10;
    if (IS_AFFECTED(ch,AFF_HASTE))
        dual_chance*=1.2;

    if (get_eq_char(ch,WEAR_DUAL_WIELD) != NULL && ch->pcdata->learned[gsn_third_attack] > 10)
    {
	if (number_percent( ) < dual_chance)
	{
	    one_hit(ch,victim,gsn_dual_wield);
	    check_improve(ch,gsn_dual_wield,TRUE,3);
	    if (ch->fighting != victim)
		return;
	} else {
	    check_improve(ch,gsn_dual_wield,FALSE,3);
	}
    }

    chance = get_skill(ch,gsn_fourth_attack)/5 + GET_HITROLL(ch) / 15;

    if (IS_AFFECTED(ch,AFF_SLOW))
	chance /= 2;
    if (IS_AFFECTED(ch,AFF_HASTE))
        chance*=1.3;
    if ( number_percent() < chance )
    {
	one_hit( ch, victim, dt );
	check_improve(ch,gsn_fourth_attack,TRUE,6);
	if (ch->fighting != victim )
	    return;
    }

    dual_chance = get_skill(ch,gsn_dual_wield)/4 + GET_HITROLL(ch) / 15;
    if (IS_AFFECTED(ch,AFF_HASTE))
        dual_chance*=1.2;
    if (get_eq_char(ch,WEAR_DUAL_WIELD) != NULL && ch->pcdata->learned[gsn_fourth_attack] > 10)
    {
	if (number_percent( ) < dual_chance)
	{
	    one_hit(ch,victim,gsn_dual_wield);
	    check_improve(ch,gsn_dual_wield,TRUE,6);
	    if (ch->fighting != victim)
		return;
	} else {
	    check_improve(ch,gsn_dual_wield,FALSE,5);
	}
    }
	
	int off_chance = 3 * get_skill(ch,skill_lookup("unarmed offense")) / 4;
	if (IS_AFFECTED(ch,AFF_HASTE)) off_chance = 3 * off_chance / 2;
	if (check_imperial_training(ch) == IMPERIAL_OFFENSE) off_chance = 5 * off_chance / 4;
	
	if (get_eq_char(ch,WEAR_WIELD) == NULL && get_eq_char(ch,WEAR_DUAL_WIELD) == NULL &&
		ch->pcdata->learned[skill_lookup("unarmed offense")] > 10) {
		if (number_percent() < off_chance) {
			one_hit(ch,victim,dt);
			check_improve(ch,skill_lookup("unarmed offense"),TRUE,3);
			if (number_percent() < off_chance / 2) {
				one_hit(ch,victim,dt);
				check_improve(ch,skill_lookup("unarmed offense"),TRUE,5);
			}
		}
		else check_improve(ch,skill_lookup("unarmed offense"),FALSE,3);
	}

    if (is_affected(victim,gsn_blackjack)) 
    {
	affect_strip(victim,gsn_blackjack);
	return;
    }

    /* imperial training */
    if (check_imperial_training(ch) == IMPERIAL_OFFENSE && get_skill(ch,gsn_third_attack)>80)
	    one_hit(ch, victim, dt);

    int extraAttacks;
    if(ch->numAttacks > 0)
	for (extraAttacks = 1;extraAttacks<=ch->numAttacks;extraAttacks++)
		if (extraAttacks <= 20)
			one_hit(ch,victim,dt);

    return;
}

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

    	if (ch->fighting != victim)
        	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);
       	 	}
    	}

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

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

    	chance = get_skill(ch,gsn_second_attack)/2;
    	dual_chance = ch->level*2/3;

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

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

    	if (IS_AFFECTED(ch,AFF_HASTE))
		dual_chance *= 6/4;

    	if (number_percent() < dual_chance && get_eq_char(ch,WEAR_DUAL_WIELD) != NULL)
    	{
		one_hit(ch,victim,gsn_dual_wield);
		if (ch->fighting != victim)
			return;
    	}

    	chance = get_skill(ch,gsn_third_attack)/4;
     	dual_chance *= 2/3;

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

    	if (IS_AFFECTED(ch,AFF_HASTE))
		dual_chance *= 3/2;

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

    	if (number_percent() < dual_chance && get_eq_char(ch,WEAR_DUAL_WIELD) != NULL)
    	{
		one_hit(ch,victim,gsn_dual_wield);
		if (ch->fighting != victim)
			return;
    	}

    	if (ch->pIndexData->vnum >= 28000 && ch->pIndexData->vnum <= 28011)
    	{
		int hits=number_range(1,2);
		int x;

		for (x=0; x<hits; x++)	
		{
	    		one_hit(ch,victim,dt);
	    		if (ch->fighting != victim)
	 			return;
		}
    	}

    	if (ch->wait > 0)
        	return;

    	/* now for the skills */
    	number = number_range(0,9);

    	switch(number)
    	{
    	case (0) :
        if (IS_SET(ch->off_flags,OFF_BASH))
            do_bash(ch,"");
	else if (IS_SET(ch->off_flags,OFF_TAIL))
	    do_tail(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_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,"");
        }
	else if (IS_SET(ch->off_flags,OFF_UNDEAD_DRAIN))
		do_undead_drain(ch,"");
	break;
    	case (9) :
	if ( IS_SET(ch->off_flags,OFF_UNDEAD_DRAIN))
	{
		do_undead_drain(ch,"");
	}
	break;
    	}

    int extraAttacks;
    if(ch->numAttacks > 0)
	for (extraAttacks = 1;extraAttacks<=ch->numAttacks;extraAttacks++)
		if(extraAttacks <= 20)
			one_hit(ch,victim,dt);
}


/*
 * Hit one guy once.
 */
void one_hit(CHAR_DATA *ch, CHAR_DATA *victim, int dt)
{
	one_hit_new(ch,victim,dt,HIT_SPECIALS,HIT_BLOCKABLE,HIT_NOADD,HIT_NOMULT,NULL);
}

void one_hit_new( CHAR_DATA *ch, CHAR_DATA *victim, int dt, bool specials, bool blockable, int addition, int multiplier, char *dnoun)
{
    OBJ_DATA *wield;
    int dam, mdam, fchance, tchance, diceroll, diceroll2 = 0, sn, skill, dam_type, tmp_dt, tdt=dt;
    bool result, truestrike = FALSE, exeresult;
    const char *attack;
    char buf1[MAX_STRING_LENGTH], buf2[MAX_STRING_LENGTH], buf3[MAX_STRING_LENGTH];
	
    /* just in case */
    if (victim == ch || ch == NULL || victim == NULL)
        return;

    if(dt == TYPE_TRUESTRIKE)
    {
	truestrike = TRUE;
	dt = TYPE_UNDEFINED;
    }

    if ( victim->position == POS_DEAD || (ch->in_room != victim->in_room))
        return;

    if (is_safe(ch,victim))
	return;

    /*
     * Figure out the type of damage message.
     */
    wield = get_eq_char( ch, WEAR_WIELD );

    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(is_affected(ch,gsn_executioner) && number_percent()<5 && specials==TRUE && tdt==TYPE_UNDEFINED)
    {
      	act("$n darts forward and gracefully strikes you!",ch,0,victim,TO_VICT);
     	act("$n darts forward and gracefully strikes $N!",ch,0,victim,TO_NOTVICT);
      	act("Moving fluidly, you dart forward and gracefully strike $N!",ch,0,victim,TO_CHAR);
		one_hit_new( ch, victim, TYPE_UNDEFINED, HIT_NOSPECIALS, HIT_UNBLOCKABLE, HIT_NOADD, HIT_NOMULT, NULL);
		return;
    }
    if(is_affected(victim,gsn_executioner) && number_percent()<7 && dt!=gsn_flurry && dt!=gsn_drum && specials==TRUE)
    {
        act("$n smoothly redirects $N's attack, unleashing a deadly riposte!",victim,0,ch,TO_NOTVICT);
        act("You smoothly redirect $N's attack, and unleash a deadly riposte!",victim,0,ch,TO_CHAR);
        act("$n smoothly redirects your attack, unleashing a deadly riposte!",victim,0,ch,TO_VICT);
		one_hit_new( victim, ch, TYPE_UNDEFINED, HIT_NOSPECIALS, HIT_UNBLOCKABLE, HIT_NOADD, HIT_NOMULT, NULL);
		return;
    }
	
    if (IS_NPC(ch) && ch->pIndexData->vnum == 3011)
	truestrike = TRUE;

    if(get_skill(victim,gsn_backfist) !=0 && specials==TRUE)
    {
		if (number_percent() < (get_skill(victim,gsn_backfist)/4) && count_hands(ch) < 2)
		{
			act("$n steps in quickly to strike $N with a quick backfist!",victim,0,ch,TO_NOTVICT);
			act("You step in quickly to strike $N with a quick backfist!",victim,0,ch,TO_CHAR);
			act("$n steps in quickly to strike you with a quick backfist!",victim,0,ch,TO_VICT);
			exeresult = damage( victim, ch, GET_DAMROLL(victim), gsn_backfist, DAM_BASH, TRUE );
			check_improve(victim,gsn_backfist,TRUE,2);
		}
		else
		{
			check_improve(victim,gsn_backfist,FALSE,5);
		}
    }

    if(is_affected(victim,gsn_shield_of_redemption) && get_eq_char(victim,WEAR_SHIELD) != NULL && number_percent() > 40)
	damage_new(victim, ch, number_range(20,30), TYPE_UNDEFINED, DAM_HOLY, TRUE, HIT_UNBLOCKABLE, HIT_NOADD, HIT_NOMULT, "shield of redemption");

    if (wield != NULL)
	dam_type = attack_table[wield->value[3]].damage;
    else
	dam_type = attack_table[ch->dam_type].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);

    if (dt == gsn_dual_wield)
    {
		wield = get_eq_char( ch, WEAR_DUAL_WIELD );
        tmp_dt = TYPE_HIT;
        if ( wield != NULL && wield->item_type == ITEM_WEAPON )
            tmp_dt += wield->value[3];
        else 
            tmp_dt += ch->dam_type;

    	if (tmp_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;

    	if (wield == NULL)		
			sn = -1;
	
		else switch (wield->value[0])
	    	{
		    default:			sn = -1;		break;
		    case (WEAPON_SWORD):	sn = gsn_sword;		break;
		    case (WEAPON_DAGGER):	sn = gsn_dagger;	break;
		    case (WEAPON_SPEAR):	sn = gsn_spear;		break;
		    case (WEAPON_MACE):		sn = gsn_mace;		break;
		    case (WEAPON_AXE):		sn = gsn_axe;		break;
		    case (WEAPON_FLAIL):	sn = gsn_flail;		break;
		    case (WEAPON_WHIP):		sn = gsn_whip;		break;
		    case (WEAPON_POLEARM):	sn = gsn_polearm;	break;
	    	}
	    	skill = 10 + get_weapon_skill(ch,sn);
    }

    if(truestrike)
    	dam_type = DAM_TRUESTRIKE;

    if(victim->cabal==CABAL_KNIGHT && get_skill(victim,skill_lookup("blademaster"))>0 && specials==TRUE)
    {
	tchance=3+((get_skill(victim,skill_lookup("blademaster"))-75)/3);
	if(is_affected(victim,AFF_HASTE))
		tchance+=2;
	if(is_affected(victim,AFF_SLOW))
		tchance-=5;
	if(number_percent()<tchance)
	{
		attack = get_attack_noun(ch,dt);
		if(cabal_down_new(victim,CABAL_KNIGHT,FALSE))
			return;
	  	sprintf(buf1,"$n parries $N's %s, and skillfully unleashes an attack of $s own!",attack);
        	act(buf1,victim,0,ch,TO_NOTVICT);
	  	sprintf(buf2,"You parry $N's %s and skillfully unleash an attack of your own!",attack);
	  	act(buf2,victim,0,ch,TO_CHAR);
        	sprintf(buf3,"$n parries your %s and skillfully unleashes an attack of $s own!",attack);
	  	act(buf3,victim,0,ch,TO_VICT);
		attack = get_attack_noun(victim,dt);
	  	one_hit_new( victim, ch, dt, HIT_NOSPECIALS, HIT_UNBLOCKABLE, HIT_NOADD, HIT_NOMULT, str_dup(attack));
		check_improve(victim, skill_lookup("blademaster"),TRUE,5);
	  	return;
	}
    }

    if((IS_NPC(victim) && IS_SET(victim->off_flags,OFF_FADE)) || is_affected(victim,gsn_displacement))
    {
	fchance = 25 + (victim->level - ch->level);
	if(IS_AFFECTED(ch,AFF_HASTE))
		fchance-=8;
	if(IS_AFFECTED(victim,AFF_HASTE))
		fchance+=5;
	if(number_percent()<fchance)
	{
	    attack = get_attack_noun(ch,dt);
	    sprintf(buf1,"$N's %s lands on empty air near $n.",attack);
	    act(buf1,victim,0,ch,TO_NOTVICT);
	    sprintf(buf2,"$N's %s lands on empty air near you.",attack);
            act(buf2,victim,0,ch,TO_CHAR);
	    sprintf(buf3,"Your %s lands on empty air near $n.",attack);
            act(buf3,victim,0,ch,TO_VICT);

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

	    return;
	}
    }


    /*
     * Hit.
     * Calc damage.
     */
    if ( IS_NPC(ch) && (!ch->pIndexData->new_format || wield == NULL))
    {
        if (!ch->pIndexData->new_format)
        {
	    dam = number_range( ( ch->level + ch->drain_level) / 2, (ch->drain_level + 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->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;

	    if (wield->level - (ch->drain_level + ch->level) >= 35)
		dam = (dam*6)/10;
	    else if (wield->level - (ch->drain_level + ch->level) >= 25)
		dam = (dam*7)/10;
	    else if (wield->level - (ch->drain_level + ch->level) >= 15)
		dam = (dam*8)/10;
	    else if (wield->level - (ch->drain_level + ch->level) >= 5)
		dam = (dam*9)/10;

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

                if ((percent = number_percent()) <= (skill / 8))
                    dam *= 1.2;
            }
        }
        else
       	    dam = number_range( 1 + GET_DAMROLL(ch) / 12 + 7 * skill/100, (ch->level - 5) * skill/100);
    }

    /*
     * Bonuses.
     */

    dam += (ch->drain_level + ch->level)/8;

    if ( get_skill(ch,gsn_enhanced_damage) > 0 )
    {
        diceroll = number_percent();
	if (get_skill(ch,gsn_enhanced_damage_two) > 0)
	{
		diceroll2 = number_percent();
	
		if (diceroll2 < get_skill(ch,gsn_enhanced_damage_two) && diceroll2 < get_skill(ch,gsn_enhanced_damage) )
		{
			check_improve(ch,gsn_enhanced_damage_two,TRUE,5);
			diceroll2 = diceroll2 + 5;
			diceroll = diceroll2;
		}
	}
	if (get_skill(ch,gsn_enhanced_damage_three) > 0)
	{
            	check_improve(ch,gsn_enhanced_damage_three,TRUE,3);
		diceroll += get_skill(ch,gsn_enhanced_damage_three)/3;
	}
        if (diceroll <= get_skill(ch,gsn_enhanced_damage))
        {
            	check_improve(ch,gsn_enhanced_damage,TRUE,6);
            	dam += (dam * diceroll/125);
        }
    }
    else
    {
	dam *= 7;
	dam /= 10;
    } 

    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 + ch->drain_level) / 10) ;
        else 
            dam *= 2 + ((ch->drain_level + ch->level) / 8);
    }

    if ( dt == gsn_ambush )
	dam *= 5/2 + ((ch->drain_level + ch->level) / 6 );

    mdam = GET_DAMROLL(ch);

    dam += mdam * UMIN(100,skill) /100;

    if (wield != NULL && IS_WEAPON_STAT(wield,WEAPON_VORPAL) && number_percent() < 20)
    {
	act("$p emits a fierce red glow as it lashes violently at $N!",ch,wield,victim,TO_CHAR);
	act("$p emits a fierce red glow as it lashes violently at You!",ch,wield,victim,TO_VICT);
	act("$p emits a fierce red glow as it lashes violently at $N!",ch,wield,victim,TO_NOTVICT);
	dam *= 1.2;
    }

    if (wield != NULL && wield->pIndexData->vnum == OBJ_VNUM_AVENGER)
    {
	if (IS_WEAPON_STAT(wield,WEAPON_SHADOWBANE) && number_percent() < 7)
	{
		act("$p flares and sears $N!",ch,wield,victim,TO_CHAR);
		act("$p flares and sears you!",ch,wield,victim,TO_VICT);
		act("$p flares and sears $N!",ch,wield,victim,TO_NOTVICT);
		dam *= 1.5;
	}
	if (IS_WEAPON_STAT(wield,WEAPON_LIGHTBRINGER) && number_percent() < 10)
	{
		act("$p flares and sears $N!",ch,wield,victim,TO_CHAR);
		act("$p flares and sears you!",ch,wield,victim,TO_VICT);
		act("$p flares and sears $N!",ch,wield,victim,TO_NOTVICT);
		dam *= 1.7;
	}

    }

    if(!IS_NPC(ch) && ch->cabal == CABAL_RAGER 
    && !cabal_down_new(ch,CABAL_RAGER,FALSE) && number_percent()<=5 && specials==TRUE)
    {
	send_to_char("You land an especially devastating blow!\n\r",ch);
	act("$n lands an especially devastating blow!",ch,0,0,TO_ROOM);
	dam *= 3.5;
    }

    // Same as above, except for rager mobs.
    if (IS_NPC(ch) && ch->cabal == CABAL_RAGER && number_percent() < 15 && specials == TRUE
	&& (IS_CABAL_OUTER_GUARD(ch) || IS_CABAL_GUARD(ch)))
    {
        send_to_char("You land an especially devastating blow!\n\r",ch);
        act("$n lands an especially devastating blow!",ch,0,0,TO_ROOM);
        dam *= 3;
    }

    if ( dam <= 0 )
        dam = 1;

	//Bulwark of blades damage reflection -- Zornath
	if(is_affected(victim,skill_lookup("bulwark of blades"))) {
		int chance;
		AFFECT_DATA bulwark_bleed;
		
		if (get_skill(victim,skill_lookup("blade mastery")) < 1) chance = 30;
		else chance = 50;
		
		if (number_percent() < chance) {
			act("The blade barrier around $N dices your flesh as your strike $M!",ch,0,victim,TO_CHAR);
			act("The blade barrier around $N dices into $n's flesh!",ch,0,victim,TO_NOTVICT);
			act("The blade barrier around you dices into $n's flesh as $e strikes you!",ch,0,victim,TO_VICT);
		
			if (get_skill(victim,skill_lookup("blade mastery")) < 1)
				damage_newer(victim,ch,dam / 6,TYPE_UNDEFINED,DAM_SLASH,TRUE,HIT_UNBLOCKABLE,HIT_NOADD,HIT_NOMULT,"the dicing blades",SINGULAR,DAM_NOT_POSSESSIVE,NULL,FALSE);
			else {
				damage_newer(victim,ch,dam / 3,TYPE_UNDEFINED,DAM_SLASH,TRUE,HIT_UNBLOCKABLE,HIT_NOADD,HIT_NOMULT,"the dicing blades",SINGULAR,DAM_NOT_POSSESSIVE,NULL,FALSE);	
				
				//10% chance to add a bleed effect
				if (number_percent() < 10 && !is_affected(ch,skill_lookup("dicing wounds"))) {
					act("The blades dig deep into $n's flesh, unleashing a mist of blood!",ch,0,victim,TO_VICT);
					act("The blades dig deep into $n's flesh, unleashing a mist of blood!",ch,0,victim,TO_NOTVICT);
					act("The blades dig deep into your flesh, unleashing a spray of blood!",ch,0,victim,TO_CHAR);
					init_affect(&bulwark_bleed); 
					bulwark_bleed.aftype = TO_AFFECTS;
					bulwark_bleed.type = skill_lookup("dicing wounds");
					bulwark_bleed.duration = 3;
					bulwark_bleed.level = victim->level;
					bulwark_bleed.owner_name = str_dup(victim->original_name);
					bulwark_bleed.affect_list_msg = str_dup("bleeding uncontrollably");
					affect_to_char(ch,&bulwark_bleed);
				}
			}
		}
	}
	
    if(ch->cabal==CABAL_KNIGHT && get_skill(ch,skill_lookup("truestrike")) 
	&& number_percent()<((get_skill(ch,skill_lookup("truestrike"))-40)/5)-3 && !cabal_down_new(ch,CABAL_KNIGHT,FALSE) 
	&& specials==TRUE)
    {
      	act("$n unleashes a blow of true accuracy, striking through your defenses!",ch,0,victim,TO_VICT);
      	act("$n unleashes a blow of true accuracy, striking through $N's defenses!",ch,0,victim,TO_NOTVICT);
     	act("You unleash a blow of true accuracy, striking through $N's defenses!",ch,0,victim,TO_CHAR);	
	dam*=1.5;
      	result = damage_new( ch, victim, dam, dt, DAM_TRUESTRIKE, TRUE, blockable, addition, multiplier,NULL);
      	check_improve(ch,skill_lookup("truestrike"),TRUE,1);
    }
    else
    	result = damage_new( ch, victim, dam, dt, dam_type, TRUE, blockable, addition, multiplier,dnoun);

    /* 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 = 10;
            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) && !IS_AFFECTED(victim,AFF_POISON)) 
            {
                send_to_char("You feel poison coursing through your veins.\n\r", victim);
                act("$n is poisoned by the venom on $p.", victim,wield,NULL,TO_ROOM);
                init_affect(&af);
                af.where     = TO_AFFECTS;
		af.aftype    = AFT_MALADY;
                af.type      = gsn_poison;
                af.level     = level * 3/4;
                af.duration  = level / 10;
                af.location  = APPLY_STR;
                af.modifier  = -6;
                af.bitvector = AFF_POISON;
				af.owner_name	= str_dup(ch->original_name);
                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->duration < 0)
                    act("The poison on $p has worn off.",ch,wield,NULL,TO_CHAR);
            }
        }

        if (ch->fighting == victim && IS_WEAPON_STAT(wield,WEAPON_VAMPIRIC) && number_percent() < 8)
        {
            	dam = number_range(wield->level/2, wield->level);
            	act("$p draws life from $n.",victim,wield,NULL,TO_ROOM);
            	act("You feel $p drawing your life away.", victim,wield,NULL,TO_CHAR);
            	damage_old(ch,victim,dam,dt,DAM_NEGATIVE,FALSE);
            	ch->hit = UMIN(ch->hit + dam, ch->max_hit);
        }

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

        if (ch->fighting == victim && IS_WEAPON_STAT(wield,WEAPON_FROST) && number_percent() < 15)
        {
            	dam = number_range(1,wield->level / 6 + 2);
            	act("$p freezes $n.",victim,wield,NULL,TO_ROOM);
            	act("The cold touch of $p surrounds you with ice.", victim,wield,NULL,TO_CHAR);
            	cold_effect(victim,wield->level/2,dam,TARGET_CHAR);
            	damage(ch,victim,dam,dt,DAM_COLD,FALSE);
        }

        if (ch->fighting == victim && IS_WEAPON_STAT(wield,WEAPON_SHOCKING) && number_percent() < 15)
	{
            	dam = number_range(1,wield->level/5 + 2);
            	act("$n is struck by lightning from $p.",victim,wield,NULL,TO_ROOM);
            	act("You are shocked by $p.",victim,wield,NULL,TO_CHAR);
            	shock_effect(victim,wield->level/2,dam,TARGET_CHAR);
		damage(ch,victim,dam,dt,DAM_LIGHTNING,FALSE);
        }
    } // End special weapon flag if.

    tail_chain( );
    return;
}

int avenger_multiplier(CHAR_DATA *ch,OBJ_DATA *wield)
{
    	int avenge;

    	avenge = 1;
    	if (IS_EVIL(ch->fighting) && wield != NULL)
	{
		if (number_percent() < 7 && IS_WEAPON_STAT(wield,WEAPON_SHADOWBANE))
			avenge = 2;
		if (number_percent() < 7 && IS_WEAPON_STAT(wield,WEAPON_LIGHTBRINGER))
			avenge = 3/2;
	}

    	return avenge;
}

/*
 * Inflict damage from a hit.
 */

bool damage(CHAR_DATA *ch,CHAR_DATA *victim,int dam,int dt,int dam_type, bool show) 
{
	return damage_new(ch, victim, dam, dt, dam_type, show, HIT_BLOCKABLE, HIT_NOADD, HIT_NOMULT, NULL);
}


bool damage_old( CHAR_DATA *ch, CHAR_DATA *victim, int dam, int dt, int dam_type, bool show )
{
	return damage_new(ch, victim, dam, dt, dam_type, show, HIT_BLOCKABLE, HIT_NOADD, HIT_NOMULT, NULL);
}

int con_multiplier(int con, int dam) {
	float damage = dam;
	switch(con) {
		case 25: damage *= 0.955; break;
		case 24: damage *= 0.96; break;
		case 23: damage *= 0.965; break;
		case 22: damage *= 0.97; break;
		case 21: damage *= 0.975; break;
		case 20: damage *= 0.98; break;
		case 19: damage *= 0.985; break;
		case 18: damage *= 0.99; break;
		case 17: damage *= 0.995; break;
		case 16: damage *= 1; break;
		case 15: damage *= 1.02; break;
		case 14: damage *= 1.04; break;
		case 13: damage *= 1.06; break;
		case 12: damage *= 1.08; break;
		case 11: damage *= 1.1; break;
		case 10: damage *= 1.12; break;
		case 9: damage *= 1.14; break;
		case 8: damage *= 1.16; break;
		case 7: damage *= 1.18; break;
		case 6: damage *= 1.2; break;
		case 5: damage *= 1.22; break;
		case 4: damage *= 1.24; break;
		case 3: damage *= 1.26; break;
		case 2: damage *= 1.35; break;
		case 1: damage *= 1.45; break;
		default: damage *= 2; break;
	}
	return (int)damage;
}

float calculate_ac_redux(int ac) {
	float ac_mod = 0;
	//If <75% reduction
	if (ac > AC_PER_ONE_PERCENT_DECREASE_DAMAGE * 75) 
		//Damage modifier is AC divided by some predefined constant that can be tweaked to increase or decrease the effectiveness of AC. Zornath
		ac_mod = ((float)ac / (float)AC_PER_ONE_PERCENT_DECREASE_DAMAGE) / (float)100;
	//Otherwise asymptotically approach 100%
	else {
		//Finding a widening factor for (-1/x) + 100, so that redux asymptotically approaches 100 
		long widening_factor = -1 * AC_PER_ONE_PERCENT_DECREASE_DAMAGE * 75 * 25;
		long asymp_mod = widening_factor / ac + 100;
		ac_mod = (float)asymp_mod / (float)100;
	}
	return ac_mod;
}

bool damage_newer(CHAR_DATA *ch, CHAR_DATA *victim, int dam, int dt, int dam_type, bool show, bool blockable, int addition, int multiplier, char *dnoun, bool isPlural, bool showCharName, AFFECT_DATA *dealtByAffect, bool keep_invisible)
{
    OBJ_DATA *corpse;
    OBJ_DATA *obj;
    OBJ_DATA *wield;
    bool immune;
    int originaldam;
    CHAR_DATA *owner = NULL;
    bool nosafe = FALSE;
	int ac;
	
	dam = con_multiplier(get_curr_stat(victim,STAT_CON),dam);
	
	//Armor class affects damage taken now. Zornath
	switch(dt) {
		case DAM_PIERCE: ac = GET_AC(victim,AC_PIERCE); break;
		case DAM_SLASH: ac = GET_AC(victim,AC_SLASH); break;
		case DAM_BASH: ac = GET_AC(victim,AC_BASH); break;
		default: ac = GET_AC(victim,AC_EXOTIC); break;
	}
	
	dam -= dam * calculate_ac_redux(ac);
	
	//For damage dealt by affects such as poison, plague, etc., lookup the owner by name
	if (dealtByAffect) {
		owner = find_char_by_name(dealtByAffect->owner_name);
		ch = victim;
	}
	
    if ( victim->position == POS_DEAD )
        return FALSE;

    if (IS_NPC(ch) && spellbaned(ch,victim,dt))
	return FALSE;

	if (is_affected(ch,skill_lookup("valiant wrath")))
    {
		dnoun = str_dup("valiant wrath");
		dt += DAM_SOUND;
    }
	
	if (get_skill(ch,skill_lookup("elemental affinity")) > 75) {
		dam = (23 * dam) / 20;
	}

    if (!dnoun && !nosafe && is_safe(ch,victim))
	return FALSE;


    originaldam=dam;
    /*
     * Stop up any residual loopholes.
     */

    if ( dam > 3000 && dt >= TYPE_HIT)
    {
        dam = 3000;
    }

    dam+=addition;

    if (multiplier != HIT_NOMULT) 
    {
	dam *= multiplier/100.1;
    }

    if (!IS_NPC(ch) && IS_SET(ch->act,PLR_MORON))
 	dam *= .50;

    if ( victim != ch && ch->in_room == victim->in_room)
    {
        /*
         * Certain attacks are forbidden.
         * Most other attacks are returned.
         */
        check_killer( ch, victim );

        if ( victim->position > POS_STUNNED && victim != ch && !((is_same_group(ch,victim) || is_safe(ch,victim)) && dnoun && dnoun[strlen(dnoun)-1] == '*'))
        {
            if ( victim->fighting == NULL )
                set_fighting( victim, ch );
            if (victim->timer <= 4)
                victim->position = POS_FIGHTING;
        }

        if ( victim->position > POS_STUNNED && victim != ch)
        {
            if ( ch->fighting == NULL && !((is_same_group(ch,victim) || is_safe(ch,victim)) && dnoun && dnoun[strlen(dnoun)-1] == '*'))
                set_fighting( ch, victim );
        }

        /*
         * More charm stuff.
         */
        if ( victim->master == ch && !(dnoun && dnoun[strlen(dnoun)-1] == '*'))
            stop_follower( victim );
    }

    if ( (dt >= TYPE_HIT || dt == gsn_dual_wield) && ch != victim && blockable==HIT_BLOCKABLE && ch->in_room == victim->in_room && dam>0) 
    {

	if (check_shield_magnetism(ch, victim, dt)) return FALSE;

	if (check_parry(ch,victim,dt))
	{
		(check_restrike(ch,victim));
		return FALSE;
	}		
        
	if (check_dodge(ch,victim,dt))			return FALSE;

	if (check_spin(ch,victim, dt))			return FALSE;

        if (check_distance(ch,victim,dt))		return FALSE;

	if (check_unarmed_defense(ch,victim,dt))	return FALSE;
		
	if (check_shield_block(ch,victim,dt))		return FALSE;

        if (check_questdodge(ch,victim,dt))		return FALSE;
	
	if (check_ironhands(ch,victim,dt))		return FALSE;
   }

   if (ch->enhancedDamMod >= 0)
   {
	dam *= (ch->enhancedDamMod / 100);
   }

   if (is_affected(victim,gsn_static_charge))
   {
	affect_strip(victim,gsn_static_charge);
	damage_old(victim,ch,victim->level * number_range(6,8),gsn_static_charge,DAM_LIGHTNING,TRUE);
   }
   
	/* damage reduction */
    if (dam > 85)
    {
	dam = (dam - 85);
	dam *= 8;
	dam /= 10;
	dam += 85;
    }

   if (is_affected(victim,gsn_soul_channel) && dam_type != DAM_TRUESTRIKE)
   {
	AFFECT_DATA *af;
	int start, level = 0;
	af = affect_find(victim->affected,gsn_soul_channel);
	for (start = 1; start <= level; start++)
	{
		dam *= .8;
	}
    }
    if (is_affected(victim,gsn_stoneskin) && dam_type!=DAM_TRUESTRIKE)
	dam *= .8;
    if (is_affected(victim,gsn_shield) && dam_type!=DAM_TRUESTRIKE)
	dam *= .95;
    if (is_affected(victim,gsn_barrier) && dam_type!=DAM_TRUESTRIKE)
	dam *= .5;
	if (is_affected(victim,skill_lookup("aura")) && dam_type != DAM_TRUESTRIKE)
		dam *= 0.7;
		
    if (is_affected(ch,gsn_rage) && dam_type!=DAM_TRUESTRIKE)
        dam *= 1.25;

    if ( dam > 1 && ((IS_AFFECTED(victim, AFF_PROTECT_EVIL) && IS_EVIL(ch) )
    ||               (IS_AFFECTED(victim, AFF_PROTECT_GOOD) && IS_GOOD(ch) )) && dam_type!=DAM_TRUESTRIKE)
        dam -= dam / 4;

    // Dragonplate
    obj = get_eq_char(ch,WEAR_BODY);
    if (obj != NULL && obj->pIndexData->vnum == OBJ_VNUM_DRAGONPLATE)
    {
	if(!IS_AFFECTED(victim, AFF_SANCTUARY) && dam_type!=DAM_TRUESTRIKE) {
		dam *= .75;
	}
    }

    // Armored carapace 
    obj = get_eq_char(victim,WEAR_ABOUT);
    if (obj!=NULL && obj->pIndexData->vnum==28015)
	dam *= .6;

    // Aura of Darkness
    obj = get_eq_char(victim,WEAR_BODY);
    if (obj!=NULL && obj->pIndexData->vnum==28017 && (dam_type==DAM_HOLY || dam_type==DAM_NEGATIVE))
	dam *= .4;

    /* Check for fire demon belt immunity */
    obj = get_eq_char(victim,WEAR_WAIST);
    if (obj!=NULL && obj->pIndexData->vnum==28016 && dam_type==DAM_FIRE)
	dam *= .4;

	if (victim->dam_mod < 20)
		dam *= 0.2;
	else dam *= (victim->dam_mod / 100.01);

    if (check_ward_diminution(victim, ch, dam, dam_type, dt))
	dam = 1;


	if (!keep_invisible) {
	    un_camouflage( ch, NULL);
	    un_earthfade(ch, NULL);
	    un_hide(ch, NULL);
	    un_invis(ch, NULL);
	    un_sneak(ch, NULL);
	    un_duo(ch, NULL);
	}

    /*
     * Damage modifiers.
     */
    if ( dam > 1 && IS_AFFECTED(victim, AFF_SANCTUARY) && dam_type!=DAM_TRUESTRIKE) {
		if (!is_affected(victim,skill_lookup("shroud")))
			dam /= 2;
		else dam *= 0.4;
	}

    immune = FALSE; 

    /* Check for absorb */
    if (check_absorb(ch,victim,dt))
	return FALSE;

    /*
     * Check for parry, and dodge.
     */

    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/4;	break;
    }

    //ObsidianPalace
    if(IS_NPC(victim) && victim->pIndexData->vnum>28003 && victim->pIndexData->vnum<28012 && !IS_AFFECTED(victim,AFF_SANCTUARY))
	dam/=2;
    if(IS_NPC(victim) && victim->pIndexData->vnum==28006 && dam>10 && dam_type!=DAM_MENTAL)
	dam=number_range(5,25);

    if (dt == gsn_dual_wield)
	wield = get_eq_char(ch,WEAR_DUAL_WIELD);
    else wield = get_eq_char(ch,WEAR_WIELD);


    if(wield && IS_SET(victim->vuln_flags, VULN_IRON) && !str_cmp(wield->material->name,"iron"))
	dam += dam / 3;
    if(wield && IS_SET(victim->vuln_flags, VULN_SILVER) && !str_cmp(wield->material->name,"silver"))
        dam += dam / 3;
	
	if (is_affected(victim,skill_lookup("divine transferrer"))) {
		AFFECT_DATA *af;
		CHAR_DATA *transferree;
		
		af = affect_find(victim->affected,skill_lookup("divine transferrer"));
		if ((transferree = find_char_by_name(af->owner_name)) != NULL) {
			if (transferree->in_room == ch->in_room) {
				if (is_affected(transferree,skill_lookup("divine transferree"))) {
					damage_newer(ch,transferree,dam/2,dt,dam_type,TRUE,HIT_UNBLOCKABLE,HIT_NOADD,HIT_NOMULT,"the divine transferrance",PLURAL,DAM_NOT_POSSESSIVE,NULL,FALSE);
					dam /= 2;
				}
			}
		}
	}
	

    if (showCharName)
    {
    	if (show && isPlural)
       		dam_message( ch, victim, dam, dt, immune, dnoun, PLURAL, DAM_POSSESSIVE );
    	else if (show && !isPlural)
       		dam_message( ch, victim, dam, dt, immune, dnoun, SINGULAR, DAM_POSSESSIVE );
    }
    else
    {
    	if (show && isPlural)
       		dam_message( ch, victim, dam, dt, immune, dnoun, PLURAL, DAM_NOT_POSSESSIVE );
    	else if (show && !isPlural)
       		dam_message( ch, victim, dam, dt, immune, dnoun, SINGULAR, DAM_NOT_POSSESSIVE );
    }

    if ( (dt >= TYPE_HIT || dt == gsn_dual_wield) && ch != victim)
    {
      	if (is_affected(victim,gsn_self_immolation) && dam>0)
     	{
        	act("$N is burned by the flames engulfing $n!",victim,NULL,ch,TO_NOTVICT);
        	act("$N is burned by the flames engulfing you!",victim,NULL,ch,TO_CHAR);
        	act("You are burned by the flames engulfing $n!",victim,NULL,ch,TO_VICT);
        	damage_old(victim,ch,number_range(20,60),gsn_flames,DAM_FIRE, TRUE);
     	}

    }

    if (dam <= 0)
        return FALSE;

    /*
     * Hurt the victim.
     * Inform the victim of his new state.
     */
    if (is_affected(victim,skill_lookup("mana shield")) && victim->mana > dam)
    {
		victim->mana -= dam;
    }
    else if (is_affected(victim,skill_lookup("mana shield")) && victim->mana <= dam)
    {
		act("{rYour mana shield cannot withstand the force of $n's attack and shatters!{x",ch,0,victim,TO_VICT);
		act("{rThe mana shield around $N crumbles under your attack!{x",ch,0,victim,TO_CHAR);
		act("The mana shield around $N crumbles under $n's attack!",ch,0,victim,TO_NOTVICT);
		victim->hit -= (dam - victim->mana);
		victim->mana = 0;
		affect_strip(victim,skill_lookup("mana shield"));
		AFFECT_DATA shield_timer;
		init_affect(&shield_timer);
		shield_timer.aftype = AFT_MALADY;
		shield_timer.type = skill_lookup("mental exhaustion");
		shield_timer.duration = (ch->level / 5);
		shield_timer.affect_list_msg = str_dup("prevents usage of mana shield");
		affect_to_char(victim,&shield_timer);
    }
    else
    	victim->hit -= dam;
		
    if (dam_type == DAM_FIRE || dam_type == DAM_ACID)
	victim->noregen_dam += dam;
    if (victim->noregen_dam > victim->max_hit)
	victim->noregen_dam = victim->max_hit;

    if ( !IS_NPC(victim)
    &&   victim->level >= LEVEL_IMMORTAL
    &&   victim->hit < 1 
	&& !arena)
        victim->hit = 1;

		update_pos( victim );

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

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

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

    case POS_DEAD:
        act( "$n is DEAD!!", victim, 0, 0, TO_ROOM );
        send_to_char( "You have been KILLED!!\n\r\n\r", victim );
        break;

    default:
        if ( dam > victim->max_hit / 4 )
            send_to_char( "That really did HURT!\n\r", victim );
        if ( victim->hit < victim->max_hit / 4 )
            send_to_char( "You sure are BLEEDING!\n\r", victim );
        break;
    }

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

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

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

            /*
			* Dying penalty:
			*/

		if (owner)
	        raw_kill(owner, victim);
		else
	        raw_kill(ch, victim);

        /*
			* Death trigger
		*/
      if (!IS_NPC(ch)
        &&  (corpse = get_obj_list(ch,"corpse",ch->in_room->contents)) != NULL
        &&  corpse->item_type == ITEM_CORPSE_NPC && can_see_obj(ch,corpse))
        {
            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(ch->in_room != victim->in_room || dt == gsn_parting_blow)
	return TRUE;

    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
	&& !is_centurion(victim) 
        && dt != gsn_parting_blow
	&& dt != gsn_cutoff))
	    do_flee( victim, "" );
    }

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

    tail_chain( );
    return TRUE;
}

bool damage_new(CHAR_DATA *ch, CHAR_DATA *victim, int dam, int dt, int dam_type, bool show, bool blockable, int addition, int multiplier, char *dnoun)
{
    return damage_newer(ch,victim,dam,dt,dam_type,show,blockable,addition,multiplier,dnoun,TRUE,TRUE, NULL, FALSE);
}

int damage_calculate(CHAR_DATA *ch, CHAR_DATA *victim, int dt, int dam_type, bool show, bool blockable, int addition, int multiplier)
{
    OBJ_DATA *obj;
    OBJ_DATA *wield;
    int diceroll, diceroll2 = 0;
    int sn, skill;
    int dam, mdam;
    bool immune;
    int originaldam;

    wield = get_eq_char( ch, WEAR_WIELD );
    sn = get_weapon_sn(ch);
    skill = 20 + get_weapon_skill(ch,sn);

    if ( IS_NPC(ch) && (!ch->pIndexData->new_format || wield == NULL))
    {
        if (!ch->pIndexData->new_format)
        {
	    dam = number_range( ( ch->level + ch->drain_level) / 2, (ch->drain_level + 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->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;

	    if (wield->level - (ch->drain_level + ch->level) >= 35)
		dam = (dam*6)/10;
	    else if (wield->level - (ch->drain_level + ch->level) >= 25)
		dam = (dam*7)/10;
	    else if (wield->level - (ch->drain_level + ch->level) >= 15)
		dam = (dam*8)/10;
	    else if (wield->level - (ch->drain_level + ch->level) >= 5)
		dam = (dam*9)/10;

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

                if ((percent = number_percent()) <= (skill / 8))
                    dam *= 1.2;
            }
        }
        else {
       	    dam = number_range( 1 + 7 * skill/100, (ch->level - 5) * skill/100);
			dam += GET_DAMROLL(ch) / 15; 
		}
    }


    dam += (ch->drain_level + ch->level)/8;

    if ( get_skill(ch,gsn_enhanced_damage) > 0 )
    {
        diceroll = number_percent();
	if (get_skill(ch,gsn_enhanced_damage_two) > 0)
	{
		diceroll2 = number_percent();
	
		if (diceroll2 < get_skill(ch,gsn_enhanced_damage_two) && diceroll2 < get_skill(ch,gsn_enhanced_damage) )
		{
			check_improve(ch,gsn_enhanced_damage_two,TRUE,5);
			diceroll2 = diceroll2 + 5;
			diceroll = diceroll2;
		}
	}
	if (get_skill(ch,gsn_enhanced_damage_three) > 0)
	{
            	check_improve(ch,gsn_enhanced_damage_three,TRUE,3);
		diceroll += get_skill(ch,gsn_enhanced_damage_three)/3;
	}
        if (diceroll <= get_skill(ch,gsn_enhanced_damage))
        {
            	check_improve(ch,gsn_enhanced_damage,TRUE,6);
            	dam += (dam * diceroll/125);
        }
    }
    else
    {
	dam *= 7;
	dam /= 10;
    } 

    mdam = GET_DAMROLL(ch);
    dam += mdam * UMIN(100,skill) /100;

    originaldam=dam;
    if ( dam > 3000 && dt >= TYPE_HIT)
    {
        dam = 3000;
    }

    dam+=addition;

    if (multiplier != HIT_NOMULT) 
    {
	dam *= multiplier/100.1;
    }

    if (!IS_NPC(ch) && IS_SET(ch->act,PLR_MORON))
 	dam *= .50;

    if ( (dt >= TYPE_HIT || dt == gsn_dual_wield) && ch != victim && blockable==HIT_BLOCKABLE && ch->in_room == victim->in_room && dam>0) 
    {	
   }

   if (ch->enhancedDamMod >= 0)
   {
	dam *= (ch->enhancedDamMod / 100);
   }

	/* damage reduction */
    if (dam > 85)
    {
	dam = (dam - 85);
	dam *= 8;
	dam /= 10;
	dam += 85;
    }

    if (is_affected(victim,gsn_stoneskin) && dam_type!=DAM_TRUESTRIKE)
	dam *= .8;
    if (is_affected(victim,gsn_shield) && dam_type!=DAM_TRUESTRIKE)
	dam *= .95;
    if (is_affected(victim,gsn_barrier) && dam_type!=DAM_TRUESTRIKE)
	dam *= .5;
    if (is_affected(ch,gsn_rage) && dam_type!=DAM_TRUESTRIKE)
        dam *= 1.25;

    if ( dam > 1 && ((IS_AFFECTED(victim, AFF_PROTECT_EVIL) && IS_EVIL(ch) )
    ||               (IS_AFFECTED(victim, AFF_PROTECT_GOOD) && IS_GOOD(ch) )) && dam_type!=DAM_TRUESTRIKE)
        dam -= dam / 4;

    // Dragonplate
    obj = get_eq_char(ch,WEAR_BODY);
    if (obj != NULL && obj->pIndexData->vnum == OBJ_VNUM_DRAGONPLATE)
    {
	if(!IS_AFFECTED(victim, AFF_SANCTUARY) && dam_type!=DAM_TRUESTRIKE) {
		dam *= .75;
	}
    }

    // Armored carapace 
    obj = get_eq_char(victim,WEAR_ABOUT);
    if (obj!=NULL && obj->pIndexData->vnum==28015)
	dam *= .6;

    // Aura of Darkness
    obj = get_eq_char(victim,WEAR_BODY);
    if (obj!=NULL && obj->pIndexData->vnum==28017 && (dam_type==DAM_HOLY || dam_type==DAM_NEGATIVE))
	dam *= .4;

    /* Check for fire demon belt immunity */
    obj = get_eq_char(victim,WEAR_WAIST);
    if (obj!=NULL && obj->pIndexData->vnum==28016 && dam_type==DAM_FIRE)
	dam *= .4;

    if (dam_type!=DAM_TRUESTRIKE)
    	dam *= (victim->dam_mod / 100.01);

    if (check_ward_diminution(victim, ch, dam, dam_type, dt))
	dam = 1;


    /*
     * Damage modifiers.
     */
    if ( dam > 1 && IS_AFFECTED(victim, AFF_SANCTUARY) && dam_type!=DAM_TRUESTRIKE)
 	dam /= 2;

    immune = FALSE; 


    //ObsidianPalace
    if(IS_NPC(victim) && victim->pIndexData->vnum>28003 && victim->pIndexData->vnum<28012 && !IS_AFFECTED(victim,AFF_SANCTUARY))
	dam/=2;
    if(IS_NPC(victim) && victim->pIndexData->vnum==28006 && dam>10 && dam_type!=DAM_MENTAL)
	dam=number_range(5,25);

    if (dt == gsn_dual_wield)
	wield = get_eq_char(ch,WEAR_DUAL_WIELD);
    else wield = get_eq_char(ch,WEAR_WIELD);


    if(wield && IS_SET(victim->vuln_flags, VULN_IRON) && !str_cmp(wield->material->name,"iron"))
	dam -= dam / 3;
    if(wield && IS_SET(victim->vuln_flags, VULN_SILVER) && !str_cmp(wield->material->name,"silver"))
        dam -= dam / 3;


    return dam;
}

bool is_area_safe(CHAR_DATA *ch, CHAR_DATA *victim)
{
    if (victim->in_room == NULL || ch->in_room == NULL)
	return TRUE;
    if (victim == ch )
	return TRUE;
    if (victim->fighting == ch)
	return FALSE;
    if (IS_NPC(ch) && IS_GOOD(ch) && IS_GOOD(victim))
	return FALSE;
    if (IS_IMMORTAL(victim) && victim->invis_level > 2)
	return TRUE;
    if (IS_IMMORTAL(ch) && IS_IMMORTAL(victim) && victim->level > LEVEL_IMMORTAL && !is_same_group(ch,victim))
	return FALSE;
    if (IS_IMMORTAL(ch) && victim->level < ch->level && !is_same_group(ch,victim))
	return FALSE;

   /* killing mobiles */
    if (IS_NPC(victim))
    {
	if (IS_SET(victim->in_room->room_flags,ROOM_SAFE))
        {
	    send_to_char("Not in this room.\n\r",ch);
	    return TRUE;
	}
	if (is_same_group(ch,victim))
            return TRUE;
    }
    /* killing players */
    else
    {
        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(ch) && ch->master != NULL && !IS_NPC(ch->master))
            return TRUE;
        if (IS_NPC(ch))
            return FALSE;
	if (is_same_group(ch,victim))
            return TRUE;

    }
    if (!IS_NPC(ch))
        ch->ghost = (time_t)NULL;
    return FALSE;
}

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

    if (IS_NPC(ch) && victim->invis_level >= LEVEL_HERO)
	return TRUE;

    if (!IS_NPC(ch))
	{
	if (ch->pcdata->death_status == HAS_DIED)
		return TRUE;
	}
    if (!IS_NPC(victim))
	{
	if (victim->pcdata->death_status == HAS_DIED)
		return TRUE;
	}

    if(IS_NPC(ch) && IS_NPC(victim) && !IS_AFFECTED(ch,AFF_CHARM) && !IS_AFFECTED(victim,AFF_CHARM) && !ch->desc &&
	!ch->hunting && !victim->hunting && victim!=ch && !ch->desc && !victim->desc)
	return TRUE;


/* Handle Link dead players , only saves from PKS, not mobs -Ceran */
    if (!IS_NPC(victim) && victim->desc == NULL && !IS_NPC(ch)
	&& victim->fighting != ch && ch->fighting != victim)
	{
	act("The gods protect $N from $n.",ch,0,victim,TO_NOTVICT);
	act("The gods protect $N from you.",ch,0,victim,TO_CHAR);
	return TRUE;
 	}

    if (!IS_NPC(victim) && victim->pcdata->newbie==TRUE && !IS_NPC(ch))
	{
	act("$N is too young for $n to harm.",ch,0,victim,TO_NOTVICT);
	act("$N is too young for you to harm.",ch,0,victim,TO_CHAR);
	act("You are too young for $n to harm.",ch,0,victim,TO_VICT);
	return TRUE;
 	}
    if (!IS_NPC(ch) && ch->pcdata->newbie==TRUE && !IS_NPC(victim))
	{
	act("$n is too young to harm $N.",ch,0,victim,TO_NOTVICT);
	act("You are too young to harm $N. Type newbie to change this.",ch,0,victim,TO_CHAR);
	act("$n is too young to harm you.",ch,0,victim,TO_VICT);
	return TRUE;
 	}

    if (is_affected(victim,gsn_timestop))
    {
	act("$n is stuck in time and the gods protect $m.",victim,0,0,TO_ROOM);
	act("$N tries to do something but you are stuck in time and unaffected.",victim,0,ch,TO_CHAR);
	if (victim->fighting != NULL)
		victim->fighting = NULL;
	return TRUE;
    }

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

    if (IS_NPC(ch) && ch->last_fought == victim)
	return FALSE;


    if (victim->ghost > 0)
    {
	act("The gods protect $N from $n.",ch,0,victim,TO_NOTVICT);
	act("The gods protect you from $n.",ch,0,victim,TO_VICT);
	act("The gods protect $N from you.",ch,0,victim,TO_CHAR);
	return TRUE;
    }

    if (ch->ghost > 0)
    {
	if (!IS_NPC(victim))
	{
	act("The gods protect $N from $n.",ch,0,victim,TO_NOTVICT);
	act("The gods protect you from $n.",ch,0,victim,TO_VICT);
	act("The gods protect $N from you.",ch,0,victim,TO_CHAR);
		return TRUE;
	}
            if (IS_AFFECTED(victim,AFF_CHARM) && victim->master != NULL
		&& !IS_NPC(victim->master))
            {
  	act("The gods protect $N from $n.",ch,0,victim,TO_NOTVICT);
	act("The gods protect you from $n.",ch,0,victim,TO_VICT);
	act("The gods protect $N from you.",ch,0,victim,TO_CHAR);
                return TRUE;
            }

    }

    if (IS_IMMORTAL(ch) && is_affected(ch,gsn_riot) && !IS_NPC(victim))
    {
	send_to_char("You can't riot on mortals.\n\r",ch);
	return TRUE;
    }

    if (IS_IMMORTAL(ch) && ch->level > LEVEL_IMMORTAL)
        return FALSE;


    if (IS_SET(victim->act,PLR_CRIMINAL))
    {
	if (IS_NPC(ch) && ch->pIndexData->vnum == MOB_VNUM_ENFORCER)
		return FALSE;
    }
    if(IS_NPC(victim)&&victim->pIndexData->vnum==MOB_VNUM_ENFORCER)
	return FALSE;

    /* killing mobiles */
    if (IS_NPC(victim))
    {
        if (!IS_NPC(ch))
        {
            /* no charmed creatures unless in pk of master */
            if (IS_AFFECTED(victim,AFF_CHARM) && !can_pk(ch,victim->master) && !is_centurion(victim))
            {
  	act("The gods protect $N from $n.",ch,0,victim,TO_NOTVICT);
	act("The gods protect you from $n.",ch,0,victim,TO_VICT);
	act("The gods protect $N from you.",ch,0,victim,TO_CHAR);
                return TRUE;
            }
        }
	else
	{
	if (IS_AFFECTED(ch,AFF_CHARM) && IS_AFFECTED(victim,AFF_CHARM)
	&& !can_pk(ch->master,victim->master))
                return TRUE;
	}
    }
    /* killing players */
    else
    {
        /* 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 && !is_centurion(ch))
            {
                send_to_char("Players are your friends!\n\r",ch);
                return TRUE;
            }
        }
        /* player doing the killing */
        else
        {
	    if (!can_pk(ch, victim))
    	    {
	if (!IS_IMMORTAL(victim)) {
  	act("The gods protect $N from $n.",ch,0,victim,TO_NOTVICT);
	act("The gods protect you from $n.",ch,0,victim,TO_VICT);
	act("The gods protect $N from you.",ch,0,victim,TO_CHAR);
		}
        	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_IMMORTAL(ch) && ch->level > LEVEL_IMMORTAL && !area)
        return FALSE;

    if (!IS_NPC(victim) && victim->pcdata->newbie==TRUE && !IS_NPC(ch))
	  return TRUE;

    /* killing mobiles */
    if (IS_NPC(victim))
    {
        /* safe room? */
        if (IS_SET(victim->in_room->room_flags,ROOM_SAFE))
            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_CHANGER))
            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_cabal(ch))
                return TRUE;

            if (IS_SET(victim->act,PLR_KILLER) || IS_SET(victim->act,PLR_THIEF))
                return FALSE;

            if (!is_cabal(victim))
                return TRUE;

            if (ch->level > victim->level + 8)
                return TRUE;
        }

    }
    return FALSE;
}
/*
 * See if an attack justifies a KILLER flag.
 */
void check_killer( CHAR_DATA *ch, CHAR_DATA *victim )
{
    /*
     * Follow charm thread to responsible character.
     * Attacking someone's charmed char is hostile!
     */
    while ( IS_AFFECTED(victim, AFF_CHARM) && victim->master != NULL )
        victim = victim->master;

    /*
     * NPC's are fair game.
     * So are killers and thieves.
     */
    if ( IS_NPC(victim)
    ||   IS_SET(victim->act, PLR_KILLER)
    ||   IS_SET(victim->act, PLR_THIEF))
        return;

    /*
     * NPC's are cool of course (as long as not charmed).
     * Hitting yourself is cool too (bleeding).
     * So is being immortal (Alander's idea).
     * And current killers stay as they are.
     */
    if ( IS_NPC(ch)
    ||   ch == victim
    ||   ch->level >= LEVEL_IMMORTAL
    ||   !is_cabal(ch)
    ||   IS_SET(ch->act, PLR_KILLER)
    ||   ch->fighting  == victim)
        return;

    save_char_obj( ch );
    return;
}

bool check_blademaster( CHAR_DATA *ch, CHAR_DATA *victim, int dt )
{
    int chance;
    int tsn;
    char buf1[MAX_STRING_LENGTH];
    char buf2[MAX_STRING_LENGTH];
    char *attack;

    if ( !IS_AWAKE(victim) )
        return FALSE;
		

    tsn=skill_lookup("blademaster");
    chance = get_skill(victim,tsn) / 3;
    if(chance==0)
	  return FALSE;
    if ( get_eq_char( victim, WEAR_WIELD ) == NULL )
    {
        if (IS_NPC(victim))
            chance /= 2;
        else
            return FALSE;
    }
    if (IS_AFFECTED(victim,AFF_SLOW))
        chance*=.5;
    if (IS_AFFECTED(victim,AFF_HASTE))
	  chance+=8;

    if (check_imperial_training(ch) == IMPERIAL_OFFENSE)
		chance -= 20;
    if (check_imperial_training(ch) == IMPERIAL_DEFENSE)
		chance += 20;

    chance+=(get_curr_stat(victim,STAT_DEX))*.6;
    if(chance>50)
	chance=50;
    if ( number_percent( ) >= chance)
        return FALSE;
    attack=get_dam_message(ch,dt);
    sprintf(buf1,"You block $n's %s with an agile cross parry.",attack);
    sprintf(buf2,"$N blocks your %s with an agile cross parry.",attack);
    act(buf1,ch,0,victim,TO_VICT);
    act(buf2,ch,0,victim,TO_CHAR);
    check_improve(victim,tsn,TRUE,1);
    return TRUE;
}

//Hitroll vs hitroll check that returns the ratio between two characters' hitrolls, up to a predefined max_multiplier.
float hitroll_multiplier(CHAR_DATA *ch, CHAR_DATA *victim, float max_multiplier) {
	int ch_hitroll = GET_HITROLL(ch);
	int victim_hitroll = GET_HITROLL(victim);
	float hit_ratio;
	
	//Hitroll vs hitroll multiplier based on ratio
	if (victim_hitroll >= ch_hitroll) {
		hit_ratio = ch_hitroll == 0 ? ch_hitroll = 1 : ch_hitroll > 0 ? victim_hitroll / ch_hitroll : ch_hitroll / victim_hitroll;
		if (hit_ratio > max_multiplier)
			return max_multiplier;
		else 
			return hit_ratio;
	}
	return 1;
}

bool check_displacement(CHAR_DATA *ch, CHAR_DATA *victim)
{
    float chance, hit_ratio;
	int ch_hitroll, victim_hitroll;

    if (!(is_affected(victim, gsn_displacement)))
	return FALSE;
    chance = get_skill(victim,gsn_displacement);
    chance /= 1.5;
	
	ch_hitroll = GET_HITROLL(ch);
	victim_hitroll = GET_HITROLL(victim);
	
	//For simplicity...
	if (victim_hitroll <= 0) victim_hitroll = 1;
	if (ch_hitroll <= 0) ch_hitroll = 1;

	if (victim_hitroll < ch_hitroll) {
		hit_ratio = (float)ch_hitroll / (float)victim_hitroll;
		
		if (hit_ratio > 1.5)
			chance *= 1.5;
		else 
			chance *= hit_ratio;
	}

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

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

    act("$n's attack passes harmlessly through $N.",ch,NULL,victim,TO_NOTVICT);
    act("$n's attack misses you completely.",ch,NULL,victim,TO_VICT);
    act("Your attack passes harmlessly through $N.",ch,NULL,victim,TO_CHAR);
    return TRUE;
}

/*
 * Check for parry.
 */

bool check_parry( CHAR_DATA *ch, CHAR_DATA *victim, int dt )
{
    OBJ_DATA *wield, *victimwield;
    char *attack, buf1[MSL], buf2[MSL];
    int flourintine=0, ch_hitroll, victim_hitroll, roll;
	float chance, hit_ratio;

    if ( !IS_AWAKE(victim) )
        return FALSE;

    chance = get_skill(victim,gsn_parry) / 2;
	
	ch_hitroll = GET_HITROLL(ch);
	victim_hitroll = GET_HITROLL(victim);
	
	//For simplicity...
	if (victim_hitroll <= 0) victim_hitroll = 1;
	if (ch_hitroll <= 0) ch_hitroll = 1;

	if (victim_hitroll < ch_hitroll) {
		hit_ratio = (float)ch_hitroll / (float)victim_hitroll;
		
		if (hit_ratio > 1.25)
			chance *= 1.25;
		else 
			chance *= hit_ratio;
	}

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

    if (IS_AFFECTED(victim,AFF_BLIND))
        chance *= .75;

    if (IS_AFFECTED(victim,AFF_HASTE))
	  chance+=20;

    if (IS_AFFECTED(ch,AFF_HASTE))
	  chance-=15;

    chance-=5*abs((ch->size-victim->size));

    if (dt  == gsn_dual_wield)
    	wield = get_eq_char(ch,WEAR_DUAL_WIELD);
    else
	wield = get_eq_char(ch,WEAR_WIELD);

    if (wield != NULL)
    {
    	switch (wield->value[0])
    	{
		case (WEAPON_SWORD): 	chance+=5;		break;
		case (WEAPON_DAGGER): 	chance-=5;		break;
		case (WEAPON_SPEAR):	chance+=0;		break;
		case (WEAPON_STAFF):	chance+=0;		break;
		case (WEAPON_MACE):	chance-=5;		break;
		case (WEAPON_AXE):	chance-=5;		break;
		case (WEAPON_FLAIL):	chance+=10;		break;
		case (WEAPON_WHIP):	chance+=10;		break;
		case (WEAPON_POLEARM):	chance-=5;		break;
		default: break;
    	}
    }

    if((victimwield=get_eq_char(victim,WEAR_WIELD)) != NULL)
    {
    	switch (victimwield->value[0])
    	{
		case (WEAPON_SWORD): 	chance+=10; flourintine++;		break;
		case (WEAPON_DAGGER): 	chance-=20;		break;
		case (WEAPON_SPEAR):	chance+=15;		break;
		case (WEAPON_STAFF):	chance+=15;		break;
		case (WEAPON_MACE):	chance-=5;		break;
		case (WEAPON_AXE):	chance-=5;		break;
		case (WEAPON_FLAIL):	chance-=10;		break;
		case (WEAPON_WHIP):	chance-=10;		break;
		case (WEAPON_POLEARM):	chance+=10;		break;
		default: break;
    	}	
    }
	
    if ((get_skill(victim,gsn_flourintine) > 0) && flourintine == 1) 
    {
	check_improve(victim,gsn_flourintine,TRUE,1);
	chance += get_skill(victim,gsn_flourintine) / 7;
    }

    /* imperial training */
    if (check_imperial_training(ch) == IMPERIAL_OFFENSE)
	chance -= 20;
    if (check_imperial_training(victim) == IMPERIAL_DEFENSE)
	chance += 20;
    if (check_imperial_training(victim) == IMPERIAL_OFFENSE)
	chance -= 20;
    if (check_imperial_training(ch) == IMPERIAL_DEFENSE)
	chance += 20;
        
    if (!IS_NPC(victim) && IS_SET(victim->act,PLR_MORON))
 	chance /= 2;
	
	switch(get_curr_stat(victim,STAT_STR)) {
		case 25: chance += 10; break;
		case 24: chance += 8; break;
		case 23: chance += 6; break;
		case 22: chance += 4; break;
		case 21: chance += 3; break;
		case 20: chance += 2; break;
		case 19: chance += 1; break;
		default: chance += 0; break;
	}

    chance+=attack_table[get_attack_number(ch,dt)].modifier;

    if (chance > 95)	
	chance = 95;

	attack = get_dam_message(ch,dt);
	roll = number_percent();
    if ( roll >= chance)
       return FALSE;

    if (chance - roll >= 40) {
		sprintf(buf1,"You masterfully deflect $n's %s with your %s.",attack, victimwield ? weapon_name_lookup(victimwield->value[0]) : "hands");
		sprintf(buf2,"$N masterfully deflects your %s with $S %s.",attack, victimwield ? weapon_name_lookup(victimwield->value[0]) : "hands");
	}
	else if (chance - roll >= 30) {
		sprintf(buf1,"You gracefully parry $n's %s with your %s.",attack, victimwield ? weapon_name_lookup(victimwield->value[0]) : "hands");
		sprintf(buf2,"$N gracefully parries your %s with $S %s.",attack, victimwield ? weapon_name_lookup(victimwield->value[0]) : "hands");
	}
	else if (chance - roll >= 20) {
		sprintf(buf1,"You parry $n's %s with your %s.",attack, victimwield ? weapon_name_lookup(victimwield->value[0]) : "hands");
		sprintf(buf2,"$N parries your %s with $S %s.",attack, victimwield ? weapon_name_lookup(victimwield->value[0]) : "hands");
	}
	else if (chance - roll >= 10) {
		sprintf(buf1,"You manage to parry $n's %s with your %s.",attack, victimwield ? weapon_name_lookup(victimwield->value[0]) : "hands");
		sprintf(buf2,"$N manages to parry your %s with $S %s.",attack, victimwield ? weapon_name_lookup(victimwield->value[0]) : "hands");
	}
	else {
		sprintf(buf1,"You barely manage to parry $n's %s with your %s.",attack, victimwield ? weapon_name_lookup(victimwield->value[0]) : "hands");
		sprintf(buf2,"$N barely manages to parry your %s with $S %s.",attack, victimwield ? weapon_name_lookup(victimwield->value[0]) : "hands");
	}
	
    act(buf1,ch,0,victim,TO_VICT);
    act(buf2,ch,0,victim,TO_CHAR);
    check_improve(victim,gsn_parry,TRUE,2);
    return TRUE;
}

bool check_block( CHAR_DATA *ch, CHAR_DATA *victim, int dt )
{
    float chance, hit_ratio;
    int tmp_dt, ch_hitroll, victim_hitroll, roll;
    OBJ_DATA *wield;
    char buf1[MAX_STRING_LENGTH];
    char buf2[MAX_STRING_LENGTH];
    char *attack;

    if ( !IS_AWAKE(victim) )
        return FALSE;
    if (IS_NPC(victim))
	return FALSE;

    chance = get_skill(victim,gsn_block);

    if ( victim->level <skill_table[gsn_block].skill_level[victim->class])
  	return FALSE;

    chance /= 2.25;
	
	ch_hitroll = GET_HITROLL(ch);
	victim_hitroll = GET_HITROLL(victim);
	
	//For simplicity...
	if (victim_hitroll <= 0) victim_hitroll = 1;
	if (ch_hitroll <= 0) ch_hitroll = 1;

	if (victim_hitroll < ch_hitroll) {
		hit_ratio = (float)ch_hitroll / (float)victim_hitroll;
		
		if (hit_ratio > 1.25)
			chance *= 1.25;
		else 
			chance *= hit_ratio;
	}

    if (get_eq_char(victim,WEAR_WIELD) != NULL)
	return FALSE;

    if (!can_see(ch,victim))
        chance /= 2;
    if (is_affected(victim,gsn_rage))
        chance *= .75;
    if ( number_percent( ) >= chance + (victim->drain_level +  victim->level) - (ch->drain_level + ch->level) )
    {
	check_improve(victim,gsn_block,FALSE,5);
        return FALSE;
    }

/* The rest is all new dual wield stuff, with dam types displayed for
clarity when dual wielding - Ceran */
    tmp_dt = TYPE_HIT;
    if (dt  == gsn_dual_wield)
    	wield = get_eq_char(ch,WEAR_DUAL_WIELD);
    else
	wield = get_eq_char(ch,WEAR_WIELD);


    if (wield != NULL)
	tmp_dt += wield->value[3];
    else
	tmp_dt += ch->dam_type;


    if (tmp_dt > TYPE_HIT && tmp_dt < TYPE_HIT + MAX_DAMAGE_MESSAGE)
	attack = attack_table[tmp_dt - TYPE_HIT].noun;
    else
    {
	bug("In check_block, bad dam message: dt %d.",tmp_dt);
	attack = attack_table[0].name;
    }

    if (chance - roll >= 40) {
		sprintf(buf1,"You masterfully deflect $n's %s with your hands.",attack);
		sprintf(buf2,"$N masterfully deflects your %s with $S hands.",attack);
	}
	else if (chance - roll >= 30) {
		sprintf(buf1,"You gracefully block $n's %s with your hands.",attack);
		sprintf(buf2,"$N gracefully blocks your %s with $S hands.",attack);
	}
	else if (chance - roll >= 20) {
		sprintf(buf1,"You block $n's %s with your hands.",attack);
		sprintf(buf2,"$N blocks your %s with $S hands.",attack);
	}
	else if (chance - roll >= 10) {
		sprintf(buf1,"You manage to block $n's %s with your hands.",attack);
		sprintf(buf2,"$N manages to block your %s with $S hands.",attack);
	}
	else {
		sprintf(buf1,"You barely manage to block $n's %s with your hands.",attack);
		sprintf(buf2,"$N barely manages to block your %s with $S hands.",attack);
	}
	
    act(buf1,ch,0,victim,TO_VICT);
    act(buf2,ch,0,victim,TO_CHAR);
    check_improve(victim,gsn_block,TRUE,6);
    return TRUE;
}

/*
 * Check for shield block.
 */

bool check_shield_block( CHAR_DATA *ch, CHAR_DATA *victim, int dt )
{
    float chance, hit_ratio;
	int ch_hitroll, victim_hitroll, roll;
    char buf1[MAX_STRING_LENGTH];
    char buf2[MAX_STRING_LENGTH];
    char *attack;

    if ( !IS_AWAKE(victim) )
        return FALSE;

    if(victim->level < skill_table[gsn_shield_block].skill_level[victim->class])
	return FALSE;

    chance = (( get_skill(victim,gsn_shield_block) / 4) + 15);
	
	ch_hitroll = GET_HITROLL(ch);
	victim_hitroll = GET_HITROLL(victim);
	
	//For simplicity...
	if (victim_hitroll <= 0) victim_hitroll = 1;
	if (ch_hitroll <= 0) ch_hitroll = 1;

	if (victim_hitroll < ch_hitroll) {
		hit_ratio = (float)ch_hitroll / (float)victim_hitroll;
		
		if (hit_ratio > 1.35)
			chance *= 1.35;
		else 
			chance *= hit_ratio;
	}

	/* imperial training */
    if (check_imperial_training(ch) == IMPERIAL_OFFENSE)
	chance -= 10;
    if (check_imperial_training(victim) == IMPERIAL_DEFENSE)
	chance += 10;
    if (check_imperial_training(victim) == IMPERIAL_OFFENSE)
	chance -= 20;
    if (check_imperial_training(ch) == IMPERIAL_DEFENSE)
	chance += 20;

    if (is_affected(victim,gsn_shield_of_purity) && get_eq_char(victim,WEAR_SHIELD) != NULL)
	chance += 30;

    if (is_affected(victim,gsn_shield_of_justice) && get_eq_char(victim,WEAR_SHIELD) != NULL)
	chance -= 30;

	switch(get_curr_stat(victim,STAT_STR)) {
		case 25: chance += 13; break;
		case 24: chance += 10; break;
		case 23: chance += 9; break;
		case 22: chance += 7; break;
		case 20: chance += 4; break;
		case 19: chance += 2; break;
		default: chance += 0; break;
	}
	
	switch(get_curr_stat(victim,STAT_DEX)) {
		case 25: chance += 8; break;
		case 24: chance += 7; break;
		case 23: chance += 6; break;
		case 22: chance += 5; break;
		case 20: chance += 4; break;
		case 19: chance += 3; break;
		default: chance += 0; break;
	}
	
    if ( get_eq_char( victim, WEAR_SHIELD ) == NULL )
        return FALSE;
		

	roll = number_percent();
    if ( roll >= chance  )
        return FALSE;

    attack=get_dam_message(ch,dt);
	
    if (!is_affected(victim,gsn_shield_of_purity) && !is_affected(victim,gsn_shield_of_justice))
    {
    	sprintf(buf1,"You block $n's %s with your shield.",attack);
    	sprintf(buf2,"$N shield blocks your %s.",attack);
    }
    
    else if (is_affected(victim,gsn_shield_of_purity) && get_eq_char(victim,WEAR_SHIELD) != NULL)
    {
	sprintf(buf1,"Your god guides your shield into the path of $n's %s.",attack);
	sprintf(buf2,"$N gracefully deflects your %s with his divine shield.",attack);
    }

    else if (is_affected(victim,gsn_shield_of_justice) && get_eq_char(victim,WEAR_SHIELD) != NULL)
    {
	sprintf(buf1,"Blocking $n's %s with your divine shield, you execute a powerful counterattack!",attack);
	sprintf(buf2,"Blocking your %s with his divine shield, $N executes a powerful counterattack!",attack);
    }
	else {
		if (chance - roll >= 40) {
			sprintf(buf1,"You masterfully block $n's %s with your shield.",attack);
			sprintf(buf2,"$N masterfully blocks your %s with $S shield.",attack);
		}
		else if (chance - roll >= 30) {
			sprintf(buf1,"You gracefully block $n's %s with your shield.",attack);
			sprintf(buf2,"$N gracefully blocks your %s with $S shield.",attack);
		}
		else if (chance - roll >= 20) {
			sprintf(buf1,"You block $n's %s with your shield.",attack);
			sprintf(buf2,"$N blocks your %s with $S shield.",attack);
		}
		else if (chance - roll >= 10) {
			sprintf(buf1,"You manage to block $n's %s with your shield.",attack);
			sprintf(buf2,"$N manages to block your %s with $S shield.",attack);
		}
		else {
			sprintf(buf1,"You barely manage to block $n's %s with your shield.",attack);
			sprintf(buf2,"$N barely manages to block your %s with $S shield.",attack);
		}
	}

    act(buf1,ch,0,victim,TO_VICT);
    act(buf2,ch,0,victim,TO_CHAR);
    if (is_affected(victim, gsn_shield_of_justice) && get_eq_char(victim,WEAR_SHIELD) != NULL)
one_hit_new(victim,ch,TYPE_UNDEFINED,HIT_NOSPECIALS,HIT_UNBLOCKABLE,HIT_NOADD,200,"strike of justice");
    check_improve(victim,gsn_shield_block,TRUE,4);
    return TRUE;
}

/*
 * Check for dodge.
 */

bool check_dodge( CHAR_DATA *ch, CHAR_DATA *victim, int dt )
{
    char buf1[MSL], buf2[MSL], *attack;
    int dex, dexa, fam, ch_hitroll, victim_hitroll, roll;
	float hit_ratio, chance;

    if ( !IS_AWAKE(victim) )
        return FALSE;

    chance = ( 3 * get_skill(victim,gsn_dodge) / 10);

    dex = get_curr_stat(victim,STAT_DEX);
    dexa= get_curr_stat(ch,STAT_DEX);
	
	ch_hitroll = GET_HITROLL(ch);
	victim_hitroll = GET_HITROLL(victim);
	
	//For simplicity...
	if (victim_hitroll <= 0) victim_hitroll = 1;
	if (ch_hitroll <= 0) ch_hitroll = 1;
	
	//Only increase the chance if the victim has more hitroll than the opponent. This is to prevent mage
	//classes from getting gibbed since they don't stack hitroll right now. Dodge will stay the same for
	//mages but increase for melee classes that utilize hitroll up to 1.5x the base chance, which can be at
	//most 30%. Zornath
	if (victim_hitroll < ch_hitroll) {
		hit_ratio = (float)ch_hitroll / (float)victim_hitroll;
		
		if (hit_ratio > 1.5)
			chance *= 1.5;
		else 
			chance *= hit_ratio;
	}

    if (dex <= 5)
	chance += 0;
    else if (dex <= 10)
	chance += dex/2;
    else if (dex <=15)
	chance += (2*dex/3);
    else if (dex <= 20)
	chance += dex;
    else
	chance += 3*dex/2;

    chance+=dex-dexa;
    chance+=(ch->size-victim->size)*5;

    if((fam = get_skill(ch,gsn_wilderness_fam) > 0) && isInWilderness(ch))
	chance += fam/2;

    /* imperial training */
    if (check_imperial_training(ch) == IMPERIAL_OFFENSE)
	chance -= 20;
    if (check_imperial_training(ch) == IMPERIAL_DEFENSE)
	chance += 20;
    if (check_imperial_training(victim) == IMPERIAL_OFFENSE)
	chance -= 20;
    if (check_imperial_training(victim) == IMPERIAL_DEFENSE)
	chance += 20;
    if (!can_see(victim,ch))
        chance /= 2;
    if (!IS_NPC(victim) && IS_SET(victim->act,PLR_MORON))
	chance /= 2;

    // haste/slow
    if (IS_AFFECTED(victim,AFF_HASTE))
	chance += 20;
    if (IS_AFFECTED(victim,AFF_SLOW))
	chance -= 20;
    if (IS_AFFECTED(ch,AFF_HASTE))
        chance -= 20;
    if (IS_AFFECTED(ch,AFF_SLOW))
        chance += 20;

    if (chance > 95)    
	chance = 95; 
	
	roll = number_percent();
    if ( roll >= chance)
        return FALSE;

    attack=get_dam_message(ch,dt);
    if (chance - roll >= 40) {
		sprintf(buf1,"You deftly dodge $n's %s.",attack);
		sprintf(buf2,"$N deftly dodges your %s.",attack);
	}
	else if (chance - roll >= 30) {
		sprintf(buf1,"You gracefully sidestep $n's %s.",attack);
		sprintf(buf2,"$N gracefully sidesteps your %s.",attack);
	}
	else if (chance - roll >= 20) {
		sprintf(buf1,"You dodge $n's %s.",attack);
		sprintf(buf2,"$N dodges your %s.",attack);
	}
	else if (chance - roll >= 10) {
		sprintf(buf1,"You manage to avoid $n's %s.",attack);
		sprintf(buf2,"$N manages to avoid your %s.",attack);
	}
	else {
		sprintf(buf1,"You barely escape $n's %s.",attack);
		sprintf(buf2,"$N barely escapes your %s.",attack);
	}
	

    if(isInWilderness(ch) && check_fam(ch,attack))
	return TRUE;

    act(buf1,ch,0,victim,TO_VICT);
    act(buf2,ch,0,victim,TO_CHAR);
    check_improve(victim,gsn_dodge,TRUE,5);
    return TRUE;
}

/*
 * Check for quest dodge.
 */

bool check_questdodge( CHAR_DATA *ch, CHAR_DATA *victim, int dt )
{
    float chance, hit_ratio;
    char buf1[MAX_STRING_LENGTH];
    char buf2[MAX_STRING_LENGTH];
    char *attack;
    int dex, dexa, ch_hitroll, victim_hitroll, roll;

    if ( !IS_AWAKE(victim) )
        return FALSE;

	if (get_skill(victim,gsn_questdodge) == 0)
		return FALSE;

	chance = ( 3 * get_skill(victim,gsn_questdodge) / 7);
	
	ch_hitroll = GET_HITROLL(ch);
	victim_hitroll = GET_HITROLL(victim);
	
	//For simplicity...
	if (victim_hitroll <= 0) victim_hitroll = 1;
	if (ch_hitroll <= 0) ch_hitroll = 1;

	if (victim_hitroll < ch_hitroll) {
		hit_ratio = (float)ch_hitroll / (float)victim_hitroll;
		
		if (hit_ratio > 1.3)
			chance *= 1.3;
		else 
			chance *= hit_ratio;
	}
    dex = get_curr_stat(victim,STAT_DEX);
    dexa= get_curr_stat(ch,STAT_DEX);
    if (dex <= 5)
	chance += 0;
    else if (dex <= 10)
	chance += dex/2;
    else if (dex <=15)
	chance += (2*dex/3);
    else if (dex <= 20)
	chance += (8*dex/10);
    else
	chance += dex;
    chance+=dex-dexa;
    chance+=(ch->size-victim->size)*5;
    if (is_affected(ch,gsn_executioner))
	  chance+=30;

	roll = number_percent();
    if ( roll >= chance)
      return FALSE;
    attack=get_dam_message(ch,dt);
	if (chance - roll >= 40) {
		sprintf(buf1,"You deftly evade $n's %s.",attack);
		sprintf(buf2,"$N deftly evades your %s.",attack);
	}
	else if (chance - roll >= 30) {
		sprintf(buf1,"You gracefully dart around $n's %s.",attack);
		sprintf(buf2,"$N gracefully darts around your %s.",attack);
	}
	else if (chance - roll >= 20) {
		sprintf(buf1,"You evade $n's %s.",attack);
		sprintf(buf2,"$N evades your %s.",attack);
	}
	else if (chance - roll >= 10) {
		sprintf(buf1,"You manage to evade $n's %s.",attack);
		sprintf(buf2,"$N manages to evade your %s.",attack);
	}
	else {
		sprintf(buf1,"You barely evade $n's %s.",attack);
		sprintf(buf2,"$N barely evades your %s.",attack);
	}
    act(buf1,ch,0,victim,TO_VICT);
    act(buf2,ch,0,victim,TO_CHAR);
    check_improve(victim,gsn_questdodge,TRUE,5);
    return TRUE;
}

/*
 * Check for defensive spin.
 */

bool check_spin( CHAR_DATA *ch, CHAR_DATA *victim, int dt )
{
	float chance, hit_ratio;
	int tmp_dt, victim_hitroll, ch_hitroll, roll;
	OBJ_DATA *wield;
	char buf1[MAX_STRING_LENGTH];
	char buf2[MAX_STRING_LENGTH];
	char *attack;
	
	if ((chance = get_skill(victim,gsn_spin) / 2) == 0) {
		return FALSE;
	}

	ch_hitroll = GET_HITROLL(ch);
	victim_hitroll = GET_HITROLL(victim);
	
	//For simplicity...
	if (victim_hitroll <= 0) victim_hitroll = 1;
	if (ch_hitroll <= 0) ch_hitroll = 1;

	if (victim_hitroll < ch_hitroll) {
		hit_ratio = (float)ch_hitroll / (float)victim_hitroll;
		
		if (hit_ratio > 1.25)
			chance *= 1.25;
		else 
			chance *= hit_ratio;
	}
	
	wield = get_eq_char(victim,WEAR_WIELD);

	if (wield == NULL) {
		return FALSE;
	}

	if (wield != NULL)
	{
		switch (wield->value[0])
		{
			case (WEAPON_STAFF):
			 	chance+= get_skill(victim,gsn_staff) / 10;
				break;
			case (WEAPON_SPEAR):
				chance+= get_skill(victim,gsn_spear) / 10;
				break;
			default:
				return FALSE;
				break;
		}
	}

	if ( !IS_AWAKE(victim) )
	return FALSE;

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

	if (IS_AFFECTED(victim,AFF_BLIND))
		chance *= .75;
	if (IS_AFFECTED(victim,AFF_HASTE))
		chance+=20;
	if (IS_AFFECTED(ch,AFF_HASTE))
		chance-=15;

	switch(get_curr_stat(victim,STAT_STR)) {
		case 25: chance += 13; break;
		case 24: chance += 10; break;
		case 23: chance += 9; break;
		case 22: chance += 7; break;
		case 20: chance += 4; break;
		case 19: chance += 2; break;
		default: chance += 0; break;
	}
	
	switch(get_curr_stat(victim,STAT_DEX)) {
		case 25: chance += 6; break;
		case 24: chance += 5; break;
		case 23: chance += 4; break;
		case 22: chance += 3; break;
		case 20: chance += 2; break;
		case 19: chance += 1; break;
		default: chance += 0; break;
	}
	
	tmp_dt = TYPE_HIT;

	roll = number_percent();
	if ( roll >= chance)
	{
		check_improve(victim,gsn_spin,FALSE,2);
		return FALSE;
	}

    attack=get_dam_message(ch,dt);
    if (chance - roll >= 40) {
		sprintf(buf1,"You masterfully spin your %s, blocking $n's %s.", wield ? weapon_name_lookup(wield->value[0]) : "hands", attack);
		sprintf(buf2,"$N masterfully spins $S %s, blocking your %s.",wield ? weapon_name_lookup(wield->value[0]) : "hands",attack);
	}
	else if (chance - roll >= 30) {
		sprintf(buf1,"You gracefully deflect $n's %s with a defensive spin.",attack);
		sprintf(buf2,"$N gracefully deflects your %s with a defensive spin.",attack);
	}
	else if (chance - roll >= 20) {
		sprintf(buf1,"You spin your %s and fend off $n's %s.",wield ? weapon_name_lookup(wield->value[0]) : "hands",attack);
		sprintf(buf2,"$N spins $S %s, fending off your %s.",wield ? weapon_name_lookup(wield->value[0]) : "hands",attack);
	}
	else if (chance - roll >= 10) {
		sprintf(buf1,"You manage to spin and deflect $n's %s.",attack);
		sprintf(buf2,"$N manages to spin and deflect your %s.",attack);
	}
	else {
		sprintf(buf1,"You barely deflect $n's %s with a defensive spin.",attack);
		sprintf(buf2,"$N barely deflects your %s with a defensive spin.",attack);
	}
    act(buf1,ch,0,victim,TO_VICT);
    act(buf2,ch,0,victim,TO_CHAR);
    check_improve(victim,gsn_spin,TRUE,2);
    return TRUE;
}

bool check_distance( CHAR_DATA *ch, CHAR_DATA *victim, int dt )
{
    int sn = skill_lookup("distance"), ch_hitroll, victim_hitroll;
	float chance, hit_ratio;
    OBJ_DATA *wield;
    char buf1[MAX_STRING_LENGTH];
    char buf2[MAX_STRING_LENGTH];
    char *attack;

    if ( !IS_AWAKE(victim) )
        return FALSE;

    if(get_skill(victim,sn)<5)
	return FALSE;

    chance = (( get_skill(victim,sn) / 4) + 15);
	
	ch_hitroll = GET_HITROLL(ch);
	victim_hitroll = GET_HITROLL(victim);
	
	//For simplicity...
	if (victim_hitroll <= 0) victim_hitroll = 1;
	if (ch_hitroll <= 0) ch_hitroll = 1;

	if (victim_hitroll < ch_hitroll) {
		hit_ratio = (float)ch_hitroll / (float)victim_hitroll;
		
		if (hit_ratio > 1.35)
			chance *= 1.35;
		else 
			chance *= hit_ratio;
	}

	/* imperial training */
	if (check_imperial_training(ch) == IMPERIAL_OFFENSE)
		chance -= 10;
	if (check_imperial_training(victim) == IMPERIAL_DEFENSE)
		chance += 10;
	if (check_imperial_training(victim) == IMPERIAL_OFFENSE)
		chance -= 20;
	if (check_imperial_training(ch) == IMPERIAL_DEFENSE)
		chance += 20;
    chance+=20*(victim->size-ch->size);
    chance+=10*(get_curr_stat(victim,STAT_STR)-get_curr_stat(ch,STAT_STR));
    if(IS_AFFECTED(victim,AFF_HASTE))
		chance+=15;
    if(IS_AFFECTED(ch,AFF_HASTE))
		chance-=15;
    if(((wield=get_eq_char(victim,WEAR_WIELD)) == NULL || wield->value[0]!=WEAPON_POLEARM))
		return FALSE;
    chance += (victim->drain_level + victim->level - (ch->drain_level + ch->level));
    chance=URANGE(5,chance,65);
    if ( number_percent( ) >= chance  )
        return FALSE;
    attack=get_dam_message(ch,dt);
    if(number_percent()<(chance/4))
    {
	 sprintf(buf1,"You keep $n at bay with your $p, knocking $m off balance with a counter strike.");
	 sprintf(buf2,"$N keeps you at bay with $S $p, knocking you off balance with a counter strike.");
    	 act(buf1,ch,wield,victim,TO_VICT);
    	 act(buf2,ch,wield,victim,TO_CHAR);
	 sprintf(buf1,"$N keeps $n at bay with $S $p, knocking $m off balance with a counter strike.");
	 act(buf1,ch,wield,victim,TO_NOTVICT);
	 one_hit_new(victim,ch,sn,HIT_SPECIALS,HIT_UNBLOCKABLE,HIT_NOADD,75,NULL);
	 WAIT_STATE(ch,PULSE_VIOLENCE*1.5);
	 return TRUE;
    }
    sprintf(buf1,"You keep $n's %s at bay with your polearm.",attack);
    sprintf(buf2,"$N keeps your %s at bay with $s polearm.",attack);
    if(IS_SET(victim->wiznet,WIZ_PERCENT))
        sprintf(buf1,"You keep $n's %s at bay with your polearm. (%.0f%%)",attack,chance);
    if(IS_SET(ch->wiznet,WIZ_PERCENT))
        sprintf(buf2,"$N keeps your %s at bay with $S polearm. (%.0f%%)",attack,chance);
    act(buf1,ch,0,victim,TO_VICT);
    act(buf2,ch,0,victim,TO_CHAR);
    check_improve(victim,sn,TRUE,2);
    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 )
    {
        victim->position = POS_DEAD;
        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 )
{
    	char buf[MAX_STRING_LENGTH];

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

	if (ch == victim)
		return;

    	if ( IS_AFFECTED(ch, AFF_SLEEP) )
        	affect_strip( ch, gsn_sleep );
			
		if ( is_affected(victim, skill_lookup("resurrect"))) {
			send_to_char("{RYou lose your focus and the resurrection fails!{x\n\r",victim );
			affect_strip(victim,skill_lookup("resurrect"));
		}
		
		if ( is_affected(ch, skill_lookup("resurrect"))) {
			send_to_char("{RYou lose your focus and the resurrection fails!{x\n\r",ch );
			affect_strip(ch,skill_lookup("resurrect"));
		}

    	if (is_affected(victim,gsn_trip_wire))
    	{
    		send_to_char("You lost your trip wire in the frey.\n\r",victim);
		affect_strip(victim,gsn_trip_wire);
    	}

    	if (is_affected(ch,gsn_trip_wire))
    	{
    		send_to_char("You lost your trip wire in the frey.\n\r",ch);
    		affect_strip(ch,gsn_trip_wire);
    	}

    	ch->fighting = victim;
    	ch->position = POS_FIGHTING;
	ch->pause = UMAX(ch->pause, 10);
	victim->pause = UMAX(victim->pause, 10);

    	if (is_centurion(victim))
    	{
		sprintf(buf,"empire Help! %s is attacking me at %s!",PERS(ch,victim), victim->in_room->name);
		do_ccb(victim,buf);
    	}

    	if (IS_SET(victim->progtypes,MPROG_ATTACK))
       		(victim->pIndexData->mprogs->attack_prog) (victim,ch);

    	return;
}

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

    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;
            update_pos( fch );
        }
    }

    return;
}



/*
 * Make a corpse out of a character.
 */
void make_corpse( CHAR_DATA *killer,CHAR_DATA *ch )
{
    char buf[MAX_STRING_LENGTH];
    OBJ_DATA *corpse;
    OBJ_DATA *obj;
    OBJ_DATA *obj_next;
    OBJ_DATA *head;
    char *name, wizbuf[MAX_STRING_LENGTH], *objown;
	MOB_INDEX_DATA *pMobIndex;

	objown = NULL;

    if (IS_NPC(ch) && ch->pIndexData->vnum == 13724)
    {
	act("One of $n's massive heads falls decapitated onto the ground.",ch,0,0,TO_ROOM);
    	head = create_object(get_obj_index(OBJ_VNUM_HYDRA_HEAD),0);
	if (head != NULL)
	obj_to_room(head,ch->in_room);
    }

    if ( IS_NPC(ch) )
    {
        name            = str_dup(ch->short_descr);
        corpse          = create_object(get_obj_index(OBJ_VNUM_CORPSE_NPC), 0);
        corpse->corpse_of = str_dup(ch->short_descr);
		corpse->timer   = number_range( 5, 8 );

		free_string(corpse->talked);
		if (IS_NPC(killer))
			corpse->talked = str_dup(killer->short_descr);
		else
			corpse->talked = str_dup(killer->name);
			
			pMobIndex = ch->pIndexData;
			
		// Begin gold calculation
		float gold = 0;
		
		//presumably single kills
		if (ch->level < 30) gold = 10 * (ch->level) + number_range(1,10);
		else if (ch->level <= 53) { gold = 52.1*(ch->level-30) + number_range(275,300); gold -= pMobIndex->killed * 10; }
		else if (ch->level <= 60) { gold = 214.2 *(ch->level-53) + number_range(1300,1500); gold -= pMobIndex->killed * 30; }
		else if (ch->level <= 70) { gold = 500*(ch->level-60) + number_range(2700,3000); gold -= pMobIndex->killed * 100; }
		
		//now we're getting to possibly high-level group kills, so the gold scales much faster to compensate
		else if (ch->level <= 75) { gold = 1200*(ch->level-70) + number_range(7500,8000); gold -= pMobIndex->killed * 250; }
		else if (ch->level <= 80) { gold = 16000*(ch->level-75) + number_range(13300,14000); gold -= pMobIndex->killed * 450; }
		else { gold = 20000*(ch->level-80) + number_range(90000,94000); gold -= pMobIndex->killed * 1000; }
		// End gold calculation
		
		obj_to_obj( create_money((int)gold), corpse );
		corpse->cost = 0;
    }
    else
    {
        name            = str_dup(ch->name);
        corpse          = create_object(get_obj_index(OBJ_VNUM_CORPSE_PC), 0);
		corpse->corpse_of = str_dup(ch->name);
        corpse->timer   = number_range( 20, 35 );
    	if(ch->in_room && IS_EXPLORE(ch->in_room))
        	corpse->timer   = number_range(6,9);
	corpse->value[4] = ch->hometown;
        REMOVE_BIT(ch->act,PLR_CANLOOT);
	free_string(corpse->talked);
	if (IS_NPC(killer))
		corpse->talked = str_dup(killer->short_descr);
	else
		corpse->talked = str_dup(killer->name);
	
	corpse->owner = str_dup(ch->original_name);

            if (ch->gold > 1)
            {
                obj_to_obj(create_money(ch->gold), corpse);
		ch->gold = 0;
            }

        corpse->cost = 0;
    }

    corpse->level = ch->level;
    corpse->owner_class = ch->class;
     if (IS_SET(ch->act,ACT_UNDEAD) || IS_SET(ch->form,FORM_UNDEAD))
	set_bit(&corpse->extra_flags,CORPSE_NO_ANIMATE);


    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 );
    corpse->ohp = ch->max_hit;
    for ( obj = ch->carrying; obj != NULL; obj = obj_next )
    {
		bool takeItem = TRUE;
		bool putInCorpse = TRUE;
        obj_next = obj->next_content;

		if(!IS_NPC(ch))
			objown = str_dup(obj->carried_by->original_name);
	        
	    if (obj->wear_loc == WEAR_BRAND)
			takeItem = FALSE;
		
		if (obj->owner != NULL)
		{
			if (!str_cmp(obj->owner,ch->original_name)) {
				act("$p flashes brightly and returns to $n!",ch,obj,NULL,TO_ROOM);
				act("$p pulses brightly beside you as you collapse, following you through death itself.",ch,obj,NULL,TO_CHAR);
				takeItem = FALSE;
			}
		}

		if (takeItem)
			obj_from_char( obj );

	    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 = 2;
				remove_bit(&obj->extra_flags,ITEM_ROT_DEATH);
		}

		remove_bit(&obj->extra_flags,ITEM_VIS_DEATH);

		
		if (obj->pIndexData->limcount > obj->pIndexData->limtotal
			 && obj->pIndexData->limtotal > 0)
		{
			act("$p flashes brightly and vaporizes.",ch,obj,NULL,TO_ROOM);
			extract_obj( obj );
			putInCorpse = FALSE;
		}
		
	    if (obj->wear_loc == WEAR_BRAND)
			putInCorpse = FALSE;

		if (obj->owner != NULL)		
			if (!str_cmp(obj->owner,ch->original_name))
				putInCorpse = FALSE;
		
		if (putInCorpse) {
			obj_to_obj( obj, corpse );
			if(!IS_NPC(ch)) {
				free_string(wizbuf);
				free_string(objown);
			}
		}	
    }

    obj_to_room( corpse, ch->in_room );

    return;
}



/*
 * Improved Death_cry contributed by Diavolo.
 */
void death_cry( CHAR_DATA *ch )
{
    ROOM_INDEX_DATA *was_in_room;
    char *msg;
    int door;
    long vnum;

    vnum = 0;
    msg = "You hear $n's death cry.";

    switch ( number_bits(4))
    {
    case  0: msg  = "$n hits the ground ... DEAD.";                     break;
    case  1:
        if (ch->material == 0)
        {
            msg  = "$n splatters blood on your armor.";
            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;
        }
    }

    if (IS_SET(ch->parts,PART_HEAD) && is_affected(ch,gsn_decapitate))
    {
       msg  = "$n's severed head plops on the ground.";
       vnum = OBJ_VNUM_SEVERED_HEAD;
    }

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

    if ( vnum != 0 )
    {
        char buf[MAX_STRING_LENGTH];
        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 );

        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 );

        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;
        }

        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_new( CHAR_DATA *ch,CHAR_DATA *victim, bool deathCry, bool fLook)
{
int i, cloak=0;
    ROOM_INDEX_DATA *location;
    AFFECT_DATA af;
    AFFECT_DATA *paf, *paf_next;
    CHAR_DATA *gch, *gch_next, *zombie;
    OBJ_DATA *trophy, *obj, *strap, *duelcorpse;
    ROOM_INDEX_DATA *arena_room, *old_room;
    char buf[MAX_STRING_LENGTH], *cname;
    char wizbuf[MAX_STRING_LENGTH];
    bool unholy=0;
    bool credit_timer=0;

    stop_fighting( victim, TRUE );

    if (check_darkshout(ch) == DARKSHOUT_NECRUVIAN)
    {
		if (IS_GOOD(victim))
		{
			printf_to_char(ch, "You invoke your bond with The Lich Necruvian and siphon life from the lifeless body of %s.\n\r", 
				victim->name);
			ch->hit = UMIN( ch->hit + number_fuzzy(victim->level), ch->max_hit );
		}
    }

    if (is_affected(victim,gsn_cloak_form))
        do_cloak(victim,"auto");

    if (IS_NPC(victim) && victim->pIndexData->vnum == 3059) // PRACTICE DUMMY
    {
	act("$n's skull glows brightly and $n rises from $s ashes!",victim,0,0,TO_ROOM);
	return;
    }

    if (IS_NPC(victim) && victim->pIndexData->vnum == MOB_VNUM_DECOY)
    {
	death_cry(victim);
	act("$n vanishes in a poof of smoke!",victim,0,0,TO_ROOM);
    }
    else
    {
	if (deathCry)
    		death_cry( victim );
    

    	if (!IS_NPC(victim) && IS_IMMORTAL(victim))
    	{
            if (victim->pcdata->imm_death)
            {
            	act("$t.",victim,NULL,NULL,TO_ROOM);
            	act("$t.",victim,NULL,NULL,TO_CHAR);
            }
            else
            {
            	act("$n's skull glows brightly and $n rises from $s ashes!",victim,0,0,TO_ROOM);
            	send_to_char("Your skull glows brightly and you rise from your ashes!\n\r",victim);
            }
            return;
    	}

    	for (obj = victim->carrying;obj != NULL;obj = obj->next_content)
    	{
    	    if (IS_SET(obj->progtypes,IPROG_DEATH))
      	    	if ((obj->pIndexData->iprogs->death_prog) (obj,victim))
            	{
          	    victim->position = POS_STANDING;
          	    return;
            	}
    	}

    	if ( IS_SET(victim->progtypes,MPROG_DEATH))
	{
    	    if ((victim->pIndexData->mprogs->death_prog) (victim,ch))
      	    {
            	victim->position = POS_STANDING;
            	return;
      	    }
	}

    	if(IS_NPC(ch) && IS_AFFECTED(ch,AFF_CHARM) && ch->master && ch->master->in_room && ch->master->in_room == ch->in_room)
	    ch = ch->master;

    	// If bard phantom kills, killer becomes phantom->owner 
    	if(IS_NPC(ch) && ch->pIndexData->vnum == MOB_VNUM_PHANTOM && ch->owner)
	    ch = ch->owner;

    	if (!IS_NPC(victim)) 
    	{
	    if (arena) 
	    {

	    	/* MAIN STUFF */
	    	sprintf(buf,"%s is killed by %s!",victim->name,ch->original_name);
	    	do_arena_echo(buf);
	    	char_from_room(victim);
	    	location = get_room_index(26000);
	    	char_to_room(victim,location);
	    	victim->ghost = 1;

	    	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);
            	affect_strip(victim,gsn_decapitate);
            	affect_strip(victim,gsn_shackles);
            	affect_strip(victim,gsn_boneshatter);
            	affect_strip(victim,gsn_gouge);
		affect_strip(victim,skill_lookup("hex"));
		affect_strip(victim,skill_lookup("weaken"));
		affect_strip(victim,skill_lookup("impale"));
		affect_strip(victim,skill_lookup("crossslice"));
		affect_strip(victim,skill_lookup("insectswarm"));

            	victim->hit		= victim->max_hit;
            	victim->mana   	= victim->max_mana;
            	victim->move	= victim->max_move;
            	update_pos( victim);

	    	send_to_char("You have died and turned into an invincible ghost a few seconds.\n\r",victim);
	    	act("$n suddenly appears as a ghost.",victim,0,0,TO_ROOM);

		/* TROPHY CODE */
	    	trophy = create_object(get_obj_index(OBJ_VNUM_ARENA_TROPHY),0);
	    	sprintf( buf, trophy->short_descr, victim->original_name);
	    	free_string( trophy->short_descr );
	    	trophy->short_descr = str_dup( buf );
	    	sprintf( buf, trophy->description, victim->original_name);
	    	free_string( trophy->description );
	    	trophy->description = str_dup( buf );
	    	obj_to_char(trophy,ch);
	    	act("You receive $p.",ch,trophy,0,TO_CHAR);
	    	act("$n receives $p.",ch,trophy,0,TO_ROOM);
  	    	return;
	    } // End arena
    	} // End npc check for arena

    	temp_death_log(ch,victim);

    	/* AP unholy bless check --Dioxide */
    	if (check_unholy_new(ch,victim,get_eq_char(ch,WEAR_WIELD)) || check_unholy_new(ch,victim,get_eq_char(ch,WEAR_DUAL_WIELD))) 
 	{
	    unholy = TRUE;
    	} else {
	    unholy = FALSE;
    	}

    	if (is_affected(victim,gsn_unholy_timer)) 
    	{
	    unholy = TRUE;
    	}
	
	if (is_affected(victim,gsn_credit_timer))
	{
	    credit_timer = TRUE;
	}

    	strap = get_eq_char(victim, WEAR_STRAPPED);

    	if (strap != NULL) 
	{
	    do_strap(victim,strap);
    	}

    	make_corpse( ch,victim );

    } // End npc/pc decoy check.

    if(!IS_NPC(ch) && !IS_NPC(victim) && victim!=ch)
    	pay_bounty(ch, victim);

    if (ch && victim) 
    {
        sprintf( wizbuf, "%s died to %s at %s [room %ld]",
            (IS_NPC(victim) ? victim->short_descr : victim->original_name),
            (IS_NPC(ch) ? ch->short_descr : ch->original_name),
            victim->in_room->name, victim->in_room->vnum);

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

	free_string(wizbuf);
    }

    for (gch = char_list; gch != NULL; gch = gch_next)
    {
	gch_next = gch->next;
  	if (IS_NPC(gch) && gch->master == victim)
		extract_char(gch,TRUE);
    }

    if ( IS_NPC(victim) )
    {
        victim->pIndexData->killed++;
        kill_table[URANGE(0, victim->level, MAX_LEVEL-1)].killed++;
        extract_char( victim, TRUE );
        return;
    }

    for (paf=victim->affected; paf!=NULL; paf=paf_next)
    {
	paf_next=paf->next;

        if (paf->type == gsn_unholy_bless && (IS_NPC(ch) || arena))
            continue;

	if (!paf->dispel_at_death)
	    continue;

       	affect_remove( victim, paf );
    }

    extract_char( victim, FALSE );
    if(is_affected(victim,gsn_cloak_form)) cloak=1;

    for (paf=victim->affected; paf!=NULL; paf=paf_next)  
    {
        paf_next=paf->next;

	if (paf->type == gsn_unholy_bless && (IS_NPC(ch) || arena))
	    continue;

	if (paf->dispel_at_death == FALSE)
	    continue;

        affect_remove( victim, paf );             
    }

    victim->affected_by = race_table[victim->race].aff;

    for (i = 0; i < 4; i++)
        victim->armor[i]= 100;
    victim->position    = POS_RESTING;
    victim->hit         = victim->pcdata->perm_hit/2;
    victim->mana        = victim->pcdata->perm_mana/2;
    victim->move        = victim->pcdata->perm_move/2;
    victim->pcdata->condition[COND_HUNGER] 	= 48;
    victim->pcdata->condition[COND_THIRST] 	= 48;
    victim->pcdata->condition[COND_DRUNK] 	= 0;
    victim->pcdata->condition[COND_FULL] 	= 0;
    victim->pcdata->condition[COND_DEHYDRATED]	= 0;
    victim->pcdata->condition[COND_STARVING] 	= 0;
    REMOVE_BIT(victim->act,PLR_CRIMINAL);
    victim->ghost = 8;
    send_to_char("You have died and turned into an invincible ghost for a few minutes.\n\r",victim);

    if (victim->hometown)
		location = get_room_index(hometown_table[victim->hometown].recall);
    else
		location = get_room_index(ROOM_VNUM_TEMPLE);

    char_from_room(victim);
    char_to_room(victim,location);

    init_affect(&af);
    af.where 		= TO_AFFECTS;
    af.aftype 		= AFT_SKILL;
    af.type 		= skill_lookup("infravision");
	af.name			= str_dup("ghost");
    af.duration 	= 20;
    af.location 	= 0;
    af.bitvector 	= AFF_INFRARED|AFF_PASS_DOOR|AFF_FLYING;
    af.modifier 	= 0;
	char msg_buf[MSL];
	sprintf(msg_buf,"turned into a ghostly spirit");
	af.affect_list_msg = str_dup(msg_buf);
    af.level		= victim->level;
    affect_to_char(victim,&af);

    if (unholy) 
    {
	if (!is_affected(victim, skill_lookup("unholy guard")))
	{
		init_affect(&af);
    		af.where 	= TO_AFFECTS;
		af.aftype 	= AFT_SPELL;
    		af.type 	= skill_lookup("unholy guard");
    		af.duration 	= 18;
    		af.location 	= 0;
    		af.modifier 	= 0;
			char msg_buf[MSL];
			sprintf(msg_buf,"protects your soul from unholy bless");
			af.affect_list_msg = str_dup(msg_buf);
    		af.level	= victim->level;
			af.dispel_at_death = FALSE;
    		affect_to_char(victim,&af);
	}
    }

    if (!credit_timer)
    {
		if (!IS_NPC(victim) && !IS_NPC(ch)) {
			char quest_buf[MSL];
			sprintf(quest_buf,"As $N collapses, you find yourself holding %d quest credits!",QUEST_CREDITS_PER_PK);
			act(quest_buf,ch,0,victim,TO_CHAR);
			gain_quest_credits(ch,QUEST_CREDITS_PER_PK);

			init_affect(&af);
			af.where 	= TO_AFFECTS;
			af.aftype 	= AFT_SKILL;
			af.type 	= gsn_credit_timer;
			af.duration 	= 30;
			af.location 	= 0;
			af.modifier 	= 0;
			af.name			= str_dup("quest guard");
			af.affect_list_msg	= str_dup("cannot be harvested for quest credits");
			af.level	= victim->level;
			af.dispel_at_death = FALSE;
			affect_to_char(victim,&af);
		}
    }
		
    victim->last_fight_name = NULL;
    victim->last_fight_time = 0;
	
    // con death
    if (!IS_NPC(victim))
    {
	if (ch->race == race_lookup("lich"))
		victim->pcdata->death_count=4;
	else
		victim->pcdata->death_count++;

	if ( (victim->pcdata->death_count >= 4) && !IS_IMMORTAL(victim) && !(victim->perm_stat[STAT_CON] < 3))
	{
		victim->perm_stat[STAT_CON] -= 1;
		victim->pcdata->death_count = 0;
		send_to_char("With this death you feel your vitality draining away from you.\n\r",victim);
	}
	if (victim->perm_stat[STAT_CON] < CON_DIE_BOUND) {
		SET_BIT(victim->act, PLR_DENY);
		perm_death_log(victim,2);
		send_to_char("You gasp your final breaths. Your vitality has faded.\n\r",victim);
		wiznet("$N dies of constitution loss.",victim,NULL,0,0,0);
		stop_fighting(victim,TRUE);
		victim->pause = 0;
		save_char_obj(victim);
		cname	= str_dup(victim->original_name);
		do_quit_new(victim,"",TRUE);
		delete_char(cname, TRUE);
		return;
	}
	if (victim->perm_stat[STAT_CON] < 5)
		send_to_char("The banshee wails as you feel closer to a permanent death.\n\r",victim);
    } // End con death

    if(!IS_NPC(ch) && ch->in_room->vnum==ROOM_FORCE_DUEL)
    {
	init_affect(&af);
	af.where 	= TO_AFFECTS;
	af.aftype 	= AFT_POWER;
        af.type 	= gsn_honorable_combat;
	af.duration 	= 50;
	af.location 	= 0;
	af.modifier 	= 0;
	af.bitvector	= 0;
	char msg_buf[MSL];
	sprintf(msg_buf,"safe from honorable combat");
	af.affect_list_msg = str_dup(msg_buf);
	af.level	= ch->level;
	affect_to_char(victim,&af);

	char_from_room(ch);
	old_room=get_room_index(ch->pcdata->old_room);
	arena_room=get_room_index(ROOM_FORCE_DUEL);
	char_to_room(ch,old_room);
	act("$n arrives in a blaze of white light, having triumphed honorably over $N!\n\r",ch,0,victim,TO_ROOM);
	for (duelcorpse = arena_room->contents; duelcorpse != NULL; duelcorpse = duelcorpse->next)
    	{
	    if(duelcorpse->in_room==arena_room)
	    {
	    	obj_from_room(duelcorpse);
		obj_to_room(duelcorpse,old_room);
	    }
    	}

        for (zombie = arena_room->people; zombie != NULL; zombie = zombie->next_in_room)
	{
	    if (zombie!=NULL && IS_NPC(zombie) && IS_AFFECTED(zombie,AFF_CHARM) && zombie->pIndexData->vnum==MOB_VNUM_ZOMBIE)
	    {
		char_from_room(zombie);
		char_to_room(zombie,old_room);
	    }
    	}
    } // End force duel

    if (fLook)
    	do_look(victim,"auto");
    return;
}

void raw_kill( CHAR_DATA *ch,CHAR_DATA *victim )
{
    raw_kill_new( ch, victim, TRUE, TRUE );
}

void group_gain( CHAR_DATA *ch, CHAR_DATA *victim )
{
    char buf[MAX_STRING_LENGTH];
    CHAR_DATA *gch;
    CHAR_DATA *lch;
    int xp;
    int members;
    int group_levels;
    long quest_credit_gain;
	
    /*
     * 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 ) )
        {
            if(!IS_NPC(gch)) members++;
            group_levels+=gch->level;
            if(IS_NPC(gch)) group_levels+=gch->level;
        }
    }

    if ( members == 0 )
    {
        members = 1;
    }

    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;
	bool owner = FALSE;

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

        if ( gch->level - lch->level > 8 )
        {
            send_to_char( "You are too high for this group.\n\r", gch );
            continue;
        }

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


        xp = xp_compute( gch, victim, members, group_levels );
	quest_credit_gain = quest_credit_compute( gch, victim, members );

        if (IS_NPC(victim))
	{
		if(victim->quest_credits <= 0)
		{
			sprintf( buf, "You receive %d experience points.\n\r", xp );
			send_to_char( buf, gch );
		}
		else
		{
			sprintf( buf, "You receive %d experience points.\n\r", xp);
			send_to_char( buf, gch );
			sprintf( buf, "{RAs %s collapses, you suddenly feel an unusually large weight of precious quest credits burden you.{x\n\r", victim->short_descr);
			send_to_char( buf, gch );
			sprintf( buf, "You find an extra %ld quest credits in your possession!\n\r", quest_credit_gain );
			send_to_char( buf, gch );
			gain_quest_credits( gch, quest_credit_gain );
		}
	}
        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;

	ch->unholy_name = str_dup(ch->name);

	if (str_cmp(obj->owner,ch->unholy_name) )
	{
	owner = TRUE;
	}

            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) )
	    ||   ( IS_OBJ_STAT(obj, ITEM_ANTI_NEUT)    &&
	         (ch->pcdata->ethos == 0))
	    ||   ( IS_OBJ_STAT(obj, ITEM_ANTI_CHAOTIC) &&
		 (ch->pcdata->ethos < 0))
	    ||   ( IS_WEAPON_STAT(obj,WEAPON_UNHOLY)  && (owner)))
            {
                act( "You are zapped by $p.", ch, obj, NULL, TO_CHAR );
                act( "$n is zapped by $p.",   ch, obj, NULL, TO_ROOM );
                obj_from_char( obj );
                obj_to_room( obj, ch->in_room );
            }
        }
    }

    return;
}

long quest_credit_compute( CHAR_DATA *ch, CHAR_DATA *victim, int group_amount)
{
    int quest_credit_gain = 0;

    if (IS_NPC(victim) && victim->quest_credits > 0)
	quest_credit_gain = victim->quest_credits;
    
    else
    {
   	  if (group_amount == 1)
		{
		if (victim->level < 45)
			quest_credit_gain = 0;
		else 
			quest_credit_gain = (victim->level / 18);
		}

  	  else if (group_amount == 2)
		{
		if (victim->level < 45)
			quest_credit_gain = 0;
		else 
			quest_credit_gain = (victim->level / 18) / 3;
		}
    	  else if (group_amount == 3)
		{
		if (victim->level < 45)
			quest_credit_gain = 0;
		else 
			quest_credit_gain = (victim->level / 18) / 3;
		}
   	  else if (group_amount > 3)
		{
		if (victim->level < 45)
			quest_credit_gain = 0;
		else 
			quest_credit_gain = (victim->level / 18) / (group_amount -2);
		}
     }

	return quest_credit_gain;
}

/*
 * 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 group_amount, int glevel )
{
    int xp,base_exp;
    int level_range;
    double mult;

    mult=((double)(gch->level)/glevel)*group_amount;
    if(mult>=1) { mult=(1+mult)/2;
    } else {
       mult=mult*mult;
    }
    mult = URANGE(.25,mult,1.1);

    level_range = victim->level - gch->level;

    /* compute the base exp */
    switch (level_range)
    {
        default :       base_exp =   0;         break;
        case -9 :       base_exp =   2;         break;
        case -8 :       base_exp =   4;         break;
        case -7 :       base_exp =   7;         break;
        case -6 :       base_exp =   12;         break;
        case -5 :       base_exp =  14;         break;
        case -4 :       base_exp =  25;         break;
        case -3 :       base_exp =  36;         break;
        case -2 :       base_exp =  55;         break;
        case -1 :       base_exp =  70;         break;
        case  0 :       base_exp =  88;         break;
        case  1 :       base_exp =  110;         break;
        case  2 :       base_exp = 131;         break;
        case  3 :       base_exp = 153;         break;
        case  4 :       base_exp = 165;         break;
    }

    if (level_range > 4)
        base_exp = 165 + 15 * (level_range - 4);
    if(mult<1&&level_range>4)
        base_exp = (2*base_exp+165)/3;

    if (IS_SET(victim->act,ACT_NOALIGN))
        xp = base_exp;

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

        else if (victim->alignment > 0)
            xp = -30;

        else
            xp = base_exp;
    }

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

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

        else
            xp = base_exp;
    }


    else /* neutral */
    {
            xp = base_exp;
    }

    xp = (xp*2)/3;

    xp=xp*mult;
    xp = number_range (xp, xp * 5/4);



    /* adjust for grouping */
    if (group_amount == 2)
        xp = (xp * 5)/3;
    if (group_amount == 3)
        xp = (xp * 7)/3;
    if (group_amount > 3)
	xp /= (group_amount - 2);

    return xp;
}


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

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

    if (is_affected(victim,skill_lookup("mana shield")) && victim->mana > dam)
    {
		vs = "{xis absorbed by the mana shield around"; vp = "{xis absorbed by the mana shield around";
    }
    else {
		if (is_affected(victim,skill_lookup("mana shield")) && victim->mana <= dam)
			dam = dam - victim->mana;
			
		if (dam < 0) { vs = "fail to harm";	vp = "fails to harm"; dam = 0;	}
		else if ( dam ==   0 ) { vs = "miss";       vp = "misses";          }
	    else if ( dam <=   2 ) { vs = "scratch";    vp = "scratches";       }
	    else if ( dam <=   4 ) { vs = "graze";      vp = "grazes";          }
	    else if ( dam <=   7 ) { vs = "hit";        vp = "hits";            }
	    else if ( dam <=  11 ) { vs = "injure";     vp = "injures";         }
	    else if ( dam <=  15 ) { vs = "wound";      vp = "wounds";          }
	    else if ( dam <=  20 ) { vs = "maul";       vp = "mauls";           }
	    else if ( dam <=  25 ) { vs = "decimate";   vp = "decimates";       }
	    else if ( dam <=  30 ) { vs = "devastate";  vp = "devastates";      }
	    else if ( dam <=  37 ) { vs = "maim";       vp = "maims";           }
	    else if ( dam <=  45 ) { vs = "MUTILATE";   vp = "MUTILATES";       }
	    else if ( dam <=  55 ) { vs = "EVISCERATE"; vp = "EVISCERATES";     }
	    else if ( dam <=  65 ) { vs = "DISMEMBER";  vp = "DISMEMBERS";   }
	    else if ( dam <=  85 ) { vs = "MASSACRE";   vp = "MASSACRES";       }
	    else if ( dam <=  100 ) { vs = "MANGLE";     vp = "MANGLES";         }
	    else if ( dam <= 135 ) { vs = "*** DEMOLISH ***";
	                             vp = "*** DEMOLISHES ***";                 }
	    else if ( dam <= 160 ) { vs = "*** DEVASTATE ***";
	                             vp = "*** DEVASTATES ***";                 }
	    else if ( dam <= 250)  { vs = "=== OBLITERATE ===";
	                             vp = "=== OBLITERATES ===";                }
	    else if ( dam <= 330)  { vs = ">>> ANNIHILATE <<<";
	                             vp = ">>> ANNIHILATES <<<";                }
	    else if ( dam <= 380)  { vs = "<<< ERADICATE >>>";
	                             vp = "<<< ERADICATES >>>";                 }
	    else                   { vs = "do UNSPEAKABLE things to";
	                             vp = "does UNSPEAKABLE things to";         }
	}
	
    punct   = (dam <= 25) ? '.' : '!';

    if (dt  == gsn_dual_wield) 
    {
    	wield = get_eq_char(ch,WEAR_DUAL_WIELD);
		dt = TYPE_HIT;
		if (wield != NULL)
			dt += wield->value[3];
		else
			dt += ch->dam_type;
    }

    if ( dt == TYPE_HIT )
    {
        if (ch == victim)
        {
            sprintf( buf1, "$n %s $melf%c [%d]",vp,punct,dam);
            sprintf( buf2, "You %s yourself%c [%d]",vs,punct,dam);
        }
        else
        {
			for (gch = victim->in_room->people; gch != NULL; gch = gch->next_in_room)
			{
			    if (gch != ch && gch != victim)
			    {
		            sprintf( buf1, "$n's {r%s{x %s%c [%d]",  vp, get_descr_form(victim,gch,FALSE), punct, dam);
					act(buf1,ch,NULL,gch,TO_VICT);
			    }
			}

            sprintf( buf2, "You {r%s{x $N%c [%d]", vs, punct, dam );
            sprintf( buf3, "$n {r%s{x you%c [%d]", 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
        {
            dt  = TYPE_HIT+17;
            attack  = attack_table[0].noun;
        }

		if (dnoun)
			attack = str_dup(dnoun);

        if (immune)
        {
            if (ch == victim)
            {
				if (!showCharName)
					sprintf(buf1,"$n is unaffected by $s own %s.",attack);
				else
					sprintf(buf1,"$n is unaffected by %s.",attack);
                sprintf(buf2,"Luckily, you are immune to that.");
            }
            else
            {
				if (showCharName) {
					sprintf(buf1,"$N is unaffected by $n's %s!",attack);
					sprintf(buf2,"$N is unaffected by your %s!",attack);
					sprintf(buf3,"$n's %s is powerless against you.",attack);
				}
				else {
					sprintf(buf1,"$N is unaffected by %s!",attack);
					sprintf(buf2,"$N is unaffected by %s!",attack);
					sprintf(buf3,"%s is powerless against you.",attack);
				}
                
            }
        }
        else
        {
            if (ch == victim)
            {
				for (gch = victim->in_room->people; gch != NULL; gch = gch->next_in_room)
				{
				    if (gch != ch && gch != victim)
				    {
						if (showCharName)
						{
							if (isPlural)
				                sprintf( buf1, "$n's %s {r%s{x $m%c [%d]",  attack, vp, punct, dam );
							else
								sprintf( buf1, "$n's %s {r%s{x $m%c [%d]",  attack, vs, punct, dam );
						}
						else
						{
							if (isPlural)
				                sprintf( buf1, "%s {r%s{x $n%c [%d]",  attack, vp, punct, dam );
							else
								sprintf( buf1, "%s {r%s{x $n%c [%d]",  attack, vs, punct, dam );
						}
						act(buf1,ch,NULL,gch,TO_VICT);
				    }
				}
				if (showCharName)
				{
					if (isPlural)
		                sprintf( buf2, "Your %s {r%s{x you%c [%d]",attack,vp,punct, dam);
					else
						sprintf( buf2, "Your %s {r%s{x you%c [%d]",attack,vs,punct, dam);
				}
				else
				{
					if (isPlural)
		                sprintf( buf2, "%s {r%s{x you%c [%d]",attack,vp,punct, dam);
					else
						sprintf( buf2, "%s {r%s{x you%c [%d]",attack,vs,punct, dam);
				}
            }
            else
            {
				for (gch = victim->in_room->people; gch != NULL; gch = gch->next_in_room)
				{
				    if (gch != ch && gch != victim)
				    {
						if (showCharName)
						{
							if (isPlural)
			 					sprintf(buf1, "$n's %s {r%s{x %s%c [%d]", attack, vp, get_descr_form(victim,gch,FALSE), punct, dam);
							else
								sprintf(buf1, "$n's %s {r%s{x %s%c [%d]", attack, vs, get_descr_form(victim,gch,FALSE), punct, dam);
						}
						else
						{
							if (isPlural)
								sprintf(buf1, "%s {r%s{x %s%c [%d]", attack, vp, get_descr_form(victim,gch,FALSE), punct, dam);
							else
								sprintf(buf1, "%s {r%s{x %s%c [%d]", attack, vs, get_descr_form(victim,gch,FALSE), punct, dam);
						}
						act(buf1,ch,NULL,gch,TO_VICT);
				    }
				}
		
				if (showCharName)
				{
					if (isPlural)
		                sprintf( buf2, "Your %s {r%s{x $N%c [%d]",  attack, vp, punct, dam );
					else
						sprintf( buf2, "Your %s {r%s{x $N%c [%d]",  attack, vs, punct, dam );
					if (isPlural)
		                sprintf( buf3, "$n's %s {r%s{x you%c [%d]", attack, vp, punct, dam );
					else
						sprintf( buf3, "$n's %s {r%s{x you%c [%d]", attack, vs, punct, dam );
				}
				else
				{
					if (isPlural)
		                sprintf( buf2, "%s {r%s{x $N%c [%d]",  attack, vp, punct, dam );
					else
						sprintf( buf2, "%s {r%s{x $N%c [%d]",  attack, vs, punct, dam );
					if (isPlural)
		                sprintf( buf3, "%s {r%s{x you%c [%d]", attack, vp, punct, dam );
					else
						sprintf( buf3, "%s {r%s{x you%c [%d]", attack, vs, punct, dam );
				}
            }
        }
    }

    if (ch == victim)
    {
	act_new(buf2,ch,NULL,NULL,TO_CHAR,POS_INCAP);
    }
    else
    {
        act( buf2, ch, NULL, victim, TO_CHAR );
        act( buf3, ch, NULL, victim, TO_VICT );
    }

    if (dt != gsn_poison && dt != gsn_plague && dt != gsn_starvation && dt != gsn_dehydrated)
    {
    	if (!IS_IMMORTAL(ch))
		{
		    if (!IS_NPC(victim))
		    {
				ch->pause = 10;
		    }
		    else
		    {
				ch->pause = 1;
		    }
		}

	   	if (!IS_IMMORTAL(victim))
		{
		    if (!IS_NPC(ch))
		    {
			victim->pause = 10;
		    }
		    else
		    {
			ch->pause = 1;
		    }
		}
    }
    return;
}



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


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

    if (IS_AFFECTED(ch,AFF_BLIND))

    {
        act("You can't see the person to disarm them!",ch,NULL,victim,TO_CHAR);
        return;
    }

    if (IS_NPC(ch) && (IS_AFFECTED(ch,AFF_BLIND)))
       return;

    if ( IS_OBJ_STAT(obj,ITEM_NOREMOVE) || IS_OBJ_STAT(obj,ITEM_NODISARM))
    {
        act("$S weapon won't budge!",ch,NULL,victim,TO_CHAR);
        act("$n tries to disarm you, but your weapon won't budge!",
            ch,NULL,victim,TO_VICT);
        act("$n tries to disarm $N, but fails.",ch,NULL,victim,TO_NOTVICT);
        return;
    }

	if (is_affected(ch,gsn_unholy_affinity) && ((obj2 = get_eq_char(ch,WEAR_WIELD)) != NULL) && is_affected_obj(obj2,gsn_unholy_bless))
	{
		act("$n tries to disarm you, but you refuse to let go!",victim,0,ch,TO_CHAR);
		act("You try to disarm $n, but he won't let go of $s weapon!",victim,0,ch,TO_VICT);
		act("$N tries to disarm $n, but $n holds onto $s weapon!",victim,0,ch,TO_NOTVICT);
		return;
	}

    act( "$n DISARMS you and sends your weapon flying!",
         ch, NULL, victim, TO_VICT    );
    act( "You disarm $N!",  ch, NULL, victim, TO_CHAR    );
    act( "$n disarms $N!",  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 to owner if owned item
		if (strcmp(obj->owner,victim->name) == 0) {
			act( "$N's $p twitches on the ground, then returns to $M!", ch, obj, victim, TO_NOTVICT);
			act( "$p twitches on the ground, then returns to yout!", ch, obj, victim, TO_VICT);
			obj_to_char( obj, victim );
		}
    }

reslot_weapon(victim);

    if ((secondary = get_eq_char(victim,WEAR_DUAL_WIELD)) != NULL)
    {
	unequip_char(victim,secondary);
	equip_char(victim,secondary,WEAR_WIELD);
    }
    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]))
    	{
        	send_to_char("You turn red in the face, but nothing happens.\n\r",ch);
        	return;
    	}

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

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

	if (IS_AFFECTED(ch,AFF_SLOW))
	{
		send_to_char("You're feeling way too lethargic to berserk.\n\r", ch);
		return;
	}

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

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

    	if (ch->max_hit == 0)
		hp_percent = 0;
     	else
    		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 -= 100;
        	ch->move /= 1.2;

        	ch->hit += (ch->drain_level + ch->level) * 4;
        	ch->hit = UMIN(ch->hit,ch->max_hit);

        	send_to_char("Your pulse races as you are consumed by rage!\n\r",ch);
        	act("$n gets a wild look in $s eyes.",ch,NULL,NULL,TO_ROOM);
        	check_improve(ch,gsn_berserk,TRUE,2);

		init_affect(&af);
        	af.where        = TO_AFFECTS;
        	af.type         = gsn_berserk;
        	af.level        = ch->level;
		af.duration 	= number_range(4,9);
        	af.modifier     = 10;
        	af.bitvector    = AFF_BERSERK;
		af.aftype	= AFT_SKILL;

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

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

		af.modifier 	= -2 * AC_PER_ONE_PERCENT_DECREASE_DAMAGE;
        	af.location     = APPLY_AC;
        	affect_to_char(ch,&af);
    	}
    	else
    	{
        	WAIT_STATE(ch,PULSE_VIOLENCE);
        	ch->mana -= 25;

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

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

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

    	if (IS_NPC(ch) && IS_AFFECTED(ch,AFF_CHARM))
		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_AFFECTED(ch,AFF_CHARM) && ch->master == victim)
    	{
        	act("But $N is your friend!",ch,NULL,victim,TO_CHAR);
        	return;
    	}

    	if (is_affected(victim,gsn_protective_shield))
    	{
		act("$N's bash seems to slide around you.",victim,0,ch,TO_CHAR);
		act("$N's bash seems to slide around $n.",victim,0,ch,TO_NOTVICT);
		act("Your bash seems to slide around $n.",victim,0,ch,TO_VICT);
		WAIT_STATE(ch,PULSE_VIOLENCE*.5);
		return;
    	}

    	if (is_affected(victim,gsn_asscounter))
    	{
		act("You deftly sidestep $N's bash, throwing them to the ground.",victim,0,ch,TO_CHAR);
        	act("$n quickly dodges $N's bash, throwing $s down in the process.",victim,0,ch,TO_NOTVICT);
        	act("$n deftly dodges your bash, throwing you to the ground in the process.",victim,0,ch,TO_VICT);
        	WAIT_STATE(ch,2 * PULSE_VIOLENCE);
        	dam = victim->level*2 + number_percent()*2 - 50;
        	damage_old(victim,ch,dam,gsn_throw,DAM_BASH,TRUE);
        	affect_strip( victim, gsn_asscounter );
		return;
    	}

    	if (is_affected(victim, skill_lookup("wraithform")))
    	{
		act("$N's tries to bash you but stumbles through thin air.",victim,0,ch,TO_CHAR);
		act("$N's tries to bash $n but stumbles through thin air.",victim,0,ch,TO_NOTVICT);
		act("You stumble as you try to bash $n but stumble through thin air.",victim,0,ch,TO_VICT);
		WAIT_STATE(ch,PULSE_VIOLENCE*1);
		return;
    	}

    	chance += ch->carry_weight / 250;
    	chance -= victim->carry_weight / 200;

    	if (ch->size < victim->size)
        	chance += (ch->size - victim->size) * 20;
    	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 -= 40;

    	/* level */
    	chance += (ch->drain_level + ch->level - victim->level - victim->drain_level);
	
	if (!IS_NPC(ch) && !IS_NPC(victim) && (victim->fighting == NULL || ch->fighting == NULL))
	{
		sprintf(buf,"Help! %s is bashing me!",PERS(ch,victim));
		do_myell(victim,buf);
	}


    	if (!IS_NPC(victim) && chance < get_skill(victim,gsn_dodge) )
        	chance -= 3 * (get_skill(victim,gsn_dodge) - chance);

    	/* now the attack */
    	if (number_percent() < chance )
    	{
        	act("$n sends you sprawling with a powerful bash!", ch,NULL,victim,TO_VICT);
        	act("You slam into $N, and send $M flying!",ch,NULL,victim,TO_CHAR);
        	act("$n sends $N sprawling with a powerful bash.", ch,NULL,victim,TO_NOTVICT);
        	check_improve(ch,gsn_bash,TRUE,1);
        	WAIT_STATE(victim, 2 * PULSE_VIOLENCE);
        	damage_old(ch,victim,number_range(2,2 + 2 * ch->size + chance/20),gsn_bash, DAM_BASH,TRUE);
        	WAIT_STATE(ch,skill_table[gsn_bash].beats);
        	victim->position = POS_RESTING;
	}
   	else
   	{
        	damage_old(ch,victim,0,gsn_bash,DAM_BASH,FALSE);
        	act("You fall flat on your face!", ch,NULL,victim,TO_CHAR);
        	act("$n falls flat on $s face.", ch,NULL,victim,TO_NOTVICT);
        	act("You evade $n's bash, causing $m to fall flat on $s face.", ch,NULL,victim,TO_VICT);
		check_cheap_shot(victim,ch);
        	check_improve(ch,gsn_bash,FALSE,1);
        	ch->position = POS_RESTING;
        	WAIT_STATE(ch,skill_table[gsn_bash].beats);
    	}
    	check_killer(ch,victim);
}

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

    one_argument(argument,arg);

    if ( (chance = get_skill(ch,gsn_dirt)) == 0
    ||   (IS_NPC(ch) && !IS_SET(ch->off_flags,OFF_KICK_DIRT) && ch->pIndexData->vnum!=MOB_VNUM_ENFORCER)
    ||   (!IS_NPC(ch)
    &&    ch->level < skill_table[gsn_dirt].skill_level[ch->class]))
    {
        send_to_char("You get your feet dirty.\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("$E's already been blinded.",ch,NULL,victim,TO_CHAR);
        return;
    }

    if(victim->position==POS_SLEEPING) {
	send_to_char("Their eyes are closed.\n\r",ch);
	return;
    }

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

    if (is_safe(ch,victim))
        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 (is_affected(victim, gsn_shield_of_dust))
    {
	act("Your dirt is blocked by $N's shield of dust!",ch,NULL,victim,TO_CHAR);
	act("$n kicks dirt at you but it is stoped by your shield of dust!", ch,NULL,victim,TO_VICT);
	act("$n's dirt is deflected by $N's shield of dust!",ch,NULL,victim,TO_NOTVICT);
	return;
    }

    /* 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 -= 30;

    /* level */
    chance += (ch->drain_level + ch->level - victim->level - victim->drain_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("There isn't any dirt to kick.\n\r",ch);
        return;
    }

    /* now the attack */
    if (number_percent() < chance)
    {
        AFFECT_DATA af;
        act("$n is blinded by the dirt in $s eyes!",victim,NULL,NULL,TO_ROOM);
        act("$n kicks dirt in your eyes!",ch,NULL,victim,TO_VICT);
	if (!IS_NPC(ch) && !IS_NPC(victim) && ( (victim->fighting == NULL) || (ch->fighting == NULL)))
		do_myell(victim,"Help! Someone just kicked dirt in my eyes!");

        damage(ch,victim,number_range(2,5),gsn_dirt,DAM_TRUESTRIKE,TRUE);
        send_to_char("You can't see a thing!\n\r",victim);
        check_improve(ch,gsn_dirt,TRUE,2);
        WAIT_STATE(ch,skill_table[gsn_dirt].beats);

	init_affect(&af);
        af.where        = TO_AFFECTS;
        af.type         = gsn_dirt;
	af.aftype 	= AFT_MALADY;
        af.level        = ch->level + ch->drain_level;
        af.duration     = 0;
        af.location     = APPLY_HITROLL;
        af.modifier     = -4;
        af.bitvector    = AFF_BLIND;

        affect_to_char(victim,&af);
    }
    else
    {
	if (!IS_NPC(ch) && !IS_NPC(victim) && (victim->fighting == NULL || ch->fighting == NULL))
	{
		switch(number_range(0,1))
		{
		case (0):
			sprintf(buf,"Help! %s just tried to kick dirt in my eyes!",PERS(ch,victim));
		break;
		case (1):
			sprintf(buf,"Die, %s you dirty fool!",PERS(ch,victim));
		break;
		}
		do_myell(victim,buf);
	}
        damage(ch,victim,0,gsn_dirt,DAM_NONE,TRUE);

        check_improve(ch,gsn_dirt,FALSE,2);
        WAIT_STATE(ch,skill_table[gsn_dirt].beats);
    }
        check_killer(ch,victim);
}

void do_trip( CHAR_DATA *ch, char *argument )
{
    char arg[MAX_INPUT_LENGTH];
    CHAR_DATA *victim;
    int chance;
    int dam;
    AFFECT_DATA af;
    char buf[MAX_STRING_LENGTH];

    one_argument(argument,arg);

    if ( (chance = get_skill(ch,gsn_trip)) == 0
    ||   (IS_NPC(ch) && !IS_SET(ch->off_flags,OFF_TRIP) && ch->pIndexData->vnum!=MOB_VNUM_ENFORCER)
    ||   (!IS_NPC(ch)
          && ch->level < skill_table[gsn_trip].skill_level[ch->class]))
    {
        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_AFFECTED(victim,AFF_FLYING)
	&& !is_affected(victim,gsn_earthbind))
    {
        act("$S feet aren't on the ground.",ch,NULL,victim,TO_CHAR);
        return;
    }

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

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

    if (is_affected(victim,gsn_asscounter))
    {
        act("You dart to the side kicking the inside of $N's knee!",victim,0,ch,TO_CHAR);
        act("$n darts to the side kicking the inside of $N's knee!",victim,0,ch,TO_NOTVICT);
        act("$n dodges your trip, then kicks the inside of your knee!",victim,0,ch,TO_VICT);
        WAIT_STATE(victim,1 * PULSE_VIOLENCE);
        dam = victim->level*2 + number_percent()*2 - 50;
        damage_old(victim,ch,dam,gsn_legbreak,DAM_BASH,TRUE);

         if (!is_affected(ch,gsn_legbreak))
           {
		init_affect(&af);
                af.where     = TO_AFFECTS;
		af.aftype = AFT_MALADY;
                af.type      = gsn_legbreak;
                af.level     = victim->level;
                af.duration  = victim->level/5;
                af.bitvector = 0;
                af.location  = APPLY_DEX;
                af.modifier  = 1-(victim->level/5);
                affect_to_char(ch,&af);
            }
        affect_strip( victim, gsn_asscounter );
        return;
 }

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

    /* 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 -= 40;

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


    /* now the attack */
    if (number_percent() < chance)
    {
        act("$n trips you and you go down!",ch,NULL,victim,TO_VICT);
        act("You trip $N and $N goes down!",ch,NULL,victim,TO_CHAR);
        act("$n trips $N, sending $M to the ground.",ch,NULL,victim,TO_NOTVICT);
        check_improve(ch,gsn_trip,TRUE,1);

	if (!IS_NPC(ch) && !IS_NPC(victim)
	&& (ch->fighting == NULL || victim->fighting == NULL))
	{
	    	sprintf(buf,"Help! %s just tripped me!",PERS(ch,victim));
	    do_myell(victim,buf);
	}
        WAIT_STATE(victim,2 * PULSE_VIOLENCE);
        WAIT_STATE(ch,skill_table[gsn_trip].beats);
        victim->position = POS_RESTING;
        damage(ch,victim,number_range(2, 2 +  2 * victim->size),gsn_trip, DAM_BASH,TRUE);
	check_downstrike(ch,victim);
	check_cheap_shot(ch,victim);
    }
    else
    {
	if (!IS_NPC(ch) && !IS_NPC(victim)
	&& (ch->fighting == NULL || victim->fighting == NULL))
	{
		sprintf(buf,"Help! %s just tried to trip me!",PERS(ch,victim));
	    do_myell(victim,buf);
	}
        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);
    }
        check_killer(ch,victim);
}

void do_hit( CHAR_DATA *ch, char *argument )
{
    char arg[MAX_INPUT_LENGTH];
    CHAR_DATA *victim;

    one_argument( argument, arg );

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

    if ( arg[0] == '\0' )
    {
	send_to_char( "Switch targets to 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( "Are you crazy?\n\r", ch );
        return;
    }

    if ( victim->fighting != ch )
    {
	send_to_char( "That person isn't fighting you.\n\r", ch );
	return;
    }

    ch->fighting = victim;
    return;
}

void do_kill( CHAR_DATA *ch, char *argument )
{
    char arg[MAX_INPUT_LENGTH];
    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;
    }
/*  Allow player killing   */
    if ( !IS_NPC(victim) )
    {
        send_to_char( "You must MURDER a player.\n\r", ch );
        return;
    }
    if ( victim == ch )
    {
        send_to_char( "You hit yourself.  Ouch!\n\r", ch );
        multi_hit( ch, ch, TYPE_UNDEFINED );
        return;
    }

    if ( is_safe( ch, victim ) )
        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;
    }

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



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



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

    one_argument( argument, arg );

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

    if ((IS_AFFECTED(ch,AFF_CHARM) || (IS_NPC(ch) && IS_SET(ch->act,ACT_PET)))
    && !is_centurion(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( "Suicide is a mortal sin.\n\r", ch );
        return;
    }

    if ( is_safe( ch, victim ) )
        return;

	if (check_chargeset(ch,victim)) {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;
    }

    WAIT_STATE( ch, 1 * PULSE_VIOLENCE );
    if (IS_NPC(ch))
        sprintf(buf, "Help! I am being attacked by %s!",ch->short_descr);
    else
    {
        switch(number_range(1,6))
        {
	default:
            sprintf(buf, "Help!  I am being attacked by %s!",PERS(ch,victim));
            break;
        case (1):
            sprintf(buf, "Help!  I am being attacked by %s!",PERS(ch,victim));
            break;
        case (2):
            sprintf(buf, "Die %s, you dirty fool!", PERS(ch,victim));
            break;
        case (3): case (4):
            sprintf(buf, "Help!  %s is attacking me!", PERS(ch,victim));
            break;
        case (5):
            sprintf(buf, "How dare you attack me %s!", PERS(ch,victim));
            break;
        case (6):
            sprintf(buf, "Help!  %s is hurting me!", PERS(ch,victim));
            break;
        }
    }

/* Added a myell hack of yell so Enforcer cabal members can see if a PK
yell is faked or not (see myell in act_comm.c for this).
-Ceran
*/
    do_myell( victim, buf );
    multi_hit( ch, victim, TYPE_UNDEFINED );
    return;
}

void do_backstab( CHAR_DATA *ch, char *argument )
{
    char arg[MAX_INPUT_LENGTH];
    CHAR_DATA *victim;
    OBJ_DATA *obj;
    int dam;
    char buf[MAX_STRING_LENGTH];

    one_argument( argument, arg );


    if ( (get_skill(ch,gsn_backstab) == 0 )
	|| ch->level < skill_table[gsn_backstab].skill_level[ch->class])
    {
	if (!IS_NPC(ch))
	{
	send_to_char("You don't know how to backstab.\n\r",ch);
	return;
	}
    }

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

    if (ch->fighting != NULL)
    {
        send_to_char("You're facing the wrong end.\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;
    }

        obj= get_eq_char(ch,WEAR_WIELD);

        if (obj == NULL)
        {
        send_to_char("You must be wielding a weapon to backstab.\n\r",ch);
        return;
        }

        if (obj->value[0] != WEAPON_DAGGER)
        {
        obj = get_eq_char(ch,WEAR_DUAL_WIELD);
        if (obj == NULL)
        {
        send_to_char("You must be wielding a weapon to backstab.\n\r",ch);
        return;
        }
        }

        if (obj->value[0] != WEAPON_DAGGER)
        {
        send_to_char("You need to be wielding a dagger to backstab.\n\r",ch);
        return;
        }

    if ( is_safe(ch, victim ) )
      return;

    if (check_chargeset(ch,victim)) {return;}

    if ( victim->fighting != NULL )
    {
	send_to_char( "That person is moving around too much to backstab.\n\r", ch );
	return;
    }

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

    WAIT_STATE( ch, skill_table[gsn_backstab].beats );
    if ( number_percent( ) < get_skill(ch,gsn_backstab)
    || ( get_skill(ch,gsn_backstab) >= 2 && !IS_AWAKE(victim) ) )
    {
        check_improve(ch,gsn_backstab,TRUE,1);
	if (!IS_NPC(ch) && !IS_NPC(victim) && victim->fighting == NULL)
	{
	switch(number_range(0,1))
	{
	case (0):
	sprintf(buf,"Die, %s you backstabbing fool!",PERS(ch,victim));
	break;
	case (1):
	sprintf(buf,"Help! I'm being backstabbed by %s!",PERS(ch,victim));
	break;
	}
	do_myell(victim,buf);
	}


	one_hit_new(ch,victim,gsn_backstab,HIT_NOSPECIALS,HIT_UNBLOCKABLE,HIT_NOADD,HIT_NOMULT,NULL);
    }
    else
    {
        check_improve(ch,gsn_backstab,FALSE,1);
	if (!IS_NPC(ch) && !IS_NPC(victim) && victim->fighting == NULL)
	{
	switch(number_range(0,1))
	{
	case (0):
	sprintf(buf,"Die, %s you backstabbing fool!",PERS(ch,victim));
	break;
	case (1):
	sprintf(buf,"Help! I'm being backstabbed by %s!",PERS(ch,victim));
	break;
	}
	do_myell(victim,buf);
	}


        damage( ch, victim, 0, gsn_backstab,DAM_NONE,TRUE);
    }


     if (ch->level < skill_table[gsn_dual_backstab].skill_level[ch->class])
	return;

    if (number_range(0,3) == 0)
    {
	if (get_skill(ch,gsn_dual_backstab) != 100)
		check_improve(ch,gsn_dual_backstab,FALSE,1);
	return;
    }

    if (number_percent() > (get_skill(ch,gsn_dual_backstab) + ch->level - victim->level) )
    {
	check_improve(ch,gsn_dual_backstab,FALSE,1);
	dam  = 0;
    }
    else
    {
	dam = dice(obj->value[1], obj->value[2]) * get_skill(ch,gsn_dual_backstab)/100;
        if ((ch->drain_level + ch->level) < 35)         dam *= number_range(2,4);
        else if ((ch->drain_level + ch->level) < 40)    dam *= number_range(2,5);
        else if ((ch->drain_level + ch->level) < 45)    dam *= number_range(3,5);
        else if ((ch->drain_level + ch->level) < 50)    dam *= number_range(10,25); /* 4,6 */
        else dam *= number_range(15,30); /* 4,7 */

        dam += (ch->damroll * get_skill(ch,gsn_dual_backstab)/100);
    }
    damage_old(ch,victim,dam,gsn_dual_backstab,DAM_NONE,TRUE);

    return;
}

void do_rescue( CHAR_DATA *ch, char *argument )
{
    char arg[MAX_INPUT_LENGTH];
    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 fleeing 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 ( ( fch = victim->fighting ) == NULL )
    {
        send_to_char( "That person is not fighting right now.\n\r", ch );
        return;
    }

    if (victim->fighting == ch)
	return send_to_char( "You cannot rescue someone who is attacking you!\n\r",ch);

    if (ch->fighting == victim)
	return send_to_char( "Rescue the person you're fighting?\n\r",ch);

    if (is_safe(ch,victim->fighting))
	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;
    }

    WAIT_STATE(victim,12);
    act( "You rescue $N!",  ch, NULL, victim, TO_CHAR    );
    act( "$n rescues you!", ch, NULL, victim, TO_VICT    );
    act( "$n rescues $N!",  ch, NULL, victim, TO_NOTVICT );
    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_kick( CHAR_DATA *ch, char *argument )
{
    CHAR_DATA *victim;
    int dam;

    if ( !IS_NPC(ch)
    &&   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 (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;
    }

    WAIT_STATE( ch, skill_table[gsn_kick].beats );
    if ( get_skill(ch,gsn_kick) > number_percent())
    {
	dam = (ch->drain_level + ch->level)/2;
	dam += number_range(0,(ch->drain_level + ch->level)/6);
	dam += number_range(0,(ch->drain_level + ch->level)/6);
	dam += number_range(0,(ch->drain_level + ch->level)/6);
	dam += number_range(0,(ch->drain_level + ch->level)/6);
	dam += number_range(0,(ch->drain_level + ch->level)/6);
	dam += number_range(0,(ch->drain_level + ch->level)/6);
	dam += number_range(ch->level/5,ch->level/4);

	if (!IS_NPC(ch))
	{
		if (!str_cmp(class_table[ch->class].name,"channeler"))
		if (!str_cmp(class_table[ch->class].name,"necromancer"))
		if (!str_cmp(class_table[ch->class].name,"elementalist"))
		{
			dam *= 3;
			dam /= 4;
		}
	}

	if (spike_toed_boots(ch))
	    dam *= 3;

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




void do_disarm( CHAR_DATA *ch, char *argument )
{
    CHAR_DATA *victim=0;
    OBJ_DATA *obj,*obj2;
    int dam;
    AFFECT_DATA af;
    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 (IS_AFFECTED(ch,AFF_BLIND))

    {
        act("You can't see the person to disarm them!",ch,NULL,victim,TO_CHAR);
        return;
    }

    if (IS_NPC(ch) && (IS_AFFECTED(ch,AFF_BLIND)))
       return;

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

    if (is_affected(victim,gsn_asscounter))
    {
        act("With blinding speed you hit $N's arm, breaking it!",victim,0,ch,TO_CHAR);
        act("With blinding speed $n hits $N's arm, breaking it!",victim,0,ch,TO_NOTVICT);
        act("With blinding speed $n hits your arm, breaking it instantly!",victim,0,ch,TO_VICT);
        WAIT_STATE(victim,2 * PULSE_VIOLENCE);
        dam = victim->level*2 + number_percent()*2 - 50;
        damage_old(victim,ch,dam,gsn_armbreak,DAM_BASH,TRUE);

        if (!is_affected(ch,gsn_armbreak))
              {
		init_affect(&af);
                af.where     = TO_AFFECTS;
                af.type      = gsn_armbreak;
		af.aftype = AFT_MALADY;
                af.level     = victim->level;
                af.duration  = victim->level/5;
                af.bitvector = 0;
                af.location  = APPLY_DEX;
                af.modifier  = 1-(victim->level/5);
                affect_to_char(ch,&af);
                af.location  = APPLY_STR;
                af.modifier  = 1-(victim->level/5);
                af.bitvector = 0;
                affect_to_char(ch,&af);
          	}
        affect_strip( victim, gsn_asscounter );
        return;
    }

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

	if (is_affected(victim,gsn_spiderhands) )
	{
		act("You try to disarm $N, but $s hands stick to his weapon.",
			ch,NULL,victim,TO_CHAR);
		act("$n tries to disarm you, but your hands stick to your weapon.",
			ch,NULL,victim,TO_VICT);
		act("$n tries to disarm $N, but their hands stick to their weapon.",
			ch,NULL,victim,TO_NOTVICT);
		return;
	}

        if (is_affected(victim,gsn_unholy_affinity) && ((obj2 = get_eq_char(victim,WEAR_WIELD)) != NULL) && is_affected_obj(obj2,gsn_unholy_bless))
        {
                act("$N tries to disarm you, but you refuse to let go!",victim,0,ch,TO_CHAR);
                act("You try to disarm $n, but he won't let go of $s weapon!",victim,0,ch,TO_VICT);
                act("$N tries to disarm $n, but $n holds onto $s weapon!",victim,0,ch,TO_NOTVICT);
                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 */
    chance *= 8;
    chance /=10;

    /* 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 -= 1.25 * get_curr_stat(victim,STAT_STR);

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

    /* and now the attack */
    if (number_percent() < chance)
    {
        WAIT_STATE( ch, skill_table[gsn_disarm].beats );
        disarm( ch, victim );
        check_improve(ch,gsn_disarm,TRUE,1);
    }
    else
    {
        WAIT_STATE(ch,skill_table[gsn_disarm].beats);
        act("You fail to disarm $N.",ch,NULL,victim,TO_CHAR);
        act("$n tries to disarm you, but fails.",ch,NULL,victim,TO_VICT);
        act("$n tries to disarm $N, but fails.",ch,NULL,victim,TO_NOTVICT);
        check_improve(ch,gsn_disarm,FALSE,1);
    }
    check_killer(ch,victim);
    return;
}


void do_circle_stab( CHAR_DATA *ch, char *argument )
{
    bool attempt_dual;
    char arg[MAX_INPUT_LENGTH];
    CHAR_DATA *victim;
    CHAR_DATA *v_check;
    CHAR_DATA *v_next;
    OBJ_DATA *obj;
    int chance;
    int dam;

    attempt_dual = FALSE;
    one_argument(argument,arg);

    if ( (chance = get_skill(ch,gsn_circle)) == 0
    ||  IS_NPC(ch)
    ||  (!IS_NPC(ch) && ch->level < skill_table[gsn_circle].skill_level[ch->class]) )
    {
	send_to_char("Circling? 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 (ch->fighting == NULL)
	{
	send_to_char("You can't circle someone like that.\n\r",ch);
	return;
	}


    for (v_check = ch->in_room->people; v_check != NULL; v_check = v_next)
    {
	v_next = v_check->next_in_room;

	if (v_check->fighting == ch)
	{
	send_to_char("Not while you're defending yourself!\n\r",ch);
	return;
	}
    }

    if (victim == ch)
    {
	send_to_char("huh?\n\r", ch);
	return;
    }

   obj = get_eq_char(ch,WEAR_WIELD);
   if (obj == NULL || obj->value[0] != WEAPON_DAGGER)
	{
	attempt_dual = TRUE;
	obj = get_eq_char(ch,WEAR_DUAL_WIELD);
	}

	if (obj == NULL)
	{
	send_to_char("You must wield a dagger to circle stab.\n\r",ch);
	return;
	}

    if (obj->value[0] != 2)
    {
	send_to_char("You must wield a dagger to circle stab.\n\r",ch);
	return;
    }

    chance += (ch->drain_level + ch->level - victim->level - victim->drain_level);
    chance = URANGE(5, chance, 95);

    WAIT_STATE(ch,skill_table[gsn_circle].beats);

    if (number_percent() < chance)
    {
   	act("You circle around $N to land a critical strike.",ch,NULL,victim,TO_CHAR);
	act("$n cirlces around you to land a critical strike.",ch,NULL,victim,TO_VICT);
	act("$n circles $N to land a critical strike.",ch,NULL,victim,TO_NOTVICT);
	check_improve(ch,gsn_circle,TRUE,1);
	dam = dice(obj->value[1],obj->value[2]);
	dam += 40;

	if ((ch->drain_level + ch->level) <= 15)
		dam *= 1;
	else if ((ch->drain_level + ch->level) <= 20)
		dam *= 3/2;
	else if ((ch->drain_level + ch->level) < 25)
		dam *= 2;
	else if ((ch->drain_level + ch->level) < 30)
		dam *= 7/3;
	else if ((ch->drain_level + ch->level) < 40)
		dam *= 5/2;
	else if ((ch->drain_level + ch->level) <= 49)
		dam *= 7/2;
	else if ((ch->drain_level + ch->level) <= 55)
		dam *= 10/3;
	else dam *= 10/3;


	damage_old(ch,victim,dam,gsn_circle, attack_table[obj->value[3]].damage, TRUE);
    }
    else
    {
	check_improve(ch,gsn_circle,FALSE,1);

	damage_old(ch,victim,0,gsn_circle,DAM_NONE,TRUE);
    }

    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 );
}


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



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

    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( "You failed.\n\r", ch );
        return;
    }

    act( "You point at $M and $S heart stops!",  ch, NULL, victim, TO_CHAR    );
    act( "$n points at you and your heart suddenly stops!", ch, NULL, victim, TO_VICT    );
    act( "$n points at $N and $E falls over clenching his chest!",  ch, NULL, victim, TO_NOTVICT );
    raw_kill(ch, victim );
    n_logf("%s has slain %s", ch->name, victim->name);
    return;
}


void spell_evil_eye(int sn,int level, CHAR_DATA *ch,void *vo, int target)
{
    CHAR_DATA *victim = (CHAR_DATA *) vo;
    int dam, modify, saves;

    if (victim == ch)
    {
	send_to_char("You can't do such a thing.\n\r",ch);
	return;
    }

    act("$n's eyes turn pitch-black and a surging darkness erupts at $N.",ch,NULL,victim,TO_NOTVICT);
    act("Your eyes turn pitch-black and a stream of pure negative energy streams out at $N.",ch,NULL,victim,TO_CHAR);
    send_to_char("You feel a sudden intense agony burning into your skull.\n\r",victim);

    if (IS_SET(victim->affected_by,AFF_BLIND) )
    {
	dam = dice(level,8);
	if (saves_spell(level,victim, DAM_NEGATIVE) )
	dam /= 2;
	damage_old(ch,victim,dam,sn,DAM_NEGATIVE, TRUE);
	return;
    }

   saves = 1;
   for (modify = 0; modify < 4; modify ++)
    {
	if (saves_spell(level, victim, DAM_NEGATIVE))
		saves++;
    }

    if (saves == 0)
    {
	act("$n's surging darkness devestates $N's skull, killing $M instantly!",ch,NULL,victim,TO_NOTVICT);
	act("Your darkness slays $N!",ch,NULL,victim,TO_CHAR);
	send_to_char("With a violent burning sensation your mind vaporises.\n\r",victim);
	raw_kill(ch,victim);
    	return;
    }

    dam = dice(level, 16);
    dam /= (saves + 1);

    damage_old(ch,victim,dam,sn,DAM_NEGATIVE,TRUE);
    return;

}


void spell_power_word_kill(int sn,int level,CHAR_DATA *ch,void *vo, int target)
{
    CHAR_DATA *victim = (CHAR_DATA *) vo;
    int dam,saves,modify;

    saves = 0;

    act("$n points a finger at $N and utters the word, 'Die'.",ch,NULL,victim,TO_NOTVICT);
    act("$n points a finger at you and utters the word, 'Die'.",ch,NULL,victim,TO_VICT);
    send_to_char("You intone a word of unholy power.\n\r",ch);

    for ( modify = 0; modify < 5; modify++)
    {
	if (saves_spell(level-1,victim,DAM_NEGATIVE) )
		saves++;
    }

    if(IS_IMMORTAL(ch) && (victim->level<ch->level)) { saves=0; }
    if (saves == 0)
    {
	act("$N shudders in shock as $S heart explodes!", ch, NULL,victim,TO_NOTVICT);
	send_to_char("You feel your heart rupture in a violent explosion of pain!\n\r",victim);
	act("Your word of power vaporises $N's heart, killing $M instantly!",ch,NULL,victim,TO_CHAR);
	raw_kill(ch,victim);
    	return;
    }
    dam = dice(level,14);
    dam /= saves;
    damage_old(ch,victim,dam,sn,DAM_NEGATIVE,TRUE);

	return;
}

void do_lunge( CHAR_DATA *ch, char *argument)
{
        CHAR_DATA *victim;
        int chance, dam;
        char arg[MAX_INPUT_LENGTH];
        OBJ_DATA *wield;
        int multiplier;

	dam = 0;
        one_argument(argument,arg);
        if ((chance = get_skill(ch,gsn_lunge) ) == 0
        || (ch->level < skill_table[gsn_lunge].skill_level[ch->class]) )
        {
        send_to_char("Lunging? 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 == ch)
        {
        send_to_char("You can't lunge at yourself!\n\r",ch);
        return;
        }

        wield = get_eq_char(ch,WEAR_WIELD);
        if ((wield == NULL)
        || (( wield->value[0] != WEAPON_SWORD)
        && ( wield->value[0] != WEAPON_SPEAR)
        && ( wield->value[0] != WEAPON_POLEARM) ))
        {
        send_to_char("You must be wielding a sword, spear or polearm to lunge.\n\r",ch);
        return;
        }

        if (is_safe(ch,victim) )
        return;

	if (check_chargeset(ch,victim)) {return;}

        chance += ch->carry_weight/25;
        chance -= victim->carry_weight/20;
        chance += (ch->size - victim->size)*20;
        chance -= get_curr_stat(victim,STAT_DEX);
        chance += get_curr_stat(ch,STAT_STR)/3;
        chance += get_curr_stat(ch,STAT_DEX)/2;
        if (IS_AFFECTED(ch,AFF_HASTE) )
                chance += 10;
        if (IS_AFFECTED(victim,AFF_HASTE) )
                chance = 20;
        chance += (ch->drain_level + ch->level - victim->level - victim->drain_level);

        act("$n attempts to impale $N with a quick lunge!",ch,0,victim,TO_NOTVICT);
        act("You attempt to impale $N with a quick lunge!",ch,0,victim,TO_CHAR);
        act("$n attempts to impale you with a quick lunge!",ch,0,victim,TO_VICT);

        if (number_percent() < chance)
        {
        check_improve(ch,gsn_lunge,TRUE,1);
        WAIT_STATE(ch,skill_table[gsn_lunge].beats);
        if (wield->pIndexData->new_format)
                dam = dice(wield->value[1],wield->value[2]);
        else
                dam = number_range(wield->value[1],wield->value[2]);

        if (get_skill(ch,gsn_enhanced_damage) > 0 )
        {
        if (number_percent() <= get_skill(ch,gsn_enhanced_damage) )
                {
                check_improve(ch,gsn_enhanced_damage,TRUE,1);
dam += dam*(number_range(60,100)/100) * ch->pcdata->learned[gsn_enhanced_damage]/100;
                }
        }

        dam += GET_DAMROLL(ch);
        dam *= ch->pcdata->learned[gsn_lunge];
	dam /= 100;
        multiplier = number_range((ch->drain_level + ch->level)/8,(ch->drain_level + ch->level)/4);
        multiplier /= 10;
	multiplier += 6/4;
        dam *= multiplier;

        if (dam <= 0)
                dam = 1;
        damage_old(ch,victim,dam,gsn_lunge,DAM_PIERCE,TRUE);
        }
        else
        {
        damage_old(ch,victim,dam,gsn_lunge,DAM_PIERCE,TRUE);
        check_improve(ch,gsn_lunge,FALSE,1);
        WAIT_STATE(ch,skill_table[gsn_lunge].beats);
        }
        return;
}

void do_bandage(CHAR_DATA *ch,char *argument)
{
        CHAR_DATA *victim;
        char arg[MAX_INPUT_LENGTH];
        AFFECT_DATA af;

        one_argument(argument,arg);

        if ( (get_skill(ch,gsn_bandage) == 0)
        || (ch->level < skill_table[gsn_bandage].skill_level[ch->class]) )
        {
        	send_to_char("Huh?\n\r",ch);
        	return;
        }

	if (cabal_down(ch,CABAL_RAGER))
		return;

        if (is_affected(ch,gsn_bandage))
        {
        	send_to_char("You can't apply more aid yet.\n\r",ch);
        	return;
        }

        if (ch->mana < 50)
        {
        	send_to_char("You don't have the mana.\n\r",ch);
        	return;
        }

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

        if (number_percent() > ch->pcdata->learned[gsn_bandage])
        {
        	act("You fail to apply battle dressing to $N's wounds.",ch,0,victim,TO_CHAR);
        	act("$n fumbles with $s bandages but fails to use them effectively.",ch,0,0,TO_ROOM);
        	ch->mana -= 35;
        	check_improve(ch,gsn_bandage,FALSE,3);
        	return;
        }

        ch->mana -= 50;

        if (victim != ch)
        {
        	act("$n applies bandages to $N's battle wounds.",ch,0,victim,TO_NOTVICT);
        	act("You apply bandages to $N's battle wounds.",ch,0,victim,TO_CHAR);
        	act("$n applies bandages to your battle wounds.",ch,0,victim,TO_VICT);
        }
        else
        {
        	act("$n applies bandages to $mself.",ch,0,0,TO_ROOM);
        	send_to_char("You apply battle dressing to yourself.\n\r",ch);
        }

        send_to_char("You feel better.\n\r",victim);

        victim->hit = UMIN(victim->hit + (9*ch->level), victim->max_hit);
	if (number_percent() < 60)
	{
		if (IS_AFFECTED(victim,AFF_PLAGUE))
		{
			affect_strip(victim,gsn_plague);
			act("The sores on $n's body vanish.\n\r",victim,0,0,TO_ROOM);
			send_to_char("The sores on your body vanish.\n\r",victim);
		}
	}

	if (number_percent() < 60)
	{
	 	if (is_affected(victim, gsn_blindness))
	 	{
	  		affect_strip(victim, gsn_blindness);
	  		send_to_char("Your vision returns!\n\r",victim);
	 	}
	}

	if (number_percent() < 60)
	{
		if (is_affected(victim,gsn_poison))
		{
			affect_strip(victim,gsn_poison);
			send_to_char("A warm feeling goes through your body.\n\r",victim);
			act("$n looks better.",victim,0,0,TO_ROOM);
		}

		if (is_affected(victim,gsn_poison_dust))
		{
			affect_strip(victim,gsn_poison_dust);
			send_to_char("The dust in your eyes is cleaned out.\n\r",victim);
			act("The dust in $n's eyes looks cleaned out.",victim,0,0,TO_ROOM);
		}
	}

        check_improve(ch,gsn_bandage,TRUE,3);
	init_affect(&af);
        af.where 	= TO_AFFECTS;
        af.type 	= gsn_bandage;
        af.location 	= 0;
        af.duration 	= number_range(5,8);
        af.modifier 	= 0;
        af.bitvector 	= 0;
		char msg_buf[MSL];
		sprintf(msg_buf,"unable to bandage");
		af.affect_list_msg = str_dup(msg_buf);
        af.level 	= ch->level;
	af.aftype 	= AFT_POWER;
        affect_to_char(ch,&af);
        return;
}

void do_herb(CHAR_DATA *ch,char *argument)
{
        CHAR_DATA *victim;
        char arg[MAX_INPUT_LENGTH];
        AFFECT_DATA af;

        one_argument(argument,arg);

        if ( (get_skill(ch,gsn_herb) == 0)
        || (ch->level < skill_table[gsn_herb].skill_level[ch->class]) )
        {
        send_to_char("Huh?\n\r",ch);
        return;
        }
        if (is_affected(ch,gsn_herb))
        {
        send_to_char("You can't find any more herbs.\n\r",ch);
        return;
        }
    if ( (ch->in_room->sector_type != SECT_FOREST) && (ch->in_room->sector_type != SECT_MOUNTAIN)
        && (ch->in_room->sector_type != SECT_HILLS ) && (ch->in_room->sector_type != SECT_DESERT)
        && (ch->in_room->sector_type != SECT_FIELD ))
        {
        send_to_char("You can't find any herbs here.\n\r",ch);
        return;
        }

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

        if (number_percent() > ch->pcdata->learned[gsn_herb])
        {
        send_to_char("You search for herbs but fail to find any.\n\r",ch);
        act("$n looks about in the bushes but finds nothing.",ch,0,0,TO_ROOM);
        check_improve(ch,gsn_herb,FALSE,4);
        return;
        }

        if (victim != ch)
        {
        act("$n applies herbs to $N.",ch,0,victim,TO_NOTVICT);
        act("You apply herbs to $N.",ch,0,victim,TO_CHAR);
        act("$n applies herbs to you.",ch,0,victim,TO_VICT);
        }

	if (victim == ch)
	{
        act("$n applies herbs to $mself.",ch,0,0,TO_ROOM);
        send_to_char("You find herbs and apply them to yourself.\n\r",ch);
        }

	send_to_char("You feel better.\n\r",victim);

	if (IS_AFFECTED(victim,AFF_PLAGUE) && number_percent() > 30)
	{
	affect_strip(victim,gsn_plague);
	act("The sores on $n's body vanish.\n\r",victim,0,0,TO_ROOM);
	send_to_char("The sores on your body vanish.\n\r",victim);
	}

        check_improve(ch,gsn_herb,TRUE,4);

        victim->hit = UMIN(victim->hit + (4*(ch->drain_level + ch->level)), victim->max_hit);
	init_affect(&af);
        af.where = TO_AFFECTS;
        af.type = gsn_herb;
        af.location = 0;
        af.duration = 4;
        af.modifier = 0;
        af.bitvector = 0;
		char msg_buf[MSL];
		sprintf(msg_buf,"unable to search for herbs");
		af.affect_list_msg = str_dup(msg_buf);
	af.aftype = AFT_SKILL;
        af.level = ch->level + ch->drain_level;
        affect_to_char(ch,&af);
        return;
}

void do_cleave(CHAR_DATA *ch,char *argument)
{
	OBJ_DATA *weapon;
        CHAR_DATA *victim;
        char arg[MAX_INPUT_LENGTH];
        int dam, chance, dam_type;
        char buf[MAX_STRING_LENGTH];
        int sn;
	int skill;

        if ( ( ( chance = get_skill(ch,gsn_cleave)) == 0)
        || (ch->level < skill_table[gsn_cleave].skill_level[ch->class]) )
        {
        send_to_char("You don't know how to cleave.\n\r",ch);
        return;
        }

        one_argument(argument,arg);
        weapon = get_eq_char(ch,WEAR_WIELD);

    	if (weapon == NULL)
	{
        send_to_char("You need to wield a sword or axe to cleave.\n\r",ch);
        return;
        }

        if ((weapon->value[0] != WEAPON_SWORD)
        && (weapon->value[0] != WEAPON_AXE) )
        {
        send_to_char("You need to wield a sword or axe to cleave.\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("You can't do such a thing.\n\r",ch);
        return;
        }
        if (victim->fighting != NULL)
        {
        send_to_char("They are moving too much to cleave.\n\r",ch);
        return;
        }
        if (victim->hit < victim->max_hit*9/10)
        {
        send_to_char("They are too hurt and watchful to cleave right now...\n\r",ch);
        return;
        }

        if (is_safe(ch,victim))
                return;

	if (check_chargeset(ch,victim)) {return;}

        chance /= 5;
        if ((ch->drain_level + ch->level - victim->drain_level + victim->level) < 0)
                chance -= (ch->drain_level + ch->level - victim->drain_level - victim->level)*3;
        else
                chance += (ch->drain_level + ch->level - victim->level - victim->drain_level);
        chance += get_curr_stat(ch,STAT_STR)/2;
        chance -= get_curr_stat(victim,STAT_DEX)/3;  /* Improve evasion */
        chance -= get_curr_stat(victim,STAT_STR)/4;  /* Improve repelling */
        chance -= get_curr_stat(victim,STAT_CON)/4;  /* Shock survival */
        dam_type = attack_table[weapon->value[3]].damage;


        if (!can_see(victim,ch))
                chance += 5;
        chance -= dice(2,6);
        chance = URANGE(2,chance,10);

	if (IS_IMMORTAL(victim))
	    chance = 0;

	if (IS_CABAL_OUTER_GUARD(victim))
	    chance = 0;

        if (number_percent() < 50)
                sprintf(buf,"Die, %s you butchering fool!",PERS(ch,victim));
        else
                sprintf(buf,"Help! %s just tried to cleave me in half!",PERS(ch,victim));

        sn = get_weapon_sn(ch);
        skill = get_weapon_skill(ch,sn) + ch->pcdata->learned[gsn_cleave] + 10;
        skill = URANGE(0,skill/2,100);

        if (IS_IMP(ch)) {
                chance += 100;
        }

        act("You make a brutal swing at $N in an attempt to cleave them in half.",ch,0,victim,TO_CHAR);
        act("$n attempts to cleave you in half with a brutal slice.",ch,0,victim,TO_VICT);
        act("$n makes an attempt to cleave $N in half.",ch,0,victim,TO_NOTVICT);

	if (IS_IMP(victim)) {
		act("You make a brutal swing at $N in an attempt to cleave them in half, but miss and chop your own head off.",ch,0,victim,TO_CHAR);
		act("$n attempts to cleave you in half with a brutal slice, but misses and chops thier own head off.",ch,0,victim,TO_VICT);
		act("$n makes an attempt to cleave $N in half but misses and chops their own head off!",ch,0,victim,TO_NOTVICT);
		raw_kill(victim,ch);
		return;
	}

    if (IS_NPC(victim))
	victim->last_fought = ch;

        if (number_percent() > chance)
        {
            check_improve(ch,gsn_cleave,FALSE,5);
            if (weapon->pIndexData->new_format)
                dam = dice(weapon->value[1],weapon->value[2])*skill/100;
            else
                dam = number_range(weapon->value[1]*skill/100,weapon->value[2]*skill/100);
        
	    dam *= number_range((ch->drain_level + ch->level)/10,(ch->drain_level + ch->level)/7);
            damage_old(ch,victim,dam,gsn_cleave,dam_type,TRUE);
            if (!IS_NPC(victim) && !IS_NPC(ch) && victim->hit > 1)
                do_myell(victim,buf);
	    WAIT_STATE(ch,PULSE_VIOLENCE*3);
	    WAIT_STATE(victim,PULSE_VIOLENCE*2);
            return;
        }

    act("Your cleave slices $S body in half with a clean cut!",ch,0,victim,TO_CHAR);
    act("$n cleaves you in half, tearing your body into two bloody bits!",ch,0,victim,TO_VICT);
    act("$n cleaves $N into to bits of bloody flesh!",ch,0,victim,TO_NOTVICT);
    check_improve(ch,gsn_cleave,TRUE,5);
    raw_kill(ch,victim);
    return;
}


void do_deathstrike(CHAR_DATA *ch,char *argument)
{
        CHAR_DATA *victim;
        int chance, dam;
        char arg[MAX_INPUT_LENGTH];
        char buf[MAX_INPUT_LENGTH];
/*	AFFECT_DATA af;	*/

        one_argument(argument,arg);
        if (IS_NPC(ch))
                return;

	if ((get_skill(ch,gsn_deathstrike) == 0)
	|| ch->level < skill_table[gsn_deathstrike].skill_level[ch->class])
	{
	send_to_char("Huh?\n\r",ch);
	return;
	}

	if (is_affected(ch,gsn_deathstrike))
	{
	send_to_char("You can't build up the intensity to deathstrike yet.\n\r",ch);
	return;
	}

        if (arg[0] == '\0')
        {
        send_to_char("Attempt to destroy who's skull?\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("You can't do that.\n\r",ch);
        return;
        }
        if (victim->fighting != NULL || victim->position == POS_FIGHTING)
        {
        send_to_char("They are moving around too much to get in close for the kill.\n\r",ch);
        return;
        }

        if (is_safe(ch,victim))
                return;

        if (victim->hit < victim->max_hit)
        {
        send_to_char("They have too much blood on them right now to locate their strike point.\n\r",ch);
        return;
        }
        chance = get_skill(ch,gsn_deathstrike)/2;
        chance += ch->level;
        chance -= victim->level * 3/2;
        chance -= number_range(0,15);
        if (!can_see(victim,ch))
                chance += 10;
        if (victim->position == POS_FIGHTING)
                chance -= 25;
        else if (victim->position == POS_SLEEPING)
                chance += 10;
        else chance -= 10;

        chance /= 2;
        chance = URANGE(2,chance,90);

        act("$n strikes out at $N with deadly intensity.",ch,0,victim,TO_NOTVICT);
        act("You strike out at $N with deadly intensity.",ch,0,victim,TO_CHAR);
        act("$n strikes at you with deadly intensity.",ch,0,victim,TO_VICT);

        if (number_percent() < chance)
        {
        send_to_char("With agonising pain your skull is smashed by the blow!\n\r",victim);
        act("Your blow shatters $N's skull into bloody fragments!",ch,0,victim,TO_CHAR);
        act("$N's skull is shattered into bits of mangled flesh and bone by $n's strike!",ch,0,victim,TO_NOTVICT);
        raw_kill(ch,victim);
        check_improve(ch,gsn_deathstrike,TRUE,3);
        return;
        }
        else
        {
        send_to_char("You feel a sharp pain searing your skull!\n\r",victim);
        act("Your deathstrike smashes $N's skull but fails to kill.",ch,0,victim,TO_CHAR);
        dam = ch->level * 2;
        dam += dice(ch->level, 4);
        damage_old(ch,victim,dam,gsn_deathstrike,DAM_PIERCE,TRUE);
        check_improve(ch,gsn_deathstrike,FALSE,3);
        if (!IS_NPC(victim) && !IS_NPC(ch) && (victim->hit > 1))
               {
                sprintf(buf,"Help! %s just tried to kill me!",PERS(ch,victim));
                do_myell(victim,buf);
                }
        multi_hit(victim,ch,TYPE_UNDEFINED);
        }

        return;
}

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

    if (IS_NPC(ch) && IS_AFFECTED(ch,AFF_CHARM))
	return;

        if ( (chance = get_skill(ch,gsn_crush)) == 0
        || ch->level < skill_table[gsn_crush].skill_level[ch->class])
        if (!IS_NPC(ch))
	{
                send_to_char("Crushing, how do you do that again?\n\r",ch);
                return;
        }
	if ((victim = ch->fighting) == NULL)
	{
	send_to_char("You aren't fighting anyone.\n\r",ch);
	return;
	}
    if (is_affected(victim,gsn_protective_shield))
    {
	act("$N's crush attempt seems to slide around you.",victim,0,ch,TO_CHAR);
	act("$N's crush attempt seems to slide around $n.",victim,0,ch,TO_NOTVICT);
	act("Your crush attempt seems to slide around $n.",victim,0,ch,TO_VICT);
	WAIT_STATE(ch,PULSE_VIOLENCE*2);
	return;
    }

 if (is_affected(victim, skill_lookup("wraithform")))
    {
        act("$N's crush attempt seems to slide around you.",victim,0,ch,TO_CHAR);
        act("$N's crush attempt seems to slide around $n.",victim,0,ch,TO_NOTVICT);
        act("Your crush attempt seems to slide around $n.",victim,0,ch,TO_VICT);
        WAIT_STATE(ch,PULSE_VIOLENCE*2);
        return;
    }

	chance -= chance/4;
        chance += (ch->drain_level + ch->level - victim->drain_level - victim->level) * 2;
        chance += get_curr_stat(ch,STAT_STR);
        chance -= get_curr_stat(victim,STAT_DEX)/3;
        chance -= get_curr_stat(victim,STAT_STR)/2;
        if (ch->size < victim->size)
                chance += (ch->size - victim->size)*25;
        else
                chance += (ch->size - victim->size)*10;
        if (number_percent() < chance)
	{
	if (check_roll(ch,victim, gsn_crush))
	{
	check_improve(ch,gsn_crush,TRUE,2);
	act("$N rolls free of $n's crush.",ch,0,victim,TO_NOTVICT);
	act("You roll out of $n's crush attempt.",ch,0,victim,TO_VICT);
	act("$N rolls free of your crush attempt.",ch,0,victim,TO_CHAR);
	return;
	}
        act("$n grabs you and slams you to the ground with bone crushing force!",ch,0,victim,TO_VICT);
        act("You grab $N and slam $M to the ground with bone crushing force!",ch,0,victim,TO_CHAR);
        act("$n slams $N to the ground with bone crushing force!",ch,0,victim,TO_NOTVICT);
        check_improve(ch,gsn_crush,TRUE,4);
        if ((ch->drain_level + ch->level) < 20)
                dam = 20;
        else if ((ch->drain_level + ch->level) < 25)
                dam = 30;
        else if ((ch->drain_level + ch->level) < 30)
                dam = 40;
        else if ((ch->drain_level + ch->level) < 35)
                dam = 50;
        else if ((ch->drain_level + ch->level) < 40)
                dam = 60;
        else if ((ch->drain_level + ch->level) < 52)
                dam = 70;
        else
                dam = 70;
        dam += str_app[get_curr_stat(ch,STAT_STR)].todam;
        WAIT_STATE(victim,2*PULSE_VIOLENCE);
        WAIT_STATE(ch,2*PULSE_VIOLENCE);
        damage_old(ch,victim,dam,gsn_crush,DAM_BASH,TRUE);
        victim->position = POS_RESTING;

        if (ch->fighting == victim)
                check_ground_control(ch,victim,chance,dam);
        return;

	}
        act("Your crush attempt misses $N.",ch,0,victim,TO_CHAR);
        act("$n lashes out wildly with $s arms but misses.",ch,0,0,TO_ROOM);
        WAIT_STATE(ch,2*PULSE_VIOLENCE);
        check_improve(ch,gsn_crush,FALSE,3);
        return;

}

void check_ground_control(CHAR_DATA *ch,CHAR_DATA *victim,int chance,int dam)
{
	if (chance < 10)
		return;
	if (dam == 0)
		return;

        chance += get_skill(ch,gsn_ground_control)/2;
        chance /= 3;

  	chance -= number_range(5,15);
	chance = URANGE(5,chance,60);

        if (ch->level < skill_table[gsn_ground_control].skill_level[ch->class])
                return;
        if (number_percent() > chance)
	{
                check_improve(ch,gsn_ground_control,FALSE,3);
                return;

	}
        act("With brutal skill you grind $N against the ground with your weight.",ch,0,victim,TO_CHAR);
        act("$n takes hold of $N and grinds $M against the ground.",ch,0,victim,TO_NOTVICT);
        act("$n grinds you against the ground with brutal skill.",ch,0,victim,TO_VICT);
        dam -= 10;
        check_improve(ch,gsn_ground_control,TRUE,2);
        damage_old(ch,victim,dam,gsn_ground_control,DAM_BASH,TRUE);
        WAIT_STATE(victim,2*PULSE_VIOLENCE);
        return;

}


void do_riot(CHAR_DATA *ch,char *argument)
{
    CHAR_DATA *gch;
    int bonus;
     AFFECT_DATA af;

    if ( (get_skill(ch,gsn_riot) == 0 )
	|| ch->level < skill_table[gsn_riot].skill_level[ch->class])
	{
	send_to_char("Huh?\n\r",ch);
	return;
 	}

    if (ch->mana < 40)
    {
	send_to_char("You don't have the mana.\n\r",ch);
	return;
    }

    if (is_affected(ch,gsn_riot))
    {
	send_to_char("You can't stir up another riot yet.\n\r",ch);
	return;
    }
    if (number_percent() > ch->pcdata->learned[gsn_riot])
    {
	send_to_char("You try to incite a riot amongst your group but fail.\n\r",ch);
	act("$n gestures around angrily, trying to build up anger and discord but fails.",ch,0,0,TO_ROOM);
	ch->mana -= 20;
	check_improve(ch,gsn_riot,FALSE,2);
	return;
    }

    send_to_char("You stir up a riot with your actions!\n\r",ch);
	init_affect(&af);
    af.where = TO_AFFECTS;
	af.aftype = AFT_POWER;
    af.type = gsn_riot;
    af.level = ch->level + ch->drain_level;
    af.bitvector = 0;
    af.duration = ( 2 + (ch->drain_level + ch->level)/8);
    af.location = APPLY_HITROLL;

    if ((ch->drain_level + ch->level) < 20)
	bonus = 6;
    else if ((ch->drain_level + ch->level) < 25)
	bonus = 7;
    else if ((ch->drain_level + ch->level) < 30)
	bonus = 8;
    else if ((ch->drain_level + ch->level) < 35)
	bonus = 9;
    else if ((ch->drain_level + ch->level) < 38)
	bonus = 10;
    else
	bonus = 12;

    af.modifier = bonus;
    affect_to_char(ch,&af);
    af.location = APPLY_DAMROLL;
    affect_to_char(ch,&af);
    send_to_char("You are filled with terrible fury!\n\r",ch);

    for (gch = ch->in_room->people; gch != NULL; gch = gch->next_in_room)
    {
	if (!is_same_group(ch,gch) || !IS_AWAKE(gch))
		continue;
	if (is_affected(gch,gsn_riot))
		continue;
	if (gch->trust > 51)
	        continue;
	if (gch == ch)
		continue;
	af.location = APPLY_DAMROLL;
	affect_to_char(gch,&af);
	af.location = APPLY_HITROLL;
	affect_to_char(gch,&af);
	send_to_char("You are filled with a terrible fury!\n\r",gch);
    	act("$n gets a terrible look of anger in $s eyes.",gch,0,0,TO_ROOM);
    }

    check_improve(ch,gsn_riot,TRUE,2);
    ch->mana -= 40;
    return;
}



void do_tail(CHAR_DATA *ch, char *argument)
{
    char arg[MAX_INPUT_LENGTH];
    CHAR_DATA *victim;
    int chance, dam;
    int knock;

    one_argument(argument,arg);

    if (IS_NPC(ch) && IS_AFFECTED(ch,AFF_CHARM))
	return;

    if ( (chance = get_skill(ch,gsn_tail)) == 0
    ||   (IS_NPC(ch) && !IS_SET(ch->off_flags,OFF_TAIL))
    ||   (!IS_NPC(ch)
    &&    ch->level < skill_table[gsn_tail].skill_level[ch->class]))
    {
	send_to_char("You don't have a tail to strike with like 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;
    }

    chance = URANGE(5,chance,90);

    chance += (ch->level - victim->level);
    chance -= get_curr_stat(victim,STAT_DEX);
    chance += get_curr_stat(ch,STAT_DEX)/3;
    chance += get_curr_stat(ch,STAT_STR)/3;

	act("$n violently lashes out with $s tail.",ch,0,0,TO_ROOM);
	send_to_char("You violently lash out with your tail!\n\r",ch);

    if (number_percent() > chance)
    {
	damage_old(ch,victim,0,gsn_tail,DAM_BASH,TRUE);
	return;
    }

    dam = dice(ch->level, 3);
    knock = (ch->level + 15);

    damage_old(ch,victim,dam,gsn_tail,DAM_BASH,TRUE);
    if (number_percent() < knock)
    {
	act("$n is sent crashing to the ground by the force of the blow!",victim,0,0,TO_ROOM);
	send_to_char("The tail strike sends you crashing to the ground!\n\r",victim);
	WAIT_STATE(victim,( 3 * PULSE_VIOLENCE/2));
    }
    WAIT_STATE(ch,2*PULSE_VIOLENCE);
    return;
}


void do_spellbane(CHAR_DATA *ch, char *argument)
{
	AFFECT_DATA af;

	if (get_skill(ch,gsn_spellbane) < 10
	|| ch->level < skill_table[gsn_spellbane].skill_level[ch->class])
	{
	send_to_char("Huh?\n\r",ch);
	return;
	}
	if (is_affected(ch,gsn_spellbane))
	{
	send_to_char("You are already turning spells.\n\r",ch);
	return;
	}

	if (ch->mana < 50)
	{
send_to_char("You don't have the mana.\n\r",ch);
	return;
	}

	if (number_percent() > get_skill(ch,gsn_spellbane))
	{
	send_to_char("You think of your hatred of magic but can not sustain it.\n\r",ch);
act("$n makes some angry gestures and goes red in the face, but nothing happens.",ch,0,0,TO_ROOM);
	ch->mana -= 25;
	check_improve(ch,gsn_spellbane,FALSE,1);
	return;
	}

	init_affect(&af);
	af.where = TO_AFFECTS;
	af.type = gsn_spellbane;
	af.level = ch->level + ch->drain_level;
	af.duration = (5 + (ch->drain_level + ch->level)/5);
	af.location = APPLY_SAVES;
	af.modifier = (-5 -ch->level/4);
	af.bitvector = 0;
	af.aftype = AFT_POWER;

	affect_to_char(ch,&af);
	char msg_buf[MSL];
	sprintf(msg_buf,"grants a chance to reprise against magic");
	af.affect_list_msg = str_dup(msg_buf);
	af.location = APPLY_NONE;
	af.modifier = 0;
	affect_to_char(ch,&af);

	act("$n fills the air with $s hatred of magic.",ch,0,0,TO_ROOM);
	send_to_char("You surround yourself with your hatred of magic.\n\r",ch);
    if (is_affected(ch,gsn_undead_drain))
    {
	if (saves_spell(50,ch,DAM_OTHER))
	{
	send_to_char("Your spellbane burns away the negative draining magic of the undead.\n\r",ch);

	affect_strip(ch,gsn_undead_drain);
	}
    }

check_improve(ch,gsn_spellbane,TRUE,1);
	ch->mana -= 50;
	return;

}

bool spellbaned(CHAR_DATA *caster, CHAR_DATA *victim, int sn)
{
	bool status = FALSE;
  	int chance;

    	if (cabal_down_new(victim,CABAL_RAGER,FALSE))
		return FALSE;

     	if (!is_affected(victim,gsn_spellbane))
    	{
		return FALSE;
    	}

	if(number_percent()<26) 
 	{
		return FALSE;
	}

    	if ( sn >= TYPE_HIT && sn < (TYPE_HIT + MAX_DAMAGE_MESSAGE) )
		return FALSE;

    	if (skill_table[sn].slot == 0)
	  	return FALSE;

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

	if (caster == victim)
		return FALSE;

    	if ( skill_table[sn].target == TAR_CHAR_DEFENSIVE)
		status = TRUE;
    	else
	{
		chance = 50 + (victim->level - caster->level) * 2;
		chance -= victim->saving_throw;
		chance = URANGE(10,chance,50);

		if (IS_NPC(victim) &&
		victim->pIndexData->vnum == MOB_VNUM_RAGER)
			chance += 25;

		if (number_percent() < chance)
			status = TRUE;
	}

	if (status)
	{
		act("$n's spellbane reflects $N's spell!",victim,0,caster,TO_NOTVICT);
		act("Your spellbane reflects $N's spell!",victim,0,caster,TO_CHAR);
		act("$n's spellbane reflects your spell!",victim,0,caster,TO_VICT);

    		if (skill_table[sn].target != TAR_CHAR_OFFENSIVE)
      			damage_old(victim,caster,dice(caster->level,2),gsn_spellbane,DAM_ENERGY,TRUE);	
	}
    	return status;
}

void do_throw(CHAR_DATA *ch,char *argument)
{
    CHAR_DATA *victim;
    int dam, chance;
    char arg[MAX_INPUT_LENGTH];

    if ( (chance = get_skill(ch,gsn_throw)) == 0
    || ch->level < skill_table[gsn_throw].skill_level[ch->class])
    {
        send_to_char("Throwing? What's that?\n\r",ch);
        return;
    }

    one_argument(argument,arg);
    if (arg[0] == '\0')
        victim = ch->fighting;
    else
        victim = get_char_room(ch,arg);

    if (victim == NULL)
    {
        send_to_char("They aren't here.\n\r",ch);
        return;
    }
    if (victim == ch)
    {
        send_to_char("Now that would be a bit stupid.\n\r",ch);
        return;
    }
    if ((victim->fighting != ch) && (ch->fighting != victim))
    {
        send_to_char("But you aren't engaged in combat with them.\n\r",ch);
        return;
    }

    if (hands_full(ch))
    {
        send_to_char("You can't throw, your hands are filled with items.\n\r",ch);
        return;
    }
/*
    if (is_affected(ch,gsn_palm))
    {
        send_to_char("You can't throw, you're fighting with open hand palms.\n\r",ch);
        return;
    }
*/
    if (is_affected(victim,gsn_protective_shield))
    {
	act("$N's throw seems to slide around you.",victim,0,ch,TO_CHAR);
	act("$N's throw seems to slide around $n.",victim,0,ch,TO_NOTVICT);
	act("Your throw seems to slide around $n.",victim,0,ch,TO_VICT);
	WAIT_STATE(ch,PULSE_VIOLENCE*2);
	return;
    }
    chance += (ch->drain_level + ch->level - victim->level - victim->drain_level);
    chance -= get_curr_stat(victim,STAT_DEX);
    chance += get_curr_stat(ch,STAT_DEX)/2;
    chance *= 9;
    chance /= 10;
    chance = URANGE(5, chance, 90);

    if (number_percent() > chance)
    {
        dam = 0;
	check_improve(ch,gsn_throw,FALSE,3);
    }
    else
    {
	if (check_roll(ch,victim,gsn_throw))
	{
	check_improve(ch,gsn_throw,TRUE,2);
	act("$N rolls free of $n's throw.",ch,0,victim,TO_NOTVICT);
	act("You roll out of $n's throw attempt.",ch,0,victim,TO_VICT);
	act("$N rolls free of your throw attempt.",ch,0,victim,TO_CHAR);
	return;
	}

        if ((ch->drain_level + ch->level) <= 18)    dam = 30;
        else if ((ch->drain_level + ch->level) <= 22)   dam = 35;
        else if ((ch->drain_level + ch->level) <= 25)   dam = 40;
        else if ((ch->drain_level + ch->level) <= 28)   dam = 45;
        else if ((ch->drain_level + ch->level) <= 32)   dam = 48;
        else if ((ch->drain_level + ch->level) <= 35)   dam = 52;
        else if ((ch->drain_level + ch->level) <= 38)   dam = 56;
        else if ((ch->drain_level + ch->level) <= 40)   dam = 60;
        else if ((ch->drain_level + ch->level) <= 43)   dam = 64;
        else if ((ch->drain_level + ch->level) <= 45)   dam = 68;
        else if ((ch->drain_level + ch->level) <= 48)   dam = 70;
        else                        dam = 72;

	act("$n grabs $N and throws $M to the ground with stunning force!",ch,0,victim,TO_NOTVICT);
	act("You grab $N and throw $M to the ground with stunning force!",ch,0,victim,TO_CHAR);
	act("$n grabs you and throws you to the ground with stunning force!",ch,0,victim,TO_VICT);

        dam += str_app[get_curr_stat(ch,STAT_STR)].todam;
        check_improve(ch,gsn_throw,TRUE,3);
        WAIT_STATE(victim,2*PULSE_VIOLENCE);
    }

    damage_old(ch,victim,dam,gsn_throw,DAM_BASH,TRUE);
    WAIT_STATE(ch,2*PULSE_VIOLENCE);
    if (ch->fighting == victim)
        check_ground_control(ch,victim,chance,dam);

    return;
}

void do_palm(CHAR_DATA *ch,char *argument)
{
    AFFECT_DATA af;
    int chance;

    if ( (chance = get_skill(ch,gsn_palm)) == 0
    || ch->level < skill_table[gsn_palm].skill_level[ch->class])
    {
        send_to_char("You don't have the ability to use palm striking martial arts.\n\r",ch);
        return;
    }

    if (is_affected(ch,gsn_palm))
    {
        send_to_char("You're already fighting with concentrated open hand martial arts.\n\r",ch);
        return;
    }

    if (ch->mana <= 60)
    {
        send_to_char("You don't have the mana.\n\r",ch);
        return;
    }

    if (get_eq_char(ch,WEAR_WIELD) != NULL
	|| get_eq_char(ch,WEAR_DUAL_WIELD) != NULL)
	{
	send_to_char("You can't start using open palm striking while using weapons.\n\r",ch);
	return;
	}

    if (number_percent() >= chance)
    {
        send_to_char("You flex your hands but cannot grasp the concentration required.\n\r",ch);
        check_improve(ch,gsn_palm,FALSE,2);
        ch->mana -= 30;
        return;
    }

    act("$n slowly spreads $s hands and a look of deadly concentration clouds $s eyes.",ch,0,0,TO_ROOM);
    send_to_char("You feel your mind relax and pass power to your opened hands.\n\r",ch);
	init_affect(&af);
    af.where = TO_AFFECTS;
    af.type = gsn_palm;
    af.location = 0;
    af.modifier = 0;
    af.duration = ((ch->drain_level + ch->level)/3);
    af.level = ch->drain_level + ch->level;
    af.bitvector = 0;
	af.aftype = AFT_SKILL;
	char msg_buf[MSL];
	sprintf(msg_buf,"utilizing open palm martial arts");
	af.affect_list_msg = str_dup(msg_buf);
    affect_to_char(ch,&af);
    check_improve(ch,gsn_palm,TRUE,2);

    return;
}

void do_nerve(CHAR_DATA *ch,char *argument)
{
    char buf[MAX_STRING_LENGTH];
    CHAR_DATA *victim;
    char arg[MAX_INPUT_LENGTH];
    AFFECT_DATA af;
    int chance;

    if ( (chance = get_skill(ch,gsn_nerve)) == 0
    || ch->level < skill_table[gsn_nerve].skill_level[ch->class])
    {
        send_to_char("You don't know how to use nerve pressure tactics.\n\r",ch);
        return;
    }

    one_argument(argument,arg);
    if (arg[0] == '\0')
        victim = ch->fighting;
    else
        victim = get_char_room(ch,arg);

    if (victim == NULL)
    {
        send_to_char("Attempt to put pressure on who's nerves?\n\r",ch);
        return;
    }
    if (victim == ch)
    {
        send_to_char("You can't do that.\n\r",ch);
        return;
    }
    if (is_safe(ch,victim))
	return;

    if (is_affected(victim,gsn_nerve))
    {
	send_to_char("They have already been weakened using nerve pressure.\n\r",ch);
	return;
    }


    chance += (ch->drain_level + ch->level - victim->level  - victim->drain_level)*3;
    chance -= get_curr_stat(victim,STAT_DEX)/3;
    chance += get_curr_stat(ch,STAT_DEX)/2;
    chance -= get_curr_stat(victim,STAT_CON)/3;

    if (number_percent() > chance)
    {
        act("$n grasps $N's arm but fails to apply the right pressure point.",ch,0,victim,TO_NOTVICT);
        act("You grasp $N's arm but fail to apply the right pressure point.",ch,0,victim,TO_CHAR);
        act("$n grasps your arm but fails to apply the right pressure point.",ch,0,victim,TO_VICT);
        check_improve(ch,gsn_nerve,FALSE,3);
        WAIT_STATE(ch,PULSE_VIOLENCE);
        return;
    }
    else
    {
    act("$n grasps $N's arm and weakens $m with pressure points.",ch,0,victim,TO_NOTVICT);
    act("You grasp $N's arm and weaken $m with pressure points.",ch,0,victim,TO_CHAR);
    act("$n grasps your arm and weakens you with pressure point.",ch,0,victim,TO_VICT);
    check_improve(ch,gsn_nerve,TRUE,3);
	init_affect(&af);
    af.where = TO_AFFECTS;
    af.type = gsn_nerve;
    af.location = APPLY_STR;
    af.duration = ((ch->drain_level + ch->level)/5);
    af.bitvector = 0;
    af.modifier = -3;
	af.aftype = AFT_SKILL;
    af.level = ch->drain_level + ch->level;
    affect_to_char(victim,&af);
    WAIT_STATE(ch,PULSE_VIOLENCE);
    }

	if (!IS_NPC(ch) && !IS_NPC(victim)
	&& (ch->fighting == NULL
	|| victim->fighting == NULL) )
	{
sprintf(buf,"Help, %s is attacking me!",PERS(ch,victim));
do_myell(victim,buf);
	}
    if (victim->fighting == NULL)
    {
	multi_hit(victim,ch,TYPE_UNDEFINED);
    }

    return;
}

void check_follow_through(CHAR_DATA *ch, CHAR_DATA *victim, int dam)
{
    int chance;

    chance = get_skill(ch,gsn_follow_through);

    if (ch->level <skill_table[gsn_follow_through].skill_level[ch->class])
        return;

    chance /= 2;
    chance -= number_range(0,15);

    if (IS_AFFECTED(ch, AFF_HASTE))
	chance += 15;

    if (chance <= 0)
	return;

    if (number_percent() < chance)
    {
        act("$n's leg sweeps around and strikes with a follow through!",ch,0,0,TO_ROOM);
        act("Your leg sweeps around to land a follow through kick!",ch,0,0,TO_CHAR);
        damage_old(ch,victim, dam, gsn_follow_through, DAM_BASH,TRUE);
        check_improve(ch,gsn_follow_through,TRUE,2);
    }
    else
        check_improve(ch,gsn_follow_through,FALSE,3);

    return;
}



void do_blindness_dust(CHAR_DATA *ch,char *argument)
{
        CHAR_DATA *vch;
        CHAR_DATA *vch_next;
        AFFECT_DATA af;
        int chance;
        bool fighting = FALSE;
        char buf[MAX_STRING_LENGTH];

        if ( (chance = get_skill(ch,gsn_blindness_dust)) == 0
        || ch->level < skill_table[gsn_blindness_dust].skill_level[ch->class])
        {
        send_to_char("You don't know how to make blindness dust to throw.\n\r",ch);
        return;
        }
        if (ch->mana < 18)
        {
        send_to_char("You don't have the mana.\n\r",ch);
        return;
        }
        if (number_percent() > chance)
        {
        act("$n hurls some dust into the air but it is blown away.",ch,0,0,TO_ROOM);
        send_to_char("You throw out some dust but it is blown away.\n\r",ch);
        ch->mana -= 9;
        check_improve(ch,gsn_blindness_dust,FALSE,2);
        WAIT_STATE(ch,12);
        return;
        }
        act("$n hurls a handful of dust into the room!",ch,0,0,TO_ROOM);
        send_to_char("You throw a handful of blindness dust into the room!\n\r",ch);
        check_improve(ch,gsn_blindness_dust,TRUE,2);
        if (ch->fighting != NULL)
                fighting = TRUE;

	init_affect(&af);
        af.where = TO_AFFECTS;
        af.type = gsn_blindness_dust;
        af.level = ch->drain_level + ch->level;
        af.duration = 1;
        af.bitvector = AFF_BLIND;
        af.location = APPLY_HIT;
        af.modifier = -3;
	af.aftype = AFT_SKILL;
        ch->mana -= 18;
        WAIT_STATE(ch,12);
        for (vch = ch->in_room->people; vch != NULL; vch = vch_next)
        {
        vch_next = vch->next_in_room;
        if (is_safe(ch,vch))
		 continue;
        if (is_same_group(ch,vch))
		continue;
        if (!IS_AFFECTED(vch,AFF_BLIND)
        && !saves_spell(ch->drain_level + ch->level,vch,DAM_OTHER))
	{
	act("$n appears blinded.",vch,0,0,TO_ROOM);
	send_to_char("You get dust in your eyes.\n\r",vch);
                affect_to_char(vch,&af);
	}
        if (!IS_NPC(vch) && !IS_NPC(ch)
        && (vch->fighting == NULL || (!fighting)))
                {
        sprintf(buf,"Help! %s just threw dust in my eyes!",PERS(ch,vch));
                do_myell(vch,buf);
                }

                if (vch->fighting == NULL)
                        multi_hit(vch,ch,TYPE_UNDEFINED);

        }

        return;
}

void do_poison_dust(CHAR_DATA *ch,char *argument)
{
        CHAR_DATA *vch;
        CHAR_DATA *vch_next;
        AFFECT_DATA af;
        int chance;
        bool fighting = FALSE;
        char buf[MAX_STRING_LENGTH];

        if ( (chance = get_skill(ch,gsn_poison_dust)) == 0
        || ch->level < skill_table[gsn_poison_dust].skill_level[ch->class])
        {
        send_to_char("You don't know how to make poison dust to throw.\n\r",ch);
        return;
        }
        if (ch->mana < 20)
        {
        send_to_char("You don't have the mana.\n\r",ch);
        return;
        }
        if (number_percent() > chance)
        {
        act("$n hurls some dust into the air but it is blown away.",ch,0,0,TO_ROOM);
        send_to_char("You throw out some dust but it is blown away.\n\r",ch);
        ch->mana -= 10;
        WAIT_STATE(ch,12);
        check_improve(ch,gsn_poison_dust,FALSE,2);
        return;
        }
        act("$n hurls a handful of dust into the room!",ch,0,0,TO_ROOM);
        send_to_char("You throw a handful of poison dust into the room!\n\r",ch);
        check_improve(ch,gsn_poison_dust,TRUE,2);
          if (ch->fighting != NULL)
                fighting = TRUE;

	init_affect(&af);
        af.where = TO_AFFECTS;
        af.type = gsn_poison_dust;
        af.level = ch->drain_level + ch->level;
        af.duration = (ch->drain_level + ch->level)/5;
        af.bitvector = AFF_POISON;
        af.location = APPLY_STR;
        af.modifier = -3;
	af.aftype = AFT_SKILL;
        ch->mana -= 20;
        WAIT_STATE(ch,12);
        for (vch = ch->in_room->people; vch != NULL; vch = vch_next)
        {
        vch_next = vch->next_in_room;
        if (is_safe(ch,vch))    continue;
        if (is_same_group(ch,vch))      continue;
        if (!IS_AFFECTED(vch,AFF_POISON)
        && !saves_spell(ch->drain_level + ch->level,vch,DAM_OTHER))
	{
	act("$n turns green and looks sick.",vch,0,0,TO_ROOM);
	send_to_char("You suddenly feel very sick.\n\r",vch);
                affect_to_char(vch,&af);
	}

        if (!IS_NPC(vch) && !IS_NPC(ch)
        && (vch->fighting == NULL || (!fighting)))
                {
        sprintf(buf,"Help! %s just threw dust in my eyes!",PERS(ch,vch));
                do_myell(vch,buf);
                }
                if (vch->fighting == NULL)
                        multi_hit(vch,ch,TYPE_UNDEFINED);

        }
        return;
}

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

        if ( (chance = get_skill(victim,gsn_roll)) == 0
        || victim->level < skill_table[gsn_roll].skill_level[victim->class])
                return FALSE;

        chance *= 4;
        chance /= 5;
        chance += get_curr_stat(victim,STAT_DEX);
        chance -= victim->carry_weight/100;
        if (number_percent() > chance)
                {
                check_improve(victim,gsn_roll,FALSE,2);
                return FALSE;
                }

        check_improve(victim,gsn_roll,TRUE,2);
        return TRUE;
}

void do_warcry(CHAR_DATA *ch,char *argument)
{
        AFFECT_DATA af;
        int chance;
        if ( (chance = get_skill(ch,gsn_warcry)) == 0
        || ch->level < skill_table[gsn_warcry].skill_level[ch->class])
        {
        send_to_char("You don't know how to warcry properly.\n\r",ch);
        return;
        }

        if (is_affected(ch,gsn_warcry))
        {
        send_to_char("You are already affected by a warcry.\n\r",ch);
        return;
        }
        if (ch->mana < 20)
        {
        send_to_char("You don't have the mana.\n\r",ch);
        return;
        }

        if (number_percent() > chance)
        {
        act("$n makes some soft grunting noises.",ch,0,0,TO_ROOM);
        send_to_char("You make soft grunting sounds but nothing happens.\n\r",ch);
        check_improve(ch,gsn_warcry,FALSE,2);
        ch->mana -= 10;
        WAIT_STATE(ch,12);
        return;
        }

        act("$n lets out a blood freezing warcry!",ch,0,0,TO_ROOM);
        send_to_char("You let out a fierce warcry!\n\r",ch);
        check_improve(ch,gsn_warcry,TRUE,2);
	init_affect(&af);
        af.where = TO_AFFECTS;
	af.aftype = AFT_SKILL;
        af.type = gsn_warcry;
        af.modifier = (ch->drain_level + ch->level)/7;
        af.location = APPLY_HITROLL;
        af.duration = ch->drain_level + ch->level;
        af.bitvector = 0;
        af.level = ch->drain_level + ch->level;
        affect_to_char(ch,&af);
	af.location = APPLY_SAVES;
        af.modifier = -(ch->level/10);
        affect_to_char(ch,&af);
        ch->mana -= 20;
        WAIT_STATE(ch,12);
        return;
}

void check_downstrike(CHAR_DATA *ch,CHAR_DATA *victim)
{
    OBJ_DATA *wield;
    int dam;
    int chance;

    chance = get_skill(ch,gsn_downstrike);

    if (chance <= 10)	
	return;

    if (ch->level < skill_table[gsn_downstrike].skill_level[ch->class])
	return;

    chance /= 4.5;
    chance += (ch->drain_level + ch->level - victim->level - victim->drain_level);
    chance -= get_curr_stat(victim,STAT_DEX)/3;
    chance += get_curr_stat(ch,STAT_DEX)/3;

    chance = URANGE(2, chance, 35);

    if (number_percent() > chance)
    {
    	check_improve(ch,gsn_downstrike,FALSE,1);
	return;
    }

    wield = get_eq_char(ch,WEAR_WIELD);
    if (wield == NULL || wield->value[0]!=2)
	wield = get_eq_char(ch,WEAR_DUAL_WIELD);
    if (wield == NULL || wield->value[0]!=2)
	return;

    dam = dice(wield->value[1],wield->value[2]);
    dam += ch->damroll;

    act("You strike at $N with a downward thrust of your dagger!",ch,0,victim,TO_CHAR);
    act("$n strikes at you with a downward thrust of $s dagger!",ch,0,victim,TO_VICT);
    act("$n strikes at $N with a downward thrust of $s dagger!",ch,0,victim,TO_NOTVICT);
    check_improve(ch,gsn_downstrike,TRUE,1);
    damage_old(ch,victim,dam,gsn_downstrike,attack_table[wield->value[3]].damage, TRUE);
    return;
}




void do_enlist(CHAR_DATA *ch,char *argument)
{
    CHAR_DATA *victim;
    char arg[MAX_INPUT_LENGTH];
    int level;
    char buf[MAX_STRING_LENGTH];
    AFFECT_DATA af;
    int chance;
    CHAR_DATA *check;

    chance = get_skill(ch,gsn_enlist);
    if (chance <= 10
    || ch->level < skill_table[gsn_enlist].skill_level[ch->class])
    {
        send_to_char("You do not have the skills required to enlist mercenary aid.\n\r",ch);
        return;
    }
    one_argument(argument,arg);
    if (is_affected(ch,gsn_enlist))
    {
	send_to_char("You haven't built up the nerve to recruit anyone else yet.\n\r",ch);
	return;
    }

    if (arg[0] == '\0')
    {
        send_to_char("Who do you wish to enlist as a follower?\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("You can't recruit yourself.\n\r",ch);
        return;
    }
    if (!IS_NPC(victim))
    {
        send_to_char("Why not just ask them to join you?\n\r",ch);
        return;
    }
    for (check = char_list; check != NULL; check = check->next)
    {
	if (is_affected(check,gsn_enlist) && check->master == ch)
	{
	send_to_char("You already have a devoted recruit following you.\n\r",ch);
	return;
	}
    }

    if (!IS_SET(victim->act,ACT_WARRIOR))
    {
	send_to_char("You may only enlist the aid of those trained as warriors.\n\r",ch);
        return;
    }

    level = ch->drain_level + ch->level;

    if ((IS_GOOD(ch) && IS_EVIL(victim))
       || (IS_EVIL(ch) && IS_GOOD(victim)))
       level = 0;

    if (IS_NEUTRAL(victim) || IS_NEUTRAL(ch))
        level -= 4;

    if (IS_AFFECTED(victim,AFF_CHARM))
        level = 0;
    if ( (victim->level + 8) > level)
	level = 0;

    if (saves_spell(level,victim,DAM_OTHER) || level == 0)
    {
        if (number_percent() < 50)
            do_say(victim,"I don't follow scum such as you!");
        else
            do_say(victim,"You couldn't recruit a mangy dog to your company!");
        sprintf(buf,"Help! I'm being attacked by %s!",PERS(victim,ch));
        do_myell(ch,buf);
        multi_hit(victim,ch,TYPE_UNDEFINED);
        return;
    }

    victim->leader = ch;
    victim->master = ch;
	init_affect(&af);
    af.where = TO_AFFECTS;
	af.aftype = AFT_SKILL;
    af.type = gsn_enlist;
    af.modifier = 0;
    af.level = ch->drain_level + ch->level;
    af.bitvector = AFF_CHARM;
    af.duration = ch->drain_level + ch->level;
    af.location = 0;
    affect_to_char(victim,&af);
    af.bitvector = 0;
    af.duration = 15;
	af.affect_list_msg = str_dup("unable to enlist aid");
    affect_to_char(ch,&af);
    act("$N salutes you and prepares to follow into combat.",ch,0,victim,TO_CHAR);
    act("$N salutes $n and falls into line with $s.",ch,0,victim,TO_NOTVICT);
    return;
}



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

        chance = get_skill(ch,gsn_tame);
        one_argument(argument,arg);
        if (arg[0] == '\0')
                victim = ch->fighting;
        else
                victim = get_char_room(ch,arg);
        if (victim == NULL)
        {
        send_to_char("They aren't here to tame though.\n\r",ch);
        return;
        }
        if (!IS_NPC(victim))
        {
        send_to_char("Why not just talk to them about your problems?\n\r",ch);
        return;
        }
        else if (!IS_SET(victim->act,ACT_AGGRESSIVE)
        && !IS_SET(victim->off_flags,SPAM_MURDER))
        {
        send_to_char("They are as tame as they can be.\n\r",ch);
        return;
        }

        chance += (ch->drain_level + ch->level - victim->level - victim->drain_level)*3;
        if (chance > 90)        chance = 90;
        WAIT_STATE(ch,12);
        if (number_percent() > chance)
        {
        act("$n tries to calm down $N but fails.",ch,0,victim,TO_NOTVICT);
        act("$n tries to calm you down but fails.",ch,0,victim,TO_VICT);
        act("You try to calm $N down but fail.",ch,0,victim,TO_CHAR);
        check_improve(ch,gsn_tame,FALSE,2);
        return;
        }
        act("$n calms $N down.",ch,0,victim,TO_NOTVICT);
        act("You calm $N down.",ch,0,victim,TO_CHAR);
        act("$n calms you down.",ch,0,victim,TO_VICT);
        check_improve(ch,gsn_tame,TRUE,2);
        stop_fighting(victim,TRUE);
     victim->last_fought = NULL;
        REMOVE_BIT(victim->act,ACT_AGGRESSIVE);
        REMOVE_BIT(victim->off_flags,SPAM_MURDER);
        return;
}

void do_find_water(CHAR_DATA *ch,char *argument)
{
        OBJ_DATA *spring;
        int chance;
        chance = get_skill(ch,gsn_find_water);
        if (chance > 95)        chance = 95;
        if (chance == 0
        || ch->level < skill_table[gsn_find_water].skill_level[ch->class])
        {
        send_to_char("You poke the ground with a stick but find no water that way.\n\r",ch);
        return;
        }
        if (ch->mana < 15)
        {
        send_to_char("You don't have the mana.\n\r",ch);
        return;
        }
        if (ch->in_room->sector_type == SECT_WATER_SWIM
        || ch->in_room->sector_type == SECT_WATER_NOSWIM)
        {
        send_to_char("Water water all around but not a drop to drink..\n\r",ch);
        return;
        }
        if (number_percent() > chance)
        {
        act("$n pokes the ground with a stick then scratches $s head.",ch,0,0,TO_ROOM);
        send_to_char("You poke about on the ground but fail to find any water.\n\r",ch);
        check_improve(ch,gsn_find_water,FALSE,1);
        ch->mana -= 7;
        WAIT_STATE(ch,18);
        return;
        }
        act("$n pokes at the ground and digs up a spring of natural water!",ch,0,0,TO_ROOM);
        send_to_char("You poke about for a bit and eventually dig up a spring of water.\n\r",ch);
        WAIT_STATE(ch,18);
        ch->mana -= 15;
        spring = create_object(get_obj_index(OBJ_VNUM_SPRING),0);
        check_improve(ch,gsn_find_water,TRUE,1);
        obj_to_room(spring,ch->in_room);
        return;
}

void do_track(CHAR_DATA *ch,char *argument)
{
        CHAR_DATA *victim;
        int chance, dir;
        char arg[MAX_INPUT_LENGTH];
        char buf[MAX_STRING_LENGTH];

        dir = 0;
	chance = get_skill(ch,gsn_track);

        if (chance == 0
        || ch->level < skill_table[gsn_track].skill_level[ch->class])
        {
        send_to_char("You peer intently at the ground but discern nothing.\n\r",ch);
        return;
        }
        one_argument(argument,arg);
        victim = get_char_world(ch,arg);
        chance *= 2;
        chance /= 3;
        if (ch->in_room->sector_type == SECT_INSIDE)
                chance -= 40;
        else if (ch->in_room->sector_type == SECT_CITY)
                chance -= 35;
        else if (ch->in_room->sector_type >= SECT_WATER_SWIM
        && ch->in_room->sector_type < SECT_DESERT)
                chance = 0;
        else if (ch->in_room->sector_type == SECT_FOREST)
                chance += 25;

        if (victim != NULL && !IS_NPC(victim))
                dir = victim->pcdata->track_dir[ch->in_room->vnum];

        if (number_percent() > chance
        || victim == NULL
        || !IS_NPC(victim)
        || dir == 0)
        {
        act("$n peers intently at the ground but doesn't seem to find anything.",ch,0,0,TO_ROOM);
        send_to_char("You peer intently at the ground but uncover nothing new.\n\r",ch);
        check_improve(ch,gsn_track,FALSE,2);
        WAIT_STATE(ch,18);
        return;
        }
        act("$n peers at the ground and seems more enlightened.",ch,0,0,TO_ROOM);

sprintf(buf,"You peer at the surroundings and find that %s left %s last time they were here.\n\r",
victim->name,
(dir == 1) ? "north" : (dir == 2) ? "east" : (dir == 3) ? "south" :
(dir == 4) ? "west" : (dir == 5) ? "up" : "down");
        send_to_char(buf,ch);
        WAIT_STATE(ch,18);
        check_improve(ch,gsn_track,TRUE,2);
        return;
}

void do_shield_cleave(CHAR_DATA *ch,char *argument)
{
	char buf[MAX_STRING_LENGTH];
        char arg[MAX_INPUT_LENGTH];
        int chance;
        OBJ_DATA *weapon;
        OBJ_DATA *shield;
        bool using_primary = TRUE;
  	CHAR_DATA *victim;

        one_argument(argument,arg);
        if (arg[0] == '\0')
                victim = ch->fighting;
        else
                victim = get_char_room(ch,arg);

        chance = get_skill(ch,gsn_shield_cleave);
        if (chance == 0
        || ch->level < skill_table[gsn_shield_cleave].skill_level[ch->class])
        {
        send_to_char("You don't know the methods to cleave a shield in two.\n\r",ch);
        return;
        }
        weapon = get_eq_char(ch,WEAR_WIELD);
        if (weapon == NULL)
        {
        weapon = get_eq_char(ch,WEAR_DUAL_WIELD);
        using_primary = FALSE;
        }
        if (weapon == NULL
        || (weapon->value[0] != WEAPON_SWORD
        && weapon->value[0] != WEAPON_AXE) )
        {
        send_to_char("You must be wielding an axe or sword to shield cleave.\n\r",ch);
        return;
        }
        if (victim == NULL)
        {
        send_to_char("But they aren't here.\n\r",ch);
        return;
        }
    if (victim == ch)
    {
send_to_char("That isn't possible.\n\r",ch);
return;
}
        if ((shield = get_eq_char(victim,WEAR_SHIELD)) == NULL)
        {
        send_to_char("But they aren't using a shield.\n\r",ch);
        return;
        }

        chance *= 9;
        chance /= 10;
        chance += (ch->level - victim->level)*3;
        chance -= shield->level;
	if(IS_AFFECTED(ch,AFF_BLIND))
		chance -= 50;
        if (!using_primary)
                chance -= 15;
    if (!IS_NPC(victim) && ch->fighting != victim)
    {
sprintf(buf,"Help! %s is trying to cleave my shield!",PERS(ch,victim));
	do_myell(victim,buf);
    }

	if (is_affected(victim,gsn_shield_of_purity))
	{
		act("$n attempts to strike a mighty blow to $N's shield!",ch,0,victim,TO_NOTVICT);
       		act("$n attempts to strike a mighty blow to your shield!",ch,0,victim,TO_VICT);
        	act("You attempt to strike a mighty blow to $N's shield!",ch,0,victim,TO_CHAR);
		act("$N skillfully deflects your shield-cleave attempt and counters with a powerful strike!",ch,0,victim,TO_CHAR);
		act("You gracefully deflect $n's shield-cleave attempt and counter with a powerful strike!",ch,0,victim,TO_VICT);
		act("$N skillfully deflects $n's shield-cleave attempt and counters with a powerful strike!",ch,0,victim,TO_NOTVICT);
		one_hit_new(victim,ch,TYPE_UNDEFINED,HIT_NOSPECIALS,HIT_UNBLOCKABLE,HIT_NOADD,225,"strike of purity");
		check_improve(ch,gsn_shield_cleave,FALSE,1);
		WAIT_STATE(ch,12);
		return;
	}

	if (is_affected(victim,gsn_shield_of_justice))
	{
		act("$n attempts to strike a mighty blow to $N's shield!",ch,0,victim,TO_NOTVICT);
       		act("$n attempts to strike a mighty blow to your shield!",ch,0,victim,TO_VICT);
        	act("You attempt to strike a mighty blow to $N's shield!",ch,0,victim,TO_CHAR);
		act("$N meets your shield-cleave attempt with incredible force using $S divine shield, reflecting your attack!",ch,0,victim,TO_CHAR);
		act("$N meets $n's shield-cleave attempt with incredible force using $S divine shield, reflecting $S attack!",ch,0,victim,TO_NOTVICT);
		act("You meet $n's shield-cleave with incredible force using your divine shield, reflecting $S attack!",ch,0,victim,TO_VICT);
one_hit_new(victim,ch,TYPE_UNDEFINED,HIT_NOSPECIALS,HIT_UNBLOCKABLE,HIT_NOADD,150,"reflected attack");		
		check_improve(ch,gsn_shield_cleave,FALSE,1);
		WAIT_STATE(ch,12);
		return;
	}

	if (is_affected(victim,gsn_shield_of_redemption))
	{
		act("$N positions $Mself to minimize the effectiveness of your shield-cleave.",ch,0,victim,TO_CHAR);
		act("$N positions $Mself to minimize the effectiveness of $n's shield-cleave.",ch,0,victim,TO_NOTVICT);
		act("You position yourself to minimize the effectiveness of $n's shield-cleave.",ch,0,victim,TO_VICT);
		chance -= 25;
	}

	if (is_affected(victim,gsn_shield_of_truth) && victim->pcdata->learned[skill_lookup("shieldbash")] > 75)
	{
		act("Striking preemptively, $N catches you offguard during your shield-cleave attempt and drives at you with $S shield!",ch,0,victim,TO_CHAR);
		act("$N's slams into you with his shield and sends you flying!",ch,0,victim,TO_CHAR);
		act("Striking preemptively, $N catches $n offguard during $s shield-cleave attempt and drives at $n with $S shield!",ch,0,victim,TO_NOTVICT);
		act("$N's slams into $n with his shield and sends $M flying!",ch,0,victim,TO_NOTVICT);
		act("Striking preemptively, you catch $n offguard during $s shield-cleave attempt and drive at $M with your shield!",ch,0,victim,TO_VICT);
		act("You slam into $n with your shield and send $M flying!",ch,0,victim,TO_VICT);
		WAIT_STATE(victim,skill_table[gsn_shieldbash].beats+PULSE_VIOLENCE);
		ch->position = POS_RESTING;
		check_improve(victim,gsn_shieldbash,TRUE,1);
		act("Your god senses the proximity of $n through your shield!",ch,0,victim,TO_VICT);
		int sapHealth = GET_DAMROLL(victim) * .75;
		act("The shield's energy reaches out and saps $n's health, using it to fuel your own!",ch,0,victim,TO_VICT);
		act("The energy surrounding $N's divine shield reaches out and saps your health!",ch,0,victim,TO_CHAR);
		act("The energy surrounding $N's divine shield reaches out and saps $n's health!",ch,0,victim,TO_NOTVICT);		
		damage_new(victim,ch,sapHealth,TYPE_UNDEFINED,DAM_HOLY,TRUE,HIT_UNBLOCKABLE,HIT_NOADD,100,"strike of truth");
		act("$N absorbs your lost health!",ch,0,victim,TO_CHAR);
		victim->hit += sapHealth;
		if (victim->hit > victim->max_hit)
			victim->hit = victim->max_hit;
		check_improve(ch,gsn_shield_cleave,FALSE,1);
		return;
	}

        if (number_percent() > chance)
        {
        act("$n makes a mighty blow at $N's shield but fails to cleave it.",ch,0,victim,TO_NOTVICT);
        act("$n lands a mighty blow to your shield but fails to cleave it.",ch,0,victim,TO_VICT);
        act("You strike a mighty blow to $N's shield but fail to cleave it.",ch,0,victim,TO_CHAR);
        check_improve(ch,gsn_shield_cleave,FALSE,1);
        WAIT_STATE(ch,12);

multi_hit(victim,ch,-1);
        return;
        }
        act("$n's mighty blow cleaves $N's shield in half!",ch,0,victim,TO_NOTVICT);
        act("Your mighty blow cleaves $N's shield in half!",ch,0,victim,TO_CHAR);
        act("$n strikes your shield with powerful force, cleaving it in two!",ch,0,victim,TO_VICT);
	if (is_affected(victim,gsn_shield_of_redemption))
	{
		act("$N's divine shield shatters, consuming you in a torrent of holy energy!",ch,0,victim,TO_CHAR);
		act("Your divine shield shatters, consuming $n in a torrent of holy energy!",ch,0,victim,TO_VICT);
		act("$N's divine shield shatters, consuming $n in a torrent of holy energy!",ch,0,victim,TO_NOTVICT);damage_new(victim,ch,victim->level*2 + number_range(1,20),TYPE_UNDEFINED,DAM_HOLY,TRUE,HIT_UNBLOCKABLE,HIT_NOADD,HIT_NOMULT,"holy fire"); 
damage_new(victim,ch,victim->level*2 + number_range(1,20),TYPE_UNDEFINED,DAM_HOLY,TRUE,HIT_UNBLOCKABLE,HIT_NOADD,HIT_NOMULT,"holy fire"); 
damage_new(victim,ch,victim->level*2 + number_range(1,20),TYPE_UNDEFINED,DAM_HOLY,TRUE,HIT_UNBLOCKABLE,HIT_NOADD,HIT_NOMULT,"holy fire"); 
damage_new(victim,ch,victim->level*2 + number_range(1,20),TYPE_UNDEFINED,DAM_HOLY,TRUE,HIT_UNBLOCKABLE,HIT_NOADD,HIT_NOMULT,"holy fire"); 
damage_new(victim,ch,victim->level*2 + number_range(1,20),TYPE_UNDEFINED,DAM_HOLY,TRUE,HIT_UNBLOCKABLE,HIT_NOADD,HIT_NOMULT,"holy fire"); 
	}
        extract_obj(shield);
        WAIT_STATE(ch,12);
	check_improve(ch,gsn_shield_cleave,TRUE,1);
    multi_hit(victim,ch,-1);

        return;
}

/* more race skills...Ceran */

void do_breath_fire(CHAR_DATA *ch,char *argument)
{
    AFFECT_DATA af;
    CHAR_DATA *victim;
    OBJ_DATA *obj_lose;
    OBJ_DATA *obj_next;
    char arg[MAX_INPUT_LENGTH];
    int dam, chance;
    int hpch, level;

    level = ch->drain_level + ch->level;
    chance = get_skill(ch,gsn_breath_fire);
    if (chance == 0
    || ch->level < skill_table[gsn_breath_fire].skill_level[ch->class])
    {
    send_to_char("You aren't able to breath fire.\n\r",ch);
    return;
    }

    if (is_affected(ch,gsn_breath_fire))
    {
    send_to_char("You haven't yet regained the heat in your body to create more flames.\n\r",ch);
    return;
    }

    one_argument(argument,arg);
    if (arg[0] == '\0')
        victim = ch->fighting;
    else
        victim = get_char_room(ch,arg);

    if (victim == NULL)
    {
    send_to_char("They aren't here.\n\r",ch);
    return;
    }
    if (ch->mana < 20)
    {
    send_to_char("You don't have the mana.\n\r",ch);
    return;
    }
    if (number_percent() > chance)
    {
    send_to_char("You try to breath forth fire but only smokes comes out.\n\r",ch);
    act("$n opens $s mouth but only a thick plume of black smoke comes forth.",ch,0,0,TO_ROOM);
    ch->mana -= 10;
    check_improve(ch,gsn_breath_fire,FALSE,1);
    return;
    }
	init_affect(&af);
    af.where = TO_AFFECTS;
	af.aftype = AFT_SKILL;
    af.type = gsn_breath_fire;
    af.location = 0;
    af.modifier = 0;
    af.duration = 4;
	af.affect_list_msg = str_dup("unable to breath fire");
    af.bitvector = 0;
    af.level = ch->drain_level + ch->level;
    affect_to_char(ch,&af);

    act("$n breaths forth a cone of searing flames!",ch,0,0,TO_ROOM);
    send_to_char("You breath forth a cone of searing flames!\n\r",ch);

    if ( number_percent( ) < level && !saves_spell( level - 2, victim,DAM_FIRE ) )
    {
	for ( obj_lose = victim->carrying; obj_lose != NULL;
	obj_lose = obj_next )
	{
	    char *msg;

	    obj_next = obj_lose->next_content;
	    if ( number_bits( 2 ) != 0 )
		continue;

	    switch ( obj_lose->item_type )
	    {
	    default:             continue;
	    case ITEM_CONTAINER: msg = "$p ignites and burns!";   break;
	    case ITEM_POTION:    msg = "$p bubbles and boils!";   break;
	    case ITEM_SCROLL:    msg = "$p crackles and burns!";  break;
	    case ITEM_STAFF:     msg = "$p smokes and chars!";    break;
	    case ITEM_WAND:      msg = "$p sparks and sputters!"; break;
	    case ITEM_FOOD:      msg = "$p blackens and crisps!"; break;
	    case ITEM_PILL:      msg = "$p melts and drips!";     break;
	    }

	    act( msg, victim, obj_lose, NULL, TO_CHAR );
	    extract_obj( obj_lose );
	}
    }

    hpch = UMAX( 10, ch->hit );
    dam  = number_range( (hpch/7) + 1, hpch/3 );
    if ( saves_spell( level - 2, victim, DAM_FIRE ) )
	dam /= 2;
    damage_old( ch, victim, dam, gsn_breath_fire, DAM_FIRE,TRUE);
    check_improve(ch,gsn_breath_fire,TRUE,1);
    return;
}


void do_rear_kick(CHAR_DATA *ch,char *argument)
{
    CHAR_DATA *victim;
    int dam;
/*
    AFFECT_DATA af;
*/
    if (str_cmp(race_table[ch->race].name,"centaur"))
    {
    send_to_char("You don't have a centaur's rear legs to kick like that.\n\r",ch);
    return;
    }

    if ( !IS_NPC(ch)
    &&   ch->level < skill_table[gsn_rear_kick].skill_level[ch->class] )
    {
	send_to_char("You do not have the ability to rear kick yet.\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 are not fighting anyone.\n\r", ch );
	return;
    }

    WAIT_STATE( ch, 24 );
    act("$n whips about and kicks out with $s hind legs!",ch,0,0,TO_ROOM);
    act("You whip about and kick out with your hind legs!",ch,0,0,TO_CHAR);

    if ( IS_NPC(ch) || number_percent( ) < ch->pcdata->learned[gsn_rear_kick] )
    {
        dam = number_range(ch->level/2,ch->level);
        dam += get_curr_stat(ch,STAT_STR);
        dam += number_range(1,ch->drain_level + ch->level);
        dam += number_range((ch->drain_level + ch->level)/4, (ch->drain_level + ch->level)/2);

        if (dam < 1)
                dam = 1;
        if (dam > 140)
                dam = 140;

        damage_old( ch, victim, dam, gsn_rear_kick,DAM_BASH, TRUE );
        check_improve(ch,gsn_rear_kick,TRUE,1);
    }
    else
    {
        damage_old( ch, victim, 0, gsn_rear_kick,DAM_BASH,TRUE );
        check_improve(ch,gsn_rear_kick,FALSE,1);
    }

    return;
}

void do_strap(CHAR_DATA *victim,OBJ_DATA *strap) {
	CHAR_DATA *vch;
	CHAR_DATA *vch_next;

	if (strap->pIndexData->vnum == 5750) {
	act("\x01B[1;31m$n's $p explodes in a blinding flash of light!\x01B[0;37m",victim,strap,0,TO_ROOM);
	act("\x01B[1;31mYour $p explodes in a blinding flash of light!\x01B[0;37m",victim,strap,0,TO_CHAR);
	for (vch = victim->in_room->people; vch != NULL; vch = vch_next)
	{
	vch_next = vch->next_in_room;
	if (vch == victim) {
		continue;
	}
	if (IS_NPC(vch)) {
		continue;
	}
	if (vch->level > LEVEL_HERO) {
		continue;
	}
	act("$n detonates in an eruption of blood and fluids!",vch,strap,0,TO_ROOM);
	act("You detonate in an eruption of blood and fluids!",vch,strap,0,TO_CHAR);
	act( "$n is DEAD!!", vch, 0, 0, TO_ROOM );
	send_to_char( "You have been KILLED!!\n\r\n\r", vch );
	raw_kill(victim,vch);
	}
	unequip_char(victim,strap);
	obj_from_char(strap);
	extract_obj(strap);
	}
	if (strap->pIndexData->vnum == 5751) {
	unequip_char(victim,strap);
	obj_from_char(strap);
	extract_obj(strap);
	}
	return;
}

/* dying of old age */
void age_death(CHAR_DATA *ch)
{
    ROOM_INDEX_DATA *pRoomIndex;
    char *cname;
    AFFECT_DATA af;


    if (IS_NPC(ch))
        return;


	pRoomIndex = get_room_index(1212);
 
    if (pRoomIndex == NULL)
        return;

/* For now default to the players recall, or midgaard */
        pRoomIndex = get_room_index(hometown_table[ch->hometown].recall);
	if (pRoomIndex == NULL)
		pRoomIndex = get_room_index(ROOM_VNUM_TEMPLE);

    stop_fighting(ch,TRUE);
    make_corpse(ch,ch);
    char_from_room(ch);
    char_to_room(ch,pRoomIndex);
    do_look(ch,"auto");
    send_to_char("You have died and become a permanent ghost, awaiting your final departure.\n\r",ch);
    cname   = str_dup(ch->original_name);
    if( ((ch->played + (current_time - ch->logon)) / 3600) >= 15)
                delete_char(cname,TRUE);        // >= 15 hours. Make name unusable.
        else
                delete_char(cname,FALSE);
    init_affect(&af);
    af.aftype = AFT_INVIS;
    af.type   = skill_lookup("age death");
    af.duration = -1;
    af.strippable = FALSE;
    affect_to_char(ch,&af);
    return;
}



void do_forage(CHAR_DATA *ch,char *argument)
{
        OBJ_DATA *berry_1;
        OBJ_DATA *berry_2;
        int chance, found;

    if ( (chance = get_skill(ch,gsn_forage)) == 0
    || (ch->level < skill_table[gsn_forage].skill_level[ch->class]) )
    {
        send_to_char("You aren't able to decide on which plants are edible.\n\r",ch);
	return;
    }
    if (ch->in_room->sector_type != SECT_FOREST)
    {
    send_to_char("You aren't in a suitable forest region where you can apply your plant lore.\n\r",ch);
    return;
    }

    if (chance > 90)
        chance = 90;

    if (number_percent() > chance)
    {
    act("$n messes about in the undergrowth but comes up looking perplexed.",ch,0,0,TO_ROOM);
    send_to_char("You search around but find nothing you can recognise as edible.\n\r",ch);
    check_improve(ch,gsn_forage,FALSE,2);
    WAIT_STATE(ch,12);
    return;
    }

    act("$n messes about in the nearby bushes and comes out with some berries.",ch,0,0,TO_ROOM);
    send_to_char("You search around and find some edible berries in the bushes.\n\r",ch);
    check_improve(ch,gsn_forage,TRUE,2);

    found = number_range(1,3);

    berry_1 = create_object(get_obj_index(OBJ_VNUM_BERRY),1);
    if (berry_1 == NULL)
        return;
    obj_to_char(berry_1,ch);

    if (found >= 2)
    {
        berry_2 = create_object(get_obj_index(OBJ_VNUM_BERRY),1);
        obj_to_char(berry_2,ch);
    }
/*
    if (found >= 3)
    {
        berry_3 = create_object(get_obj_index(OBJ_VNUM_BERRY),1);
        obj_to_char(berry_3,ch);
    }
    if (found >= 4)
    {
        berry_4 = create_object(get_obj_index(OBJ_VNUM_BERRY),1);
        obj_to_char(berry_4,ch);
    }
*/

    return;
}

void do_defend(CHAR_DATA *ch,char *argument)
{
    CHAR_DATA *victim;
    char arg[MAX_STRING_LENGTH];
    char buf[MAX_STRING_LENGTH];

    one_argument(argument,arg);
        if ( (get_skill(ch,gsn_defend) == 0)
        || (ch->level < skill_table[gsn_defend].skill_level[ch->class]) )
    {
        send_to_char("You aren't able to defend other people.\n\r",ch);
	return;
    }

    if (arg[0] == '\0')
    {
    if (ch->defending == NULL)
    sprintf(buf,"You aren't defending anyone right now.\n\r");
    else
    sprintf(buf,"You are defending %s.\n\r",ch->defending->name);
    send_to_char(buf,ch);
    return;
    }
    victim = get_char_room(ch,arg);
    if (victim == NULL)
    {
    send_to_char("They aren't here.\n\r",ch);
    return;
    }
    if (victim == ch)
    {
    send_to_char("You no longer defend anyone.\n\r",ch);
    ch->defending = NULL;
    return;
    }
    if (IS_NPC(victim))
    {
    send_to_char("They don't need to be defended.\n\r",ch);
    return;
    }
    if (ch->defending != NULL)
    {
        act("You stop defending $N.",ch,0,ch->defending,TO_CHAR);
        act("$n stops defending you.",ch,0,ch->defending,TO_VICT);
    }
    sprintf(buf,"You start defending %s.",victim->name);
	act(buf,ch,0,victim,TO_CHAR);

    ch->defending = victim;
    act("$n is now defending you.",ch,0,victim,TO_VICT);
    return;
}

/* New flee...this allows 'flee <direction>' for the thief skill escape.
-Ceran
*/
void do_flee( CHAR_DATA *ch, char *argument )
{
    ROOM_INDEX_DATA *was_in;
    ROOM_INDEX_DATA *now_in;
    CHAR_DATA *victim;
    char arg[MAX_INPUT_LENGTH];
    int attempt, chance, dir;

	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;
    }

    if (IS_ROOM_AFFECTED(ch->in_room,AFF_ROOM_WALL_THORNS))
    {
	if (check_wall_thorns(ch))
		return;
    }

    if (is_affected(ch,gsn_aristaeia))
    {
	send_to_char("You are too filled with righteous wrath to flee!\n\r",ch);
	check_parting_blow(ch,victim);
	return;
    }

    if (is_affected(ch,gsn_shadowstrike) && number_percent()<20)
    {
		act("$n tries to flee but the shadowy arms stop his movements.",ch,0,0,TO_ROOM);
		act("You try to flee but the shadow arms block you.",ch,0,0,TO_CHAR);
		WAIT_STATE(ch,2*PULSE_VIOLENCE);
		return;
	}

    if (is_affected(ch,gsn_shackles) && number_percent()<20)
    {
		act("$n tries to flee but trips over his shackles.",ch,0,0,TO_ROOM);
		act("You try to flee but trip over your shackles.",ch,0,0,TO_CHAR);
		WAIT_STATE(ch,PULSE_VIOLENCE);
		check_cheap_shot(ch->fighting,ch);
		return;
    }
    if (is_affected(ch,gsn_entwine))
    {
        act("$n tries to flee with $s legs entwined, but trips.",ch,NULL,NULL,TO_ROOM);
        act("You try to flee with your legs entwined, but trip.",ch,NULL,NULL,TO_CHAR);
        check_downstrike(victim,ch);
        check_cheap_shot(victim,ch);
          WAIT_STATE(ch,PULSE_VIOLENCE);
          return;
    }
    if (is_affected(ch,gsn_bloodthirst) && number_percent()<70 )
    {
      send_to_char("You gasp for breath as you attempt to snap out of your insanity!\n\r",ch);
      act("$n gasps for breath, attempting to snap out of $s insanity!",ch,NULL,NULL,TO_ROOM);
      WAIT_STATE(ch,PULSE_VIOLENCE);
    }

    if (is_affected(ch,gsn_bind) )
    {
	act("$n attempts to flee but his bindings cause $m to trip up and fall!",ch,0,0,TO_ROOM);
	act("You attempt to flee but your bindings cause you to trip up and fall!",ch,0,0,TO_CHAR);
	WAIT_STATE(ch,PULSE_VIOLENCE);
	check_cheap_shot(ch->fighting,ch);
	check_parting_blow(ch,victim);
	return;
    }

	if (check_cutoff(ch,victim)) {
		return;
	}

    one_argument(argument,arg);
    chance = get_skill(ch,gsn_escape);
    if (chance > 90) chance=90;

    dir = 10;

    if (arg[0] == '\0')             dir=10;
    else if (!str_cmp(arg,"north")) dir=0;
    else if (!str_cmp(arg,"east"))  dir=1;
    else if (!str_cmp(arg,"south")) dir=2;
    else if (!str_cmp(arg,"west"))  dir=3;
    else if (!str_cmp(arg,"up"))    dir=4;
    else if (!str_cmp(arg,"down"))  dir=5;
    else                            dir=10;

    was_in = ch->in_room;

    if (was_in==NULL)
    {
      bug("In do_flee: ch->in_room is NULL.",0);
      return;
    }

    if (chance>0 && number_percent()>chance && dir!=10)
    {
      send_to_char("Trying to escape...\n\r",ch);
    }

    for ( attempt = 0; attempt < 6; attempt++ )
    {
        EXIT_DATA *pexit;
        int door;

        if (dir>5 || dir<0) door=number_door()%6;
        else door = dir;

        pexit = was_in->exit[door];

        if ( pexit == 0) continue;

        if (pexit->u1.to_room == NULL
            ||   ( IS_SET(pexit->exit_info, EX_CLOSED)
	        && (!IS_AFFECTED(ch,AFF_PASS_DOOR) ))
            ||   number_range(0,ch->daze) != 0
            || ( IS_NPC(ch)
            &&   IS_SET(pexit->u1.to_room->room_flags, ROOM_NO_MOB) ) )
          continue;

	
	if (attempt == 0)
		check_parting_blow(ch,victim);

        move_char( ch, door, FALSE );

        if ( ( now_in = ch->in_room ) == was_in )
            continue;

	stop_fighting(ch,TRUE);
	ch->last_fought = NULL;
        ch->in_room = was_in;
	if (is_affected(ch, gsn_owaza))
	{
		send_to_char("Your attempt at owaza fails as you flee.\n\r",ch);
		affect_strip(ch, gsn_owaza);
	}
        act( "$n has fled!", ch, NULL, NULL, TO_ROOM );

        ch->in_room = now_in;

        if ( !IS_NPC(ch) )
        {
            send_to_char( "You flee from combat!\n\r", ch );

	if (dir != 10 && get_skill(ch,gsn_escape) > 2)
	check_improve(ch,gsn_escape,2,TRUE);
        }

        return;
    }

    send_to_char( "PANIC! You couldn't escape!\n\r", ch );
    return;
}

void do_pugil(CHAR_DATA *ch,char *argument)
{
    char arg[MAX_INPUT_LENGTH];
    CHAR_DATA *victim;
    OBJ_DATA *obj;
    int chance;
    int dam;

    one_argument(argument,arg);

    if ( (chance = get_skill(ch,gsn_pugil)) == 0
    ||  IS_NPC(ch)
    ||  (!IS_NPC(ch) && ch->level < skill_table[gsn_pugil].skill_level[ch->class]) )
    {
        send_to_char("You're not trained in the art of pugiling.\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 (ch->fighting == NULL)
	{
        send_to_char("You can't pugil someone like that.\n\r",ch);
	return;
	}

    if (victim == ch)
    {
        send_to_char("That would be a bit stupid.\n\r", ch);
	return;
    }

   obj = get_eq_char(ch,WEAR_WIELD);
   if (obj == NULL || obj->value[0] != WEAPON_STAFF)
    {
    send_to_char("You must be wielding a staff to pugil.\n\r",ch);
    return;
    }

    chance += (ch->level - victim->level);
    chance = URANGE(5, chance, 90);

    WAIT_STATE(ch,skill_table[gsn_pugil].beats);

    if (number_percent() < chance)
    {
        act("You smash $N with a bone crushing pugil!",ch,NULL,victim,TO_CHAR);
        act("$n smashes you with a bone crushing pugil!",ch,NULL,victim,TO_VICT);
        act("$n pugils $N with a bone crushing pugil!",ch,NULL,victim,TO_NOTVICT);
        check_improve(ch,gsn_pugil,TRUE,1);
	dam = dice(obj->value[1],obj->value[2]);
        dam += (get_skill(ch,gsn_enhanced_damage) * dam/100);
        if (ch->level <= 20)
            {
            dam *= number_range(10,13);
            dam /= 10;
            }
        else if (ch->level <= 25)
            {
            dam *= number_range(11,14);
            dam /= 10;
            }
        else if (ch->level <= 30)
            {
            dam *= number_range(12,15);
            dam /= 10;
            }
        else if (ch->level <= 35)
            {
            dam *= number_range(12,17);
            dam /= 10;
            }
        else if (ch->level <= 40)
            {
            dam *= number_range(13,18);
            dam /= 10;
            }
        else
            {
            dam *= number_range(14,20);
            dam /= 10;
            }

        damage_old(ch,victim,dam,gsn_pugil, attack_table[obj->value[3]].damage, TRUE);
    }
    else
    {
        check_improve(ch,gsn_pugil,FALSE,1);

        damage_old(ch,victim,0,gsn_pugil,DAM_NONE,TRUE);
    }

    return;
}


void do_protection_heat_cold(CHAR_DATA *ch,char *argument)
{
    AFFECT_DATA af;
    int chance;
    chance = get_skill(ch,gsn_protection_heat_cold);

    if (chance == 0
	|| ch->level <skill_table[gsn_protection_heat_cold].skill_level[ch->class])
    {
send_to_char("You don't know how to protect yourself from the elements.\n\r",ch);
	return;
    }

    if (is_affected(ch,gsn_protection_heat_cold))
    {
    send_to_char("You are already protected from the elements.\n\r",ch);
    return;
    }

    if (number_percent() > chance)
    {
	send_to_char("You try to protect yourself from the elements but fail.\n\r",ch);
	check_improve(ch,gsn_protection_heat_cold,FALSE,1);
	return;
    }

	init_affect(&af);
    af.where = TO_AFFECTS;
	af.aftype = AFT_SKILL;
    af.type = gsn_protection_heat_cold;
    af.level = ch->level;
    af.modifier = 0;
    af.duration = ch->level;
    af.bitvector = 0;
    af.location = 0;
	af.affect_list_msg = str_dup("grants protection against heat and cold-elemental attacks");
    affect_to_char(ch,&af);
    send_to_char("You are protected from the elements.\n\r",ch);
	check_improve(ch,gsn_protection_heat_cold,TRUE,1);
    return;
}

void do_undead_drain(CHAR_DATA *ch,char *argument)
{
	CHAR_DATA *vch;
	int sn_drain;
	if (ch->level < 40) return;

	for (vch = ch->in_room->people; vch != NULL; vch = vch->next_in_room)
	{
	if (vch->fighting == ch
	&& number_percent() > 70)
			break;
	}

if (vch == NULL)
		vch = ch->fighting;
	sn_drain = skill_lookup("undead drain");
	if (sn_drain == -1)
	return;

	(*skill_table[sn_drain].spell_fun) (sn_drain,ch->level,ch,vch,TAR_CHAR_OFFENSIVE);
	return;
}

char * check_evaluation_fight(CHAR_DATA *ch,CHAR_DATA *victim)
{
    int percent;
    char wound[100];
    char buf[MAX_STRING_LENGTH];

    if ((victim = ch->fighting) != NULL && can_see(ch,victim))
    {
        if (victim->max_hit > 0)
            percent = victim->hit * 100 / victim->max_hit;
        else
            percent = -1;

        if (percent >= 100)
            sprintf(wound,"is in perfect condition.");
        else if (percent >= 95)
            sprintf(wound,"has a few scratches.");
        else if (percent >= 90)
            sprintf(wound,"has a few bruises.");
        else if (percent >= 80)
             sprintf(wound,"has some small wounds.");
        else if (percent >= 70)
            sprintf(wound,"has some big nasty cuts.");
        else if (percent >= 60)
            sprintf(wound,"has quite a few wounds.");
        else if (percent >= 50)
            sprintf(wound,"is bleeding profusely.");
        else if (percent >= 40)
            sprintf(wound,"is gushing blood.");
        else if (percent >= 30)
            sprintf(wound,"is screaming in pain.");
        else if (percent >= 20)
            sprintf(wound,"is spasming in shock.");
        else if (percent >= 10)
            sprintf(wound,"is writhing on the ground.");
        else if (percent >= 1)
            sprintf(wound,"is convulsing near death.");
        else
            sprintf(wound,"is nearly dead.");
	}
	return str_dup(buf);
}

void do_iron_resolve(CHAR_DATA *ch,char *argument)
{
    AFFECT_DATA af;

    if (is_affected(ch,gsn_iron_resolve))
    {
        send_to_char("Your mind is already firmly set on your inner being.\n\r",ch);
        return;
    }
    if (ch->mana < 100)
    {
        send_to_char("You don't have the mental concentration right now.\n\r",ch);
        return;
    }

    if (number_percent() > get_skill(ch,gsn_iron_resolve))
    {
        send_to_char("You try to concentrate on your inner being but fail to maintain it.\n\r",ch);
        ch->mana -= 50;
        WAIT_STATE(ch,12);
        return;
    }

    send_to_char("You feel yourself come together as mind and body.\n\r",ch);

	init_affect(&af);
    af.where = TO_AFFECTS;
	af.aftype = AFT_SKILL;
    af.type = gsn_iron_resolve;
    af.level = ch->level;
    af.location = 0;
    af.bitvector = 0;
    af.modifier = 0;
    af.duration = ch->level/3;
    ch->mana -= 100;
    WAIT_STATE(ch,12);
}

void do_quiet_movement(CHAR_DATA *ch, char *argument)
{
    AFFECT_DATA af;
    int chance;

    chance = get_skill(ch,gsn_quiet_movement);
    if (chance == 0
    || ch->level < skill_table[gsn_quiet_movement].skill_level[ch->class])
    {
        send_to_char("You don't know how to move with silent stealth through the wilderness.\n\r",ch);
        return;
    }

    if (is_affected(ch,gsn_quiet_movement))
    {
        send_to_char("You are already attempting to move silently through the wilderness.\n\r",ch);
        return;
    }
    if (ch->in_room->sector_type == SECT_FOREST)
    {
        send_to_char("You attempt to move quietly through the forest.\n\r",ch);
    }
    else if (ch->in_room->sector_type == SECT_MOUNTAIN)
    {
        send_to_char("You attempt to move quietly through the mountains.\n\r",ch);
    }
    else if (ch->in_room->sector_type == SECT_HILLS)
    {
        send_to_char("You attempt to move quietly through the hills.\n\r",ch);
    }
    else
    {
        send_to_char("You aren't in the right kind of wilderness to movee quietly.\n\r",ch);
        return;
    }

    if (number_percent() > chance)
    {
        check_improve(ch,gsn_quiet_movement,FALSE,1);
        return;
    }
    check_improve(ch,gsn_quiet_movement,TRUE,1);

	init_affect(&af);
    af.where = TO_AFFECTS;
    af.type = gsn_quiet_movement;
	af.aftype = AFT_SKILL;
    af.location = 0;
    af.modifier = 0;
    af.duration = ch->level;
    af.level = ch->level;
	char msg_buf[MSL];
	sprintf(msg_buf,"moving silently");
	af.affect_list_msg = str_dup(msg_buf);
    af.bitvector = 0;
    affect_to_char(ch,&af);
    return;
}

void do_executioners_grace(CHAR_DATA *ch,char *argument)
{
	AFFECT_DATA af;
	int chance = get_skill(ch,gsn_executioner);
	bool night=FALSE;

	if(chance==0)
	{
		send_to_char("You don't know how to move with the deadly grace of an executioner.\n\r",ch);
		return;
	}

	if(number_percent() > chance)
	{
		send_to_char("You fail to move with the deadly grace of an executioner.\n\r",ch);
		WAIT_STATE(ch,PULSE_VIOLENCE*4);
		return;
	}

	if(is_affected(ch,gsn_executioner))
	{
		send_to_char("You are already moving with the deadly grace of an executioner.\n\r",ch);
		WAIT_STATE(ch,PULSE_VIOLENCE*4);
		return;
	}

	send_to_char("You begin to flow with the deadly grace of an executioner.\n\r",ch);

	night = (weather_info.sunlight == SUN_DARK ? TRUE : FALSE);

	init_affect(&af);
	af.where 	= TO_AFFECTS;
	af.type 	= gsn_executioner;
	af.location 	= APPLY_DAMROLL;
	af.modifier 	= night ? 25 : 15;
	af.level 	= ch->level;
	af.duration 	= night ? ch->level/2 : ch->level/4;
	af.bitvector 	= AFF_BERSERK;
	af.aftype 	= AFT_SKILL;
	ch->mana-=300;
	affect_to_char(ch,&af);
	return;
}
void do_spike(CHAR_DATA *ch,char *argument)
{
        CHAR_DATA *victim;
        int chance, dam;
        char arg[MAX_INPUT_LENGTH];

        one_argument(argument,arg);
        if (IS_NPC(ch))
                return;
	if (ch->position == POS_FIGHTING)
	{
        send_to_char("You can't spike them in the heat of battle.\n\r",ch);
        return;
        }


	if ((get_skill(ch,gsn_spike) == 0)
	|| ch->level < skill_table[gsn_spike].skill_level[ch->class])
	{
	send_to_char("Huh?\n\r",ch);
	return;
	}

        if (arg[0] == '\0')
        {
        send_to_char("Attempt to spike which person?\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("You can't do that.\n\r",ch);
        return;
        }
        if (victim->fighting != NULL || victim->position == POS_FIGHTING)
        {
        send_to_char("They are moving around too much to get in close for the kill.\n\r",ch);
        return;
        }

        if (is_safe(ch,victim))
                return;

        chance = get_skill(ch,gsn_spike)/2;
        chance += ch->level;
        chance -= victim->level * 3/2;
        chance -= number_range(0,15);
        if (!can_see(victim,ch))
                chance += 10;
        if (victim->position == POS_FIGHTING)
                chance -= 25;
        else if (victim->position == POS_SLEEPING)
                chance += 10;
        else chance -= 10;

        chance /= 2;
        chance = URANGE(2,chance,90);

        act("$n strikes out at $N with deadly intensity.",ch,0,victim,TO_NOTVICT);
        act("You strike out at $N with deadly intensity.",ch,0,victim,TO_CHAR);
        act("$n strikes at you with deadly intensity.",ch,0,victim,TO_VICT);

        if (number_percent() < chance)
        {
        send_to_char("With agonising pain your skull is smashed by the blow!\n\r",victim);
        act("Your blow shatters $N's skull into bloody fragments!",ch,0,victim,TO_CHAR);
        act("$N's skull is shattered into bits of mangled flesh and bone by $n's strike!",ch,0,victim,TO_NOTVICT);
        raw_kill(ch,victim);
	WAIT_STATE(ch,PULSE_VIOLENCE*2);
        check_improve(ch,gsn_spike,TRUE,2);
        return;
        }
        else
        {
        send_to_char("You feel a sharp pain searing your skull!\n\r",victim);
        act("Your deathstrike smashes $N's skull but fails to kill.",ch,0,victim,TO_CHAR);
        dam = ch->level * 2;
        dam += dice(ch->level, 4);
        damage_old(ch,victim,dam,gsn_spike,DAM_PIERCE,TRUE);
        WAIT_STATE(ch,PULSE_VIOLENCE);
	check_improve(ch,gsn_spike,FALSE,1);
	}

	return;
}


bool check_unholy_bless(CHAR_DATA *ch, CHAR_DATA *victim) {

	AFFECT_DATA af;
	AFFECT_DATA *paf;
	AFFECT_DATA *paf_next;
        int sn, hitmod = 0, manamod = 0, hrollmod = 0, drollmod = 0, vdrollmod = 0, i;

	if (IS_NPC(victim))
		return FALSE;

	if (!is_affected(ch,gsn_unholy_bless)) {
		return FALSE;
	}

	if (is_affected(victim,gsn_unholy_timer)) {
		return FALSE;
	}

	sn = skill_lookup("unholy bless");

	/* check if victim is AP and take his charges */
        if (is_affected(victim,gsn_unholy_bless) && victim != ch) {
		for ( paf = victim->affected; paf != NULL; paf = paf_next )
		{
			paf_next = paf->next;
			if ( paf->type == sn ) {
				switch (paf->location)
				{
				default: break;
				case APPLY_DAMROLL: vdrollmod = paf->modifier; break;
				}
			}
		}
		vdrollmod = (vdrollmod - 1) / 6;
		if (vdrollmod < 1) {
			vdrollmod = 0;
		}
	} else {
		vdrollmod = 0;
	}

	for (i=0; i < vdrollmod+1; i++) {
	for ( paf = ch->affected; paf != NULL; paf = paf_next )
	{
		paf_next = paf->next;
		if ( paf->type == sn ) {
			switch (paf->location)
			{
			default: break;
			case APPLY_HIT: hitmod = paf->modifier; affect_remove( ch, paf ); break;
			case APPLY_MANA: manamod = paf->modifier; affect_remove( ch, paf ); break;
			case APPLY_HITROLL: hrollmod = paf->modifier; affect_remove( ch, paf ); break;
			case APPLY_DAMROLL: drollmod = paf->modifier; affect_remove( ch, paf ); break;
			}
		}
	}

	hitmod += 10;
	manamod += 10;
	hrollmod += 3;
	drollmod += 3;

	init_affect(&af);
	af.where = TO_AFFECTS;
	af.aftype = AFT_SPELL;
	af.type = sn;
	af.level = ch->level;
	af.duration = -1;
	af.bitvector = 0;
	af.modifier = hitmod;
	af.location = APPLY_HIT;
	affect_to_char(ch,&af);
	af.modifier = manamod;
	af.location = APPLY_MANA;
	affect_to_char(ch,&af);
	af.modifier = hrollmod;
	af.location = APPLY_HITROLL;
	affect_to_char(ch,&af);
	af.modifier = drollmod;
	af.location = APPLY_DAMROLL;
	affect_to_char(ch,&af);
	act("\x01B[1;31m$n's body pulses as power drains from $N's corpse!\x01B[0;37m",ch,0,victim,TO_NOTVICT);
	act("\x01B[1;31m$n's body pulses as power drains from your corpse!\x01B[0;37m",ch,0,victim,TO_VICT);
	act("\x01B[1;31mYour body pulses as you drain power from $N's corpse!\x01B[0;37m",ch,0,victim,TO_CHAR);
	}
	return TRUE;
}

bool check_unholy_new(CHAR_DATA *ch, CHAR_DATA *victim, OBJ_DATA *obj)
{
	AFFECT_DATA *af,*af_next,paf;
	int hmod=0, hpmod=0, dmod=0, mmod=0;
	bool dual = FALSE;
	
	if (obj == get_eq_char(ch,WEAR_DUAL_WIELD)) dual = TRUE;

	if(obj == NULL)
		return FALSE;
	int sn = skill_lookup("unholy bless");
	if((af = affect_find_obj(obj,sn)) == NULL)
		return FALSE;
	if(IS_NPC(victim) || is_affected(victim,skill_lookup("unholy guard")))
		return FALSE;

	for (af = obj->affected; af != NULL; af = af_next )
       	 	{
                af_next = af->next;
                if ( af->type == sn ) {
                        switch (af->location)
                        {
                        default: break;
                        case APPLY_HIT: hpmod = af->modifier; affect_remove_obj( obj, af ); break;
                        case APPLY_MANA: mmod = af->modifier; affect_remove_obj( obj, af ); break;
                        case APPLY_HITROLL: hmod = af->modifier; affect_remove_obj( obj, af ); break;
                        case APPLY_DAMROLL: dmod = af->modifier; affect_remove_obj( obj, af ); break;
                        }
                }
		}

	hmod += 1;
	hpmod += 50;
	mmod += 50;
	dmod += 1;

	init_affect(&paf);
	paf.where = TO_OBJECT;
	paf.duration = -1;
	paf.level = ch->level;
	paf.type = sn;
	paf.owner_name = str_dup(ch->original_name);
	paf.location = APPLY_HIT;
	paf.modifier = hpmod;
	affect_to_obj(obj,&paf);
	paf.location = APPLY_MANA;
	paf.modifier = mmod;
	affect_to_obj(obj,&paf);
	paf.location = APPLY_HITROLL;
	paf.modifier = hmod;
	affect_to_obj(obj,&paf);
	paf.location = APPLY_DAMROLL;
	paf.modifier = dmod;
	affect_to_obj(obj,&paf);

	unequip_char(ch,obj);
	if (dual)
		equip_char(ch,obj,WEAR_DUAL_WIELD);
	else
		equip_char(ch,obj,WEAR_WIELD);
	act("{R$p writhes in your grip and you feel a new energy enter your body as you steal $N's soul.{x",ch,obj,victim,TO_CHAR);
	act("{R$p seems to twist and writhe in $n's grip as a chill runs down your spine.{x",ch,obj,0,TO_ROOM);
	return TRUE;
}

void do_drive(CHAR_DATA *ch, char *argument)
{
	CHAR_DATA *victim = ch->fighting;
	AFFECT_DATA af;
	char buf[MSL];
	char arg[MSL];
	int direction = -1;

	one_argument(argument,arg);
	if (get_skill(ch, skill_lookup("drive")) < 5)
		return send_to_char("You do not know how to drive others.\n\r",ch);
	if (victim == NULL)
		return send_to_char("But you aren't fighting anyone!\n\r",ch);
	if (arg[0] != '\0' && IS_NPC(victim))
		return send_to_char("You cannot seem to budge them.\n\r",ch);
	if (arg[0] == '\0')
		return send_to_char("Drive in which direction?\n\r",ch);

	if (!str_prefix(arg,"east") || !str_prefix(arg,"west") || !str_prefix(arg,"north") || !str_prefix(arg,"south") || !str_prefix(arg,"up") || !str_prefix(arg,"down"))
	{
		if (!str_prefix(arg,"east"))
			direction = DIR_EAST;
		else if (!str_prefix(arg,"west"))
			direction = DIR_WEST;
		else if (!str_prefix(arg,"north"))
			direction = DIR_NORTH;
		else if (!str_prefix(arg,"south"))
			direction = DIR_SOUTH;
		else if (!str_prefix(arg,"up"))
			direction = DIR_UP;
		else if (!str_prefix(arg,"down"))
			direction = DIR_DOWN;

		if (number_percent() < get_skill(ch, skill_lookup("drive")) * .75)
		{
			sprintf(buf,"Help! %s is driving me away!",ch->name);
			do_myell(victim,buf);
			if (direction != DIR_UP && direction != DIR_DOWN)
				sprintf(buf,"You charge at %s and drive %s to the %s!",IS_NPC(victim) ? victim->short_descr : victim->name, him_her[URANGE(0, victim->sex, 2)], dir_name[direction]);
			else
				sprintf(buf,"You charge at %s and drive %s %swards!",IS_NPC(victim) ? victim->short_descr : victim->name, him_her[URANGE(0, victim->sex, 2)], dir_name[direction]);
			act(buf,ch,0,victim,TO_CHAR);
			if (direction != DIR_UP && direction != DIR_DOWN)
				sprintf(buf,"%s charges at %s, driving %s to the %s!",IS_NPC(ch) ? ch->short_descr : ch->name,IS_NPC(victim) ? victim->short_descr : victim->name, him_her[URANGE(0, victim->sex, 2)], dir_name[direction]);
			else
				sprintf(buf,"%s charges at %s, driving %s %swards!",IS_NPC(ch) ? ch->short_descr : ch->name,IS_NPC(victim) ? victim->short_descr : victim->name, him_her[URANGE(0, victim->sex, 2)], dir_name[direction]);
			act(buf,ch,0,victim,TO_NOTVICT);
			if (direction != DIR_UP && direction != DIR_DOWN)
				sprintf(buf,"%s charges at you, driving you to the %s!",IS_NPC(ch) ? ch->short_descr : ch->name, dir_name[direction]);
			else
				sprintf(buf,"%s charges at you, driving you %swards!",IS_NPC(ch) ? ch->short_descr : ch->name,dir_name[direction]);
			act(buf,ch,0,victim,TO_VICT);	
			WAIT_STATE(ch,PULSE_VIOLENCE*2);
		}
		else
		{
			sprintf(buf,"Help! %s is trying to drive me away!",ch->name);
			do_myell(victim,buf);
			if (direction != DIR_UP && direction != DIR_DOWN)
				sprintf(buf,"You charge at %s, but fail to drive %s to the %s!",IS_NPC(victim) ? victim->short_descr : victim->name, him_her[URANGE(0, victim->sex, 2)], dir_name[direction]);
			else
				sprintf(buf,"You charge at %s, but fail to drive %s %swards!",IS_NPC(victim) ? victim->short_descr : victim->name, him_her[URANGE(0, victim->sex, 2)], dir_name[direction]);
			act(buf,ch,0,victim,TO_CHAR);
			if (direction != DIR_UP && direction != DIR_DOWN)
				sprintf(buf,"%s charges at %s, but fails to drive %s to the %s!",IS_NPC(ch) ? ch->short_descr : ch->name,IS_NPC(victim) ? victim->short_descr : victim->name, him_her[URANGE(0, victim->sex, 2)], dir_name[direction]);
			else
				sprintf(buf,"%s charges at %s, but fails to drive %s %swards!",IS_NPC(ch) ? ch->short_descr : ch->name,IS_NPC(victim) ? victim->short_descr : victim->name, him_her[URANGE(0, victim->sex, 2)], dir_name[direction]);
			act(buf,ch,0,victim,TO_NOTVICT);
			if (direction != DIR_UP && direction != DIR_DOWN)
				sprintf(buf,"%s charges at you, but fails to drive you to the %s!",IS_NPC(ch) ? ch->short_descr : ch->name, dir_name[direction]);
			else
				sprintf(buf,"%s charges at you, but fails to drive you %swards!",IS_NPC(ch) ? ch->short_descr : ch->name,dir_name[direction]);
			act(buf,ch,0,victim,TO_VICT);
			WAIT_STATE(ch,PULSE_VIOLENCE*2);
			return;
		}

	if (direction != -1)
		stop_fighting(ch,TRUE);
		init_affect(&af);
		af.aftype = 	AFT_INVIS;
		af.type =	skill_lookup("drive");
		affect_to_char(victim,&af);
		move_char(ch,direction,FALSE);
		move_char(victim,direction,FALSE);
		affect_remove(victim,&af);
		set_fighting(ch,victim);
		WAIT_STATE(ch,PULSE_VIOLENCE*2);
		return;
	}

	else
		return send_to_char("That is not a valid direction.",ch);
}

	
void do_bind(CHAR_DATA *ch,char *argument)
{
	CHAR_DATA *victim;
        int chance;
	AFFECT_DATA af;
        
	char arg[MAX_INPUT_LENGTH];
        one_argument(argument,arg);
        
	if (IS_NPC(ch))
                return;
	
	if (get_skill(ch,gsn_bind) == 0)
	{
		send_to_char("Huh?\n\r",ch);
		return;
	}

        if (arg[0] == '\0')
        {
        	send_to_char("Attempt to bind who?\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("You can't do that.\n\r",ch);
        	return;
        }

        if (victim->position != POS_SLEEPING)
        {
        	send_to_char("They must be sleeping for you to bind them.\n\r",ch);
        	return;
        }


	if (is_affected(victim,gsn_bind))
	{
	  	send_to_char("They are already bound.\n\r",ch);
	  	return;
	}

	if (is_safe(victim, ch))
		return;

	chance = get_skill(ch,gsn_bind)-20;

	if(is_affected(victim,AFF_HASTE))
		chance-=30;

	if(is_affected(ch,AFF_HASTE))
		chance+=15;

	if(get_curr_stat(victim,STAT_DEX)>get_curr_stat(ch,STAT_DEX))
		chance-=20;

	if(number_percent() < chance)
	{
		init_affect(&af);
		af.aftype	= AFT_SKILL;
		af.where 	= TO_AFFECTS;
		af.type 	= gsn_bind;
		af.level 	= ch->level;
		af.duration 	= -1;
		af.bitvector 	= AFF_BLIND;
		af.modifier 	= -5;
		af.location 	= APPLY_DEX;
		affect_to_char(victim,&af);
		act("$n puts a sack over $N's head and ties a rope around his legs tightly.",ch,0,victim,TO_NOTVICT);
		send_to_char("You feel someone putting something over your head and legs.", victim);
		act("You put a sack over $N's head and tie a rope around his legs tightly.",ch,0,victim,TO_CHAR);
		WAIT_STATE(ch,PULSE_VIOLENCE);
		check_improve(ch,gsn_bind,TRUE,1);
	}
	else
	{
		act("$n tries to put a sack over $N's head but it rips.",ch,0,victim,TO_NOTVICT);
		send_to_char("You feel someone trying to put something over your head and legs.",victim);
		act("You try to put a sack over $N's head but it rips.",ch,0,victim,TO_CHAR);
		WAIT_STATE(ch,PULSE_VIOLENCE*3);
		check_improve(ch,gsn_bind,FALSE,3);
	}
	return;
}
void check_cheap_shot(CHAR_DATA *ch, CHAR_DATA *victim)
{
	int chance;
	int dam;
	chance=get_skill(ch,gsn_cheap_shot);
	if(chance<2)
		return;
	if(is_affected(victim,AFF_HASTE))
		chance-=30;
	if(is_affected(ch,AFF_HASTE))
		chance+=15;
	if(is_affected(victim,AFF_FLYING))
		chance-=20;
	chance*=.65;
	if(number_percent() < chance)
	{
		act("Seizing upon $N's moment of weakness, you brutally kick him while he's down!",ch,0,victim,TO_CHAR);
		act("Seizing upon your moment of weakness, $n brutally kicks you while you're down!",ch,0,victim,TO_VICT);
		act("Seizing upon $N's moment of weakness, $n brutally kicks him while he's down!",ch,0,victim,TO_NOTVICT);
		dam=40;
		if(number_percent() < 10)
		{
			act("$N grunts in pain as you land a particularly vicious kick!",ch,0,victim,TO_CHAR);
			act("You grunt in pain as $n lands a particularly vicious kick!",ch,0,victim,TO_VICT);
			act("$N grunts in pain as $n lands a particularly vicious kick!",ch,0,victim,TO_NOTVICT);
			dam=125;
			ADD_WAIT_STATE(victim,PULSE_VIOLENCE);
		}
		if (spike_toed_boots(ch))
			dam *= 1.5;
		damage_old(ch,victim,dam,gsn_cheap_shot,DAM_PIERCE,TRUE);
		check_improve(ch,gsn_cheap_shot,TRUE,1);
		ADD_WAIT_STATE(victim,PULSE_VIOLENCE);
		return;
	}
	else
	{
		send_to_char("You were unable to get a cheap shot in.\n\r",ch);
		check_improve(ch,gsn_cheap_shot,FALSE,1);
		return;
	}
}
void do_unbind(CHAR_DATA *ch,char *argument)
{
	if(!is_affected(ch,gsn_bind))
	{
		send_to_char("You are not bound.\n\r",ch);
		return;
	}
	if(number_percent()>30)
	{
		act("You break free of the bindings on your head and legs.",ch,0,0,TO_CHAR);
		act("$n breaks free of the bindings on $s head and legs.",ch,0,0,TO_ROOM);
		affect_strip( ch, gsn_bind );
		WAIT_STATE(ch,PULSE_VIOLENCE);
	}
	else
	{
		act("You fail to break free of the bindings on your head and legs.",ch,0,0,TO_CHAR);
		act("$n fails to break free of the bindings on $s head and legs.",ch,0,0,TO_ROOM);
		WAIT_STATE(ch,PULSE_VIOLENCE);
	}
}

void do_blitz( CHAR_DATA *ch, char *argument ) // Do not disable this! -Det.
{
	char arg[MAX_INPUT_LENGTH];
	CHAR_DATA *victim;
	int chance, imod;
	char buf[MAX_STRING_LENGTH];
	bool isDS;

	if (cabal_down(ch,CABAL_RAGER))
		return;

	one_argument(argument,arg);

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

	if (IS_NPC(ch) && IS_AFFECTED(ch,AFF_CHARM))
	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 blitz your brains out, but fail.\n\r",ch);
		return;
	}
	if ((victim->fighting!=ch) && (ch->fighting != NULL))
	{
		send_to_char("You must be directly fighting that person to blitz them.\n\r",ch);
		return;
	}
	if (is_safe(ch,victim))
	return;

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

	/* modify chance */
	chance += ch->carry_weight / 200;
	chance -= victim->carry_weight / 200;
	if (ch->size < victim->size)
	{
		chance += (ch->size - victim->size) * 5;
	} else {
		chance += (ch->size - victim->size) * 5;
	}
	if (is_affected(victim,gsn_protective_shield))
	{
		chance -= 5;
	}
	 if (is_affected(victim, skill_lookup("wraithform")))
	{
		chance -= 5;
	}
	if (is_affected(victim,gsn_fireshield))
	{
		chance -= 5;
	}
	chance += get_curr_stat(ch,STAT_STR) + 5;
	chance -= (get_curr_stat(victim,STAT_DEX));
	chance -= GET_AC(victim,AC_BASH) /20;
    	if (IS_SET(ch->off_flags,OFF_FAST) || IS_AFFECTED(ch,AFF_HASTE))
	{
		chance += 10;
	}
    	if (is_affected(ch,skill_lookup("bloodthirst")))
	{
		chance += 10;
	}
    	if (is_affected(ch,skill_lookup("berserk")))
	{
		chance += 10;
	}
	if (IS_SET(victim->off_flags,OFF_FAST) || IS_AFFECTED(victim,AFF_HASTE))
	{
		chance -= 5;
	}
	chance += (ch->level - victim->level);
	if (!IS_NPC(ch) && !IS_NPC(victim) && (victim->fighting == NULL || ch->fighting == NULL))
	{
		sprintf(buf,"Help! %s is blitzing me!",PERS(ch,victim));
		do_myell(victim,buf);
	}
	if (!IS_NPC(victim) && chance < get_skill(victim,gsn_dodge) )
	{
		chance -= 3 * (get_skill(victim,gsn_dodge) - chance);
	}

	imod = 25;

	isDS = FALSE;

        if (!IS_NPC(ch) )
                chance += 15;

	/* now the attack */
	if (number_percent() < chance - 20)
	{
		act("$n pummels you to the ground with excruciating force!", ch,NULL,victim,TO_VICT);
		act("You slam into $N, pummeling $M into the ground!",ch,NULL,victim,TO_CHAR);
		act("$n pummels $N into the ground with a powerful blitz.",ch,NULL,victim,TO_NOTVICT);
		damage_old(ch,victim,(3 * ch->size + chance),gsn_blitz,DAM_BASH,TRUE);
		check_improve(ch,gsn_blitz,TRUE,3);
		WAIT_STATE(victim,PULSE_VIOLENCE*1.5);
		WAIT_STATE(ch,2*PULSE_VIOLENCE);
		if (number_percent() > 90)
		{
			if (is_affected(victim,gsn_sanctuary) && (number_percent() < chance-imod))
			{
				if (check_dispel(ch->level-3,victim,skill_lookup("sanctuary")))
				{
					act("$n looks stunned as $s mind wanders from $s spells.",victim,0,0,TO_ROOM);
					act("Your head throbs with pain as you lose control over your spells.",victim,0,0,TO_CHAR);
					act("The white aura about $n vanishes!",victim,NULL,NULL,TO_ROOM);
					isDS = TRUE;
				}
			}
			if ((isDS == FALSE) && is_affected(victim,gsn_fireshield) && (number_percent() < chance-imod))
			{
				if (check_dispel(ch->level,victim,skill_lookup("fireshield")))
				{
					act("$n looks stunned as $s mind wanders from $s spells.",victim,0,0,TO_ROOM);
					act("Your head throbs with pain as you lose control over your spells.",victim,0,0,TO_CHAR);
					act("The fire around $n vanishes!",victim,NULL,NULL,TO_ROOM);
					isDS = TRUE;

				}
			}

			if ((isDS == FALSE) && is_affected(victim,gsn_stoneskin) && (number_percent() < chance-imod))
			{
				if (check_dispel(ch->level-2,victim,skill_lookup("stone skin")))
				{
					act("$n looks stunned as $s mind wanders from $s spells.",victim,0,0,TO_ROOM);
					act("Your head throbs with pain as you lose control over your spells.",victim,0,0,TO_CHAR);
					act("The skin of $n softens into flesh!",victim,NULL,NULL,TO_ROOM);
					isDS = TRUE;

				}
			}
			if ((isDS == FALSE) && is_affected(victim,gsn_wraithform) && (number_percent() < chance-imod))
			{
				if (check_dispel(ch->level-2,victim,skill_lookup("wraithform")))
				{
					act("$n looks stunned as $s mind wanders from $s spells.",victim,0,0,TO_ROOM);
					act("Your head throbs with pain as you lose control over your spells.",victim,0,0,TO_CHAR);
					act("The body of $n fades back into the Prime Material Plane!",victim,NULL,NULL,TO_ROOM);
					isDS = TRUE;

				}
			}
			if ((isDS == FALSE) && is_affected(victim,gsn_shroud) && (number_percent() < chance-imod))
			{
				if (check_dispel(ch->level,victim,skill_lookup("shroud")))
				{
					act("$n looks stunned as $s mind wanders from $s spells.",victim,0,0,TO_ROOM);
					act("Your head throbs with pain as you lose control over your spells.",victim,0,0,TO_CHAR);
					act("The black aura about $n vanishes!",victim,NULL,NULL,TO_ROOM);
					isDS = TRUE;

				}
			}
		}
	} else {
		damage_old(ch,victim,0,gsn_blitz,DAM_BASH,FALSE);
		act("You fall over and bite the dust!",ch,NULL,victim,TO_CHAR);
		act("$n falls flat on $s face, eating a mouthful of dirt.",ch,NULL,victim,TO_NOTVICT);
		act("You evade $n's blitz, and $e falls flat on $s face.",ch,NULL,victim,TO_VICT);
		check_cheap_shot(victim,ch);
		check_improve(ch,gsn_blitz,FALSE,3);
		ch->position = POS_RESTING;
		WAIT_STATE(ch,2*PULSE_VIOLENCE);
	}
	return;
}

void check_parting_blow( CHAR_DATA *ch, CHAR_DATA *victim )
{
	if (get_skill(victim,gsn_parting_blow) > 1)
     	{
		if (number_percent() < get_skill(victim,gsn_parting_blow))
         	{
			act("You get in one more shot as $N flees.",victim,0,ch,TO_CHAR);
			act("$n gets in one more shot as $N flees.",victim,0,ch,TO_NOTVICT);
			act("$n gets in one more shot as you flee.",victim,0,ch,TO_VICT);
			one_hit(victim,ch,gsn_parting_blow);
			check_improve(victim,gsn_parting_blow,TRUE,1);
		} else {
			check_improve(victim,gsn_parting_blow,TRUE,1);
		}
	}
	return;
}

bool check_ironhands( CHAR_DATA *ch, CHAR_DATA *victim, int dt )
{
    float chance, hit_ratio;
    char buf1[MAX_STRING_LENGTH];
    char buf2[MAX_STRING_LENGTH];
    char *attack;
	int ch_hitroll, victim_hitroll, str = get_curr_stat(victim,STAT_STR);

    if ( !IS_AWAKE(victim) )
        return FALSE;

    if (IS_NPC(victim))
        return FALSE;

    if ((chance = get_skill(victim,gsn_ironhands) / 3) == 0)
        return FALSE;
		
		

    if (get_eq_char(victim,WEAR_WIELD) != NULL)
        return FALSE;

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

    if (!can_see(ch,victim))
        chance *= number_range(6/10,3/4);
		
	ch_hitroll = GET_HITROLL(ch);
	victim_hitroll = GET_HITROLL(victim);
	
	//For simplicity...
	if (victim_hitroll <= 0) victim_hitroll = 1;
	if (ch_hitroll <= 0) ch_hitroll = 1;

	if (victim_hitroll < ch_hitroll) {
		hit_ratio = (float)ch_hitroll / (float)victim_hitroll;
		
		if (hit_ratio > 1.1)
			chance *= 1.1;
		else 
			chance *= hit_ratio;
	}
	
	if (str <= 5)
	chance += 0;
    else if (str <= 10)
	chance += str/2;
    else if (str <=15)
	chance += (str);
    else if (str <= 20)
	chance += (6*str/5);
    else
	chance += 3*str/2;

    if ( number_percent( ) >= ((chance + (victim->level +ch->level) - 40)/2))
    {
        check_improve(victim,gsn_ironhands,FALSE,5);
        return FALSE;
    }

    attack=get_dam_message(ch,dt);

    sprintf(buf1,"You parry $n's %s.",attack);
    sprintf(buf2,"$N parries your %s.",attack);
    act(buf1,ch,0,victim,TO_VICT);
    act(buf2,ch,0,victim,TO_CHAR);
    check_improve(victim,gsn_ironhands,TRUE,6);
    return TRUE;
}

bool check_unarmed_defense( CHAR_DATA *ch, CHAR_DATA *victim, int dt )
{
    int ch_hitroll, victim_hitroll, dex = get_curr_stat(victim,STAT_DEX);
	float chance, hit_ratio;
    char buf1[MAX_STRING_LENGTH];
    char buf2[MAX_STRING_LENGTH];
    char *attack;

    if ( !IS_AWAKE(victim) )
        return FALSE;

    if (IS_NPC(victim))
        return FALSE;

    if ((chance = get_skill(victim,gsn_unarmed_defense) /2) == 0)
        return FALSE;
		
	ch_hitroll = GET_HITROLL(ch);
	victim_hitroll = GET_HITROLL(victim);
	
	//For simplicity...
	if (victim_hitroll <= 0) victim_hitroll = 1;
	if (ch_hitroll <= 0) ch_hitroll = 1;

	if (victim_hitroll < ch_hitroll) {
		hit_ratio = (float)ch_hitroll / (float)victim_hitroll;
		
		if (hit_ratio > 1.25)
			chance *= 1.25;
		else 
			chance *= hit_ratio;
	}

    if (get_eq_char(victim,WEAR_WIELD) != NULL)
        return FALSE;

	if (dex <= 5)
	chance += 0;
    else if (dex <= 10)
	chance += dex/2;
    else if (dex <=15)
	chance += (2*dex/3);
    else if (dex <= 20)
	chance += dex;
    else
	chance += 3*dex/2;
	
    if (!can_see(ch,victim))
        chance /= 2;

    chance += get_curr_stat(victim,STAT_DEX) - get_curr_stat(ch,STAT_DEX);

    if (IS_AFFECTED(victim, AFF_HASTE))
	chance += 10;

    if (IS_AFFECTED(ch, AFF_HASTE))
	chance -= 10;

    if (number_percent() >= chance)
    {
        check_improve(victim,gsn_unarmed_defense,FALSE,5);
        return FALSE;
    }

    attack=get_dam_message(ch,dt);

    sprintf(buf1,"You deftly avoid $n's %s.",attack);
    sprintf(buf2,"$N deftly avoids your %s.",attack);
    act(buf1,ch,0,victim,TO_VICT);
    act(buf2,ch,0,victim,TO_CHAR);
    check_improve(victim,gsn_unarmed_defense,TRUE,6);
    return TRUE;
}

char *get_dam_message(CHAR_DATA *ch, int dt)
{
        return get_attack_noun(ch,dt);
}

char * get_attack_noun(CHAR_DATA *ch, int dt)
{
    OBJ_DATA *wield;
    int tmp_dt;
    char *attack;
	
	if (is_affected(ch,skill_lookup("valiant wrath")))
    {
		attack = str_dup("valiant wrath");
		return attack;
	}

    tmp_dt = TYPE_HIT;
    if (dt == gsn_dual_wield)
        wield = get_eq_char(ch,WEAR_DUAL_WIELD);
    else
		wield = get_eq_char(ch,WEAR_WIELD);
        if (wield != NULL)
			tmp_dt += wield->value[3];
    else
        tmp_dt += ch->dam_type;
    if (tmp_dt > TYPE_HIT && tmp_dt < TYPE_HIT + MAX_DAMAGE_MESSAGE)
        attack = attack_table[tmp_dt - TYPE_HIT].noun;
    else
    {
        attack = attack_table[17].noun;
    }
    return attack;
}

int get_attack_number(CHAR_DATA *ch, int dt)
{
      OBJ_DATA *wield;
      int tmp_dt;

      tmp_dt = TYPE_HIT;
      if (dt  == gsn_dual_wield)
          wield = get_eq_char(ch,WEAR_DUAL_WIELD);
      else
          wield = get_eq_char(ch,WEAR_WIELD);
        if (wield != NULL)
          tmp_dt += wield->value[3];
      else
          tmp_dt += ch->dam_type;
      if (tmp_dt > TYPE_HIT && tmp_dt < TYPE_HIT + MAX_DAMAGE_MESSAGE)
        return (tmp_dt - TYPE_HIT);
      return 1;
}

void do_gslay (CHAR_DATA * ch, char *argument)
  {
  CHAR_DATA *victim;
  char arg[MAX_INPUT_LENGTH];
  char buf[MAX_STRING_LENGTH];

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

  if ((victim = get_char_world (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 ("You failed.\n\r", ch);
  return;
  }

  act ("You slay $M in accordance with your will!", ch,
  NULL,
  victim, TO_CHAR);
  act ("$n slays you according to his will!", ch, NULL, victim,
TO_VICT);
  act ("$n slays $N in accordance with his will!", ch,
  NULL,
  victim, TO_NOTVICT);

  sprintf(buf, "{WAn Immortal {Gglares at {Y%s {Gand he explodes into a million pieces!{x", victim->name);
  do_echo(ch, buf);

  raw_kill (ch, victim );

  do_help(ch, "rules" );

  return;
  }

void do_ambush( CHAR_DATA *ch, char *argument )
{
    char arg[MAX_INPUT_LENGTH];
    CHAR_DATA *victim;
    char buf[MAX_STRING_LENGTH];   
    int chance;

    
    one_argument( argument, arg);


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

    if (ch->fighting != NULL)
    {
	send_to_char("But you're still fighting!\n\r",ch);
	return;
    }
    else if ((victim = get_char_room(ch,arg)) == NULL)
    {
	send_to_char("They aren't here.\n\r",ch);
	return;
    }
    else if (!IS_AFFECTED(ch, AFF_CAMOUFLAGE) || can_see(victim, ch) )
    {
	send_to_char("But they can still see you.\n\r",ch);
	return;
    }
 
    if ( victim == ch )
    {
	send_to_char("That's just not possible.\n\r",ch);
	return;
    }
    if ( is_safe( ch, victim ) )
      return;

	if (check_chargeset(ch,victim)) {return;}

    chance = get_skill(ch,gsn_moving_ambush);
    if (victim->fighting != NULL 
	&& ( chance < 3
	|| ch->level < skill_table[gsn_moving_ambush].skill_level[ch->class]))
    {
	send_to_char("They are moving around too much to ambush.\n\r",ch);
	return;
    }

    if (victim->fighting != NULL
	&& number_percent() >= chance)
	{
	send_to_char("You can't quite pin them down for your ambush.\n\r",ch);
	return; 
	}

	if (!IS_NPC(ch) && !IS_NPC(victim) && victim->fighting == NULL)
	{
	sprintf(buf,"Help! I've been ambushed by %s!",PERS(ch,victim));
	do_myell(victim,buf);
	}

   WAIT_STATE( ch, skill_table[gsn_ambush].beats );
   if ( (number_percent( ) < get_skill(ch, gsn_ambush) )
   || ( get_skill(ch,gsn_ambush) >= 2 && !IS_AWAKE(victim) ) )
    {
	check_improve(ch,gsn_ambush, TRUE,1);
	multi_hit( ch, victim, gsn_ambush );
    }
    else
    {
	check_improve(ch,gsn_ambush, FALSE,1);
	damage( ch, victim, 0, gsn_ambush, DAM_NONE, TRUE);
    }

    return;
}

bool spike_toed_boots(CHAR_DATA *ch)
{
    OBJ_DATA *boots;

    boots = get_eq_char(ch, WEAR_FEET);

    if (boots != NULL && boots->pIndexData->vnum == 29801)
	return TRUE;

    return FALSE;
}

bool check_ward_diminution(CHAR_DATA *mage, CHAR_DATA *attacker, int dam, int type, int dt)
{
	AFFECT_DATA *ward;
	AFFECT_DATA new_ward;
	int mod=0, duration=0;

	if (!is_affected(mage, gsn_ward_diminution))
		return FALSE;

	if (number_percent() > 35)
		return FALSE;

	if (mage == attacker)
		return FALSE;

	if (type > 3)
		return FALSE;

	ward = affect_find(mage->affected, gsn_ward_diminution);

	if (!ward)
		return FALSE;

	mod = ward->modifier;
	duration = ward->duration;

	if (mod >= mage->max_hit / 2)
	{
		act("Your ward of diminution crumbles under the force of $N's attack.", mage, 0, attacker, TO_CHAR);
		act("$n's ward of diminution crumbles under the force of your attack.", mage, 0, attacker, TO_VICT);
		act("$n's ward of diminution crumbles under the force of $N's attack.", mage, 0, attacker, TO_NOTVICT);
		affect_strip(mage, gsn_ward_diminution);
		return FALSE;
	}

	mod += dam;

	affect_strip(mage, gsn_ward_diminution);

	init_affect(&new_ward);
    	new_ward.where     	= TO_AFFECTS;
        new_ward.aftype		= AFT_POWER;
    	new_ward.type      	= gsn_ward_diminution;
    	new_ward.level     	= 51;
    	new_ward.duration  	= duration;
    	new_ward.location  	= 0;
    	new_ward.modifier  	= mod;
    	new_ward.bitvector 	= 0;
    	affect_to_char( mage, &new_ward );

	act("Your ward absorbs the pain of $N's attack!", mage, 0, attacker, TO_CHAR);
	act("$n's ward absorbs the pain of your attack!", mage, 0, attacker, TO_VICT);
	act("$n's ward absorbs the pain of $N's attack!", mage, 0, attacker, TO_NOTVICT);

	return TRUE;
}

void check_paladin_combo(CHAR_DATA *ch, CHAR_DATA *victim)
{
	int level = 0, sn = gsn_paladin_tech_counter_pc;
	AFFECT_DATA *af, *af_next, affect;
	OBJ_DATA *wield = get_eq_char(ch,WEAR_WIELD);
		
	for (af = ch->affected; af != NULL; af = af_next)
	{
		af_next = af->next;
		if (af->type == sn)
			level = af->level;
	}
	
	if (!is_affected(ch,sn))
		return;
	if (level == 15 || level == 25 || level == 35 || level == 45 || level == 55 || level == 65)
		do_say(ch,"Raaaagh!!");
	if (level == 15)
	{
		act("$n's $p glows softly.",ch,wield,victim,TO_VICT);
		act("$n's $p glows softly.",ch,wield,victim,TO_NOTVICT);
		act("$p glows softly.",ch,wield,victim,TO_CHAR);
		act("$n delivers a powerful slice!",ch,wield,victim,TO_VICT);
		act("$n delivers a powerful slice!",ch,wield,victim,TO_NOTVICT);
		act("You slash $N with great force!",ch,wield,victim,TO_CHAR);
		one_hit_new(ch,victim,TYPE_UNDEFINED,HIT_NOSPECIALS,HIT_UNBLOCKABLE,HIT_NOADD,300,"slice");
		affect_strip(ch,sn);
		return;
	}

	if (level == 25)
	{
		act("$n's $p glows faintly.",ch,wield,victim,TO_VICT);
		act("$n's $p glows faintly.",ch,wield,victim,TO_NOTVICT);
		act("$p glows faintly.",ch,wield,victim,TO_CHAR);
		act("$n delivers a powerful slice!",ch,wield,victim,TO_VICT);
		act("$n delivers a powerful slice!",ch,wield,victim,TO_NOTVICT);
		act("You slash $N with great force!",ch,wield,victim,TO_CHAR);
		one_hit_new(ch,victim,TYPE_UNDEFINED,HIT_NOSPECIALS,HIT_UNBLOCKABLE,HIT_NOADD,500,"slice");
		obj_cast_spell(skill_lookup("cure light"),51,ch,ch,wield);
		affect_strip(ch,sn);
		return;
	}

	if (level == 35)
	{
		act("$n's $p hums loudly.",ch,wield,victim,TO_VICT);
		act("$n's $p hums loudly.",ch,wield,victim,TO_NOTVICT);
		act("$p hums loudly.",ch,wield,victim,TO_CHAR);
		act("$n delivers a powerful strike of faith!",ch,wield,victim,TO_VICT);
		act("$n delivers a powerful strike of faith!",ch,wield,victim,TO_NOTVICT);
		act("You slash $N with immense force!",ch,wield,victim,TO_CHAR);
		one_hit_new(ch,victim,TYPE_UNDEFINED,HIT_NOSPECIALS,HIT_UNBLOCKABLE,HIT_NOADD,700,"strike of faith");
		obj_cast_spell(skill_lookup("cure serious"),51,ch,ch,wield);
		if(number_percent()<50)
		{
			act("You feel your bones shatter under the force of $n's attack!",ch,wield,victim,TO_VICT);
			act("$N's bones shatter under the force of $n's attack!",ch,wield,victim,TO_NOTVICT);
			act("$N's bones shatter under the force of your attack!",ch,wield,victim,TO_CHAR);
			init_affect(&affect);
			affect.aftype = AFT_SKILL;
			affect.level = 51;
			affect.type = gsn_boneshatter;
			affect.duration = 7;
			affect.location = APPLY_DEX;
			affect.modifier = -5;
			affect_to_char(victim,&affect);
			affect.location = APPLY_STR;
			affect.modifier = -5;
			affect_to_char(victim,&affect);
		}
		affect_strip(ch,sn);
		return;
	}

	if (level == 45)
	{
		act("$n's $p glows with radiant light.",ch,wield,victim,TO_VICT);
		act("$n's $p glows with radiant light.",ch,wield,victim,TO_NOTVICT);
		act("$p glows with radiant light.",ch,wield,victim,TO_CHAR);
		act("$n delivers a powerful strike of fervor!",ch,wield,victim,TO_VICT);
		act("$n delivers a powerful strike of fervor!",ch,wield,victim,TO_NOTVICT);
		act("You slash $N with immense force!",ch,wield,victim,TO_CHAR);
		one_hit_new(ch,victim,TYPE_UNDEFINED,HIT_NOSPECIALS,HIT_UNBLOCKABLE,HIT_NOADD,850,"strike of fervor");
		obj_cast_spell(skill_lookup("cure critical"),51,ch,ch,wield);

		if(number_percent()<50)
		{
			act("You feel frail.",ch,wield,victim,TO_VICT);
			act("$N seems more frail.",ch,wield,victim,TO_NOTVICT);
			act("$N seems more frail.",ch,wield,victim,TO_CHAR);
			init_affect(&affect);
			affect.aftype = AFT_SKILL;
			affect.type = gsn_soften;
			affect.level = 51;
			affect.duration = 3;
			affect.location = APPLY_DAM_MOD;
			affect.modifier = 10;
			affect_to_char(victim,&affect);
		}
		affect_strip(ch,sn);
		return;
	}
	
	if (level == 55)
	{
		act("$n's $p shines brightly.",ch,wield,victim,TO_VICT);
		act("$n's $p shines brightly.",ch,wield,victim,TO_NOTVICT);
		act("$p shines brightly.",ch,wield,victim,TO_CHAR);
		act("$n delivers a powerful strike of conviction!",ch,wield,victim,TO_VICT);
		act("$n delivers a powerful strike of conviction!",ch,wield,victim,TO_NOTVICT);
		act("You slash $N with immense force!",ch,wield,victim,TO_CHAR);
		one_hit_new(ch,victim,TYPE_UNDEFINED,HIT_NOSPECIALS,HIT_UNBLOCKABLE,HIT_NOADD,1000,"strike of conviction");
		obj_cast_spell(skill_lookup("heal"),51,ch,ch,wield);

		if(number_percent()<50 && !is_affected(ch,gsn_boneshatter))
		{
			act("You feel your bones shatter under the force of $n's attack!",ch,wield,victim,TO_VICT);
			act("$N's bones shatter under the force of $n's attack!",ch,wield,victim,TO_NOTVICT);
			act("$N's bones shatter under the force of your attack!",ch,wield,victim,TO_CHAR);
			init_affect(&affect);
			affect.aftype = AFT_SKILL;
			affect.level = 51;
			affect.type = gsn_boneshatter;
			affect.duration = 3;
			affect.location = APPLY_DEX;
			affect.modifier = -8;
			affect_to_char(victim,&affect);
			affect.location = APPLY_STR;
			affect.modifier = -8;
			affect_to_char(victim,&affect);
		}
		if(number_percent()<50 && !is_affected(ch,gsn_soften))
		{
			act("You feel frail.",ch,wield,victim,TO_VICT);
			act("$N seems more frail.",ch,wield,victim,TO_NOTVICT);
			act("$N seems more frail.",ch,wield,victim,TO_CHAR);
			init_affect(&affect);
			affect.aftype = AFT_SKILL;
			affect.level = 51;
			affect.type = gsn_soften;
			affect.duration = 3;
			affect.location = APPLY_DAM_MOD;
			affect.modifier = 15;
			affect_to_char(victim,&affect);
		}
		affect_strip(ch,sn);
		return;
	}

	if (level == 65)
	{
		act("$n's $p pulses with power!",ch,wield,victim,TO_VICT);
		act("$n's $p pulses with power!",ch,wield,victim,TO_NOTVICT);
		act("$p pulses with power!",ch,wield,victim,TO_CHAR);
		act("$n delivers a powerful strike of virtue!",ch,wield,victim,TO_VICT);
		act("$n delivers a powerful strike of virtue!",ch,wield,victim,TO_NOTVICT);
		act("You slash $N with immense force!",ch,wield,victim,TO_CHAR);
		one_hit_new(ch,victim,TYPE_UNDEFINED,HIT_NOSPECIALS,HIT_UNBLOCKABLE,HIT_NOADD,1200,"strike of divine virtue");
		obj_cast_spell(skill_lookup("rejuvenate"),51,ch,ch,wield);
		if (!is_affected(victim,gsn_boneshatter))
		{
			init_affect(&affect);
			affect.aftype = AFT_INVIS;
			affect.level = 51;
			affect.type = gsn_boneshatter;
			affect.duration = 3;
			affect.aftype = AFT_SKILL;
			affect.location = APPLY_DEX;
			affect.modifier = -10;
			affect_to_char(victim,&affect);
			affect.aftype = AFT_SKILL;
			affect.location = APPLY_STR;
			affect.modifier = -10;
			affect_to_char(victim,&affect);
		}
		if (!is_affected(victim,gsn_soften))
		{
			act("You feel frail.",ch,wield,victim,TO_VICT);
			act("$N seems more frail.",ch,wield,victim,TO_NOTVICT);
			act("$N seems more frail.",ch,wield,victim,TO_CHAR);
			init_affect(&affect);
			affect.aftype = AFT_SKILL;
			affect.type = gsn_soften;
			affect.level = 51;
			affect.duration = 3;
			affect.location = APPLY_DAM_MOD;
			affect.modifier = 20;
			affect_to_char(victim,&affect);
		}
		affect_strip(ch,sn);
		return;
	}
	if (level > 65)
	{
		act("The power running through your veins becomes too much to bare and you lose your focus!",ch,0,0,TO_CHAR);
		affect_strip(ch,sn);
	}
	return;
}	

void do_swordplay(CHAR_DATA *ch, char *argument)
{
	AFFECT_DATA *af, *af_next, affectCounter, affectLanded, initialAffect;
	OBJ_DATA *wield = get_eq_char(ch,WEAR_WIELD), *victimWield, *secondary;
	CHAR_DATA *victim = ch->fighting;
	int level = 0, sn = gsn_paladin_tech_counter_pc;

	if (get_skill(ch,gsn_swordplay) < 5)
		return send_to_char("You are not learned in two-handed swordplay.\n\r",ch);

	if ( wield == NULL || 
	     wield->value[0] != WEAPON_SWORD || 
  	     ( wield->value[0] == WEAPON_SWORD &&              !IS_WEAPON_STAT(wield,WEAPON_TWO_HANDS) ) )
		return send_to_char("You must be using a two-handed sword to use the paladin techniques.\n\r",ch);

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

	if (argument[0] == '\0')
		return send_to_char("Which technique (Jab, Slash, Charge, Thrust, Downslash, Doubleslash, Whirl)?\n\r",ch);

	if (number_percent() > get_skill(ch,skill_lookup("swordplay")))
	{
		act("$n attempts to execute a complex maneuver with $s sword, but botches it and fails.",ch,0,0,TO_ROOM);
		return send_to_char("You attempt to execute a swordplay maneuver, but botch it.\n\r",ch);
		WAIT_STATE(ch,PULSE_VIOLENCE*2);
	}
	
	check_improve(ch,gsn_swordplay,TRUE,4);
	victimWield = get_eq_char(victim,WEAR_WIELD);
	secondary = get_eq_char(victim,WEAR_DUAL_WIELD);

	for (af = ch->affected; af != NULL; af = af_next)
	{
		af_next = af->next;
		if (af->type == sn)
			level = af->level;
	}

	if (!is_affected(ch,sn))
	{
		init_affect(&initialAffect);
		initialAffect.aftype = AFT_INVIS;
		initialAffect.level = 0;
		initialAffect.type = sn;
		initialAffect.duration = 1;
		affect_to_char(ch,&initialAffect);
	}

	if (!str_prefix(argument,"slash"))
	{
		act("Bringing $p around, $n slashes you across the stomach!",ch,wield,victim,TO_VICT);
		act("Bringing $p sword around, $n slashes $N across the stomach!",ch,wield,victim,TO_NOTVICT);
		act("Bringing $p around, you slash $N across the stomach!",ch,wield,victim,TO_CHAR);
		if(number_percent() < 20 && !is_affected(victim,gsn_cross_slice))
		{
			act("$n's slash leaves a deep wound within you!",ch,0,victim,TO_VICT);
			act("$n's slash leaves a deep wound within $N!",ch,0,victim,TO_NOTVICT);
			act("Your slash leaves a deep wound within $N!",ch,0,victim,TO_CHAR);
			init_affect(&affectLanded);
			affectLanded.where  = TO_AFFECTS;
			affectLanded.aftype = AFT_SKILL;
			affectLanded.type = gsn_cross_slice;
			affectLanded.name = "bleeding";
			affectLanded.level = 25;
			affectLanded.duration = 10;
			affect_to_char(victim,&affectLanded);
		}
		one_hit_new(ch,victim,TYPE_UNDEFINED,HIT_NOSPECIALS,HIT_UNBLOCKABLE,HIT_NOADD,150,"slash");
		affect_strip(ch,sn);
		init_affect(&affectCounter);
		affectCounter.aftype = AFT_INVIS;
		affectCounter.level = level + 3;
		affectCounter.type = sn;
		affectCounter.duration = 1;
		affect_to_char(ch,&affectCounter);
		send_to_char("You gain 3 combo points!\n",ch);
		check_paladin_combo(ch, victim);
		WAIT_STATE(ch,PULSE_VIOLENCE*1.5);
	}	
	else if (!str_prefix(argument,"charge"))
	{
		act("Yelling a cry, $n charges towards you and uses $s momentum to deliver a powerful slice!",ch,0,victim,TO_VICT);
		act("Yelling a cry, $n charges towards $N and uses $s momentum to deliver a powerful slice!",ch,0,victim,TO_NOTVICT);
		act("Yelling a cry, you charge towards $N and use your momentum to deliver a powerful slice!",ch,0,victim,TO_CHAR);

		if(number_percent() < 30)
		{
			act("$n sees an opening in your defenses and charges into you, sending you flying!",ch,0,victim,TO_VICT);
			act("$n charges into $N, sending $S flying!",ch,0,victim,TO_NOTVICT);
			act("Seizing a moment of weakness, you charge into $N, sending $M flying!",ch,0,victim,TO_CHAR);
			WAIT_STATE(victim,PULSE_VIOLENCE*2);
		}
		one_hit_new(ch,victim,TYPE_UNDEFINED,HIT_NOSPECIALS,HIT_UNBLOCKABLE,HIT_NOADD,170,"charge");
		affect_strip(ch,sn);
		init_affect(&affectCounter);
		affectCounter.aftype = AFT_INVIS;
		affectCounter.level = level + 6;
		affectCounter.type = sn;
		affectCounter.duration = 1;
		affect_to_char(ch,&affectCounter);
		send_to_char("You gain 6 combo points!\n",ch);
		check_paladin_combo(ch, victim);
		WAIT_STATE(ch,PULSE_VIOLENCE*2.5);
	}

	else if (!str_prefix(argument,"thrust"))
	{
		act("$n thrusts $p past your defenses and into your flesh!",ch,wield,victim,TO_VICT);
		act("$n thrusts $p past $N's defenses and into $S flesh!",ch,wield,victim,TO_NOTVICT);
		act("You thrust $p past $N's defenses and into $S flesh!",ch,wield,victim,TO_CHAR);

		if(number_percent() < 20 && victimWield != NULL && can_see_obj(ch,victimWield))
		{
			if (IS_OBJ_STAT(victimWield,ITEM_NODISARM) || IS_OBJ_STAT(victimWield,ITEM_NOREMOVE) || is_affected(victim,gsn_spiderhands) || (is_affected(victim,gsn_unholy_affinity) && is_affected_obj(victimWield,gsn_unholy_bless)))
			{
				act("$n twists $p gracefully, but cannot disarm you! ",ch,wield,victim,TO_VICT);
				act("$n twists $p gracefully, but cannot disarm $N!",ch,wield,victim,TO_NOTVICT);
				act("Finding an opening, you twist $p, but cannot disarm $N!",ch,wield,victim,TO_CHAR);
			}
			else
			{
				act("$n twists $p gracefully and disarms you! ",ch,wield,victim,TO_VICT);
				act("$n twists $p gracefully and disarms $N!",ch,wield,victim,TO_NOTVICT);
				act("Finding an opening, you twist $p and disarm $N!",ch,wield,victim,TO_CHAR);
				obj_from_char( victimWield );
    				if ( IS_OBJ_STAT(victimWield,ITEM_NODROP) || IS_OBJ_STAT(victimWield,ITEM_INVENTORY) )
        				obj_to_char( victimWield, victim );
    				else
    				{
        				obj_to_room( victimWield, victim->in_room );
        				if (IS_NPC(victim) && victim->wait == 0 && can_see_obj(victim,victimWield))
        				    get_obj(victim,victimWield,NULL);
    				}

				reslot_weapon(victim);

    				if (secondary != NULL)
    				{
						unequip_char(victim,secondary);
						equip_char(victim,secondary,WEAR_WIELD);
					}
			}
		}
		one_hit_new(ch,victim,TYPE_UNDEFINED,HIT_NOSPECIALS,HIT_UNBLOCKABLE,HIT_NOADD,160,"thrust");
		affect_strip(ch,sn);
		init_affect(&affectCounter);
		affectCounter.aftype = AFT_INVIS;
		affectCounter.level = level + 5;
		affectCounter.type = sn;
		affectCounter.duration = 1;
		affect_to_char(ch,&affectCounter);
		send_to_char("You gain 5 combo points!\n",ch);
		check_paladin_combo(ch, victim);
		WAIT_STATE(ch,PULSE_VIOLENCE*2);
	}

	else if (!str_prefix(argument,"downslash"))
	{
		act("$n swings $p diagonally across your legs!",ch,wield,victim,TO_VICT);
		act("$n swings $p diagonally across $N's legs!",ch,wield,victim,TO_NOTVICT);
		act("You swing $p diagonally across $N's legs!",ch,wield,victim,TO_CHAR);

		if(number_percent() < 20 && !is_affected(victim,gsn_hobble))
		{
			act("A shooting pain runs through your thigh and you find yourself limping!",ch,0,victim,TO_VICT);
			act("$N's eyes widen as $S thigh begins pouring blood!",ch,0,victim,TO_NOTVICT);
			act("$N's eyes widen as $S thigh begins pouring blood!",ch,0,victim,TO_CHAR);
			init_affect(&affectLanded);
			affectLanded.where  = TO_AFFECTS;
			affectLanded.aftype = AFT_SKILL;
			affectLanded.type = gsn_hobble;
			affectLanded.level = 51;
			affectLanded.duration = number_range(1,3);
			affect_to_char(victim,&affectLanded);
			affectLanded.location = APPLY_DEX;
			affectLanded.modifier = number_range(-6,-4);
			affect_to_char(victim,&affectLanded);
		}

		one_hit_new(ch,victim,TYPE_UNDEFINED,HIT_NOSPECIALS,HIT_UNBLOCKABLE,HIT_NOADD,130,"downslash");
		affect_strip(ch,sn);
		init_affect(&affectCounter);
		affectCounter.aftype = AFT_INVIS;
		affectCounter.level = level + 4;
		affectCounter.type = sn;
		affectCounter.duration = 1;
		affect_to_char(ch,&affectCounter);
		send_to_char("You gain 4 combo points!\n",ch);
		check_paladin_combo(ch, victim);
		WAIT_STATE(ch,PULSE_VIOLENCE*1.75);
	}


	else if (!str_prefix(argument,"jab"))
	{
		act("$n quickly jabs you with $p!",ch,wield,victim,TO_VICT);
		act("$n quickly jabs $N with $p!",ch,wield,victim,TO_NOTVICT);
		act("You quickly jab $N with $p!",ch,wield,victim,TO_CHAR);

		one_hit_new(ch,victim,TYPE_UNDEFINED,HIT_NOSPECIALS,HIT_UNBLOCKABLE,HIT_NOADD,110,"jab");
		affect_strip(ch,sn);
		init_affect(&affectCounter);
		affectCounter.aftype = AFT_INVIS;
		affectCounter.level = level + 2;
		affectCounter.type = sn;
		affectCounter.duration = 1;
		affect_to_char(ch,&affectCounter);
		send_to_char("You gain 2 combo points!\n",ch);
		check_paladin_combo(ch, victim);
		WAIT_STATE(ch,PULSE_VIOLENCE);
	}

	else if (!str_prefix(argument,"doubleslash"))
	{
		act("$n brings $p around and slashes you across the chest!",ch,wield,victim,TO_VICT);
		act("$n brings $p around and slashes $N across the chest!",ch,wield,victim,TO_NOTVICT);
		act("You bring $p around and slash $N across the chest!",ch,wield,victim,TO_CHAR);
		one_hit_new(ch,victim,TYPE_UNDEFINED,HIT_NOSPECIALS,HIT_UNBLOCKABLE,HIT_NOADD,150,"slash");
		if (victim != NULL) {
			act("$n quickly spins and brings $p around a second time, slamming its flat into $N's head!",ch,wield,victim,TO_VICT);
			act("$n quickly spins and brings $p around a second time, slamming its flat into $N's head!",ch,wield,victim,TO_NOTVICT);
			act("You quickly spin and bring $p around a second time, slamming its flat into $N's head!",ch,wield,victim,TO_CHAR);
			one_hit_new(ch,victim,TYPE_UNDEFINED,HIT_NOSPECIALS,HIT_UNBLOCKABLE,HIT_NOADD,150,"smash");
		}
		affect_strip(ch,sn);
		init_affect(&affectCounter);
		affectCounter.aftype = AFT_INVIS;
		affectCounter.level = level + 7;
		affectCounter.type = sn;
		affectCounter.duration = 1;
		affect_to_char(ch,&affectCounter);
		send_to_char("You gain 7 combo points!\n",ch);
		check_paladin_combo(ch, victim);
		WAIT_STATE(ch,PULSE_VIOLENCE*2.5);
	}

	else if (!str_prefix(argument,"whirl"))
	{
		CHAR_DATA *target, *targetLooper;
		int whirl;
		char message[MSL];

		for (target = ch->in_room->people; target != NULL; target = targetLooper)
		{
			targetLooper = target->next;
			if (target->fighting == ch)
			{
				act("$n whirls and brings $p around, dicing $s enemies!",ch,wield,0,TO_ROOM);
				whirl = number_range(1,4);
				if (whirl == 1) sprintf(message,"$n slashes you across the chest!");
				else if (whirl == 2) sprintf(message,"$n's slash catches you in the arm!");
				else if (whirl == 3) sprintf(message,"$n's slash connects with your stomach!");
				else if (whirl == 4) sprintf(message,"$n's slash cleaves into your leg!");
				act(message,ch,wield,target,TO_VICT);
				act("You whirl and bring $p around, dicing your enemies!",ch,wield,target,TO_CHAR);
				one_hit_new(ch,target,TYPE_UNDEFINED,HIT_NOSPECIALS,HIT_UNBLOCKABLE,HIT_NOADD,100,"whirl");
				affect_strip(ch,sn);
				
			}
		}
		init_affect(&affectCounter);
		affectCounter.aftype = AFT_INVIS;
		affectCounter.level = level + 8;
		affectCounter.type = sn;
		affectCounter.duration = 1;
		affect_to_char(ch,&affectCounter);
		send_to_char("You gain 8 combo points!\n",ch);
		check_paladin_combo(ch, victim);
		WAIT_STATE(ch,PULSE_VIOLENCE*3);
	}

	else
		return send_to_char("That is not a known swordplay maneuver.\n\r",ch);
	return;
}

void do_lash(CHAR_DATA *ch, char *argument)
{
	char arg[MIL];
	CHAR_DATA *victim;
	int chance;
	char buf[MSL];
	OBJ_DATA *weapon;

	one_argument(argument,arg);
 
	if ((chance = get_skill(ch, gsn_lash)) == 0)
	{   
	  	send_to_char("You don't have the skill to lash people's legs.\n\r",ch);
	  	return;
	}

	if (IS_NPC(ch) && IS_AFFECTED(ch,AFF_CHARM))
	  	return;

	weapon = get_eq_char(ch,WEAR_WIELD);
	if (weapon == NULL || (weapon->value[0] != WEAPON_WHIP && weapon->value[0] != WEAPON_FLAIL) )
	{
	  	chance -= 15;
	  	weapon = get_eq_char(ch,WEAR_DUAL_WIELD);
	}
	if (weapon == NULL)
	{
	  	send_to_char("You aren't wielding any weapon to lash with.\n\r",ch);
	  	return;
	}
	if (weapon->value[0] != WEAPON_WHIP && weapon->value[0] != WEAPON_FLAIL)
	{
	  	send_to_char("You need to be wielding a whip or flail to lash.\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_SLEEPING || victim->position == POS_RESTING)
	{
	  	act("$N isn't on $S feet.",ch,NULL,victim,TO_CHAR);
	  	return;
	} 

	if (victim == ch)
	{
	  	send_to_char("You try to lash your feet and look clumsy doing it.\n\r",ch);
	  	return;
	}

	if (is_safe(ch, victim))
	  	return;

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

	if (IS_SET(ch->off_flags,OFF_FAST) || IS_AFFECTED(ch,AFF_HASTE))
	  	chance += 5;
	if (IS_SET(victim->off_flags,OFF_FAST) || IS_AFFECTED(victim,AFF_HASTE))
	  	chance -= 15;
	chance += get_curr_stat(ch,STAT_DEX)/2;
	chance -= get_curr_stat(victim,STAT_DEX)/2;
	if (IS_AFFECTED(victim,AFF_FLYING))
	  	chance -= dice(2,5);
	if (!IS_NPC(ch) && (ch->class == CLASS_CHANNELER
	|| ch->class == CLASS_NECROMANCER
	|| ch->class == CLASS_ELEMENTALIST) )
	  	chance -= 10;

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

	if (!IS_NPC(ch) && !IS_NPC(victim) && (victim->fighting == NULL || ch->fighting == NULL))
	{
	 	sprintf(buf,"Help! %s is lashing me!",PERS(ch,victim));
	  	do_myell(victim,buf);
	}
	if (number_percent() > chance)
	{
	  	act("$n lashes at $N's legs but misses.",ch,0,victim,TO_NOTVICT);
	  	act("$n lashes at your legs but misses.",ch,0,victim,TO_VICT);
	  	act("You lash at $N's legs but miss.",ch,0,victim,TO_CHAR);
	  	check_improve(ch,gsn_lash,FALSE,1);
	  	WAIT_STATE(ch,skill_table[gsn_lash].beats);
	  	return;
	}
	act("$n lashes $N's legs, sending $M crashing to the ground.",ch,0,victim,TO_NOTVICT);
	act("$n lashes your legs, sending you crashing to the ground.",ch,0,victim,TO_VICT);
	act("You lash $N's legs, sending $M crashing to the ground.",ch,0,victim,TO_CHAR);
	check_improve(ch,gsn_lash,TRUE,1);
	WAIT_STATE(victim,2 * PULSE_VIOLENCE);
	WAIT_STATE(ch,PULSE_VIOLENCE*2);
	damage(ch,victim,dice(2,7),gsn_lash,DAM_BASH,TRUE);
	check_cheap_shot(ch,victim);
	victim->position = POS_RESTING;
	return;
}

bool check_shield_magnetism( CHAR_DATA *ch, CHAR_DATA *victim, int dt )
{
	OBJ_DATA *weapon;
	float chance = 0;
	char *attack;
	char buf1[MSL], buf2[MSL];

	if ( !IS_AWAKE(victim) )
		return FALSE;
	
	if (!is_affected(victim, skill_lookup("ward of magnetism")))
		return FALSE;
	
	weapon = (dt == gsn_dual_wield ? get_eq_char(ch, WEAR_DUAL_WIELD) : get_eq_char(ch, WEAR_WIELD));
	
	if (weapon == NULL) return FALSE;
	
	if (!IS_METAL(weapon)) return FALSE;
	
	chance = 80;
	
	//Mobs are dumb and can't swap out weapons. They were getting totally crushed by this skill, so I'm going to reduce its effectiveness against them. Zornath
	if (!IS_NPC(ch))
		chance -= weapon->weight * 3;
	else {
		chance -= weapon->weight * 6;
		if (chance < 15) chance = 15;
	}
		
	chance += get_curr_stat(ch, STAT_STR) * 1.5;
	
	chance = UMIN(chance, 95);
	
	if (number_percent() > chance) return FALSE;
	
	attack = get_dam_message(ch,dt);
	
	sprintf(buf1,"$n's %s is repelled by your ward of magnetism.", attack);
	sprintf(buf2,"Your %s is repelled by $N's ward of magnetism.", attack);
	
	act(buf1,ch,0,victim,TO_VICT);
	act(buf2,ch,0,victim,TO_CHAR);
	
	return TRUE;
}