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


/* VARIABLES */
extern struct char_data *mob_list;

extern char buf2[SMALL_BUFSIZE];
extern char buf3[SMALL_BUFSIZE];

void	do_mob_flags(void)
{
	struct char_data *mob, *next_mob, *who, *target;
	struct say_data *say, *next_say;
	struct object_data *obj;
	int t,c=0;

	for(mob=mob_list;mob;mob=next_mob) {
		next_mob=mob->next_in_list;
		if(mob->says && (_random(1,12) == 1)) {
			for(c=1,say=mob->says;say->next;say=say->next)
				c++;
			c = _random(1,c);
			for(say=mob->says;c>1;say=say->next)
				--c;
			send_2_room(mob,INVIS_CHK,say->sentence);
		}

		if(mob->POSITION == POS_STANDING) {
			if((target=get_aggr_victim(mob))) {
				init_fight(mob,target);
			} else if(BTST(NPC_FLAGS(mob),SCAVENGER) && ANY_OBJECTS(mob)) {
				do_get(mob,"get all");
				do_wear(mob,"wear all");
				do_mob_wield(mob);
			} else if(BTST(NPC_FLAGS(mob),ACT_THIEF) && ANY_PEOPLE(mob)) {
				/* Steal an object from anyone in the room */
				for(c=0,who=ANY_PEOPLE(mob);who;c++,who=who->next_in_room);
				if(c) {
					t = _random(1,c);
					for(c=1,who=ANY_PEOPLE(mob);c != t;c++,who=who->next_in_room);
					t = who->INT + who->WIS + who->EXP;
					c = mob->INT + mob->EXP + mob->DEX;
					if(who->carrying && (_random(1,c) > t)) {
						for(c=0,obj=who->carrying;obj;c++,obj=obj->next_carried);
						t = _random(1,c);
						for(c=1,obj=who->carrying;c != t;c++,obj=obj->next_carried);
						obj_from_char(obj);
						obj_2_char(obj, mob);
						sprintf(buf2,"steals %s from %s!\n\r",obj->name,who->name);
						send_2_xcept(mob,who,INVIS_CHK,buf2);
						sprintf(buf2,"steals %s from YOU!\n\r",obj->name);
						send_2_char(mob,who,INVIS_CHK,buf2);
					}
				}
			}
		}
	}
}

void	move_mobs(void)
{
	struct char_data *mob, *next_mob, *target;

	for(mob=mob_list;mob;mob=next_mob) {
		next_mob=mob->next_in_list;
		if(mob->POSITION == POS_STANDING && !BTST(NPC_FLAGS(mob),SENTINEL))
			mob_movement(mob);
	}
	return;
}

void do_mob_wield(struct char_data *mob)
{
	struct object_data *obj, *obj_next;

	if(mob->wearing[0])
		return;

	for(obj=mob->carrying;obj;obj=obj_next) {
		obj_next=obj->next_carried;
		if(obj->OBJ_DIE) {
			get_target(buf3,obj->name,0);
			sprintf(buf2,"wield %s",buf3);
			do_wield(mob,buf2);
		}
	}
}

struct char_data *get_aggr_victim(struct char_data *mob)
{
	struct char_data *who, *who_next;

	if(BTST(ROOM_FLAGS(mob),NO_FIGHT) || !BTST(NPC_FLAGS(mob),AGGRESSIVE))
		return(0);

	for(who=ANY_PEOPLE(mob);who;who=who_next) {
		who_next=who->next_in_room;
      if(who != mob && see_char_chk(mob,who) && ((who->desc) && (who->desc->connected != CON_LINKLESS))) {
			if(BTST(who->SPECIALS,PKILLER))
				return(who);
			else if(BTST(mob->ANTI_ALIGN,who->ALIGN))
				return(who);
			else if(BTST(mob->ANTI_SEX,who->SEX))
				return(who);
			else if(BTST(mob->ANTI_CLASS,who->CLASS))
				return(who);
		}
	}
	return(0);
}

void mob_movement(struct char_data *mob)
{
	int exit,c;

	if(_random(1,18) != 1)
		return;

	for(c=0,exit=0;c<10;c++)
		if(IN_ROOM(mob)->exits[c])
			exit++;

	if(!exit)
		return;
	exit = _random(1,exit);

	for(c=0;c<10;c++) {
		if(IN_ROOM(mob)->exits[c])
			if(!(--exit))
				break;
	}

	do_direction(mob,c);

	return;
}

void check_health(void)
{
	extern struct descriptor_data *desc_list;
	struct descriptor_data *point, *next_point;
	struct char_data *mob, *next_mob;
	int bonus;

	for(point=desc_list;point;point=next_point) {
		next_point=point->next_in_list;

		/* Calculate heal rate */
		if((bonus = point->character->CON / 8) < 1)
			bonus = 1;

		/* Reward sleeping parties */
		if(point->character->POSITION == POS_ASLEEP) {
			bonus *= 3;
		}

		/* Check if they are incapacitated */
		if(point->character->HIT < 1) {
			if((--point->character->HIT) < -10) {
				create_corpse(point->character,0);
			}
		} else if(point->character->HIT < point->character->MAX_HIT) {
			point->character->HIT += bonus;
			if(point->character->HIT > point->character->MAX_HIT)
				point->character->HIT = point->character->MAX_HIT;
		}

		/* Check if they need more movement points */
		if(point->character->MOVE < point->character->MAX_MOVE) {
			point->character->MOVE += bonus;
			if(point->character->MOVE > point->character->MAX_MOVE)
				point->character->MOVE = point->character->MAX_MOVE;
		}

		if(point->character->POSITION < POS_STANDING)
			bonus++;

		// Time to sober up or fight disease/poison and stuff.
		if(point->character->DRUNK > 0)
			point->character->DRUNK -= bonus + (point->character->CON/6);
      if(point->character->DRUNK < 0)
			point->character->DRUNK = 0;

		if(point->character->STATE == STAT_POISEND)
		{
			if(point->character->POISEN >= 100)
			{
				point->character->POISEN = 100;
				point->character->POSITION = POS_INCAP;	
				bonus = 0;	
			}
			point->character->POISEN -= bonus + (point->character->STR/9);
			if(point->character->POISEN < 0)
				point->character->POISEN = 0;
		}
			
	}
}

