// #include "scripts/common.txt"

//Attacks
//* Flaming rocks that fly out from the center and go up in an arc and down towards the sides all around and fireborn spawn randomly from them
//* slam fists into ground and stags come up into ground where player was a few frames before
//* shockwave of fire rings come out from the ground and player needs to jump
//* fireballs go up from enemy and go straight at player (campaigner attack particles)

//spawn flame rocks and hide the boss he jumps down shortly after and is invincible
//regenerationstart.fkx when jumping back in

//fx188 steam coming up from ground
//watersteam

	//anim_aiRangeAttack10 - Shaman Powerup Speel Cast
	//anim_aiRangeAttack9 - Demon Attack (shoots fireball)
	//anim_aiRangeAttack7 - GunFire (Plasma guy fast crouch shot)
	//anim_aiRangeAttack6 - Tribal Dart1
	//anim_aiRangeAttack5 - GunFire (Plasma guy fast shot)
	//anim_aiRangeAttack4 - Heatseeking shaman spell cast
	//anim_aiRangeAttack3 - Grenade
	//anim_aiRangeAttack2 - GunFire
	//anim_aiRangeAttack1 - Shaman Spell Attack
	//anim_aiMelee2-5
	//anim_aiAltMelee1
	//anim_aiAltMelee2 - Double Swing
	//anim_aiAltMelee3 -  BackFist
	//anim_aiTeleportIn - Shaman Teleport up from ground
	//anim_aiTeleportOut - Shaman Begin Teleporting
	//hanging - anim_special_event01

	//fx 133 - bubble lightning shot
	//fx 244 - lots of blood
	//fx 247 - long hunter heat seeking boomrang
	//fx 254 - plant attack
	//fx 256 - slow demon fireball
	//fx 257 - fast demon fireball
	//fx 258 - fastest demon fireball

	//generic_242.kfx yellow particles go forward and bounce on floor
	//generic_224.kfx rock particles explode bounce on floor
	//generic_240.kfx yellow lightning
	//generic_90.kfx sparks
	//shockwave.kfx
				
enum FirebornBossState
{
	FBS_START = 0, //come up from the ground
    FBS_THINK, //think of what to do next
    FBS_FLAME_ROCKS, //launch flaming rocks in all directions
	FBS_FIST_SLAM, //slam fists into ground and stags come up into ground where player is going to be
	FBS_SHOCKWAVE, //shockwave of fire rings come out from the ground and player needs to jump
	FBS_DIRECTBOLTS, //fireballs go up from enemy and go straight at player (campaigner attack particles)
	FBS_JUMPAWAY, //spawn firerocks and jump away and return shortly after with shockwave
    FBS_DEAD,
    
    NUM_FIREBORN_BOSS_STATES
}

const array<int> FB_STAG_ANIMS = {anim_aiMelee2, anim_aiMelee3, anim_aiMelee5, anim_aiAltMelee1, anim_aiAltMelee3};
const float FB_SHOCKWAVE_TIME = 2.0f;

final class BP_FirebornBoss : ScriptObject
{
	kActor @self;
	int startHealth;
	int state;
	int prevState;
	float stateTime;
	float lastStateTime;
	float lookAtYaw;
	float healthPercent;
	kVec3 startOrigin;
	bool playerGrounded;
	float playerYaw;
	kVec3 playerOrigin;
	kVec3 playerVel;
	kVec3 dirToPlayer;
	float distToPlayer;
	float stagTime;
	int stage;
	kActor@ centerPoint; //rock spawn point, and other
	array<kActor@> shockwavePoints; //shockwave spawn points
	float shockwaveTime;
	bool shockwaveActive;
	kActor@ boltSpawnPoint; //direct bolts attack
	array<kActor@> rollingRocks;
	kSelectionListInt actionList;
	//------------------------------------------------------------------------------------------------------------------------
    BP_FirebornBoss(kActor @actor)
    {
		@self = @actor;
		self.Flags() |= AF_ALWAYSACTIVE;
		startHealth = 1;
		state = FBS_START;
		stateTime = 0.0f;
		lastStateTime = -1.0f;
		lookAtYaw = 0.0f;
		healthPercent = 0.0f;
		distToPlayer = 0.0f;
		stagTime = 0.0f;
		shockwaveActive = false;
		shockwaveTime = 0.0f;
		SetStage(0);
    }
	//------------------------------------------------------------------------------------------------------------------------
	void OnSpawn()
    {
		
    }
	//------------------------------------------------------------------------------------------------------------------------
	// Animation Callbacks
	//------------------------------------------------------------------------------------------------------------------------
	void TriggerEvent(kActor @instigator, const float w, const float x, const float y, const float z)
    {
    }
	//------------------------------------------------------------------------------------------------------------------------
    void MeleeAttack1(kActor @instigator, const float w, const float x, const float y, const float z)
    {
    }
	//------------------------------------------------------------------------------------------------------------------------
    void MeleeAttack2(kActor @instigator, const float w, const float x, const float y, const float z)
    {
    }
	//------------------------------------------------------------------------------------------------------------------------
    void MeleeAttack3(kActor @instigator, const float w, const float x, const float y, const float z)
    {
    }
	//------------------------------------------------------------------------------------------------------------------------
    void SwooshTrail1(kActor @instigator, const float w, const float x, const float y, const float z)
    {
	}
	//------------------------------------------------------------------------------------------------------------------------
    void HighPriestSpellAttack(kActor @instigator, const float w, const float x, const float y, const float z)
    {
    }
	//------------------------------------------------------------------------------------------------------------------------
    void DemonAttack(kActor @instigator, const float w, const float x, const float y, const float z)
    {
    }
	//------------------------------------------------------------------------------------------------------------------------
    void DropItem(kActor @instigator, const float w, const float x, const float y, const float z)
    {
	}
	//------------------------------------------------------------------------------------------------------------------------
    void InjurySound(kActor @instigator, const float w, const float x, const float y, const float z)
    {
    }
	//------------------------------------------------------------------------------------------------------------------------
	void FootStepPuff(kActor @instigator, const float a, const float x, const float y, const float z)
    {
	}
	//------------------------------------------------------------------------------------------------------------------------
    bool IsPlayerLocked()
    {
        return (Player.Actor().Health() > 0 && Player.Locked());
    }
	//------------------------------------------------------------------------------------------------------------------------
	void SetState(const int newState)
	{
		OnStateExit(newState);
		lastStateTime = -1.0f;
		stateTime = 0.0f;
		prevState = state;
		state = newState;
		OnStateEnter();
	}
	//------------------------------------------------------------------------------------------------------------------------
	bool StateTimeReached(const float time)
	{
		return lastStateTime < time && stateTime >= time;
	}
	//------------------------------------------------------------------------------------------------------------------------
	void OnStateEnter()
	{
		switch (state)
		{
			case FBS_START:
			{
				self.Flags() |= AF_INVINCIBLE;
				break;
			}
			case FBS_THINK:
			{
				//if I don't do this check then his height changes
				if (!self.AnimState().IsPlaying(anim_aiStanding))
				{
					self.AnimState().Blend(anim_aiStanding, 4.0f, 8.0f, ANF_LOOP|ANF_BLEND);
				}
				break;
			}
			case FBS_FLAME_ROCKS:
			{
				self.AnimState().Blend(anim_event04, 4.0f, 8.0f, ANF_LOOP|ANF_BLEND); //hands in air
				break;
			}
			case FBS_FIST_SLAM:
			{
				stagTime = 0.0f;
				break;
			}
			case FBS_SHOCKWAVE:
			{
				shockwaveActive = false;
				self.AnimState().Blend(anim_aiRangeAttack9, 4.0f, 8.0f, ANF_LOOP|ANF_BLEND);
				break;
			}
			case FBS_DIRECTBOLTS:
			{
				self.AnimState().Blend(anim_aiRangeAttack1, 8.0f, 8.0f, ANF_LOOP|ANF_BLEND);
				break;
			}
			case FBS_JUMPAWAY:
			{
				self.AnimState().Blend(anim_aiTeleportOut, 4.0f, 8.0f, ANF_BLEND);
				self.RunFxEvent("FBBoss_Hide");
				self.Flags() |= AF_INVINCIBLE;
				break;
			}
		}
		//anim 24 shaman fire wand attack (anim_aiRangeAttack1)
		//anim 121 through grenade
		//anim 150 shockwave (anim_aiRangeAttack9)
		//anim_aiTeleportIn (2550) raises up from ground
		//anim_aiTeleportOut (2551) magic hand to ground
	}
	//------------------------------------------------------------------------------------------------------------------------
	void OnStateTick()
	{
		int lastState = state;
		switch (state)
		{
			case FBS_START:
			{
				if (StateTimeReached(0.0f))
				{
					self.AnimState().Blend(anim_aiTeleportIn, 16.0f, 8.0f, ANF_BLEND);
				}
				if (StateTimeReached(6.0f))
				{
					self.AnimState().Blend(anim_aiStanding, 4.0f, 8.0f, ANF_LOOP|ANF_BLEND);
				}
				if (StateTimeReached(7.0f))
				{
					SetState(FBS_THINK);
				}
				break;
			}
			case FBS_THINK:
			{
				int nextState = actionList.Select();
				if (nextState == FBS_JUMPAWAY && prevState == FBS_JUMPAWAY)
				{
					//rethink
				}
				else
				{
					SetState(nextState);
				}
				break;
			}
			case FBS_FLAME_ROCKS:
			{
				if (StateTimeReached(0.5f))
				{
					SpawnFireRocks();
				}
				if (StateTimeReached(1.5f))
				{
					self.AnimState().Blend(anim_aiStanding, 4.0f, 8.0f, ANF_LOOP|ANF_BLEND); //stand idle
				}
				if (StateTimeReached(2.0f))
				{
					SetState(FBS_THINK);
				}

				break;
			}
			case FBS_FIST_SLAM:
			{
				if (stagTime >= 5.0f)
				{
					if (!self.AnimState().IsPlaying(anim_aiStanding))
					{
						self.AnimState().Blend(anim_aiStanding, 4.0f, 8.0f, ANF_LOOP|ANF_BLEND); //stand idle
					}
					else if (self.AnimState().CycleCompleted())
					{
						SetState(FBS_THINK);
					}
				}
				else
				{
					if (self.AnimState().CycleCompleted())
					{
						int animID = ArrayRandomElement(FB_STAG_ANIMS);
						self.AnimState().Blend(animID, 4.0f, 8.0f, ANF_LOOP|ANF_BLEND);
						SpawnStags();
					}
				}
				stagTime += GAME_DELTA_TIME;
				break;
			}
			case FBS_SHOCKWAVE:
			{
				if (StateTimeReached(1.0f))
				{
					StartShockwave();
				}
				if (StateTimeReached(2.0f))
				{
					self.AnimState().Blend(anim_aiStanding, 4.0f, 8.0f, ANF_LOOP|ANF_BLEND); //stand idle
				}
				if (StateTimeReached(2.5f))
				{
					SetState(FBS_THINK);
				}
				
				
				break;
			}
			case FBS_DIRECTBOLTS:
			{
				boltSpawnPoint.Yaw() = dirToPlayer.ToYaw();
				boltSpawnPoint.SetTarget(self.GetTarget());
				for (int i = 0; i < 7; i++)
				{
					if (StateTimeReached(0.0f + (0.2f * i)))
					{
						Game.PlaySound("sounds/shaders/generic_125_spell_swoosh.ksnd");
						boltSpawnPoint.SpawnFx("fx/generic_8" + i + ".kfx", Math::vecZero);
					}
				}
				
				if (StateTimeReached(1.5f))
				{
					boltSpawnPoint.SpawnFx("fx/generic_222.kfx", kVec3(0.0f, 0.0f, 200.0f));
				}
				
				if (StateTimeReached(1.8f))
				{
					Game.PlaySound("sounds/shaders/generic_126_spell_cast_2.ksnd");
				}
				
				if (StateTimeReached(3.0f))
				{
					SetState(FBS_THINK);
				}
				break;
			}
			case FBS_JUMPAWAY:
			{
				if (StateTimeReached(0.0f))
				{
					boltSpawnPoint.Yaw() = dirToPlayer.ToYaw();
					boltSpawnPoint.SetTarget(self.GetTarget());
					Game.PlaySound("sounds/shaders/generic_125_spell_swoosh.ksnd");
					for (int i = 0; i < 7; i++)
					{
						boltSpawnPoint.SpawnFx("fx/generic_8" + i + ".kfx", Math::vecZero);
					}
				}
				
				if (StateTimeReached(2.0f))
				{
					Game.PlaySound("sounds/shaders/generic_126_spell_cast_2.ksnd");
					self.Flags() |= AF_NODRAW;
					self.Flags() &= ~AF_SOLID;
					SpawnFireRocks();
				}
				
				if (StateTimeReached(5.0f))
				{
					self.SpawnFx("fx/regeneration_start.kfx", Math::vecZero);
					self.RunFxEvent("FBBoss_JumpIn");
					self.AnimState().Set(anim_campaingerRage, 4.0f, ANF_BLEND); //jump in
					self.Flags() &= ~AF_NODRAW;
					self.Flags() |= AF_SOLID;
				}
				
				if (StateTimeReached(6.5f))
				{
					SpawnStags();
					StartShockwave();
				}
				
				if (StateTimeReached(7.0f))
				{
					SetState(FBS_THINK);
				}
				break;
			}
		}
		
		if (shockwaveActive)
		{
			shockwaveTime += GAME_DELTA_TIME;
			float outterRadius = Math::Lerp(0.0f, 5000.0f, shockwaveTime / FB_SHOCKWAVE_TIME);
			float innerRadius = Math::Lerp(0.0f, 3700.0f, shockwaveTime / FB_SHOCKWAVE_TIME);
			if (IsInRadius2(playerOrigin, centerPoint.Origin(), outterRadius, innerRadius) && playerGrounded)
			{
				kActor@ pActor = Player.Actor().CastToActor();
				pActor.InflictGenericDamage(self, 15);
				Player.Actor().PlayerFlags() |= PF_NOAIRFRICTION;
				kVec3 v = (pActor.Origin() - centerPoint.Origin()).Normalize() * 10.0f;
				v.z = 7.0f;
				pActor.Velocity() = v;
			}
		}

		if (lastState == state)
		{
			lastStateTime = stateTime;
			stateTime += GAME_DELTA_TIME;
		}
	}
	//------------------------------------------------------------------------------------------------------------------------
	void OnStateExit(const int nextState)
	{
		switch (state)
		{
			case FBS_START:
			{
				self.Flags() &= ~AF_INVINCIBLE;
				break;
			}
			case FBS_SHOCKWAVE:
			{
				shockwaveActive = false;
				break;
			}
			case FBS_JUMPAWAY:
			{
				shockwaveActive = false;
				self.Flags() &= ~AF_INVINCIBLE;
				break;
			}
		}
	}
	//------------------------------------------------------------------------------------------------------------------------
	void SpawnStags()
	{
		kVec3 playerTargetDir = (playerVel * 60.0f); //in 1.0s time
		playerTargetDir.z = 0.0f;
		kVec3 targetPos = playerOrigin + playerTargetDir;

		for (int i = 0; i < 8; i++)
		{
			//spawn a stag up from the ground near player
			float stagSpawnDist = Math::RandRange(0.0f, 640.0f);
			float stagSpawnYaw = Math::Deg2Rad(Math::RandRange(0.0f, 360.0f));
			kVec3 p = targetPos;
			p.x += Math::Sin(stagSpawnYaw) * stagSpawnDist;
			p.y += Math::Cos(stagSpawnYaw) * stagSpawnDist;
			p.z = self.FloorHeight();
			int si = self.GetSectorIndexAtLocation(p);
			ActorFactory.Spawn("FireStag", p.x, p.y, p.z, 0.0f, si);
		}
	}
	//------------------------------------------------------------------------------------------------------------------------
	void StartShockwave()
	{
		shockwaveTime = 0.0f;
		shockwaveActive = true;
		for (int i = 0; i < int(shockwavePoints.length()); i++)
		{
			Game.SpawnFx("fx/fbboss_shockwave.kfx", shockwavePoints[i].Origin(), shockwavePoints[i].SectorIndex());
		}
		Game.PlaySound("sounds/shaders/generic_157.ksnd");
	}
	//------------------------------------------------------------------------------------------------------------------------
	void SpawnFireRocks()
	{
		float yawOffset = Math::RandRange(0.0f, 360.0f);
		for (int i = 0; i < 24; i++)
		{
			kActor@ rock = ActorFactory.Spawn("Firerock", centerPoint.Origin().x, centerPoint.Origin().y, centerPoint.Origin().z, 0.0f, centerPoint.SectorIndex());
			float yaw = Math::Deg2Rad(i * (360.0f / 24.0f) + yawOffset);
			rock.Yaw() = yaw;
			kVec3 v;
			float vx = Math::RandRange(7.0f, 20.0f);
			float vy = Math::RandRange(7.0f, 20.0f);
			v.x = Math::Sin(yaw) * vx;
			v.y = Math::Cos(yaw) * vy;
			v.z = Math::RandRange(20.0f, 30.0f);
			rock.Velocity() = v;
		}
	}
	//------------------------------------------------------------------------------------------------------------------------
    void OnTick()
    {
		if (IsActorDead(self) || Camera.Active() || IsPlayerLocked())
		{
			return;
		}
		
        playerOrigin = Player.Actor().Origin();
		playerVel = Player.Actor().Movement();
		playerGrounded = Player.Actor().OnGround();
		playerYaw = Player.Actor().Yaw();
        dirToPlayer = (playerOrigin - self.Origin()).Normalize();
		distToPlayer = self.Origin().Distance(playerOrigin);
        lookAtYaw = self.GetTurnYaw(playerOrigin);
		healthPercent = float(self.Health() * 100) / startHealth;
		self.Yaw() = dirToPlayer.ToYaw();
		OnStateTick();
		
		// //yellow lightning
		// if (self.GameTicks() % 240 == 0)
		// {
			// Game.PlaySound("sounds/shaders/lightning_strike_" + (Math::RandMax(3) + 1) + ".ksnd");
			// Game.SpawnFx("fx/generic_240.kfx", kVec3(self.Origin().x, self.Origin().y, self.Origin().z + self.Height()), centerPoint.SectorIndex());
		// }
		
		
		
		
		// if (rock is null)
		// {
			// TossRock();
		// }
		// else
		// {
			// if (self.GameTicks() % 4 == 0)
			// {
				// rock.SpawnFx("fx/generic_51.kfx", kVec3(0.0f, 0.0f, 0.0f));
				// rock.SpawnFx("fx/generic_147.kfx", kVec3(0.0f, 0.0f, 0.0f));
				// //generic_242.kfx yellow particles go forward and bounce on floor
				// //generic_224.kfx rock particles explode bounce on floor
				// //generic_240.kfx yellow lightning
				// //generic_90.kfx sparks
				// //shockwave.kfx
			// }
		// }
    }
	//------------------------------------------------------------------------------------------------------------------------
    void OnBeginLevel()
    {
		PlayLoop.TagActorForBossBar(self);
		
		@centerPoint = World.GetActorByTID(1000);
		for (int i = 0; i < 8; i++)
		{
			shockwavePoints.insertLast(World.GetActorByTID(1002 + i));
		}
		@boltSpawnPoint = World.GetActorByTID(1010);
		
		for (int i = 0; i < 2; i++)
		{
			rollingRocks.insertLast(World.GetActorByTID(1012 + i));
		}
		
		startOrigin = self.Origin();
        startHealth = self.Health();
		
        self.SetTarget(Player.Actor().CastToActor());
        self.AnimState().Set(anim_aiStanding, 4.0f, ANF_ROOTMOTION | ANF_LOOP);
        //self.AnimState().Set(anim_aiRangeAttack10, 4.0f, ANF_ROOTMOTION | ANF_LOOP);
		
		//self.ImpactType() = IT_FLESH_HUMAN;
		self.ImpactType() = IT_FLESH_UNDEAD;
		//self.SetHeadTrackTarget(Player.Actor().CastToActor());
		
		kRenderModel @model = self.RenderModel();
		// chest
		model.SetTexture(0, 9);
		model.SetTexture(9, 9);
		
		// legs
		model.SetTexture(1, 5);
		model.SetTexture(3, 5);
		model.SetTexture(4, 5);
		model.SetTexture(5, 5);
		model.SetTexture(7, 5);
		model.SetTexture(8, 5);
		
		// shin
		model.SetTexture(2, 5);
		model.SetTexture(6, 5);
		
		// arms
		model.SetTexture(10, 9);
		model.SetTexture(11, 9);
		model.SetTexture(12, 9);
		model.SetTexture(13, 9);
		model.SetTexture(14, 9);
		model.SetTexture(15, 9);
		model.SetTexture(16, 9);
		model.SetTexture(17, 9); //hands
		
		model.SetTexture(18, 7); // neck
		model.SetTexture(19, 1); // face
		
		SetState(FBS_START);
		
		GetGlobalState();
    }
	//------------------------------------------------------------------------------------------------------------------------
    void OnDamage(kActor @instigator, kDictMem @damageDef, const int damage)
    {
        if (self.Health() <= 0 || damage <= 0)
        {
            return;
        }
		
		self.RunFxEvent("HitFlash");
		
		bool bValue;
		if(damageDef.GetBool("bBossExplosion", bValue) && bValue == true)
		{
			Game.SpawnFx("fx/generic_213.kfx", kVec3(self.Origin().x, self.Origin().y, self.Origin().z + (self.Height() * 0.75f)), self.SectorIndex());
		}
		
		HealthCheck(self.Health() - damage);
    }
	//------------------------------------------------------------------------------------------------------------------------
    void OnDeath(kActor @killer, kDictMem @damageDef)
    {
		SetKills(GetKills() + 1);
		Game.CallDelayedMapScript(EnemyDeathScriptID, @self, 0);
		
        self.SetTarget(null);
        self.SetHeadTrackTarget(null);
        
        state = FBS_DEAD;
		
		SpawnFireRocks();
		
		self.AnimState().Set(anim_aiDeathStand, 24.0f, 0);
		self.Flags() &= ~AF_SOLID;
		self.Flags() |= AF_DEAD;
		self.MarkPersistentBit(false);
		SetGlobalState();
    }
	//------------------------------------------------------------------------------------------------------------------------
	void HealthCheck(int health)
	{
		int newStage = 0;
		if (health > int(float(startHealth) * 0.75f))
		{
			newStage = 0;
		}
		else if (health > int(float(startHealth) * 0.5f))
		{
			newStage = 1;
		}
		else if (health > int(float(startHealth) * 0.25f))
		{
			newStage = 2;
		}
		else if (health > 0.0f)
		{
			newStage = 3;
		}
		else
		{
			newStage = 4;
		}
		
		if (newStage != stage)
		{
			SetStage(newStage);
		}
	}
	//------------------------------------------------------------------------------------------------------------------------
	void SetStage(int newStage)
	{
		stage = newStage;
		switch (stage)
		{
			case 0:
			{
				actionList.Reset();
				actionList.AddItem(FBS_FLAME_ROCKS, 90);
				actionList.AddItem(FBS_FIST_SLAM, 100);
				actionList.AddItem(FBS_SHOCKWAVE, 80);
				actionList.AddItem(FBS_DIRECTBOLTS, 80);
				break;
			}
			case 1:
			{
				actionList.Reset();
				actionList.AddItem(FBS_FLAME_ROCKS, 100);
				actionList.AddItem(FBS_FIST_SLAM, 100);
				actionList.AddItem(FBS_SHOCKWAVE, 70);
				actionList.AddItem(FBS_DIRECTBOLTS, 60);
				break;
			}
			case 2:
			{
				actionList.Reset();
				actionList.AddItem(FBS_FLAME_ROCKS, 100);
				actionList.AddItem(FBS_FIST_SLAM, 100);
				actionList.AddItem(FBS_SHOCKWAVE, 70);
				actionList.AddItem(FBS_DIRECTBOLTS, 60);
				actionList.AddItem(FBS_JUMPAWAY, 90);
				break;
			}
			case 3:
			{
				actionList.Reset();
				actionList.AddItem(FBS_FLAME_ROCKS, 100);
				actionList.AddItem(FBS_FIST_SLAM, 100);
				actionList.AddItem(FBS_SHOCKWAVE, 70);
				actionList.AddItem(FBS_JUMPAWAY, 80);
				for (int i = 0; i < int(rollingRocks.length()); i++)
				{
					rollingRocks[i].Flags() &= ~AF_NODRAW;
				}
				break;
			}
			case 4:
			{
				for (int i = 0; i < int(rollingRocks.length()); i++)
				{
					rollingRocks[i].Flags() |= AF_NODRAW;
				}
			}
		}
	}
	//------------------------------------------------------------------------------------------------------------------------
	void OnRestore()
	{
		PlayLoop.RemoveBossActor();
		self.Remove();
	}
	//------------------------------------------------------------------------------------------------------------------------
    void OnEndLevel()
    {
		SetGlobalState();
    }
	//------------------------------------------------------------------------------------------------------------------------
	void SetGlobalState()
	{
		if (Game.GetCurrentMapID() == 112)
		{
			SetFBBossStarted(true);
			SetFBBossHealth(self.Health());
		}
	}
	//------------------------------------------------------------------------------------------------------------------------
	void GetGlobalState()
	{
		bool gStarted = GetFBBossStarted();
		if (gStarted)
		{
			SetState(FBS_THINK);
			self.Health() = GetFBBossHealth();
		}
		
		HealthCheck(self.Health());
	}
	//------------------------------------------------------------------------------------------------------------------------
	void OnActivate()
	{
		self.Flags() &= ~AF_ACTIVATED;
		
		int msg = int(self.StepHeight());
		if (msg == 0) //spawn flame rocks
		{
			SpawnFireRocks();
		}
		else if (msg == 1) //set state to think
		{
			SetState(FBS_THINK);
		}
	}
	//------------------------------------------------------------------------------------------------------------------------
}
