/*********************************************************************************************/
/*                                                                                           */
/* Spider Control                                                             G.Rummery 1997 */
/*                                                                                           */
/*********************************************************************************************/

// Spider Big and Small

#include "game.h"

#define SPIDER_DAMAGE		25
#define BIG_SPIDER_DAMAGE 100

/*********************************** TYPE DEFINITIONS ****************************************/

enum spider_anims {SPIDER_EMPTY, SPIDER_STOP, SPIDER_WALK1, SPIDER_WALK2, SPIDER_ATTACK1, SPIDER_ATTACK2, SPIDER_ATTACK3, SPIDER_DEATH};

BITE_INFO spider_bite = {0,0,41, 1};

#define SPIDER_LEAP_ANIM 2

#define BIG_SPIDER_TURN  (ONE_DEGREE*4)
#define SPIDER_WALK_TURN (ONE_DEGREE*8)

#define SPIDER_MOVE_CHANCE 0x100

#define SPIDER_ATTACK3_RANGE SQUARE(WALL_L/5)
#define SPIDER_ATTACK2_RANGE SQUARE(WALL_L/2)


#define BIG_SPIDER_DIE_ANIM 2

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

void SpiderLeap(sint16 item_number, sint16 angle)
{
	ITEM_INFO *item;
	sint32 x, y, z;
	sint16 room_number;

	item = &items[item_number];

	x = item->pos.x_pos;
	y = item->pos.y_pos;
	z = item->pos.z_pos;
	room_number = item->room_number;

	CreatureAnimation(item_number, angle, 0);

	/* Is this move less than 1.5 STEP_L height. If so, don't do leap */
	if (item->pos.y_pos > y - STEP_L*3/2)
		return;

	/* Else move spider back, and do a jump instead */
	item->pos.x_pos = x;
	item->pos.y_pos = y;
	item->pos.z_pos = z;
	if (item->room_number != room_number)
		ItemNewRoom(item_number, room_number);

	item->anim_number = objects[SPIDER].anim_index + SPIDER_LEAP_ANIM;
	item->frame_number = anims[item->anim_number].frame_base;
	item->current_anim_state = SPIDER_ATTACK2;

	CreatureAnimation(item_number, angle, 0);
}

void SpiderControl(sint16 item_number)
{
	ITEM_INFO *item;
	CREATURE_INFO *spider;
	sint16 angle;
	AI_INFO info;

	if (!CreatureActive(item_number))
		return;

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

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

		CreatureMood(item, &info, TIMID);

		angle = CreatureTurn(item, SPIDER_WALK_TURN);

		switch (item->current_anim_state)
		{
		case SPIDER_STOP:
			spider->flags = 0;

			if (spider->mood == BORED_MOOD)
			{
				if (GetRandomControl() < SPIDER_MOVE_CHANCE)
					item->goal_anim_state = SPIDER_WALK1;
				else
					break;
			}
			else if (info.ahead && item->touch_bits)
				item->goal_anim_state = SPIDER_ATTACK1;
			else if (spider->mood == STALK_MOOD)
				item->goal_anim_state = SPIDER_WALK1;
			else if (spider->mood == ESCAPE_MOOD || spider->mood == ATTACK_MOOD)
				item->goal_anim_state = SPIDER_WALK2;
			break;

		case SPIDER_WALK1:
			if (spider->mood == BORED_MOOD)
			{
				if (GetRandomControl() < SPIDER_MOVE_CHANCE)
					item->goal_anim_state = SPIDER_STOP;
				else
					break;
			}
			else if (spider->mood == ESCAPE_MOOD || spider->mood == ATTACK_MOOD)
				item->goal_anim_state = SPIDER_WALK2;
			break;

		case SPIDER_WALK2:
			spider->flags = 0;

			if (spider->mood == BORED_MOOD || spider->mood == STALK_MOOD)
				item->goal_anim_state = SPIDER_WALK1;
			else if (info.ahead && item->touch_bits)
				item->goal_anim_state = SPIDER_STOP;
			else if (info.ahead && info.distance < SPIDER_ATTACK3_RANGE)
				item->goal_anim_state = SPIDER_ATTACK3;
			else if (info.ahead && info.distance < SPIDER_ATTACK2_RANGE)
				item->goal_anim_state = SPIDER_ATTACK2;
			break;

		case SPIDER_ATTACK1:
		case SPIDER_ATTACK2:
		case SPIDER_ATTACK3:
			if (!spider->flags && item->touch_bits)
			{
				CreatureEffect(item, &spider_bite, DoBloodSplat);
				lara_item->hit_points -= SPIDER_DAMAGE;
				lara_item->hit_status = 1;

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

	/* Spider can jump up half blocks, so detect these and do it */
	if (item->current_anim_state == SPIDER_ATTACK2 && item->current_anim_state == SPIDER_ATTACK1)
		CreatureAnimation(item_number, angle, 0);
	else
		SpiderLeap(item_number, angle);
}


void BigSpiderControl(sint16 item_number)
{
	/* The giant spider is very similar to the small one, but different enough to need a modified copy of the control routine */
	ITEM_INFO *item;
	CREATURE_INFO *spider;
	sint16 angle;
	AI_INFO info;

	if (!CreatureActive(item_number))
		return;

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

	if (item->hit_points <= 0)
	{
		if (item->current_anim_state != SPIDER_DEATH)
		{
			item->anim_number = objects[BIG_SPIDER].anim_index + BIG_SPIDER_DIE_ANIM;
			item->frame_number = anims[item->anim_number].frame_base;
			item->current_anim_state = SPIDER_DEATH;
		}
	}
	else
	{
		CreatureAIInfo(item, &info);

		CreatureMood(item, &info, VIOLENT);

		angle = CreatureTurn(item, BIG_SPIDER_TURN);

		switch (item->current_anim_state)
		{
		case SPIDER_STOP:
			spider->flags = 0;

			if (spider->mood == BORED_MOOD)
				break;
			else if (info.ahead && item->touch_bits)
				item->goal_anim_state = SPIDER_ATTACK1;
			else if (spider->mood == STALK_MOOD)
				item->goal_anim_state = SPIDER_WALK1;
			else if (spider->mood == ESCAPE_MOOD || spider->mood == ATTACK_MOOD)
				item->goal_anim_state = SPIDER_WALK2;
			break;

		case SPIDER_WALK1:
			if (spider->mood == BORED_MOOD)
				break;
			else if (info.ahead && item->touch_bits)
				item->goal_anim_state = SPIDER_STOP;
			else if (spider->mood == ESCAPE_MOOD || spider->mood == ATTACK_MOOD)
				item->goal_anim_state = SPIDER_WALK2;
			break;

		case SPIDER_WALK2:
			spider->flags = 0;

			if (info.ahead && item->touch_bits)
				item->goal_anim_state = SPIDER_STOP;
			else if (spider->mood == BORED_MOOD || spider->mood == STALK_MOOD)
				item->goal_anim_state = SPIDER_WALK1;
			break;

		case SPIDER_ATTACK1:
			if (!spider->flags && item->touch_bits)
			{
				CreatureEffect(item, &spider_bite, DoBloodSplat);
				lara_item->hit_points -= BIG_SPIDER_DAMAGE;
				lara_item->hit_status = 1;

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

	CreatureAnimation(item_number, angle, 0);
}