class BabelBaronOfHell : SyncEnabledMonster Replaces BaronOfHell
{
	int user_loopCounter;
	bool leftHandAttack;
	bool canClap;
	default
	{
		Health 1000;
		Radius 24;
		Height 64;
		Mass 1000;
		Speed 8;
		PainChance 24;
		Monster;
		+FLOORCLIP;
		+BOSSDEATH;
		SeeSound "baron/sight";
		PainSound "baron/pain";
		DeathSound "baron/death";
		ActiveSound "baron/active";
		Obituary "$OB_BARON";
		HitObituary "$OB_BARONHIT";
		+MISSILEMORE;
		BloodColor "green";
		Species "Baron";
		ReactionTime 4;
		PainChance "PlayerPistol", 75;
		DamageType "Monster";
		Tag "Baron of Hell (Babel)";

		BabelMonster.FearEnabled		false; //Not sure why I disabled this but I'm keeping it this way for now
		BabelMonster.FearThreshold		1000.0;
		BabelMonster.FearMaxValue		1200.0;
		BabelMonster.FearFallOff		3.0;
		BabelMonster.FearRecovery		8.0;
		BabelMonster.FearResistChance	50.0;
		BabelMonster.SyncChainCheckLOS	true;
	}

	override void BeginPlay()
	{
		super.BeginPlay();
		leftHandAttack = false;
		canClap = false;
	}

	action void A_BaronSpread()
	{
		if(!invoker.CheckMeleeRange())
		{
			let mid = invoker.A_SpawnProjectile("ParticleBaronBall", 32, 0, 0);
			if(mid)
			{
				let left = SideParticleBaronBall(invoker.A_SpawnProjectile("SideParticleBaronBall", 32, 0, -5));
				let right = SideParticleBaronBall(invoker.A_SpawnProjectile("SideParticleBaronBall", 32, 0, 5));
				left.midVelocity = mid.vel;
				left.midAngle = mid.angle;
				right.midVelocity = mid.vel;
				right.midAngle = mid.angle;
			}
		}
		else
		{
			invoker.A_CustomComboAttack("ParticleBaronBall", 32, 20 * random(1, 8), "baron/melee", "Monster");
		}
	}

	action void A_BaronSwipe(int offsetSpeed)
	{
		if(!invoker.CheckMeleeRange())
		{
			let mid = invoker.A_SpawnProjectile("ParticleBaronBall", 32, 0, 0);
			if(mid)
			{
				let side = SideParticleBaronBall(invoker.A_SpawnProjectile("SideParticleBaronBall", 32, 0, offsetSpeed));
				side.midVelocity = mid.vel;
				side.framesBeforeVelAdjust = 12;
				side.midAngle = mid.angle;
				let side2 = SideParticleBaronBall(invoker.A_SpawnProjectile("SideParticleBaronBall", 32, 0, 2 * offsetSpeed));
				side2.midVelocity = mid.vel;
				side2.framesBeforeVelAdjust = 12;
				side2.midAngle = mid.angle;
			}
		}
		else
		{
			invoker.A_CustomComboAttack("ParticleBaronBall", 32, 10 * random(1, 8), "baron/melee", "Monster");
		}
	}

	action state A_ContinueBaronAttack()
	{
		int choice = random(1, 5);
		if(choice <= 3)
		{
			return ResolveState(null);
		}
		else if(choice == 4)
		{
			if(invoker.leftHandAttack)
			{
				return ResolveState("LeftMissile");
			}
			else
			{
				return ResolveState("RightMissile");
			}
		}
		else
		{
			return ResolveState("ClapMissile");
		}
	}

	States
	{
	Spawn:
		TNT1 A 0 Nodelay
		{
			return ResolveState("Look");
		}
	Wander:
		BOSS AABBCCDD 3 Fast
		{
			A_Wander();
			A_Look();
		}
		Loop;
	Look:
		BOSS AB 10 A_Look();
		Loop;
	See:
		TNT1 A 0
		{
			ReleaseState();
			JumpIfAfraid("FearLoop");
		}
		BOSS AABBCCDD 3 Fast
		{
			bNOPAIN = false;
			A_Chase();
		}
		Goto See;
	Fear:
		//Barons getting scared can cause cascades for super fun times
		TNT1 A 0
		{
			ScareOthers("BabelMonster", random(175,262));
		}
	FearLoop:
		BOSS AABBCCDD 3 Fast
		{
			bFRIGHTENED = true;
			bNOPAIN = false;
			A_SetSpeed(10);
			isAfraid = true;
			A_Chase("Melee", null);
		}
		TNT1 A 0 JumpIfHasFear("FearLoop");
		TNT1 A 0
		{
			currentFear = 0; //clear the inventory just to be sure
			isAfraid = false;
			bFRIGHTENED = false;
			ResetGroupFear();
			A_SetSpeed(8);
		}
		Goto See;
	Melee:
	Missile:
		TNT1 A 0
		{
			//Baron attack enrages lower enemies
			TriggerSync(self.GetClassName(), 40.0);
			TriggerSync("BabelImp", 75.0);
			TriggerSync("BabelDemon", 55.0);
			TriggerSync("BabelLostSoul", 75.0);

		}
	MissileNoSignal:
		/*TNT1 A 0
		{
			bNOPAIN = true;
		}*/
		TNT1 A 0
		{
			State choice = ResolveState(null);
			if(canClap)
			{
				choice = A_JumpIfCloser(192, "ClapMissile");
			}
			if(choice == null)
			{
				//Normally I hate these for readability but it saves so much space.
				choice = leftHandAttack ? ResolveState("LeftMissile") : ResolveState("RightMissile");
			}
			return choice;
		}
	RightMissile:
		BOSS E 6 A_FaceTarget();
		BOSS F 6
		{
			A_FaceTarget();
			leftHandAttack = !leftHandAttack;
		}
		BOSS G 6
		{
			GroupFearReduction(200, "BabelMonster");
			A_BaronSwipe(-10);
			canClap = true;
		}
		TNT1 A 0 A_MonsterRefire(32, "See");
		TNT1 A 0 A_ContinueBaronAttack();//A_Jump(100, "LeftMissile", "ClapMissile");
		Goto See;
	LeftMissile:
		BOSS S 6 A_FaceTarget();
		BOSS T 6
		{
			A_FaceTarget();
			leftHandAttack = !leftHandAttack;
		}
		BOSS U 6
		{
			GroupFearReduction(200, "BabelMonster");
			A_BaronSwipe(10);
			canClap = true;
		}
		TNT1 A 0 A_MonsterRefire(32, "See");
		TNT1 A 0 A_ContinueBaronAttack();//A_Jump(100, "RightMissile", "ClapMissile");
		Goto See;
	ClapMissile:
		TNT1 A 0
		{
			bNOPAIN = true;
		}
		BOSS PQ 6 A_FaceTarget();
		BOSS R 6
		{
			GroupFearReduction(400, "BabelMonster");
			A_BaronSpread();
			canClap = false;
			/*A_SpawnProjectile("ParticleBaronBall", 32, 0, 5);
			A_SpawnProjectile("ParticleBaronBall", 32, 0, -5);
			A_CustomComboAttack("ParticleBaronBall", 32, 20 * random(1, 8), "baron/melee", "Monster");*/
		}

		Goto See;
	Pain:
		BOSS H 2 Fast;
		BOSS H 2 Fast A_BabelPain();
		TNT1 A 0
		{
			currentFear += random(0,120);
		}
		TNT1 A 0 JumpIfAfraid("FearLoop");
		TNT1 A 0 A_Jump(192, "PainOffAttack");
		Goto See;
	PainOffAttack:
		TNT1 A 0
		{
			bNOPAIN = true;
		}
		Goto Missile;
	Death.Massacre:
		BOSS I 8;
		BOSS J 8 A_Scream();
		BOSS K 8;
		BOSS L 8 A_NoBlocking;
		BOSS MN 8;
		BOSS O -1 A_BossDeath;
		Stop;
	Death:
		TNT1 A 0 A_Jump(192, "Death.Monster");
		TNT1 A 0
		{
			TriggerSync(self.GetClassName(), 40.0);
			TriggerSync("BabelImp", 70.0);
			TriggerSync("BabelZombieMan", 30.0);
			TriggerSync("BabelChaingunGuy", 40.0);
			TriggerSync("BabelShotgunGuy", 35.0);
			TriggerSync("BabelNazi", 75.0);
			TriggerSync("BabelHellKnight", 60.0);
			TriggerSync("BabelBaronOfHell", 25.0);
			TriggerDodge();
			TriggerChain("BabelRevenant", 25.0);
			TriggerChain("BabelFatso", 25.0);
		}
	Death.Monster:
		BOSS I 8
		{
			if(CVar.FindCVar("egr_gore").GetInt())
			{
				for(user_loopCounter = 0; user_loopCounter < 8; user_loopCounter++)
				{
					A_SpawnItemEx("GreenBloodSpew", random(-10, 10), random(-10, 10), random(48, 64));
				}
			}
		}
		BOSS J 8
		{
			A_Scream();
			if(CVar.FindCVar("egr_gore").GetInt())
			{
				for(user_loopCounter = 0; user_loopCounter < 3; user_loopCounter++)
				{
					A_SpawnItemEx("GreenBloodSpew", random(-10, 10), random(-10, 10), random(32, 56));
				}
			}
		}
		BOSS K 8
		{
			if(CVar.FindCVar("egr_gore").GetInt())
			{
				for(user_loopCounter = 0; user_loopCounter < 3; user_loopCounter++)
				{
					A_SpawnItemEx("GreenBloodSpew", random(-10, 10), random(-10, 10), random(24, 48));
				}
			}
		}
		BOSS L 8 A_NoBlocking;
		BOSS MN 8;
		BOSS O -1 A_BossDeath;
		Stop;
	Raise:
		BOSS O 8
		{
			A_SetSpeed(8);
		}
		BOSS NMLKJI 8;
		Goto See;
	}
}

class BaronBallFast : ParticleBaronBall
{
	default
	{
		Speed 20;
	}
}

class BaronBallSlow : ParticleBaronBall
{
	default
	{
		Speed 12;
	}
}

class ParticleBaronBall : BabelFastProjectile Replaces BaronBall
{
	default
	{
		Radius 6;
		Height 16;
		Speed 15;
		FastSpeed 20;
		Damage 9;
		Projectile;
		+STRIFEDAMAGE;
		+RANDOMIZE;
		RenderStyle "Add";
		Alpha 1;
		SeeSound "baron/attack";
		DeathSound "baron/shotx";
		decal "BaronScorch";
		DamageType "Monster";

		BabelFastProjectile.ParticleColors 0x00ff00, 0x33ff33, 0x22ff22;
		BabelFastProjectile.ParticleSizeRange 2, 4;
		BabelFastProjectile.ParticleLifeTime 25, 35;
		BabelFastProjectile.ParticleCubeOffsets 4, 4;
		BabelFastProjectile.ParticleCubeAccelerations 0.1, 0.1;
		BabelFastProjectile.LerpOffset 1.0;
		BabelFastProjectile.TrailDetail 1;
		BabelFastProjectile.HeightCorrection 1.0;
		BabelFastProjectile.StartingAlpha 0.7;
	}

	States
	{
	Spawn:
		BAL7 AB 4 Bright;
		Loop;
	Death:
		TNT1 A 0
		{
			trailSpawn = false;
		}
		BAL7 CDE 6 Bright;
		Stop;
	}
}

class SideParticleBaronBall : ParticleBaronBall
{
	default
	{
		Damage 9;
		Projectile;
		+STRIFEDAMAGE;
		+RANDOMIZE;
	}
	Vector3 midVelocity;
	double midAngle;
	int framesBeforeVelAdjust;
	bool adjusted;
	override void BeginPlay()
	{
		super.BeginPlay();
		framesBeforeVelAdjust = 25;
		adjusted = false; //optimization, probably
	}
	override void Tick()
	{
		if(!adjusted)
		{
			if(framesBeforeVelAdjust > 0)
			{
				framesBeforeVelAdjust--;
			}
			else
			{
				self.velStore = midVelocity; //adjust trails to match
				self.vel = midVelocity;
				self.angle = midAngle;
				adjusted = true;
			}
		}
		super.Tick();
	}
}