class BabelLostSoul : SyncEnabledMonster Replaces LostSoul
{
	bool hasRevived;
	//Since this doesn't derive from the base monster we have to re-define all its defaults
	default
	{
		Health 100;
		Radius 16;
		Height 56;
		Mass 50;
		Speed 8;
		Damage 3;
		PainChance 256;
		Monster;
		+FLOAT;
		+NOGRAVITY;
		+MISSILEMORE;
		+DONTFALL;
		+NOICEDEATH;
		AttackSound "skull/melee";
		PainSound "skull/pain";
		DeathSound "skull/death";
		ActiveSound "skull/active";
		Obituary "$OB_SKULL";
		+MISSILEEVENMORE;
		+NOBLOOD;
		ReactionTime 4;
		Alpha 0.75;
		RenderStyle "Translucent";
		Species "LostSoul";
		DamageType "Monster";
		Tag "Lost Soul (Babel)";
		
		BabelMonster.SyncChainCheckLOS	true;
		BabelMonster.SyncChainCheckLOF	true;
		BabelMonster.AlternatePainSound	"skull/pain2";
	}
	
	//Setup for the various Babel monster flags and variables
	//Note that the super call is before we do any setting, this is to get the defaults first then change them
	//If you reversed the order you'd end up reversing your changes
	override void BeginPlay()
	{
		super.BeginPlay();
		
		hasRevived = false;
	}
	
	States
	{
	Spawn:
		TNT1 A 0 Nodelay 
		{
			return ResolveState("Look");
		}
	Wander:
		SKUL AB 6 Fast 
		{
			A_Wander();
			A_Look();
		}
		Loop;
	Look:
		SKUL AB 10 Bright A_Look();
		Loop;
	See:
		TNT1 A 0 ReleaseState(); //Always always ALWAYS release your state lock when you start moving, or else you'll be unable to sync fire
		SKUL AB 6 Fast Bright A_Chase();
		Loop;
	MissileNoSignal:
	Missile:
		//What this does is check to see if we can see the player, then checks to see if anyone is in our line of fire
		TNT1 A 0 JumpIfCannotTarget("See");
		TNT1 A 0 HoldState();
		SKUL C 10 Bright A_FaceTarget();
	FlyLoop:
		SKUL D 4 Bright A_SkullAttack;
		SKUL CD 4 Bright;
		Goto FlyLoop+1;
	Pain:
		SKUL E 3 Bright;
		SKUL E 3 Bright A_BabelPain();
		Goto See;
	Death:
		SKUL F 6 Bright;
		SKUL G 6 Bright A_Scream();
		SKUL H 6 Bright;
		TNT1 A 0 //If we've already revived, don't do it again
		{
			if(hasRevived)
			{
				return ResolveState("noExtra");
			}
			return ResolveState(null);
		}
		TNT1 A 0 A_Jump(224, "noExtra"); //Roll a really low probability check
		TNT1 A 0 A_SpawnItemEx("RegenSoul", 0, 0, 0, 0, 0, 0, 0, SXF_NOCHECKPOSITION); //Force spawn the Lost Soul's special new ability, a Regen Soul
	noExtra:
		SKUL I 6 Bright A_NoBlocking;
		SKUL J 6;
		SKUL K 6;
		Stop;
	}
}

//This class is identical to the BabelLostSoul except it's not counted as a kill and doesn't need to face you to see you
class BabelResurrectedSoul : BabelLostSoul
{
	default
	{
		+LOOKALLAROUND;
		-COUNTKILL;
	}
}

class RegenSoul : Actor
{
	bool particles;
	double user_alpha;
	default
	{
		RenderStyle "Translucent";
		Health 1;
		Radius 16;
		Height 56;
		Mass 50;
		Speed 8;
		Monster;
		+FLOAT;
		+NOGRAVITY;
		+DONTFALL;
		+NOICEDEATH;
		+FRIGHTENED;
		Species "Ghost";
		-COUNTKILL; 
		+NOBLOOD; 
		+LOOKALLAROUND; 
		-shootable; 
		+VULNERABLE;
		-SOLID; 
		+THRUACTORS;
		Alpha 0.0;
		ActiveSound "skull/active";
		DamageType "Monster";
		Tag "Lost Soul Remnant (Babel)";
	}
	override void BeginPlay()
	{
		super.BeginPlay();
		particles = bool(CVar.FindCVar("egr_particle_toggle").GetInt());
	}
	States
	{
	Spawn:
		TNT1 A 0
		{
			user_alpha = 0.0; //Start fully translucent
		}
	Burn:
		SKUL AB 6 Bright
		{
			A_Wander();
			//This is older code I left in from v1, basically just spawns particles
			if(particles)
			{
				A_SpawnParticle ("red", SPF_FULLBRIGHT, random(20, 50), random(1,4), frandom(0,360), 16*cos(random(0,359)),16*sin(random(0,359)),frandom(4.0, 8.0), 0,0,frandom(1.0,2.0), frandom(-0.05, 0.05),frandom(-0.05, 0.05),0, 0.98, -1);
				A_SpawnParticle (0xff3300, SPF_FULLBRIGHT, random(20, 50), random(1,4), frandom(0,360), 16*cos(random(0,359)),16*sin(random(0,359)),frandom(4.0, 8.0), 0,0,frandom(1.0,2.0), frandom(-0.05, 0.05),frandom(-0.05, 0.05),0, 0.98, -1);
				A_SpawnParticle (0xe07000, SPF_FULLBRIGHT, random(20, 50), random(1,4), frandom(0,360), 16*cos(random(0,359)),16*sin(random(0,359)),frandom(4.0, 8.0), 0,0,frandom(1.0,2.0), frandom(-0.05, 0.05),frandom(-0.05, 0.05),0, 0.98, -1);
				A_SpawnParticle ("red", SPF_FULLBRIGHT, random(20, 50), random(1,4), frandom(0,360), 16*cos(random(0,359)),16*sin(random(0,359)),frandom(4.0, 8.0), 0,0,frandom(1.0,2.0), frandom(-0.05, 0.05),frandom(-0.05, 0.05),0, 0.98, -1);
				A_SpawnParticle (0xff3300, SPF_FULLBRIGHT, random(20, 50), random(1,4), frandom(0,360), 16*cos(random(0,359)),16*sin(random(0,359)),frandom(4.0, 8.0), 0,0,frandom(1.0,2.0), frandom(-0.05, 0.05),frandom(-0.05, 0.05),0, 0.98, -1);
				A_SpawnParticle (0xe07000, SPF_FULLBRIGHT, random(20, 50), random(1,4), frandom(0,360), 16*cos(random(0,359)),16*sin(random(0,359)),frandom(4.0, 8.0), 0,0,frandom(1.0,2.0), frandom(-0.05, 0.05),frandom(-0.05, 0.05),0, 0.98, -1);
				A_SpawnParticle ("red", SPF_FULLBRIGHT, random(20, 50), random(1,4), frandom(0,360), 16*cos(random(0,359)),16*sin(random(0,359)),frandom(4.0, 8.0), 0,0,frandom(1.0,2.0), frandom(-0.05, 0.05),frandom(-0.05, 0.05),0, 0.98, -1);
				A_SpawnParticle (0xff3300, SPF_FULLBRIGHT, random(20, 50), random(1,4), frandom(0,360), 16*cos(random(0,359)),16*sin(random(0,359)),frandom(4.0, 8.0), 0,0,frandom(1.0,2.0), frandom(-0.05, 0.05),frandom(-0.05, 0.05),0, 0.98, -1);
				A_SpawnParticle (0xe07000, SPF_FULLBRIGHT, random(20, 50), random(1,4), frandom(0,360), 16*cos(random(0,359)),16*sin(random(0,359)),frandom(4.0, 8.0), 0,0,frandom(1.0,2.0), frandom(-0.05, 0.05),frandom(-0.05, 0.05),0, 0.98, -1);
			}
		}
		"####" "#" 0 
		{
			//Increase our alpha, then check to see if we've regenerated
			//essentially we're using the alpha as a timer
			user_alpha = user_alpha + 0.03f;
			if(user_alpha > 0.75)
			{
				user_alpha = 0.75f;
			}
			A_SetRenderStyle(user_alpha, STYLE_Translucent);
		}
		"####" "#" 0 A_JumpIf(user_alpha >= 0.75, "Respawn");
		Loop;
	Respawn:
		//This state is neat, we try to respawn but if there's no open space we'll step around a bit more and try again. Eventually some space will have to open up and we'll respawn
		"####" "#" 0
		{
			bool spawned = false;
			Actor soul = null;
			[spawned, soul] = A_SpawnItemEx("BabelResurrectedSoul", 0, 0, 0, 0, 0, 0, 0);
			if(spawned)
			{
				BabelLostSoul(soul).hasRevived = true;
				return ResolveState("End");
			}
			else
			{
				return ResolveState("Burn");
			}
		}
	End:
		"####" "#" 0;
		Stop;
	Death: //Can be killed by rocket launchers
		SKUL F 6 Bright;
		SKUL G 6 Bright A_Scream();
		SKUL H 6 Bright;
		Stop;
	}
}