class doomplayer_s : doomplayer
{
bool hit_crit;
string hit_by;
actor hit_byactor;
actor hit_bysource;
int hit_distance;
bool forceposition;
vector3 forceposition_v;
bool hit_noarmour;

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

override void
tick(void)
{
	super.tick();
	
	if (forceposition)
		SetXYZ(forceposition_v);
}

override void
ApplyKickback(Actor inflictor, Actor source, int damage, double angle, Name mod, int flags)
{
	super.ApplyKickback(inflictor, source, (damage > 200 ? damage : 200), angle, mod, flags);
}

override void
Die(Actor source, Actor inflictor, int dmgflags, Name mod)
{
	vector3 clump, p;
	bool k_chainsaw       = !(mod == "devour" || mod == "disintegrate" || mod == "stomp" );
	bool k_pistol         = !(mod == "devour" || mod == "disintegrate");
	bool k_shotgun        = !(mod == "devour" || mod == "disintegrate");
	bool k_chaingun       = !(mod == "devour" || mod == "disintegrate");
	bool k_supershotgun   = !(mod == "devour" || mod == "disintegrate"  || mod == "stomp");
	bool k_rocketlauncher = !(mod == "devour" || mod == "disintegrate");
	bool k_plasmarifle    = !(mod == "devour" || mod == "disintegrate"  || mod == "stomp" || mod == "plasma");
	bool k_bfg9000        = !(mod == "devour" || mod == "disintegrate"  || mod == "stomp" || mod == "plasma");
	
	clump.x = pos.x+random(-64, 64);
	clump.y = pos.y+random(-64, 64);
	clump.z = GetZAt(clump.x, clump.y);
	
	if (k_chainsaw)
	{
		p.x = clump.x+random(-121, 121);
		p.y = clump.y+random(-121, 121);
		p.z = GetZAt(p.x, p.y);
		if (CheckInventory("Chainsaw", 1))
		{
			Spawn("Chainsaw", p, ALLOW_REPLACE);
			TakeInventory("Chainsaw", 1);
		}
	}
	
	if (k_pistol)
	{
		p.x = clump.x+random(-121, 121);
		p.y = clump.y+random(-121, 121);
		p.z = GetZAt(p.x, p.y);
		if (CheckInventory("Pistol", 1))
		{
			Spawn("Pistol", p, ALLOW_REPLACE);
			TakeInventory("Pistol", 1);
		}
	}
	
	if (k_shotgun)
	{
		p.x = clump.x+random(-121, 121);
		p.y = clump.y+random(-121, 121);
		p.z = GetZAt(p.x, p.y);
		if (CheckInventory("Shotgun", 1))
		{
			Spawn("Shotgun", p, ALLOW_REPLACE);
			TakeInventory("Shotgun", 1);
		}
	}
	
	if (k_rocketlauncher)
	{
		p.x = clump.x+random(-121, 121);
		p.y = clump.y+random(-121, 121);
		p.z = GetZAt(p.x, p.y);
		if (CheckInventory("RocketLauncher", 1))
		{
			Spawn("RocketLauncher", p, ALLOW_REPLACE);
			TakeInventory("RocketLauncher", 1);
		}
	}
	
	if (k_plasmarifle)
	{
		p.x = clump.x+random(-121, 121);
		p.y = clump.y+random(-121, 121);
		p.z = GetZAt(p.x, p.y);
		if (CheckInventory("PlasmaRifle", 1))
		{
			Spawn("PlasmaRifle", p, ALLOW_REPLACE);
			TakeInventory("PlasmaRifle", 1);
		}
	}
	
	if (k_supershotgun)
	{
		p.x = clump.x+random(-121, 121);
		p.y = clump.y+random(-121, 121);
		p.z = GetZAt(p.x, p.y);
		if (CheckInventory("SuperShotgun", 1))
		{
			Spawn("SuperShotgun", p, ALLOW_REPLACE);
			TakeInventory("SuperShotgun", 1);
		}
	}
	
	if (k_bfg9000)
	{
		p.x = clump.x+random(-121, 121);
		p.y = clump.y+random(-121, 121);
		p.z = GetZAt(p.x, p.y);
		if (CheckInventory("BFG9000", 1))
		{
			Spawn("BFG9000", p, ALLOW_REPLACE);
			TakeInventory("BFG9000", 1);
		}
	}
	
	if (k_chaingun)
	{
		p.x = clump.x+random(-121, 121);
		p.y = clump.y+random(-121, 121);
		p.z = GetZAt(p.x, p.y);
		if (CheckInventory("Chaingun", 1))
		{
			Spawn("Chaingun", p, ALLOW_REPLACE);
			TakeInventory("Chaingun", 1);
		}
	}
	
	super.Die(source, inflictor, dmgflags, mod);
}

int
damagescale(Actor inflictor, Actor source, int damage, int level)
{
	if (source is "Zombieman" || source is "Shotgunguy" || source is "Chaingunguy")
		damage += 2;
		
	if (inflictor is "LostSoul") damage += 10;
		
	if (inflictor is "Demon" || inflictor is "Spectre") damage += 15+level*5;
		
	if      (inflictor is "DoomImpBall") damage += 5;
	else if (source    is "Doomimp")     damage += 10;
		
	if      (inflictor is "RevenantTracer") damage += 25;
	else if (source is "Revenant")          damage += 25;
	
	if (inflictor is "Cyberdemon")    damage += level*10+5;
		
	if (source is "Arachnotron")      damage += level*5;
	if (source is "SpiderMastermind") damage += level*5;
		
	if (source is "Fatso")    damage += level*5;
	if (source is "Archvile") damage += level*5;
	
	if (inflictor is "BaronBall" && source is "BaronOfHell")
		damage += 25;
	else if (inflictor is "BaronBall" && source is "HellKnight")
		damage += 25;
	else if (source is "HellKnight" || source is "BaronOfHell")
		damage += 25;
	
	if (inflictor is "Rocket" && source is "Cyberdemon")
		damage += 25;
		
	if (inflictor is "CacodemonBall")
		damage += 10;
	else if (source is "Cacodemon")
		damage += 25;
	
	return damage;
}

int
critchance(Actor inflictor, Actor source, name mod, int level)
{
	int chance = 5;
	
	switch (skill)
	{
	default:
	case 0: chance = 5; break;
	case 1: chance = 10; break;
	case 2: chance = 15; break;
	}
	
	if      (inflictor is "Demon")         chance += level*5+5;
	else if (source is "Archvile")         chance += level*5;
	else if (source is "Arachnotron")      chance += level*5;
	else if (source is "SpiderMastermind") chance += 0;
	else if (source is "Fatso")            chance += level*5;
	else if (source is "Zombieman")        chance += level;
	else if (source is "Shotgunguy")       chance += level;
	else if (inflictor is "LostSoul")      chance += 5;
	else if (inflictor is "Cacodemon")     chance += 0;
	else if (inflictor is "PainElemental") chance += 5;
	else if (inflictor is "Doomimp")       chance += level*5;
	else if (inflictor is "Revenant")      chance += 0;
	else if (inflictor is "HellKnight")    chance += level*5+10;
	else if (inflictor is "BaronOfHell")   chance += level*5+10;
	else if (inflictor is "Cyberdemon")    chance += level*5+10;
	else if (source is "Cyberdemon")       chance += level*5+10;
	
	if (mod == "Slime")
		chance = 0;
	
	return chance;
}

name
modfor(Actor inflictor, Actor source)
{
	if      (inflictor is "Rocket"           ||
	         inflictor is "RevenantTracer"   ||
			 source    is "SpiderMastermind" ||
			 inflictor is "Archvile")  return "explode";
	else if (inflictor is "CacodemonBall")     return "plasma";
	else if (inflictor is "ArachnotronPlasma") return "plasma";
	else if (source is "Zombieman"     ||
	         source is "Shotgunguy"    ||
			 source is "Chaingunguy")          return "decapitate";
	else if (inflictor is "HellKnight" ||
	         inflictor is "Cyberdemon")        return "stomp";
	else if (inflictor is "Cacodemon"     ||
	         inflictor is "PainElemental" ||
	         inflictor is "Demon")             return "devour";
	else if (inflictor is "BaronBall")         return "disintegrate";
	return "None";
}

override int
DamageMobj(Actor inflictor, Actor source, int damage, Name mod, int flags, double angle)
{
	name newmod   = modfor(inflictor, source);
	int chance    = critchance(inflictor, source, mod, skill);
	int newdamage = damagescale(inflictor, source, damage, skill);
	int i;
	
	hit_crit  = false;
	if (random(1, 100) < chance)
	{
		newdamage *= 2+(skill/2);
		hit_crit   = true;
	}
	
	hit_by = "";
	if (source)
	{
		hit_by       = source.GetClassName();
		hit_bysource = source;
		hit_distance = distance2d(source);
	}
	if (inflictor)
		hit_byactor = inflictor;
		
	hit_noarmour = (CountInv("BasicArmor") <= 0);
	//console.printf("%d", hit_noarmour);
	
	//console.printf("mod: %s, chance: %d, newdamage: %d", mod, chance, newdamage);
	
	return super.DamageMobj(inflictor, source, newdamage, newmod, flags, angle);
}

void
deathcheck(void)
{
	if (hit_crit || hit_noarmour)
		setstatelabel("xdeath");
}

void
deathjumpsequene(void)
{
	bthruactors = true;
	
	if (hit_byactor is "Demon")
	{
		if (hit_noarmour)
			setstatelabel("xdeath.demon_noarmour");
		else
			setstatelabel("xdeath.demon");
	}
	if (hit_byactor is "LostSoul")
		setstatelabel("xdeath.shotgunguy");
	if (hit_byactor is "Revenant")
		setstatelabel("xdeath.Zombieman");
	if (hit_byactor is "Archvile")
		setstatelabel("xdeath.CyberdemonRocket");
	else if (hit_bysource is "Zombieman")
		setstatelabel("xdeath.zombieman");
	else if (hit_bysource is "Shotgunguy")
		setstatelabel("xdeath.shotgunguy");
	else if (hit_bysource is "Chaingunguy")
		setstatelabel("xdeath.shotgunguy");
	else if (hit_byactor is "RevenantTracer")
		setstatelabel("xdeath.CyberdemonRocket");
	else if (hit_byactor is "HellKnight")
	{
		HellKnight_s hk = HellKnight_s(hit_byactor);
		
		setstatelabel("xdeath.HellKnight");
		if (hk)
			hk.stomp();
	}
	else if (hit_byactor is "BaronOfHell")
	{
		BaronOfHell_s bh = BaronOfHell_s(hit_byactor);
		
		setstatelabel("xdeath.BaronOfHell");
		if (bh)
			bh.tear(self);
	}
	else if (hit_byactor is "BaronBall")
		setstatelabel("xdeath.BaronBall");
	else if (hit_byactor is "Rocket" && hit_bysource is "Cyberdemon")
		setstatelabel("xdeath.CyberdemonRocket");
	else if (hit_byactor is "Cyberdemon")
	{
		if (hit_noarmour)
			setstatelabel("xdeath.Cyberdemon_noarmour");
		else
			setstatelabel("xdeath.Cyberdemon");
	}
	else if (hit_byactor is "Cacodemon" || hit_byactor is "PainElemental")
		setstatelabel("xdeath.Cacodemon");
	else if (hit_byactor is "ArachnotronPlasma")
	{
		if (hit_noarmour)
			setstatelabel("xdeath.arachnotron_plasma_noarmour");
		else
			setstatelabel("xdeath.arachnotron_plasma");
	}
	else if (hit_byactor is "DoomImp")
		setstatelabel("xdeath.imp");
	else if (hit_bysource is "SpiderMastermind")
		setstatelabel("xdeath.CyberdemonRocket");
}

void
gibsound(void)
{	
	A_StartSound("gib/large1", CHAN_BODY);
}

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
deathdemon(bool noarmour = false)
{
	int i;
	actor a;
	bool b;
	
	if (random(1, 2) == 1)
		scale.x = -scale.x;
	
	gibsound();
	A_SkullPop("GoreFlying");
	spawnblood("GoreBitsSmall", random(-32,32), -8-random(0,32));
	spawnblood("GoreBitsSmall", random(-32,32), -8-random(0,32));
	spawnblood("GoreBitsSmall", random(-32,32), -8-random(0,32));
	spawnblood("GoreBitsSmall", random(-64,64), -8-random(0,64));
	spawnblood("GoreBitsSmall", random(-64,64), -8-random(0,64));
	spawnblood("GoreBitsSmall", random(-32,32), +8+random(0,32));
	spawnblood("GoreBitsSmall", random(-32,32), +8+random(0,32));
	spawnblood("GoreBitsSmall", random(-64,64), +8+random(0,64));
	spawnblood("GoreBitsSmall", random(-64,64), +8+random(0,64));
	spawnblood("GoreBitsSmall", random(-32,32), +8+random(0,32));
	spawnblood("GoreBitsSmall", random(-32,32), +8+random(0,32));
	spawnblood("GoreBitsSmall", random(-64,64), +8+random(0,64));
	spawnblood("GoreBitsSmall", random(-64,64), +8+random(0,64));
	spawnblood("GoreBrain", random(-24,24), -8-random(0,24));
	spawnblood("GoreBrain", random(-24,24), -8-random(0,24));
	spawnblood("GoreBrain", random(-24,24), -8-random(0,24));
	spawnblood("GoreBrain", random(-24,24), -8-random(0,24));
	spawnblood("GoreBrain", random(-24,24), -8-random(0,24));
	spawnblood("GoreBrain", random(-24,24), -8-random(0,24));
	
	if (noarmour)
	{
		spawnblood("GoreBits", random(-22,22), -8-random(0,22));
		spawnblood("GoreBits", random(-22,22), -8-random(0,22));
		spawnblood("GoreBrain", random(-24,24), -8-random(0,24));
		spawnblood("GoreBrain", random(-24,24), -8-random(0,24));
		spawnblood("GoreBitsSmall", random(-22,22), +8+random(0,22));
		spawnblood("GoreBitsSmall", random(-22,22), +8+random(0,22));
		spawnblood("GoreBitsSmall", random(-24,24), +8+random(0,24));
		spawnblood("GoreBitsSmall", random(-24,24), +8+random(0,24));
		setstatelabel("xdeath.demon_2");
	}
	else
		switch (random(1, 4))
		{
		default:
		case 1: setstatelabel("xdeath.demon_1"); break;
		case 2: setstatelabel("xdeath.demon_2"); break;
		case 3: setstatelabel("xdeath.demon_3"); break;
		case 4: setstatelabel("xdeath.demon_4"); break;
		}
}

void
deathzombieman(void)
{	
	vel.x *= 0.1;
	vel.y *= 0.1;
	vel.z *= 0.1;

	gibsound();
	headexplode();
}

void
deathshotgunguy(void)
{
	vel.x *= 0.1;
	vel.y *= 0.1;
	vel.z *= 0.1;
	
	gibsound();
	headexplode();
	
	if (hit_distance < 100)
		setstatelabel("xdeath.shotgunguy_close");
	else
		setstatelabel("xdeath.shotgunguy_far");
}

void
deathimp(void)
{	
	vel.x *= 0.1;
	vel.y *= 0.1;
	vel.z *= 0.1;

	gibsound();
	headpop();
}

void
headpop(int count = 4, int radius_start = 8, int radius_follow = 4)
{
	int px  = random(-32, 32);
	int py  = random(-32, 32);
	int i;
	
	A_SkullPop("GorePlayerHead");
	spawnblood("GoreBrain", px, random(-96, 96));
	spawnblood("GoreBrain", -px, random(-96, 96));
	spawnblood("GoreBitsSmall", px+random(-96, 96), py+random(-96, 96));
	
	for (i = 0; i < count; i++)
	{
		px += random(-radius_follow, radius_follow);
		py += random(-radius_follow, radius_follow);
		spawnblood("GoreBitsSmall", px+random(-32, 32), py+random(-32, 32));
	}
}

void
headexplode(int count = 4, int radius_start = 8, int radius_follow = 4)
{
	int px  = random(-32, 32);
	int py  = random(-32, 32);
	int i;
	
	A_SkullPop("GoreFlyingBrain");
	spawnblood("GoreBrain",  px, random(-96, 96));
	spawnblood("GoreBrain", -px, random(-96, 96));
	spawnblood("GoreBitsSmall", px+random(-96, 96), py+random(-96, 96));
	
	for (i = 0; i < count; i++)
	{
		px += random(-radius_follow, radius_follow);
		py += random(-radius_follow, radius_follow);
		spawnblood("GoreBrain", px+random(-96, 96), py+random(-96, 96));
		spawnblood("GoreBrain", px+random(-32, 32), py+random(-32, 32));
		spawnblood("GoreBrain", px+random(-32, 32), py+random(-32, 32));
		spawnblood("GoreBrain", px+random(-32, 32), py+random(-32, 32));
		spawnblood("GoreBrain", px+random(-32, 32), py+random(-32, 32));
		spawnblood("GoreBrain", px+random(-32, 32), py+random(-32, 32));
		spawnblood("GoreBrain", px+random(-96, 96), py+random(-96, 96));
		spawnblood("GoreBrain", px+random(-96, 96), py+random(-96, 96));
		spawnblood("GoreFried", px+random(-96, 96), py+random(-96, 96));
	}
}

void
deathhellknight(void)
{
	int i;
	
	vel.x *= 0.1;
	vel.y *= 0.1;
	vel.z *= 0.1;
	
	if (hit_byactor && (HellKnight(hit_byactor) || BaronOfHell(hit_byactor)))
	{
		A_Face(hit_byactor);
		SetXYZ(hit_byactor.pos);
	}
	
	headexplode(6, 8, 6);
	
	for (i = 0; i < 2; i++)
	{
		int largeradius = 22;
		int smallradius = 10;
		int offsetx     = 24;
		
		spawnblood("GoreBitsSmall", random(-largeradius, largeradius)-offsetx, random(-largeradius, largeradius));
		spawnblood("GoreBitsSmall", random(-smallradius, smallradius)-offsetx, random(-smallradius, smallradius));
		spawnblood("GoreBitsSmall", random(-smallradius, smallradius)-offsetx, random(-smallradius, smallradius));
		spawnblood("GoreBitsSmall", random(-smallradius, smallradius)-offsetx, random(-smallradius, smallradius));
		spawnblood("GoreBitsSmall", random(-smallradius, smallradius)-offsetx, random(-smallradius, smallradius));
		spawnblood("GoreBitsSmall", random(-smallradius, smallradius)-offsetx, random(-smallradius, smallradius));
		spawnblood("GoreBitsSmall", random(-largeradius, largeradius)-offsetx, random(-largeradius, largeradius));
		spawnblood("GoreBitsSmall", random(-largeradius, largeradius)-offsetx, random(-largeradius, largeradius));
		spawnblood("GoreBitsSmall", random(-largeradius, largeradius)-offsetx, random(-largeradius, largeradius));
		spawnblood("BloodBits", random(-largeradius, largeradius)-offsetx, random(-largeradius, largeradius));
		spawnblood("BloodBits", random(-largeradius, largeradius)-offsetx, random(-largeradius, largeradius));
		spawnblood("BloodBits", random(-largeradius, largeradius)-offsetx, random(-largeradius, largeradius));
		spawnblood("BloodBits", random(-largeradius, largeradius)-offsetx, random(-largeradius, largeradius));
		spawnblood("BloodBits", random(-largeradius, largeradius)-offsetx, random(-largeradius, largeradius));
		spawnblood("BloodBits", random(-largeradius, largeradius)-offsetx, random(-largeradius, largeradius));
		spawnblood("BloodBits", random(-largeradius, largeradius)-offsetx, random(-largeradius, largeradius));
		spawnblood("BloodBits", random(-largeradius, largeradius)-offsetx, random(-largeradius, largeradius));
		spawnblood("BloodBits", random(-largeradius, largeradius)-offsetx, random(-largeradius, largeradius));
		spawnblood("BloodBits", random(-largeradius, largeradius)-offsetx, random(-largeradius, largeradius));
		spawnblood("BloodBits", random(-largeradius, largeradius)-offsetx, random(-largeradius, largeradius));
		spawnblood("BloodBits", random(-largeradius, largeradius)-offsetx, random(-largeradius, largeradius));
	}
}

void
deathbaronofhell(void)
{
	vel = (0, 0, 0);
	if (hit_byactor)
	{
		forceposition = true;
		forceposition_v = pos + (0, 0, hit_byactor.height*0.75);
	}
}

void
deathbaronofhell_talkback(void)
{
	forceposition = false;
	setstatelabel("xdeath.BaronOfHell_talkback");
}

void
deathbaronball(void)
{
	vel.x *= 0.1;
	vel.y *= 0.1;
	vel.z *= 0.1;
	
	scale.x *= 0.58; // 40/104 (player.x/sprite.x)
	scale.y *= 0.58;
	if (random(1, 2) == 1)
		scale.x = -scale.x;
	height = 2;
	A_StartSound("desintegrate");
	A_SkullPop("GoreDesintegratedBrainChunk");
}

void
bodyexplode(int count = 12, int radius_start = 32, int radius_follow = 128)
{
	int px  = random(-radius_start, radius_start);
	int py  = random(-radius_start, radius_start);
	int leg = random(0, 2);
	int arm = random(0, 2);
	int i;
	
	A_SkullPop("GoreFlyingBrain");
	spawnblood("GoreBits", random(-32, 32), random(-32, 32));
	for (i = 0; i < count; i++)
	{
		px += random(-radius_follow, radius_follow);
		py += random(-radius_follow, radius_follow);
		spawnblood("GoreBitsSmall", px+random(-96, 96), py+random(-96, 96));
		spawnblood("GoreBitsSmall", px+random(-96, 96), py+random(-96, 96));
		spawnblood("GoreBitsSmall", px+random(-32, 32), py+random(-32, 32));
		spawnblood("GoreBitsSmall", px+random(-32, 32), py+random(-32, 32));
		spawnblood("GoreBitsSmall", px+random(-32, 32), py+random(-32, 32));
		spawnblood("GoreBrain", px+random(-32, 32), py+random(-32, 32));
		spawnblood("GoreBrain", px+random(-32, 32), py+random(-32, 32));
		spawnblood("GoreBrain", px+random(-96, 96), py+random(-96, 96));
		spawnblood("GoreBrain", px+random(-96, 96), py+random(-96, 96));
		spawnblood("GoreFried", px+random(-96, 96), py+random(-96, 96));
	}
	
	if (leg == 2)
	{
		spawnblood("GorePlayerLeg", random(-96, 96), random(-96, 96));
		spawnblood("GorePlayerLeg", random(-96, 96), random(-96, 96));
	}
	else if (leg == 1)
	{
		if (random(1, 2) == 1)
			spawnblood("GorePlayerLeg", random(-96, 96), random(-96, 96));
		else
			spawnblood("GorePlayerLeg", random(-96, 96), random(-96, 96));
	}
	if (arm == 2)
	{
		spawnblood("GorePlayerArm", random(-96, 96), random(-96, 96));
		spawnblood("GorePlayerArm", random(-96, 96), random(-96, 96));
	}
	else if (arm == 1)
	{
		if (random(1, 2) == 1)
			spawnblood("GorePlayerArm", random(-96, 96), random(-96, 96));
		else
			spawnblood("GorePlayerArm", random(-96, 96), random(-96, 96));
	}
	for (i = 2-leg; i > 0; i--)
	{
		int px = random(-radius_follow-32, radius_follow+32);
		int py = random(-radius_follow-32, radius_follow+32);
		spawnblood("GoreBitsSmall", px+random(-32, 32), py+random(-32, 32));
		spawnblood("GoreBitsSmall", px+random(-32, 32), py+random(-32, 32));
	}
	for (i = 2-arm; i > 0; i--)
	{
		int px = random(-radius_follow-32, radius_follow+32);
		int py = random(-radius_follow-32, radius_follow+32);
		spawnblood("GoreBitsSmall", px+random(-32, 32), py+random(-32, 32));
		spawnblood("GoreBitsSmall", px+random(-32, 32), py+random(-32, 32));
	}
}

void
deathcyberdemonrocket(void)
{
	vel.x *= 0.1;
	vel.y *= 0.1;
	vel.z *= 0.1;
	
	gibsound();
	bodyexplode();
}

void
deathcyberdemon(bool noarmour = false)
{
	int i;
	
	vel.x = 0;
	vel.y = 0;
	vel.z = 0;
	
	if (hit_byactor && Cyberdemon(hit_byactor))
		SetXYZ(hit_byactor.pos);
	
	gibsound();
	headexplode();
	for (i = 0; i < 4; i++)
	{
		spawnblood("GoreBitsSmall", random(-32,32), random(-32,32));
		spawnblood("GoreBitsSmall", random(-64,64), random(-64,64));
	}
	spawnblood("GoreBrain", random(-64,64), random(-64,64));
	spawnblood("GoreBrain", random(-64,64), random(-64,64));
	if (noarmour)
	{
		scale.y = 0.5;
		scale.x = 0.9;
		for (i = 0; i < 42; i++)
		{
			spawnblood("GoreBitsSmall", random(-126,126), random(-126,126));
			spawnblood("GoreBrain", random(-86,86), random(-86,86));
		}
	}
}

void
deathcacodemon()
{
	int i;
	
	gibsound();
	
	if (hit_byactor && Cacodemon(hit_byactor))
		SetXYZ(hit_byactor.pos);
	
	vel.x *= 0.1;
	vel.y *= 0.1;
	vel.z *= 0.1;
	
	A_SkullPop("GoreFlying");
	
	spawnblood("GorePlayerLeg", random(-32, 32), random(-32, 32));
	spawnblood("GoreBitsSmall", random(-42, 42), random(-42, 42));
	spawnblood("GoreBitsSmall", random(-42, 42), random(-42, 42));
	spawnblood("GoreBitsSmall", random(-42, 42), random(-42, 42));
	spawnblood("GoreBitsSmall", random(-42, 42), random(-42, 42));
	spawnblood("GoreBrain", random(-42, 42), random(-42, 42));
}

void
deatharachnotronplasma(int part_amount = 22)
{
	int i;
	gibsound();
	
	vel.x *= 0.1;
	vel.y *= 0.1;
	vel.z *= 0.1;
	
	A_SkullPop("GoreFlyingFried");
	for (i = 0; i < part_amount; i++)
	{
		spawnblood("GoreFried", random(-42, 42), random(-82, 82));
		spawnblood("GoreFried", random(-42, 42), random(-82, 82));
		spawnblood("BloodBits", random(-96, 96), random(-96, 96));
		spawnblood("BloodBits", random(-96, 96), random(-96, 96));
		spawnblood("BloodBits", random(-96, 96), random(-96, 96));
		spawnblood("BloodBitsBig", random(-96, 96), random(-96, 96));
	}
}

default
{
mass 4500;
}

states
{
death:
	---- A 0 deathcheck();
	goto super::death;
xdeath:
	---- A 0 deathjumpsequene();
	goto super::xdeath;
xdeath.demon:
	---- A 0 deathdemon();
xdeath.demon_noarmour:
	---- A 0 deathdemon(true);
xdeath.demon_1:
	GIBD A -1;
	stop;
xdeath.demon_2:
	GIBD B -1;
	stop;
xdeath.demon_3:
	GBTS A -1;
	stop;
xdeath.demon_4:
	GBTS D -1;
	stop;
	stop;
xdeath.HellKnight:
	XPLS A 0 deathhellknight();
	XPLS A -1;
	stop;
xdeath.BaronOfHell:
	TNT1 A 0 deathbaronofhell();
xdeath.BaronOfHell_wait:
	TNT1 A 1;
	goto xdeath.BaronOfHell_wait;
xdeath.BaronOfHell_talkback:
	GBTS E -1 headexplode();
	stop;
xdeath.BaronBall:
	DES0 A      14 deathbaronball();
	DES0 BCDEF  8;
	DES0 G     -1;
	stop;
xdeath.CyberdemonRocket:
	GIBD F -1 deathcyberdemonrocket();
	stop;
xdeath.Cyberdemon:
	GIBD E -1 deathcyberdemon();
	stop;
xdeath.Cyberdemon_noarmour:
	GBTS E -1 deathcyberdemon(true);
	stop;
xdeath.imp:
	XPLH A    8 deathimp();
	XPLH BCD  6;
	XPLH E   -1;
xdeath.zombieman:
	XPLH A    8 deathzombieman();
	XPLH BCD  6;
	XPLH E   -1;
xdeath.shotgunguy:
	XPLH A 0 deathshotgunguy();
xdeath.shotgunguy_far:
	XPLH A    8 A_SkullPop("GoreFlyingBrain");
	XPLH BCD  6;
	XPLH E   -1;
	stop;
xdeath.shotgunguy_close:
	XHAL B 0 A_SkullPop("GorePlayerHalfUpperChunk");
	XHAL B 0 A_SpawnItemEx("GoreBits", random(-32,32), random(-32,32));
	XHAL B -1;
	stop;
xdeath.cacodemon:
	GBTS C -1 deathcacodemon();
	stop;
xdeath.arachnotron_plasma:
	CMEL A 8 deatharachnotronplasma();
	CMEL BCDEF 6;
	CMEL G -1;
	stop;
xdeath.arachnotron_plasma_noarmour:
	GIBD A -1 deatharachnotronplasma(64);
	stop;
}
}
