

class CacodemonA : Cacodemon
{
    override void Die(Actor source, Actor inflictor, int dmgflags, Name MeansOfDeath)
    {
        super.Die(source, inflictor, dmgflags, MeansOfDeath);
		
		A_NoBlocking(); // Shouldn't need this, but best to be sure.
		A_SpawnItemEx ("CacodemonB", 0, -80, 0, 0, -30, 0, 0.25); // Type, x/y/z offset, z/y/z velocity, angle
		A_SpawnItemEx ("CacodemonB", 0, 80, 0, 0, 30, 0, 0.75); // Type, x/y/z offset, z/y/z velocity, angle
	}

	Default
	{
		Health 200;
		Height 84;
		Mass 200;
		Radius 45;
		Scale 1.5;
		Speed 6;
		Tag "Large Cacodemon";
		+DONTHARMSPECIES
		-DONTTHRUST
	}
	
	States
	{
	Spawn:
		HEAD A 10 A_Look;
		Loop;
	See:
		HEAD A 3 A_Chase;
		Loop;
	Missile:
		HEAD B 5 A_FaceTarget;
		HEAD C 5 A_FaceTarget;
		HEAD D 5 BRIGHT A_HeadAttack;
		Goto See;
	Pain:
		HEAD E 3;
		HEAD E 3 A_Pain;
		HEAD F 6;
		Goto See;
	Death:
		HEAD G 8; 
		HEAD H 8 A_Scream;
		HEAD I 8;
		HEAD J 8;
		HEAD K 8 A_NoBlocking;
		HEAD L -1 A_SetFloorClip;
		Stop;
	Raise:
		HEAD L 8 A_UnSetFloorClip;
		HEAD KJIHG 8;
		Goto See;
	}
}

class CacodemonB : Cacodemon
{
    override void Die(Actor source, Actor inflictor, int dmgflags, Name MeansOfDeath)
    {
        super.Die(source, inflictor, dmgflags, MeansOfDeath);
		
		A_NoBlocking(); // Shouldn't need this, but best to be sure.
		A_SpawnItemEx ("CacodemonC", 0, -60, 0, 0, -30, 0, 0.25); // Type, x/y/z offset, z/y/z velocity, angle
		A_SpawnItemEx ("CacodemonC", 0, 60, 0, 0, 30, 0, 0.75); // Type, x/y/z offset, z/y/z velocity, angle
	}
	
	Default
	{
		Health 150;
		Mass 100;
		Speed 10;
		Radius 30;
		Tag "Medium Cacodemon";
		+DONTHARMSPECIES
		-DONTTHRUST
	}
	States
	{
	Spawn:
		HEAD A 10 A_Look;
		Loop;
	See:
		HEAD A 3 A_Chase;
		Loop;
	Missile:
		HEAD B 5 A_FaceTarget;
		HEAD C 5 A_FaceTarget;
		HEAD D 5 BRIGHT A_HeadAttack;
		Goto See;
	Pain:
		HEAD E 3;
		HEAD E 3 A_Pain;
		HEAD F 6;
		Goto See;
	Death:
		HEAD G 8;
		HEAD H 8 A_Scream;
		HEAD I 8;
		HEAD J 8;
		HEAD K 8 A_NoBlocking;
		HEAD L -1 A_SetFloorClip;
		Stop;
	Raise:
		HEAD L 8 A_UnSetFloorClip;
		HEAD KJIHG 8;
		Goto See;
	}
}

class CacodemonC : Cacodemon
{
	Default
	{
		Health 50;
		Height 28;
		Mass 50;
		Speed 12;
		Radius 15;
		Scale 0.5;
		Tag "Small Cacodemon";
		+DONTHARMSPECIES
		-DONTTHRUST
	}
	States
	{
	Spawn:
		HEAD A 10 A_Look;
		Loop;
	See:
		HEAD A 3 A_Chase;
		Loop;
	Missile:
		HEAD B 3 A_FaceTarget;
		HEAD C 3 A_FaceTarget;
		HEAD D 3 A_HeadAttack2;
		Goto See;
	Pain:
		HEAD E 3;
		HEAD E 3 A_Pain;
		HEAD F 6;
		Goto See;
	Death:
		HEAD G 8;
		HEAD H 8 A_Scream;
		HEAD I 8;
		HEAD J 8;
		HEAD K 8 A_NoBlocking;
		HEAD L -1 A_SetFloorClip;
		Stop;
	Raise:
		HEAD L 8 A_UnSetFloorClip;
		HEAD KJIHG 8;
		Goto See;
	}
	void A_HeadAttack2() // No missile attacks for these!
	{
		let targ = target;
		if (targ && CheckMeleeRange())
		{
			int damage = random[pr_headattack](1, 6) * 10;
			A_StartSound (AttackSound, CHAN_WEAPON);
			int newdam = target.DamageMobj (self, self, damage, "Melee");
			targ.TraceBleed (newdam > 0 ? newdam : damage, self);
		}
	}
}

class CacodemonD : Cacodemon
{
	Default
	{
		Health 500;
		Height 150;
		Mass 500;
		Speed 5;
		Radius 80;
		Scale 2.5;
		Tag "Spawner Cacodemon";
		+DONTHARMSPECIES
	}
	States
	{
	Spawn:
		HEAD A 10 A_Look;
		Loop;
	See:
		HEAD A 3 A_Chase;
		Loop;
	Missile:
		HEAD B 5 A_FaceTarget;
		HEAD C 5 A_FaceTarget;
		// TNT1 A 0 A_Jump(128,"See"); // Only fires half the time.
		HEAD D 5 BRIGHT A_HeadSpawner;
		Goto See;
	Pain:
		HEAD E 3;
		HEAD E 3 A_Pain;
		HEAD F 6;
		Goto See;
	Death:
		HEAD G 8;
		HEAD H 8 A_Scream;
		HEAD I 8;
		HEAD J 8;
		HEAD K 8 A_NoBlocking;
		HEAD L -1 A_SetFloorClip;
		Stop;
	Raise:
		HEAD L 8 A_UnSetFloorClip;
		HEAD KJIHG 8;
		Goto See;
	}
	
	void A_HeadSpawner() // Doesn't fire missiles - spawns cacos instead.
	{
		A_SpawnItemEx ("CacodemonB", 120, 0, 0, 20, 0, 0, 0, SXF_NOCHECKPOSITION); 
		// Type, x/y/z offset, x/y/z velocity, angle, flags.
		// If I don't include this flag, the spawn fails if it thinks there's not enough room.
	}
}

class CacodemonE : Cacodemon
{
    override void Die(Actor source, Actor inflictor, int dmgflags, Name MeansOfDeath)
    {
        super.Die(source, inflictor, dmgflags, MeansOfDeath);
		A_Explode(128, 300, XF_NOTMISSILE); // Damages nearby monsters and players.

		A_NoBlocking(); // Shouldn't need this, but best to be sure.
		A_SpawnItemEx ("CacodemonC", -60, 60, 0, -21, 21, frandom(0,5), 0.125); // Type, x/y/z offset, z/y/z velocity, angle
		A_SpawnItemEx ("CacodemonC", -80, 0, 0, -30, 0, frandom(0,5), 0.25); // Type, x/y/z offset, z/y/z velocity, angle
		A_SpawnItemEx ("CacodemonC", -60, -60, 0, -21, -21, frandom(0,5), 0.325); // Type, x/y/z offset, z/y/z velocity, angle
		
		A_SpawnItemEx ("CacodemonC", 60, -60, 0, 21, -21, frandom(0,5), 0.625); // Type, x/y/z offset, z/y/z velocity, angle
		A_SpawnItemEx ("CacodemonC", 80, 0, 0, 30, 0, frandom(0,5), 0.75); // Type, x/y/z offset, z/y/z velocity, angle
		A_SpawnItemEx ("CacodemonC", 60, 60, 0, 21, 21, frandom(0,5), 0.875); // Type, x/y/z offset, z/y/z velocity, angle
	}

	Default
	{
		Health 200;
		Height 84;
		Mass 200;
		Radius 45;
		Scale 1.5;
		Speed 6;
		Tag "Unstable Cacodemon";
		+DONTHARMSPECIES
		-DONTTHRUST
		+VISIBILITYPULSE
		RenderStyle "Translucent";
	}
	
	States
	{
	Spawn:
		HEAD A 10 A_Look;
		Loop;
	See:
		HEAD A 3 A_Chase;
		Loop;
	Missile:
		HEAD B 5 A_FaceTarget;
		HEAD C 5 A_FaceTarget;
		HEAD D 5 BRIGHT A_HeadAttack;
		Goto See;
	Pain:
		HEAD E 3;
		HEAD E 3 A_Pain;
		HEAD F 6;
		Goto See;
	Death:
		HEAD G 4; 
		HEAD H 4 A_Scream;
		Stop;
	}
}