#include <stdio.h>
#include "config.h"
#include "structs.h"
#include "functions.h"
#include "db.h"
#include "utils.h"
#include "fight.h"


/* FUNCTIONS */
struct char_data *get_ch_in_room(struct char_data *ch, char *name);
void	do_fight(struct char_data *ch, struct char_data *pl);
void	init_fight(struct char_data *ch, struct char_data *pl);


/* EXTERNAL VARIABLES ETC */
extern struct descriptor_data *desc_list;
extern struct char_data *mob_list;
extern struct object_data *obj_timed;

extern char buf[SMALL_BUFSIZE];
extern char buf1[SMALL_BUFSIZE];
extern char buf2[SMALL_BUFSIZE];

void  do_attack(struct char_data *ch, char *arg)
{
   struct char_data *pl;

   if(!get_target(buf,arg,1)) {
      send_2_output("Whom do you wish to attack?\n\r",ch->desc);
   } else if(!(pl=get_ch_in_room(ch,buf))) {
      send_2_output("No one here by that name\n\r",ch->desc);
   } else if(pl == ch) {
      send_2_output("Commit suicide?? You coward!! No!\n\r",ch->desc);
   } else if(BTST(ch->in_room->flags,NO_FIGHT)) {
      send_2_output("You can't fight in here.\n\r",ch->desc);
   } else if(ch->fighting) {
      if(ch->fighting == pl)
         send_2_output("In a rush are we?\n\r",ch->desc);
      else
         send_2_output("You are already fighting someone.\n\r",ch->desc);
   } else {
      if(!BTST(ch->in_room->flags,PLAYER_KILL) && !BTST(pl->SPECIALS,NPC) && !BTST(pl->SPECIALS,PKILLER) && ch->LEVEL < GOD) {
         send_2_output("Tut, tut. Your'e in trouble now...\n\r",ch->desc);
         BSET(ch->SPECIALS,PKILLER);
      } else {
         sprintf(buf,"You attack %s\n\r",pl->name);
         send_2_output(buf,ch->desc);
      }
		init_fight(ch,pl);
		if(DEBUG_CHAR)
			printf("%s has just attacked %s\n",ch->name,pl->name);
   }
   return;
}

void	init_fight(struct char_data *ch, struct char_data *pl)
{
   send_2_char(ch,pl,INVIS_CHK,"attacks you!");
   sprintf(buf,"attacks %s",pl->name);
   send_2_xcept(ch,pl,INVIS_CHK,buf);
   ch->INVIS=0;
   ch->POSITION=POS_FIGHTING;
   ch->fighting=pl;
   if(!pl->fighting) {
      pl->INVIS=0;
      pl->POSITION=POS_FIGHTING;
      pl->fighting=ch;
	}
}

void end_fight(struct char_data *ch, struct char_data *pl)
{
	ch->POSITION = POS_STANDING;
	ch->fighting = 0;
	if(pl) {
		pl->POSITION = POS_STANDING;
		pl->fighting = 0;
	}
	if(DEBUG_CHAR)
		printf("%s has just finished fighting.\n",ch->name);
}

void	do_violence(void)
{
	struct descriptor_data *point, *next_point;
	struct char_data *ch, *pl, *ch_next;
   
	for(point=desc_list;point;point=next_point) {
      next_point=point->next_in_list;
		if(point->character->POSITION == POS_FIGHTING) {
			ch=point->character;
			pl=point->character->fighting;
			/* Check to see if either of us are playing */
			//printf("%d - %d - %d - %d\n",ch->desc->connected,see_char_chk(ch,pl),ch->IN_ROOM,pl->IN_ROOM);
			if(!ch->desc->connected || !see_char_chk(ch,pl) || (ch->in_room != pl->in_room)) {
				end_fight(ch,pl);
			} else {
				do_fight(ch,pl);
			}
		}
	}
	
	for(ch=mob_list;ch;ch=ch_next) {
		ch_next=ch->next_in_list;
		if(ch->POSITION == POS_FIGHTING) {
         if(!see_char_chk(ch->fighting,ch) || (ch->fighting->in_room != ch->in_room)) {
				end_fight(ch,pl);
         } else {
            do_fight(ch,ch->fighting);
			}
		}
	}
}

void do_fight(struct char_data *ch, struct char_data *pl)
{
	int	 thac0,power,damage,c;

	/* Calculate me chance of hitting them */
// CRTH - Sorry Matt, but the 1st level dudes didn't stand a chance!
//	thac0 = ch->THAC0 + (pl->DEX - 13)/1.5);
	thac0 = ((ch->THAC0 + ((pl->DEX - 13)/1.5))-(((ch->DEX - 13)/.5)+((ch->STR -13)/.5)));
	thac0 += (pl->LEVEL - ch->LEVEL);
	thac0 += (ch->DRUNK / 10) + (ch->POISEN / 10) + (ch->DISEASE / 10);
	if((thac0 -= (pl->ARMOR/10)) < 1)
		thac0 = 1;
	//printf("Thac0: %d -- ",thac0);
//	if((_random(1,20)) >= thac0) {
	if (((rand() % 20)+1) >= thac0) {
		//printf("**HIT**");
		if(ch->wearing[0]) /* Wielded weapon */
			damage = get_weap_dam(ch->wearing[0]) + pl->TODAM;
		else
			damage = 2 + pl->TODAM;
		pl->HIT -= damage;
	} else {
		damage = 0;
	}
	//printf("%s >> %s --> %d\n",ch->name,pl->name,damage);
	
   /* Get the hit message: miss, hit, barely hit, etc */
	if(damage) {
		power = (damage/3) + 1;
		if(power > 12)
			power = 12;
	} else {
		power = 0;
	}
	
	if(ch->wearing[0]) {
      sprintf(buf,"You %s %s with %s\n\r",dam_force[power].att_msg,pl->name,ch->wearing[0]->name);
      sprintf(buf1,"%s %s you with %s\n\r",ch->name,dam_force[power].def_msg,ch->wearing[0]->name);
      sprintf(buf2,"%s %s with %s",dam_force[power].def_msg,pl->name,ch->wearing[0]->name);
   } else {
      sprintf(buf,"You %s %s with your bare hands\n\r",dam_force[power].att_msg,pl->name);
      sprintf(buf1,"%s %s you with %s bare hands\n\r",ch->name,dam_force[power].def_msg,sex[ch->SEX].b);
      sprintf(buf2,"%s %s with %s bare hands",dam_force[power].def_msg,pl->name,sex[ch->SEX].b);
	}
	send_2_output(buf,ch->desc);
	send_2_output(buf1,pl->desc);
	send_2_xcept(ch,pl,INVIS_CHK,buf2);

	if(pl->HIT < 0) {
		ch->POSITION = POS_STANDING;
		ch->fighting = 0;
		pl->fighting = 0;
		if(pl->HIT > -10) {
			pl->POSITION = POS_INCAP;
		} else {
			long	exp = 0;
			char	mod = 1;
			if(DEBUG_CHAR)
				printf("%s has killed %s\n",ch->name,pl->name);
			sprintf(buf,"has killed %s",ch->name);
			send_2_xcept(ch,pl,INVIS_CHK,buf);
			if(ch->LEVEL == pl->LEVEL)
				mod = 2;
			if(ch->LEVEL < pl->LEVEL)
				mod = 5 + pl->LEVEL - ch->LEVEL; 
			exp = pl->MAX_HIT * mod;
			ch->EXP += exp;
			sprintf(buf,"You gained %ld exp for killing %s.\n\r",exp,pl->name);
			send_2_output(buf,ch->desc);
			do_deaddrop(pl,"drop all");
			create_corpse(pl,ch);
			while(ChkExp(ch));
			if(BTST(ch->PREFS,LOOT))
				do_get(ch,"get all");
		}
	}
}
// CRTH - Function will give you a rough (very rough) idea of if a player
// can kill somthing.
void	do_con(struct char_data *ch, char *arg)
{
   struct char_data *pl;
	char	ok = 0;
	int	odds = 0;
	long	exp = 0;
	char	mod = 1;
	
   if(!get_target(buf,arg,1))
      send_2_output("Whom do you wish to consider attacking?\n\r",ch->desc);
	else 
		if(!(pl = get_ch_in_room(ch,buf))) 
      	send_2_output("No one here by that name\n\r",ch->desc);
		else 
			if(pl == ch) 
      		send_2_output("Consider killing your self? No!\n\r",ch->desc);
			else
				ok = 1;
	if(ok)
	{
		if(ch->LEVEL == pl->LEVEL)
			mod = 2;
		if(ch->LEVEL < pl->LEVEL)
			mod = 5 + pl->LEVEL - ch->LEVEL; 
		exp = pl->MAX_HIT * mod;

		sprintf(buf,"You consider attacking \033[35m%s\033[0m.\n\r\n\r",pl->name);
		send_2_output(buf,ch->desc);
		sprintf(buf,"\033[1m\033[33m%s\033[0m vs \033[35m%s\033[0m\n\r",ch->name,pl->name);
		send_2_output(buf,ch->desc);
		sprintf(buf,"\033[36m===================\033[0m\n\r");
		send_2_output(buf,ch->desc);
		
		sprintf(buf,"LVL : \033[1m\033[33m%3d\033[0m vs \033[35m%3d\033[0m\n\r",ch->LEVEL,pl->LEVEL);
		send_2_output(buf,ch->desc);

		sprintf(buf,"STR : \033[1m\033[33m%3d\033[0m vs \033[35m%3d\033[0m\n\r",ch->STR,pl->STR);
		send_2_output(buf,ch->desc);
		
		sprintf(buf,"CON : \033[1m\033[33m%3d\033[0m vs \033[35m%3d\033[0m\n\r",ch->CON,pl->CON);
		send_2_output(buf,ch->desc);		

		sprintf(buf,"DEX : \033[1m\033[33m%3d\033[0m vs \033[35m%3d\033[0m\n\r",ch->DEX,pl->DEX);
		send_2_output(buf,ch->desc);
		
		sprintf(buf,"HIT : \033[1m\033[33m%3d\033[0m vs \033[35m%3d\033[0m\n\r",ch->HIT,pl->HIT);
		send_2_output(buf,ch->desc);
	
		sprintf(buf,"TOD : \033[1m\033[33m%3d\033[0m vs \033[35m%3d\033[0m\n\r\n\r",ch->TODAM,pl->TODAM);
		send_2_output(buf,ch->desc);
		
		// Work out the odds.
		// Str diff.
		if(ch->STR > pl->STR)
			odds += ch->STR - pl->STR;
		if(ch->STR < pl->STR)
			odds -= pl->STR - ch->STR;

		// Con diff.
		if(ch->CON > pl->CON)
			odds += ch->CON - pl->CON;
		if(ch->CON < pl->CON)
			odds -= pl->CON - ch->CON;
		
		// Dex diff.
		if(ch->DEX > pl->DEX)
			odds += ch->DEX - pl->DEX;
		if(ch->DEX < pl->DEX)
			odds -= pl->DEX - pl->DEX;

		// Hit diff.
		if(ch->HIT > pl->HIT)
			odds += ch->HIT - pl->HIT;
		if(ch->HIT < pl->HIT)
			odds -= pl->HIT - ch->HIT;

		// Todam diff.
		if(ch->TODAM > pl->TODAM)
			odds += ch->TODAM - pl->TODAM;
		if(ch->TODAM < pl->TODAM)
			odds -= pl->TODAM - ch->TODAM;

		// Level modifier.
		if(ch->LEVEL > pl->LEVEL)
			odds += ch->LEVEL - pl->LEVEL;
		if(ch->LEVEL < pl->LEVEL)
			odds -= pl->LEVEL - ch->LEVEL;

		send_2_output("ODDS: ",ch->desc);
		if(odds < 0)
		{
			sprintf(buf,"\033[31m%s Will eat you alive.\033[0m\n\r",pl->name);
			if(odds > -100)
				sprintf(buf,"\033[31mHave you chosen a head stone yet?\033[0m\n\r");
			if(odds > -70)
				sprintf(buf,"\033[31mDo you have a death wish?\033[0m\n\r");
			if(odds > -40)
				sprintf(buf,"\033[31mThis would be risky\033[0m\n\r");
			if(odds > -10)
				sprintf(buf,"\033[31mYou may loose an arm....or two...\033[0m\n\r");
			if(odds > -5)
				sprintf(buf,"\033[31mLooks close, if you want to risk it\033[0m.\n\r");
			
		}
		if(odds > 0)
		{
			sprintf(buf,"\033[1m\033[37mThis should be a fair fight.\033[0m\n\r");

			if(odds > 5)
				sprintf(buf,"\033[36mLooks close, but you should win.\033[0m\n\r");
			if(odds > 10)
				sprintf(buf,"\033[36m%s may give you a nose bleed.\033[0m\n\r",pl->name);
			if(odds > 40)
				sprintf(buf,"\033[36m%s will put up a fight.\033[0m\n\r",pl->name);
			if(odds > 70)
				sprintf(buf,"\033[36mYou will butcher and slay %s!\033[0m\n\r",pl->name);
			if(odds > 100)
				sprintf(buf,"\033[36mYou bully!!!\033[0m\n\r");
		}
		if(odds == 0)
			sprintf(buf,"\033[1m\033[37mThis should be a fair fight.\033[0m\n\r");
		
		send_2_output(buf,ch->desc);
		sprintf(buf,"\n\rIf you kill \033[35m%s\033[0m you will get EXP: \033[36m%ld\033[0m\n\r",pl->name,exp);
		send_2_output(buf,ch->desc);
	}
}

