class BloodBits : Actor
{
default
{
	+THRUACTORS;
	height 4;
	radius 24;
	mass 6000;
}

override void beginplay()
{
	super.beginplay();
	
	float s = random(5, 33) / 100.0f;
	
	scale.x = s;
	scale.y = s;
}

void
jumpspritedeath(void)
{
	switch (random(1, 3))
	{
	default:
	case 1: break;
	case 2: setstatelabel("xdeath_2"); break;
	case 3: setstatelabel("xdeath_3"); break;
	}
}

states
{
spawn:
death:
xdeath:
	XBLD A 0 jumpspritedeath();
	XBLD A -1;
	stop;
xdeath_2:
	XBLD B -1;
	stop;
xdeath_3:
	XBLD C -1;
	stop;
}
}
class BloodBitsBig : BloodBits
{
override void beginplay()
{
	super.beginplay();
	
	float s = random(33, 66) / 100.0f;
	
	scale.x = s;
	scale.y = s;
}
}

class BloodBrainBits : BloodBits
{
void
jumpspritedeath(void)
{
	switch (random(1, 4))
	{
	default:
	case 1: break;
	case 2: setstatelabel("xdeath_2"); break;
	case 3: setstatelabel("xdeath_3"); break;
	case 4: setstatelabel("xdeath_4"); break;
	}
}

states
{
spawn:
death:
xdeath:
	XBLB A 0 jumpspritedeath();
	XBLB A -1;
	stop;
xdeath_2:
	XBLB B -1;
	stop;
xdeath_3:
	XBLB C -1;
	stop;
xdeath_4:
	XBLB D -1;
	stop;
}
}

class GoreBits : Actor
{

int frame;
int tframe;
int scalestate;

default
{
	monster;
	+FRIENDLY
	+THRUACTORS
	height 8;
	health 8;
	mass 6000;
	painchance 255;
	painsound "stomp/blood";
}

bool
testposition(Actor tosee)
{
	if (!CheckSight(tosee))
	{
		A_Remove(AAPTR_DEFAULT);
		//console.printf("delete");
		return false;
	}
	return true;
}

override void
beginplay(void)
{
	super.beginplay();
	
	//health += random(0, 2);
	
	tframe = random(35, 350);
	
	float s = random(40, 100)/100.0;
	scale.x = s;
	scale.y = s;
}

override void
tick(void)
{
	super.tick();
	
	if (frame++ > tframe)
	{
		A_AlertMonsters(0, AMF_TARGETEMITTER);
		tframe = random(35, 350);
		frame = 0;
	}
}

override int
DamageMobj(Actor inflictor, Actor source, int damage, Name mod, int flags, double angle)
{
	scale.x *= 0.85 + random(1, 5)/100.0;
	scale.y *= 0.80 + random(1, 5)/100.0;
	
	if (random(1, 100) >= 99)
	{
		A_StartSound("gib/large1", CHAN_AUTO);
		for (int i = 0; i < 32; i++)
		{
			A_SpawnItemEx("BloodBits", random(-42, 42), random(-42, 42));
			A_SpawnItemEx("BloodBits", random(-42, 42), random(-42, 42));
			A_SpawnItemEx("BloodBits", random(-42, 42), random(-42, 42));
			A_SpawnItemEx("BloodBits", random(-42, 42), random(-42, 42));
			A_SpawnItemEx("BloodBits", random(-42, 42), random(-42, 42));
		}
	}
	else
	{
		A_StartSound("stomp/blood", CHAN_AUTO);
	}
	return super.DamageMObj(inflictor, source, 1, mod, flags, angle);
}

void
jumpsprite(void)
{
	float s = random(60, 100) / 100.0;
	scale.x *= s;
	scale.y *= s;
	
	if (random(1, 2) == 1)
		scale.x = -scale.x;
	
	switch (random(1, 4))
	{
	default:
	case 1: break;
	case 2: setstatelabel("spawn_2"); break;
	case 3: setstatelabel("spawn_3"); break;
	case 4: setstatelabel("spawn_4"); break;
	}
}

void
spawnblood(class<Actor> n, int x, int y)
{
	actor a;
	bool b;
	GoreBits gb;
	[b, a] = A_SpawnItemEx(n, x, y, 0, 0, 0, 0, 0, SXF_SETMASTER);
	
	gb = GoreBits(a);
	if (gb)
	{
		gb.testposition(self);
	}
}

void
jumpspritedeath(void)
{
	spawnblood("GoreBitsSmall", random(-64, 64), random(-64, 64));
	spawnblood("GoreBitsSmall", random(-64, 64), random(-64, 64));
	spawnblood("GoreBitsSmall", random(-64, 64), random(-64, 64));
	spawnblood("GoreBitsSmall", random(-64, 64), random(-64, 64));
	spawnblood("GoreBitsSmall", random(-64, 64), random(-64, 64));
	spawnblood("GoreBitsSmall", random(-64, 64), random(-64, 64));
	for (int i = 0; i < 96; i++)
		A_SpawnItemEx("BloodBits", random(-64, 64), random(-64, 64));
	
	switch (random(1, 3))
	{
	default:
	case 1: break;
	case 2: setstatelabel("xdeath_2"); break;
	case 3: setstatelabel("xdeath_3"); break;
	}
}

states
{
spawn:
	GBTS A 0 NODELAY jumpsprite();
	GBTS A -1;
	stop;
spawn_2:
	GBTS B -1;
	stop;
spawn_3:
	GBFL I -1;
	stop;
spawn_4:
	GBTS E -1;
	stop;
death:
xdeath:
	XBLD A 0 jumpspritedeath();
	XBLD A -1;
	stop;
xdeath_2:
	XBLD B -1;
	stop;
xdeath_3:
	XBLD C -1;
	stop;
}
}

class GoreBrain : GoreBits
{
default
{
	health 2;
}

override void
beginplay(void)
{
	super.beginplay();
}

void
jumpsprite(void)
{
	float s = random(5, 35) / 100.0;
	scale.x *= s;
	scale.y *= s;
	
	if (random(1, 2) == 1)
		scale.x = -scale.x;
	
	switch (random(1, 5))
	{
	default:
	case 1: break;
	case 2: setstatelabel("spawn_2"); break;
	case 3: setstatelabel("spawn_3"); break;
	case 4: setstatelabel("spawn_4"); break;
	case 5: setstatelabel("spawn_5"); break;
	}
}

void
jumpspritedeath(void)
{
	for (int i = 0; i < 32; i++)
		A_SpawnItemEx("BloodBrainBits", random(-24, 24), random(-24, 24));
	
	switch (random(1, 4))
	{
	default:
	case 1: break;
	case 2: setstatelabel("xdeath_2"); break;
	case 3: setstatelabel("xdeath_3"); break;
	case 4: setstatelabel("xdeath_4"); break;
	}
}

states
{
spawn:
	BRAI I 0 NODELAY jumpsprite();
spawn_1:
	BRAI I 1;
	loop;
spawn_2:
	BRAI J 1;
	loop;
spawn_3:
	BRAI K 1;
	loop;
spawn_4:
	BRAI L 1;
	loop;
spawn_5:
	BRAI M 1;
	loop;
death:
xdeath:
	XBLB A 0 jumpspritedeath();
	XBLB A -1;
	stop;
xdeath_2:
	XBLB B -1;
	stop;
xdeath_3:
	XBLB C -1;
	stop;
xdeath_4:
	XBLB D -1;
	stop;
}
}

class GoreFried : GoreFlyingBase
{

void
jumpsprite(void)
{
	float s = random(25, 80) / 100.0;
	scale.x = s;
	scale.y = s;
	
	if (random(1, 2) == 1)
		scale.x = -scale.x;
	if (random(1, 2) == 1)
		scale.y = -scale.y;
	
	switch (random(1, 4))
	{
	default:
	case 1: break;
	case 2: setstatelabel("spawn_2"); break;
	case 3: setstatelabel("spawn_3"); break;
	case 4: setstatelabel("spawn_4"); break;
	}
}

states
{
spawn:
	CELE A 0 NODELAY jumpsprite();
	CELE A -1;
	stop;
spawn_2:
	CELE B -1;
	stop;
spawn_3:
	CELE C -1;
	stop;
spawn_4:
	CELE D -1;
	stop;
}
}

class GoreBitsLarge : GoreBits
{
default
{
	health 10;
}
override void
beginplay(void)
{
	super.beginplay();
	float s = random(120, 150)/100.0;
	scale.x = s;
	scale.y = s;
}

void
jumpspritedeath(void)
{
	for (int i = 0; i < 64; i++)
		A_SpawnItemEx("BloodBitsBig", random(-32, 32), random(-32, 32));
	
	switch (random(1, 4))
	{
	default:
	case 1: break;
	case 2: setstatelabel("xdeath_2"); break;
	case 3: setstatelabel("xdeath_3"); break;
	case 4: setstatelabel("xdeath_4"); break;
	}
}

}

class GoreBitsSmall : GoreBits
{
default
{
	health 1;
}
override void
beginplay(void)
{
	super.beginplay();
	float s = random(25, 50)/100.0;
	scale.x = s;
	scale.y = s;
}
void
jumpsprite(void)
{
	float s = random(20, 65) / 100.0;
	scale.x *= s;
	scale.y *= s;
	
	if (random(1, 2) == 1)
		scale.x = -scale.x;
	
	switch (random(1, 4))
	{
	default:
	case 1: break;
	case 2: setstatelabel("spawn_2"); break;
	case 3: setstatelabel("spawn_3"); break;
	case 4: setstatelabel("spawn_4"); break;
	}
}

states
{
spawn:
	GIBX A 0 NODELAY jumpsprite();
	GIBX A -1;
	stop;
spawn_2:
	GBTS B -1;
	stop;
spawn_3:
	GBFL I -1;
	stop;
spawn_4:
	GBTS E -1;
	stop;
death:
xddeath:
	---- A -1;
	stop;
}
}

class GoreFlyingBase : GoreBits
{

default
{
radius 16;
height 12;
//+NOBLOCKMAP
-NOGRAVITY
+FRIENDLY
gravity 0.5;
health 2;
}

}

class GorePlayerArm : GoreFlyingBase
{

states
{
spawn:
	XARM H -1;
	stop;
death:
xdeath:
	XBLA A -1
	{		
		for (int i = 0; i < 32; i++)
			A_SpawnItemEx("BloodBits", random(-24, 24), random(-24, 24));
	}
	stop;
}

}

class GorePlayerLeg : GoreFlyingBase
{

states
{
spawn:
	XLEG A -1;
	stop;
death:
xdeath:
	XLEG B -1
	{
		A_SpawnItemEx("BloodBits", random(-16, 16), random(-16, 16));
		A_SpawnItemEx("BloodBits", random(-16, 16), random(-16, 16));
		A_SpawnItemEx("BloodBits", random(-16, 16), random(-16, 16));
		A_SpawnItemEx("BloodBits", random(-16, 16), random(-16, 16));
		A_SpawnItemEx("BloodBits", random(-16, 16), random(-16, 16));
		A_SpawnItemEx("BloodBits", random(-16, 16), random(-16, 16));
		A_SpawnItemEx("BloodBits", random(-16, 16), random(-16, 16));
		A_SpawnItemEx("BloodBits", random(-16, 16), random(-16, 16));
		A_SpawnItemEx("BloodBits", random(-16, 16), random(-16, 16));
		A_SpawnItemEx("BloodBits", random(-16, 16), random(-16, 16));
		A_SpawnItemEx("BloodBits", random(-16, 16), random(-16, 16));
		A_SpawnItemEx("BloodBits", random(-16, 16), random(-16, 16));
		A_SpawnItemEx("BloodBits", random(-16, 16), random(-16, 16));
		A_SpawnItemEx("BloodBits", random(-16, 16), random(-16, 16));
		A_SpawnItemEx("BloodBits", random(-16, 16), random(-16, 16));
		A_SpawnItemEx("BloodBits", random(-16, 16), random(-16, 16));
	}
	stop;
}

}

class GoreFlying : PlayerChunk
{

void
spawnblood(class<Actor> n, int x, int y)
{
	actor a;
	bool b;
	GoreBits gb;
	[b, a] = A_SpawnItemEx(n, x, y, 0, 0, 0, 0, 0, SXF_SETMASTER);
	
	gb = GoreBits(a);
	if (gb)
	{
		gb.testposition(self);
	}
}

default
{
Radius 8;
Height 4;

+NOBLOCKMAP
+DROPOFF
+LOWGRAVITY
+CANNOTPUSH
+SKYEXPLODE
+NOBLOCKMONST
+NOSKIN
+THRUACTORS
}

states
{
Spawn:
	GBFL ABCDEFGH 5 NODELAY A_CheckFloor("Hit");
	goto Spawn+1;
Hit:
	GBFL I 16;
	wait;
death:
	GBFL I 16;
	stop;
}

}

class GoreFlyingBrain : GoreFlying
{

default
{
scale 0.5;
}

states
{
Spawn:
	BRAI ABCDEFGH 5 NODELAY A_CheckFloor("Hit");
	goto Spawn+1;
Hit:
death:
xdeath:
	BRAI O -1
	{
		bool b;
		actor a;
		
		A_StartSound("blood/small", CHAN_AUTO);
		spawnblood("GoreBrain", random(-16, 16), random(-16, 16));
		spawnblood("GoreBrain", random(-16, 16), random(-16, 16));
		spawnblood("GoreBrain", random(-16, 16), random(-16, 16));
		spawnblood("GoreBrain", random(-32, 32), random(-32, 32));
		spawnblood("GoreBrain", random(-32, 32), random(-16, 32));
	}
	stop;
}

}

class GorePlayerHead : GoreFlying
{
states
{
spawn:
	MHEA A 5 NODELAY A_CheckFloor("Hit");
	loop;
hit:
death:
xdeath:
	MHEA A -1
	{
		int px = random(-32, 32);
		int py = random(-32, 32);
		
		for (int i = 0; i < 8; i++)
		{
			px += random(-4, 4);
			py += random(-4, 4);
			spawnblood("BloodBits", px+random(-32, 32), py+random(-32, 32));
			spawnblood("BloodBrainBits", px+random(-32, 32), py+random(-32, 32));
		}
	}
	stop;
}
}

class GoreFlyingFried : GoreFlying
{

states
{
Spawn:
	CELE C 5 NODELAY A_CheckFloor("Hit");
	goto Spawn+1;
Hit:
	CELE C 16 A_CheckPlayerDone();
	wait;
}
}

class GorePlayerHalfUpperChunk : GoreFlying
{

states
{
Spawn:
	XHAL A 5 NODELAY A_CheckFloor("Hit");
	goto Spawn+1;
Hit:
	XHAL A 16 A_CheckPlayerDone();
	wait;
}

}

class GoreDesintegratedBrain : Actor
{
default
{
	+GHOST
	+THRUACTORS
	-SOLID
	+ROLLSPRITE
	scale 0.35;
}

override void
tick(void)
{
	// Purposfully blank.
}

states
{
spawn:
	BRAD A 1;
	loop;
death:
	TNT1 A 0;
	stop;
}
}

class GoreDesintegratedBrainChunk : GoreFlying
{
GoreDesintegratedBrain attachment;

override void
BeginPlay(void)
{
	super.BeginPlay();
	attachment = GoreDesintegratedBrain(Spawn("GoreDesintegratedBrain", pos));
}

override void
tick(void)
{
	super.Tick();
	if (attachment && instatesequence(curstate, resolvestate("spawn")))
	{
		attachment.roll += 15;
		attachment.setxyz(pos);
	}
}

default
{
	scale 0.35;
}

states
{
spawn:
	TNT1 A 5 NODELAY A_CheckFloor("Hit");
	loop;
hit:
	BRAD A 16
	{
		if (attachment)
		{
			attachment.destroy();
			attachment = null;
		}
		A_CheckPlayerDone();
	}
	wait;
}

}
