#include	"world.h"

#include	"ai.h"
#include	"ai_utils.h"

#include	"ai_move.h"
#include	"ai_weapons.h"
#include	"ai_task.h"
#include	"ai_frames.h"

#include	"skat.h"
#include	"nodelist.h"

////////////////////////////////////////////////////////////////////////////////
// exports
////////////////////////////////////////////////////////////////////////////////

DllExport	void	monster_psyclaw (userEntity_t *self);

///////////////////////////////////////////////////////////////////////////////////
// satyr specific funcitons
///////////////////////////////////////////////////////////////////////////////////

void	psyclaw_melee_attack (userEntity_t *self);
void	psyclaw_ranged_attack (userEntity_t *self);

////////////////////////////////
//	psyclaw_init_frametable
//
////////////////////////////////

void	psyclaw_init_frametable (userEntity_t *self)
{
	playerHook_t	*hook = (playerHook_t *) self->userHook;
	
	ai_set_sequence_data (self, hook->frames->run [0], 1, NULL, 6, NULL, 0, -1, 0, -1, FRAME_ONCE);

	ai_set_sequence_data (self, hook->frames->atak [0], 1, NULL, 6, NULL, 0, -1, 0, -1, FRAME_ONCE);
	ai_set_sequence_data (self, hook->frames->atak [1], 1, NULL, 6, NULL, 0, -1, 0, -1, FRAME_ONCE);
	ai_set_sequence_data (self, hook->frames->atak [2], 1, NULL, 6, NULL, 0, -1, 0, -1, FRAME_ONCE);
}

////////////////////////////////
//	psyclaw_set_attack_seq
//
////////////////////////////////

void	psyclaw_set_attack_seq (userEntity_t *self)
{
	playerHook_t	*hook = (playerHook_t *) self->userHook;
	float			dist;

	dist = qv_dist (self->s.origin, self->enemy->s.origin);

	if (dist > 80)
	{
		//ai_init_sequence (self, hook->frames->atak [2], SEQUENCE_ATAK, 2);
		ai_init_sequence (self, hook->frames->run [0], SEQUENCE_RUN, 0);
		psyclaw_ranged_attack (self);
	}
	else
	{
		ai_init_sequence (self, hook->frames->atak [1], SEQUENCE_ATAK, 1);
		psyclaw_melee_attack (self);
	}

	hook->frame_flags = FRAME_ONCE;
	hook->frameInc = 1;
}

///////////////////////////
//	psyclaw_ranged_attack
//
///////////////////////////

void	psyclaw_ranged_attack (userEntity_t *self)
{
	playerHook_t	*hook = (playerHook_t *) self->userHook;
	Vector			temp;
	float			dist;

	//ai_face_enemy (self);
	hook->dflags |= DFL_FACEENEMY;

	dist = qv_dist (self->s.origin, self->enemy->s.origin);

	if (hook->frame_flags & FRAME_PLAYSOUND1)
	{
		hook->frame_flags = hook->frame_flags - FRAME_PLAYSOUND1;

		if (hook->sound1)
			gstate->sound (self, CHAN_AUTO, hook->sound1, 128, ATTN_NORM);

		ai_fire_curWeapon (self, Vector (self->s.origin) + Vector (self->view_ofs), Vector (self->enemy->s.origin) + Vector (self->enemy->view_ofs), 0, 0);
	}
	
	if (hook->frame_flags & FRAME_PLAYSOUND2)
	{
		hook->frame_flags = hook->frame_flags - FRAME_PLAYSOUND2;
		
		if (hook->sound2)
			gstate->sound (self, CHAN_AUTO, hook->sound2, 128, ATTN_NORM);

		ai_fire_curWeapon (self, Vector (self->s.origin) + Vector (self->view_ofs), Vector (self->enemy->s.origin) + Vector (self->enemy->view_ofs), 0, 0);
	}
	
	if (hook->frame_flags & FRAME_STATIC)
	{
		hook->frame_flags -= FRAME_STATIC;

		if (self->enemy->deadflag != DEAD_NO)
		{
			//	leaving, so pop off TASK_ATTACK
			task_pop (&hook->task_stack);

			ai_killed_enemy (self);

			return;
		}
		else// if (dist > hook->attack_dist || !com->Visible (self, self->enemy))
		{
			//	leaving, so pop off TASK_ATTACK
			task_pop (&hook->task_stack);

			ai_should_follow (self);

			return;
		}
/*
		else
		{
			psyclaw_set_attack_seq (self);

			return;
		}
*/
	}

	ai_attack_move (self);

	if (!(hook->ai_flags & AI_JUMP) && !(hook->ai_flags & AI_TURN))
		ai_set_think (self, psyclaw_ranged_attack, "psyclaw_ranged_attack");
}

///////////////////////////
//	psyclaw_melee_attack
//
///////////////////////////

void	psyclaw_melee_attack (userEntity_t *self)
{
	playerHook_t	*hook = (playerHook_t *) self->userHook;
	Vector			temp;
	float			dist;

	//ai_face_enemy (self);
	hook->dflags |= DFL_FACEENEMY;

	dist = qv_dist (self->s.origin, self->enemy->s.origin);

	if (hook->frame_flags & FRAME_PLAYSOUND1)
	{
		hook->frame_flags = hook->frame_flags - FRAME_PLAYSOUND1;
				
		if (hook->sound1)
			gstate->sound (self, CHAN_AUTO, hook->sound1, 128, ATTN_NORM);
	}
	
	if (hook->frame_flags & FRAME_PLAYSOUND2)
	{
		hook->frame_flags = hook->frame_flags - FRAME_PLAYSOUND2;

		if (hook->sound2)
			gstate->sound (self, CHAN_AUTO, hook->sound2, 128, ATTN_NORM);
	}
		
	if (hook->frame_flags & FRAME_STATIC)
	{
		hook->frame_flags -= FRAME_STATIC;

		if (self->enemy->deadflag != DEAD_NO)
		{
			//	leaving, so pop off TASK_ATTACK
			task_pop (&hook->task_stack);

			hook->begin_wander (self);

			return;
		}
		else if (dist > hook->attack_dist || !com->Visible (self, self->enemy))
		{
			//	leaving, so pop off TASK_ATTACK
			task_pop (&hook->task_stack);

			ai_should_follow (self);

			return;
		}
		else
		{
			psyclaw_set_attack_seq (self);

			return;
		}
	}

	ai_set_think (self, psyclaw_melee_attack, "psyclaw_melee_attack");
}

////////////////////////////
//	psyclaw_begin_attack
//
////////////////////////////

void	psyclaw_begin_attack (userEntity_t *self)
{
	playerHook_t	*hook = (playerHook_t *) self->userHook;
	float			dist;

	com->ZeroVector (self->velocity);

	psyclaw_set_attack_seq (self);

	hook->th_state = TH_ATTACK;
	hook->attack_finished = gstate->time + (hook->endFrame - hook->endFrame) * 0.1;
}

//////////////////////////
//	monster_psyclaw
//
//	creates the superfly entity and sets him up to smack down
//	everything that gets in his way.
//////////////////////////

void	monster_psyclaw (userEntity_t *self)
{
	playerHook_t		*hook;
	int					i;
	float				f;
	Vector				v;

	hook = ai_init_monster (self, TYPE_PSYCLAW);

	self->className = "monster_psyclaw";
	self->netname = "psyclaw";
/*
	gstate->Precache_Sound ("monsters/satyr/satyrattack1.wav");
	gstate->Precache_Sound ("monsters/satyr/satyrattack2.wav");
	gstate->Precache_Sound ("monsters/satyr/satyrdeath1.wav");
	gstate->Precache_Sound ("monsters/satyr/satyrdeath2.wav");
	gstate->Precache_Sound ("monsters/satyr/satyrpain1.wav");
	gstate->Precache_Sound ("monsters/satyr/satyrpain2.wav");
	gstate->Precache_Sound ("monsters/satyr/satyrsight1.wav");
	gstate->Precache_Sound ("monsters/satyr/satyrsight2.wav");
	gstate->Precache_Sound ("monsters/satyr/satyrwander1.wav");
	gstate->Precache_Sound ("monsters/satyr/satyrwander2.wav");
	gstate->Precache_Sound ("monsters/satyr/satyrscream1.wav");
	gstate->Precache_Sound ("monsters/satyr/satyrattack1.wav");
*/
	gstate->Precache_Model ("models/psyclaw.mdl");
	gstate->Precache_Model ("models/psiblast.mdl");

	gstate->SetModel (self, "models/psyclaw.mdl");
	gstate->SetSize (self, -16.0, -16.0, -24.0, 16.0, 16.0, 32.0);

	////////////////////////////////////////////////////////////////
	// set up animation stuff
	////////////////////////////////////////////////////////////////

	ai_get_sequences (self);

//	psyclaw_init_frametable (self);

	///////////////////////////////////////////////////////////
	// set up pointers to this creature's ai functions
	///////////////////////////////////////////////////////////

	hook->begin_attack = psyclaw_begin_attack;

	hook->run_speed = 240;
	hook->walk_speed = 90;
	hook->attack_dist = 400;

	self->health = 200;
	hook->dflags |= DFL_RANGEDATTACK;
	hook->max_health = 200;
	hook->pain_chance = 10;
	self->mass = 2.0;

	self->think = ai_get_spawn_node;
	self->nextthink = gstate->time + 0.2;

	self->translucent = 0;

	//////////////////////////////////////////////
	//	give monster its weapon
	//////////////////////////////////////////////
/*
	self->curWeapon = ai_weapon_create ("psiblast", psiblast_fire, NULL);
	i = 10; ai_weapon_command (self->curWeapon, "base_damage", &i);
	i = 10;	ai_weapon_command (self->curWeapon, "rnd_damage", &i);
	f = 0.0; ai_weapon_command (self->curWeapon, "spread_x", &f);
	f = 0.0; ai_weapon_command (self->curWeapon, "spread_z", &f);
	f = 250.0;	ai_weapon_command (self->curWeapon, "speed", &f);
	v = Vector (0, 16, 6);	ai_weapon_command (self->curWeapon, "ofs", &v);
*/
	self->curWeapon = ai_init_weapon (self, 10, 10, 0, 0, 250.0, hook->attack_dist, Vector (0, 16, 6), "psiblast", psiblast_fire, WEAPON_PROJECTILE);
//	gstate->InventoryAddItem (self->inventory, self->curWeapon);
}

