/***************************************************************************
 *  OBLIVION 1.2 is copyright by Wes Wagner August, 1996                   *
 *  by using this code you have agreed to the terms of the Oblivion License*
 **************************************************************************/
 

#if defined(macintosh)
#include <types.h>
#else
#include <sys/types.h>
#endif
#include <stdio.h>
#include <string.h>
#include <time.h>
#include "merc.h"
#include "color.h"
#include "critical.h"

DECLARE_DO_FUN(do_drop);

void do_critical args( (CHAR_DATA *actor, CHAR_DATA *victim, CRITICAL_DATA crit) );

void perform_critical(CHAR_DATA *actor, CHAR_DATA *victim, sh_int dam_done,
							 sh_int damage_type)
{
	int num;
	sh_int crit_type;
	sh_int crit_index;

	num=number_range(0,20)+number_range(0,20)+dam_done-10;
	if(num>55) crit_type=4;
	else if(num>45) crit_type=3;
	else if(num>35) crit_type=2;
	else if(num>25) crit_type=1;
	else crit_type=0;

	num=number_range(1,100);

	if(num>98) crit_index=14;
	else if(num>95) crit_index=13;
	else if(num>90) crit_index=12;
	else if(num>85) crit_index=11;
	else if(num>80) crit_index=10;
	else if(num>75) crit_index=9;
	else if(num>70) crit_index=8;
	else if(num>65) crit_index=7;
	else if(num>60) crit_index=6;
	else if(num>55) crit_index=5;
	else if(num>50) crit_index=4;
	else if(num>40) crit_index=3;
	else if(num>30) crit_index=2;
	else if(num>20) crit_index=1;
	else crit_index=0;

	do_critical(actor,victim,critical_table[damage_type][crit_index][crit_type]);
}

void do_critical(CHAR_DATA *actor, CHAR_DATA *victim, CRITICAL_DATA crit)
{
	char bf[MAX_STRING_LENGTH];
	AFFECT_DATA af;
	void * vo = (void *) victim;
	int target = TARGET_CHAR;
	int i;

	if(crit.act_to_actor[0]=='\0')
		return ;

	act(crit.act_to_room, actor, NULL, victim, TO_NOTVICT );
	if(IS_SET(actor->act, PLR_COLOR))
		sprintf(bf,"%s%s%s", FG_LT_BLUE, crit.act_to_actor, FG_LT_GRAY);
	else
		strcpy(bf, crit.act_to_actor);
	act(bf , actor, NULL, victim, TO_CHAR );
	if(IS_SET(victim->act, PLR_COLOR))
		sprintf(bf,"%s%s%s", FG_LT_BLUE, crit.act_to_victim, FG_LT_GRAY);
	else
		strcpy(bf, crit.act_to_victim);
	act(bf, actor, NULL, victim, TO_VICT );

	for(i=0; i<3; i++)
	{
		victim->is_stunned+=crit.victim_effects[i]->stun_for;
		victim->will_die=crit.victim_effects[i]->mortal_in;
		victim->hit-=crit.victim_effects[i]->additional_damage;
		victim->mana-=crit.victim_effects[i]->additional_mana_loss;
		victim->bleeding+=crit.victim_effects[i]->hps_per_turn;

		if(crit.victim_effects[i]->sn>1)
		{
		af.where		 = TO_AFFECTS;
		af.type		 = crit.victim_effects[i]->sn;
		af.level		 = actor->level;
		af.duration  = crit.victim_effects[i]->duration;
		af.location  = crit.victim_effects[i]->aply;
		af.modifier  = crit.victim_effects[i]->modifier;
		af.bitvector = 0;
		affect_to_char( victim, &af );

		if(i==0)
		{
		(*skill_table[crit.victim_effects[i]->sn].spell_fun) (
					crit.victim_effects[i]->sn, actor->level, actor, vo,target);
		}
		else
			if(crit.victim_effects[i]->sn!=crit.victim_effects[i-1]->sn)
				(*skill_table[crit.victim_effects[i]->sn].spell_fun) (
					crit.victim_effects[i]->sn, actor->level, actor, vo,target);
		}
	}
		actor->is_stunned+=crit.actor_effects->stun_for;
		actor->will_die=crit.actor_effects->mortal_in;
		actor->hit-=crit.actor_effects->additional_damage;
		actor->mana-=crit.actor_effects->additional_mana_loss;
		actor->bleeding+=crit.actor_effects->hps_per_turn;

		if(crit.actor_effects->sn>1)
		{
		af.where		 = TO_AFFECTS;
		af.type		 = crit.actor_effects->sn;
		af.level		 = actor->level;
		af.duration  = crit.actor_effects->duration;
		af.location  = crit.actor_effects->aply;
		af.modifier  = crit.actor_effects->modifier;
		af.bitvector = 0;
		affect_to_char( actor, &af );
		vo = (void *) actor;
		(*skill_table[crit.actor_effects->sn].spell_fun) (
			crit.actor_effects->sn, actor->level, victim, vo,target);
		}

	return ;
}

void crit_none( int sn, int level, CHAR_DATA *ch, void *vo, int target )
{
	 return;
}

void crit_broken_shieldarm( int sn, int level, CHAR_DATA *ch, void *vo, int target )
{
	OBJ_DATA *obj;

	if ( ( obj = get_eq_char( ch, WEAR_SHIELD ) ) != NULL )
	{
	 unequip_char( ch, obj );
	 do_drop(ch, obj->name);
	}

	if ( ( obj = get_eq_char( ch, WEAR_SECONDARY ) ) != NULL )
	{
	 unequip_char( ch, obj );
	 do_drop(ch, obj->name);
	}

	if ( ( obj = get_eq_char( ch, WEAR_HOLD ) ) != NULL )
	{
	 unequip_char( ch, obj );
	 do_drop(ch, obj->name);
	}

	return ;
}