/*********************************************************************************************/
/*                                                                                           */
/* Target Trap Control - TS  - 30/9/98                                                     */
/*                                                                                           */
/*********************************************************************************************/

/*---------------------------------------------------------------------------
 *	Import Headers
\*--------------------------------------------------------------------------*/

#ifdef PSX_VERSION
#include "../spec_psx/typedefs.h"
#else
#include "../specific/stypes.h"
#endif

#include "objects.h"
#include "items.h"
#include "box.h"
#include "lara.h"
#include "laraanim.h"
#include "control.h"
#include "people.h"
#include "traps.h"
#include "missile.h"
//#include "sphere.h"
//#include "effect2.h"
extern int assault_targets, assault_targets_reset;

void InitialiseTarget(sint16 item_number);
void TargetControl(sint16 item_number);
void ResetTargets();

#if defined(PSX_VERSION) && defined(RELOC)

void *func[] __attribute__((section(".header"))) = {
	&InitialiseTarget,
	&TargetControl,
	&ResetTargets,
};

#endif

/*---------------------------------------------------------------------------
 *	Constants
\*--------------------------------------------------------------------------*/


#define TARGET_UP_TIME 200
#define TARGET_DROP_SPEED (ONE_DEGREE*2)
enum target_anims{TARGET_RISE, TARGET_HIT1, TARGET_HIT2, TARGET_HIT3};

#define TARGET_HIT_POINTS 8
#define HIT1_HP 6
#define HIT2_HP 4
#define HIT3_HP 2

/*---------------------------------------------------------------------------
 *	Externals
\*--------------------------------------------------------------------------*/
//#define DEBUG_TARGET

#ifdef DEBUG_TARGET
extern char exit_message[];
#endif

#ifdef DEBUG_TARGET
static char *TargetStrings[] = {"RISE", "HIT1", "HIT2", "HIT3"};
#endif

/*---------------------------------------------------------------------------
 *	Public Functions
\*--------------------------------------------------------------------------*/

void InitialiseTarget(sint16 item_number)
{
	ITEM_INFO *item;

	item = &items[item_number];

	if (item->active)
		RemoveActiveItem(item_number);

	item->anim_number = objects[item->object_number].anim_index;
	item->frame_number = anims[item->anim_number].frame_base;
	item->current_anim_state = item->goal_anim_state = anims[item->anim_number].current_anim_state;
	item->required_anim_state = 0;
	item->pos.x_rot = item->pos.z_rot = 0;
	item->status = NOT_ACTIVE;
	item->active = item->flags = item->timer = item->item_flags[2] = 0;
	item->hit_points = objects[item->object_number].hit_points;
	item->data = NULL;
}

void TargetControl(sint16 item_number)
{
	ITEM_INFO *item;

	item = &items[item_number];

	if (item->status != ACTIVE)
		return;

	if (item->hit_points != TARGET_HIT_POINTS)
		assault_targets_reset = 0;

	if (item->hit_points != DONT_TARGET)
	{
		if (item->hit_status)
			SoundEffect(119, &item->pos, 0);

		switch (item->current_anim_state)
		{
			case TARGET_RISE:
				if (item->hit_points < HIT1_HP)
				{
					item->hit_points = HIT1_HP;
					item->goal_anim_state = TARGET_HIT1;
				}
				break;

			case TARGET_HIT1:
				if (item->hit_points < HIT2_HP)
				{
					item->anim_number = objects[item->object_number].anim_index + 2;
					item->frame_number = anims[item->anim_number].frame_base;
					item->current_anim_state = TARGET_HIT2;
					item->hit_points = HIT2_HP;
				}
				break;

			case TARGET_HIT2:
				if (item->hit_points < HIT3_HP)
				{
					item->anim_number = objects[item->object_number].anim_index + 3;
					item->frame_number = anims[item->anim_number].frame_base;
					item->current_anim_state = TARGET_HIT3;
					item->hit_points = HIT3_HP;
				}
				break;

			case TARGET_HIT3:
				if (item->hit_points <= 0 && item->hit_points != DONT_TARGET)
				{
					lara.target = NULL;
					item->hit_points = DONT_TARGET;
					item->item_flags[0] = 10*(ONE_DEGREE);	// X rot fallspeed.
					item->item_flags[1] = 0;		// Number of bounces.
					item->item_flags[2] = 1;		// Shot it to death!
				}
				break;
		}

		item->timer++;
		if (item->timer > 10*30)	// been alive for 10 seconds ?
		{
			lara.target = NULL;
			item->hit_points = DONT_TARGET;
			item->item_flags[0] = 1*(ONE_DEGREE);	// X rot fallspeed.
			item->item_flags[1] = 0;		// Number of bounces.
			item->item_flags[2] = 0;		// Shot it to death!
		}
	}

	if (item->hit_points == DONT_TARGET && item->item_flags[2] == 1)		// Shot it to death ?
	{
		item->pos.x_rot += item->item_flags[0];
		item->item_flags[0] += (ONE_DEGREE<<2) >> item->item_flags[1];

		if (item->pos.x_rot > 0x3800)
		{
			if (item->item_flags[1] == 2)
			{
				item->pos.x_rot = 0x3800;
				RemoveActiveItem(item_number);
				assault_targets--;
				return;
			}
			else
			{
				if (item->item_flags[1] == 1)
					SoundEffect(120, &item->pos, 0);
				item->pos.x_rot = 0x3800;
				item->item_flags[0] = -item->item_flags[0]>>2;
				item->item_flags[1]++;
			}
		}
	}
	else if (item->hit_points == DONT_TARGET && item->item_flags[2] == 0)		// Timer ran out ?
	{
		item->pos.x_rot -= item->item_flags[0];
		item->item_flags[0] += (ONE_DEGREE>>1) >> item->item_flags[1];

		if (item->pos.x_rot < -0x2a00)
		{
			if (item->item_flags[1] == 2)
			{
				item->pos.x_rot = -0x2a00;
				RemoveActiveItem(item_number);
				return;
			}
			else
			{
				SoundEffect(119, &item->pos, PITCH_SHIFT|0x2000000);
				item->pos.x_rot = -0x2a00;
				item->item_flags[0] = -item->item_flags[0]>>2;
				item->item_flags[1]++;
			}
		}
	}


#ifdef DEBUG_TARGET
	sprintf(exit_message, "Hit Points: %d", item->hit_points);
	PrintDbug(2, 2, exit_message);
//	sprintf(exit_message, "Mood: %d", cobra->mood);
//	PrintDbug(2, 2, exit_message);
	sprintf(exit_message, "%s", TargetStrings[item->current_anim_state]);
	PrintDbug(2, 3, exit_message);
	sprintf(exit_message, "%s", TargetStrings[item->goal_anim_state]);
	PrintDbug(2, 4, exit_message);
#endif

	AnimateItem(item);

}

void ResetTargets()
{
	long	lp;

	if (!assault_targets_reset)
	{
		assault_targets = 0;
		for (lp=0;lp<level_items;lp++)
		{
			if (items[lp].object_number == TARGETS)
			{
				InitialiseTarget(lp);
				assault_targets++;
			}
		}
		assault_targets_reset = 1;
	}
}
