#include "scripts/common.txt"

const float FIRESTAG_RISE_TIME = 2.0f;
const float FIRESTAG_RISEWAIT_TIME = 6.0f;
const float FIRESTAG_LOWER_TIME = 2.0f;
const float FIRESTAG_HIT_TIME = 1.0f; //amount of time until can hit the player again

enum FireStagState
{
	MISC_FS_START = 0,
    MISC_FS_STARTDELAY,
    MISC_FS_RISE,
	MISC_FS_RISEWAIT,
	MISC_FS_LOWER
}

class BP_FireStag : ScriptObject
{
    kActor@ self;
	bool canHit;
	float delayTime;
	float riseHeight;
	float startHeight;
	int state;
	float stateTime;
	float hitTime;
	kActor@ shadow;
	//------------------------------------------------------------------------------------------------------------------------
    BP_FireStag(kActor @actor)
    {
        @self = actor;
		canHit = false;
		hitTime = 0.0f;
		self.Flags() |= AF_ALWAYSACTIVE;
		riseHeight = Math::RandRange(174.079987f, 491.519989f);
		self.Origin().z = self.FloorHeight() - 491.519989f;
		startHeight = self.Origin().z;
		delayTime = Math::RandRange(0.5f, 1.5f);
		self.Scale().x = Math::RandRange(1.0f, 2.0f);
		self.Scale().y = Math::RandRange(1.0f, 2.0f);
		self.Scale().z = 2.0f;
		self.Yaw() = Math::Deg2Rad(Math::RandRange(0.0f, 360.0f));
		self.RunFxEvent("FireRock");
		@shadow = ActorFactory.Spawn("FireStagShadow", self.Origin().x, self.Origin().y, self.FloorHeight() + 0.5f, 0.0f, self.SectorIndex());
		shadow.Pitch() = Math::Deg2Rad(90.0f);
		shadow.RunFxEvent("FireStagShadowGrow");
		SetState(MISC_FS_START);
    }
	//------------------------------------------------------------------------------------------------------------------------
    void OnSpawn()
	{
		
	}
	//------------------------------------------------------------------------------------------------------------------------
	void SetState(const int newState)
	{
		state = newState;
		stateTime = 0.0f;
	}
	//------------------------------------------------------------------------------------------------------------------------
    void OnTick(void)
    {
		stateTime += GAME_DELTA_TIME;
		switch (state)
		{
			case MISC_FS_START:
			{
				if (stateTime >= 0.1f)
				{
					shadow.Flags() &= ~AF_NODRAW;
					
					SetState(MISC_FS_STARTDELAY);
				}
				break;
			}
			case MISC_FS_STARTDELAY:
			{
				if (stateTime >= delayTime)
				{
					canHit = true;
					self.PlaySound("sounds/shaders/stoneboulder_thud.ksnd");
					SetState(MISC_FS_RISE);
				}
				break;
			}
			case MISC_FS_RISE:
			{
				self.Origin().z = startHeight + Math::SmoothStepBP(0.0f, riseHeight, stateTime / FIRESTAG_RISE_TIME);
				if (stateTime >= FIRESTAG_RISE_TIME)
				{
					SetState(MISC_FS_RISEWAIT);
				}
				break;
			}
			case MISC_FS_RISEWAIT:
			{
				if (stateTime >= FIRESTAG_RISEWAIT_TIME)
				{
					SetState(MISC_FS_LOWER);
				}
				break;
			}
			case MISC_FS_LOWER:
			{
				self.Origin().z = startHeight + Math::SmoothStepBP(riseHeight, 0.0f, stateTime / FIRESTAG_LOWER_TIME);
				if (stateTime >= FIRESTAG_LOWER_TIME)
				{
					shadow.Remove();
					self.Remove();
					return;
				}
				break;
			}
		}
		
		hitTime += GAME_DELTA_TIME;
		if (canHit && hitTime >= FIRESTAG_HIT_TIME && IsInBounds(Player.Actor().Origin(), self.Origin(), self.Radius(), self.Height()))
		{
			hitTime = 0.0f;
			kActor@ pActor = Player.Actor().CastToActor();
			pActor.InflictGenericDamage(self, 5);
			Player.Actor().PlayerFlags() |= PF_NOAIRFRICTION;
			kVec3 v = (pActor.Origin() - self.Origin()).Normalize() * 10.0f;
			v.z = 5.0f;
			pActor.Velocity() = v;
		}
    }
	//------------------------------------------------------------------------------------------------------------------------
};
