/**************************************************************************************************************/
/*                                                                                                            */
/* Underwater creature control																				  	  G.Rummery 1997 */
/*                                                                                                            */
/**************************************************************************************************************/

// SHARK, BARACUDDA, JELLYFISH

#include "game.h"

#define SHARK_BITE 400

#define BARA_BITE 100

#define JELLY_STING 5

/******************************************* GLOBAL VARIABLES *************************************************/

enum jelly_anim {JELLY_EMPTY, JELLY_MOVE, JELLY_STOP};

#define JELLY_TURN (ONE_DEGREE*90)

enum bara_anim {BARA_EMPTY, BARA_STOP, BARA_SWIM1, BARA_SWIM2, BARA_ATTACK1, BARA_ATTACK2, BARA_DEATH};

#define BARA_DIE_ANIM 6

#define BARA_SWIM1_TURN (ONE_DEGREE*2)
#define BARA_SWIM2_TURN (ONE_DEGREE*4)

#define BARA_ATTACK1_RANGE SQUARE(WALL_L*2/3)
#define BARA_ATTACK2_RANGE SQUARE(WALL_L/3)

#define BARA_TOUCH 0xe0

BITE_INFO bara_bite = {2,-60,121, 7};


enum shark_anim {SHARK_STOP, SHARK_SWIM1, SHARK_SWIM2, SHARK_ATTACK1, SHARK_ATTACK2, SHARK_DEATH, SHARK_KILL};

#define SHARK_SWIM2_RANGE SQUARE(WALL_L*3)
#define SHARK_ATTACK1_RANGE SQUARE(WALL_L*3/4)
#define SHARK_ATTACK2_RANGE SQUARE(WALL_L*4/3)

#define SHARK_SWIM1_TURN (ONE_DEGREE/2)
#define SHARK_SWIM2_TURN (ONE_DEGREE*2)

#define SHARK_ATTACK1_CHANCE 0x800

#define SHARK_DIE_ANIM 4
#define SHARK_KILL_ANIM 19

#define SHARK_TOUCH 0x3400

BITE_INFO shark_bite = {17,-22,344, 12};

/******************************************** FUNCTION CODE ****************************************************/

void JellyControl(sint16 item_number)
{
	ITEM_INFO *item;
	CREATURE_INFO *jelly;
	sint16 angle, head;
	AI_INFO info;

	if (!CreatureActive(item_number))
		return;

	item = &items[item_number];
	jelly = (CREATURE_INFO *)item->data;
	angle = head = 0;

	if (item->hit_points <= 0)
	{
		if (ExplodingDeath(item_number, 0xffffffff, 0))
		{
			DisableBaddieAI( item_number );
			KillItem( item_number );
			item->status = DEACTIVATED;
			return;
		}
		return;
	}	
	else
	{
		CreatureAIInfo(item, &info);

		CreatureMood(item, &info, TIMID);

		angle = CreatureTurn(item, JELLY_TURN);

		switch (item->current_anim_state)
		{
		case JELLY_STOP:
			if (jelly->mood != BORED_MOOD)
				item->goal_anim_state = JELLY_MOVE;
			break;

		case JELLY_MOVE:
			if (jelly->mood == BORED_MOOD || item->touch_bits)
				item->goal_anim_state = JELLY_STOP;
			break;
		}

		/* Jelly hurts you when you touch it */
		if (item->touch_bits)
		{
			// bit of blood or a sound effect would be nice

			lara_item->hit_status = 1;
			lara_item->hit_points -= JELLY_STING;
		}
	}

	CreatureHead(item, head);

	CreatureAnimation(item_number, angle, 0);
	CreatureUnderwater(item, 0);
}


void BaracuddaControl(sint16 item_number)
{
	ITEM_INFO *item;
	CREATURE_INFO *bara;
	sint16 angle, head;
	AI_INFO info;

	if (!CreatureActive(item_number))
		return;

	item = &items[item_number];
	bara = (CREATURE_INFO *)item->data;
	angle = head = 0;

	if (item->hit_points <= 0)
	{
		if (item->current_anim_state != BARA_DEATH)
		{
			item->anim_number = objects[BARACUDDA].anim_index + BARA_DIE_ANIM;
			item->frame_number = anims[item->anim_number].frame_base;
			item->current_anim_state = BARA_DEATH;
		}

		/* Make dead shark float to surface */
		CreatureFloat(item_number);

		return;
	}	

	else
	{
		CreatureAIInfo(item, &info);

		CreatureMood(item, &info, TIMID);

		angle = CreatureTurn(item, bara->maximum_turn);

		switch (item->current_anim_state)
		{
		case BARA_STOP:
			bara->flags = 0;

			if (bara->mood == BORED_MOOD)
				item->goal_anim_state = BARA_SWIM1;
			else if (info.ahead && info.distance < BARA_ATTACK1_RANGE)
				item->goal_anim_state = BARA_ATTACK1;
			else if (bara->mood == STALK_MOOD)
				item->goal_anim_state = BARA_SWIM1;
			else
				item->goal_anim_state = BARA_SWIM2;
			break;

		case BARA_SWIM1:
			bara->maximum_turn = BARA_SWIM1_TURN;

			if (bara->mood == BORED_MOOD)
				break;
			else if (info.ahead && (item->touch_bits & BARA_TOUCH))
				item->goal_anim_state = BARA_STOP;
			else if (bara->mood != STALK_MOOD)
				item->goal_anim_state = BARA_SWIM2;
			break;

		case BARA_SWIM2:
			bara->maximum_turn = BARA_SWIM2_TURN;
			bara->flags = 0;

			if (bara->mood == BORED_MOOD)
				item->goal_anim_state = BARA_SWIM1;
			else if (info.ahead && info.distance < BARA_ATTACK2_RANGE)
				item->goal_anim_state = BARA_ATTACK2;
			else if (info.ahead && info.distance < BARA_ATTACK1_RANGE)
				item->goal_anim_state = BARA_STOP;
			else if (bara->mood == STALK_MOOD)
				item->goal_anim_state = BARA_SWIM1;
			break;

		case BARA_ATTACK1:
		case BARA_ATTACK2:
			if (info.ahead)
				head = info.angle;

			if (!bara->flags && (item->touch_bits & BARA_TOUCH))
			{
				lara_item->hit_points -= BARA_BITE;
				lara_item->hit_status = 1;
				CreatureEffect(item, &bara_bite, DoBloodSplat);

				bara->flags = 1;
			}
			break;
		}
	}

	CreatureHead(item, head);

	CreatureAnimation(item_number, angle, 0);
	CreatureUnderwater(item, STEP_L);
}


void SharkControl(sint16 item_number)
{
	ITEM_INFO *item;
	CREATURE_INFO *shark;
	sint16 angle, head;
	AI_INFO info;
	int lara_alive;
//sint16 *bounds;

	if (!CreatureActive(item_number))
		return;

	item = &items[item_number];
	shark = (CREATURE_INFO *)item->data;
	angle = head = 0;

	lara_alive = (lara_item->hit_points>0);

	if (item->hit_points <= 0)
	{
		if (item->current_anim_state != SHARK_DEATH)
		{
			item->anim_number = objects[SHARK].anim_index + SHARK_DIE_ANIM;
			item->frame_number = anims[item->anim_number].frame_base;
			item->current_anim_state = SHARK_DEATH;
		}

		/* Make dead shark float to surface */
		CreatureFloat(item_number);

		return;
	}	
	else
	{
		CreatureAIInfo(item, &info);

		CreatureMood(item, &info, VIOLENT);

		angle = CreatureTurn(item, shark->maximum_turn);

		switch (item->current_anim_state)
		{
		case SHARK_STOP:
			/* flags mark the attack status */
			shark->flags = 0;
			shark->maximum_turn = 0;

			if (info.ahead && info.distance < SHARK_ATTACK1_RANGE && info.zone_number==info.enemy_zone)
				item->goal_anim_state = SHARK_ATTACK1;
			else
				item->goal_anim_state = SHARK_SWIM1;
			break;

		case SHARK_SWIM1:
			shark->maximum_turn = SHARK_SWIM1_TURN;

			if (shark->mood == BORED_MOOD)
				break;
			else if (info.ahead && info.distance < SHARK_ATTACK1_RANGE)
				item->goal_anim_state = SHARK_STOP;
			else if (shark->mood == ESCAPE_MOOD || info.distance > SHARK_SWIM2_RANGE || !info.ahead)
				item->goal_anim_state = SHARK_SWIM2;
			break;

		case SHARK_SWIM2:
			shark->flags = 0;
			shark->maximum_turn = SHARK_SWIM2_TURN;

			if (shark->mood == BORED_MOOD)
				item->goal_anim_state = SHARK_SWIM1;
			else if (shark->mood == ESCAPE_MOOD)
				break;
			else if (info.ahead && info.distance < SHARK_ATTACK2_RANGE && info.zone_number==info.enemy_zone)
			{
				if (GetRandomControl() < SHARK_ATTACK1_CHANCE)
					item->goal_anim_state = SHARK_STOP;
				else if (info.distance < SHARK_ATTACK1_RANGE)
					item->goal_anim_state = SHARK_ATTACK2;
			}
			break;

		case SHARK_ATTACK1:
		case SHARK_ATTACK2:
			if (info.ahead)
				head = info.angle;

			if (!shark->flags && (item->touch_bits & SHARK_TOUCH))
			{
				lara_item->hit_points -= SHARK_BITE;
				lara_item->hit_status = 1;
				CreatureEffect(item, &shark_bite, DoBloodSplat);

				shark->flags = 1;
			}
			break;
		}
	}
 	
	/* Is Lara dead? We've killed her! */
	if (lara_alive && lara_item->hit_points <= 0)
	{
		CreatureKill(item, SHARK_KILL_ANIM, SHARK_KILL, EXTRA_SHARKKILL);
		return;
	}

//bounds = GetBestFrame(item);
//Log("%d:%d Bounds%d,%d %d,%d %d,%d", item->current_anim_state, item->frame_number, bounds[0], bounds[1], bounds[2], bounds[3], bounds[4], bounds[5]);

	if (item->current_anim_state != SHARK_KILL)
	{
		CreatureHead(item, head);

		CreatureAnimation(item_number, angle, 0);

		/* Don't allow shark to get above the water surface */
		CreatureUnderwater(item, WALL_L/3);
	}
	else
		AnimateItem(item);
}