#include "scripts/common.txt"
#include "scripts/BP_common.txt"

//Animations
//anim_aiStanding
//anim_aiRangeAttack1

//---Key Frame Actions---
//Description: 24 anim_aiRangeAttack1 - Shoot from spear tip 
//Frame: 15
//Event Type: 900 (Spawn Particle)
//Arg0: 375 (BP_SStatue_Blaster)
//Arg1: 107.776 (offset X)
//Arg2: -320.256 (offset Y)
//Arg3: 360.704 (offset Z)

//Description: 24 anim_aiRangeAttack1 - Shoot from spear tip sound
//Frame: 15
//Event Type: 248 (Play Sound)
//Arg0: 65 (explosion_1)
//Arg1: 107.776 (offset X)
//Arg2: -320.256 (offset Y)
//Arg3: 360.704 (offset Z)

enum SStatueStates
{
	SSS_SLEEP = 0,
	SSS_STAND,
	SSS_RANGEATTACK1,
	SSS_DEAD,
}

class BP_SStatue : ScriptObject
{
    kActor@ self;
	int state;
	float deathDelay;
	float turnAngleSpeed;
	float attackAngleRange;
	//------------------------------------------------------------------------------------------------------------------------
    BP_SStatue(kActor @actor)
	{
        @self = actor;
		
		deathDelay = 0.0f;
		state = -1;
		turnAngleSpeed = Math::Deg2Rad(5.0f);
		attackAngleRange = Math::Deg2Rad(30.0f);
    }
	//------------------------------------------------------------------------------------------------------------------------
	void OnPostBeginLevel()
	{
		SetState(SSS_SLEEP, true);
		self.SetTarget(Player.Actor().CastToActor());
	}
	//------------------------------------------------------------------------------------------------------------------------
    void OnSpawn() {}
	//------------------------------------------------------------------------------------------------------------------------
    void OnTick()
	{
		//Tick State
		switch(state)
		{
			case SSS_SLEEP:
				break;
			case SSS_STAND:
				FaceTarget();
				if (IsFacingTarget())
				{
					SetState(SSS_RANGEATTACK1);
				}
				break;
			case SSS_RANGEATTACK1:
				FaceTarget();
				if (self.AnimState().CycleCompleted())
				{
					if (!IsFacingTarget())
					{
						SetState(SSS_STAND);
					}
					else if (self.CanSee(self.GetTarget()))
					{
						SetAnimation(anim_aiRangeAttack1, ANF_ROOTMOTION, true);
					}
				}
				break;
			case SSS_DEAD:
				deathDelay += GAME_DELTA_TIME;
				if (deathDelay >= 1.0f)
				{
					self.SpawnFx("fx/generic_90.kfx", kVec3(0.0f, 0.0f, 350.0f));
					self.Remove();
					return;
				}
				break;
		}
    }
	//------------------------------------------------------------------------------------------------------------------------
	void OnActivate()
	{
		SetState(SSS_STAND);
	}
	//------------------------------------------------------------------------------------------------------------------------
    void OnRestore()
    {
		self.Remove();
    }
	//------------------------------------------------------------------------------------------------------------------------
    void OnDeath(kActor @killer, kDictMem @damageDef)
    {
		SetKills(GetKills() + 1);
		Game.CallDelayedMapScript(EnemyDeathScriptID, @self, 0);
		
		self.MarkPersistentBit(false);
		SetState(SSS_DEAD);
    }
	//------------------------------------------------------------------------------------------------------------------------
	void SetAnimation(const int animID, const int flags, const bool force = false)
	{
		if (self.AnimState().PlayingID() != animID || force)
		{
			self.AnimState().Blend(animID, 4.0f, 8.0f, flags);
		}
	}
	//------------------------------------------------------------------------------------------------------------------------
	void SetState(const int newState, const bool force = false)
	{
		if (state != newState || force)
		{
			//On Exit State
			switch(state)
			{
				case SSS_SLEEP:
					self.Flags() &= ~AF_INVINCIBLE;
					self.Flags() |= AF_SOLID;
					self.PlaySound("sounds/shaders/sstatue_wake.ksnd");
					break;
				case SSS_DEAD:
					self.Flags() |= AF_SOLID;
					break;
			}
			
			state = newState;
			
			//On Enter State
			switch(state)
			{
				case SSS_SLEEP:
					self.SetHeadTrackTarget(null);
					self.Flags() |= AF_INVINCIBLE;
					self.Flags() &= ~AF_SOLID;
					SetAnimation(anim_aiStanding, ANF_LOOP|ANF_ROOTMOTION);
					break;
				case SSS_STAND:
					self.SetHeadTrackTarget(self.GetTarget());
					SetAnimation(anim_aiStanding, ANF_LOOP|ANF_ROOTMOTION);
					break;
				case SSS_RANGEATTACK1:
					SetAnimation(anim_aiRangeAttack1, ANF_ROOTMOTION);
					break;
				case SSS_DEAD:
					self.SetHeadTrackTarget(null);
					self.Flags() &= ~AF_SOLID;
					self.AnimState().flags |= ANF_PAUSED;
					self.RunFxEvent("SStatue_Dead");
					self.PlaySound("sounds/shaders/sstatue_dead.ksnd");
					//self.SpawnFx("fx/deathrain.kfx", kVec3(0.0f, 0.0f, 350.0f));
					self.SpawnFx("fx/generic_158.kfx", kVec3(0.0f, 0.0f, 320.0f));
					//self.SpawnFx("fx/generic_166.kfx", kVec3(0.0f, 0.0f, 280.0f));
					//self.SpawnFx("fx/generic_187.kfx", kVec3(0.0f, 0.0f, 280.0f));
					self.SpawnFx("fx/generic_90.kfx", kVec3(0.0f, 0.0f, 350.0f));
					//deathrain
					//generic_158 //blue flash
					//generic_166 //blue explosion
					//generic_187 //blue explosion ring
					//generic_90 red sparks
					break;
			}
		}
	}
	//------------------------------------------------------------------------------------------------------------------------
	void FaceTarget()
	{
		TurnAngles(turnAngleSpeed, self.GetTurnYaw(Player.Actor().Origin()));
	}
	//------------------------------------------------------------------------------------------------------------------------
    void TurnAngles(const float turnSpeed, const float angles)
    {
        float temp = angles;
        float ang = angles;
        
        if(ang > turnSpeed)
        {
            ang = turnSpeed;
        }
        else if(ang < -turnSpeed)
        {
            ang = -turnSpeed;
        }
        
        ang *= GAME_FRAME_TIME;
        if (Math::Fabs(ang) > Math::Fabs(temp))
        {
            ang = temp;
        }
        
        self.Yaw() += ang;
    }
	//------------------------------------------------------------------------------------------------------------------------
    bool IsFacingTarget()
    {
		return (Math::Fabs(self.GetTurnYaw(Player.Actor().Origin())) < attackAngleRange);
    }
	//------------------------------------------------------------------------------------------------------------------------
}
