freeslot(
	"MT_AGGROMANEN",
	"S_AGGROMANEN_IDLE",
	"S_AGGROMANEN_PAIN",
	"S_AGGROMANEN_SPIKEBALL",
	"S_AGGROMANEN_SPIKEBALL2",
	"S_AGGROMANEN_SPIKEBALL3",
	"S_AGGROMANEN_SPIKEBALL4",
	"S_AGGROMANEN_SPIKEBALL5",
	"S_AGGROMANEN_LASER",
	"S_AGGROMANEN_LASER2",
	"S_AGGROMANEN_LASER3",
	"S_AGGROMANEN_LASER4",
	"S_AGGROMANEN_LASER5",
	"S_AGGROMANEN_LASER6",
	"S_AGGROMANEN_FLEE",
	"S_AGGROMANEN_FLEE2",
	"S_AGGROMANEN_FLEE3",
	"S_AGGROMANEN_FLEE4",
	"S_AGGROMANEN_FLEE5",
	"S_AGGROMANEN_FLEE6",
	"S_AGGROMANEN_RAISE",
	"S_AGGROMANEN_RAISE2",
	"S_AGGROMANEN_RAISE3",
	"S_AGGROMANEN_RAISE4",
	"S_AGGROMANEN_RAISE5",
	"S_AGGROMANEN_RAISE6",
	"SPR_AGGR"
)

states[S_AGGROMANEN_IDLE] = {
	sprite = SPR_AGGR,
	frame = A,
	tics = 1,
	action = A_Boss1Chase,
	var1 = 0, 
	var2 = 0,
	nextstate = S_AGGROMANEN_IDLE
}

states[S_AGGROMANEN_PAIN] = {
	sprite = SPR_AGGR,
	frame = A,
	tics = 48,
	action = A_Pain,
	var1 = 0, 
	var2 = 0,
	nextstate = S_AGGROMANEN_IDLE
}

states[S_AGGROMANEN_SPIKEBALL] = {
	sprite = SPR_AGGR,
	frame = A,
	tics = 3,
	action = A_Boss1Spikeballs,
	var1 = 0, 
	var2 = 3,
	nextstate = S_AGGROMANEN_SPIKEBALL2
}

states[S_AGGROMANEN_SPIKEBALL2] = {
	sprite = SPR_AGGR,
	frame = A,
	tics = 1,
	action = nil,
	var1 = 0, 
	var2 = 0,
	nextstate = S_AGGROMANEN_SPIKEBALL3
}

states[S_AGGROMANEN_SPIKEBALL3] = {
	sprite = SPR_AGGR,
	frame = A,
	tics = 3,
	action = A_Boss1Spikeballs,
	var1 = 1, 
	var2 = 3,
	nextstate = S_AGGROMANEN_SPIKEBALL4
}

states[S_AGGROMANEN_SPIKEBALL4] = {
	sprite = SPR_AGGR,
	frame = A,
	tics = 1,
	action = nil,
	var1 = 0, 
	var2 = 0,
	nextstate = S_AGGROMANEN_SPIKEBALL5
}

states[S_AGGROMANEN_SPIKEBALL5] = {
	sprite = SPR_AGGR,
	frame = A,
	tics = 3,
	action = A_Boss1Spikeballs,
	var1 = 2, 
	var2 = 3,
	nextstate = S_AGGROMANEN_IDLE
}

states[S_AGGROMANEN_LASER] = {
	sprite = SPR_AGGR,
	frame = A,
	tics = 2,
	action = A_FaceTarget,
	var1 = 0, 
	var2 = 0,
	nextstate = S_AGGROMANEN_LASER2
}

states[S_AGGROMANEN_LASER2] = {
	sprite = SPR_AGGR,
	frame = A,
	tics = 1,
	action = A_BossFireShot,
	var1 = MT_ROCKET, 
	var2 = 6,
	nextstate = S_AGGROMANEN_LASER3
}

states[S_AGGROMANEN_LASER3] = {
	sprite = SPR_AGGR,
	frame = A,
	tics = 2,
	action = A_FaceTarget,
	var1 = 0, 
	var2 = 0,
	nextstate = S_AGGROMANEN_LASER4
}

states[S_AGGROMANEN_LASER4] = {
	sprite = SPR_AGGR,
	frame = A,
	tics = 1,
	action = A_BossFireShot,
	var1 = MT_ROCKET, 
	var2 = 6,
	nextstate = S_AGGROMANEN_LASER5
}

states[S_AGGROMANEN_LASER5] = {
	sprite = SPR_AGGR,
	frame = A,
	tics = 2,
	action = A_FaceTarget,
	var1 = 0, 
	var2 = 0,
	nextstate = S_AGGROMANEN_LASER6
}

states[S_AGGROMANEN_LASER6] = {
	sprite = SPR_AGGR,
	frame = A,
	tics = 1,
	action = A_BossFireShot,
	var1 = MT_ROCKET, 
	var2 = 6,
	nextstate = S_AGGROMANEN_IDLE
}

states[S_AGGROMANEN_FLEE] = {
	sprite = SPR_AGGR,
	frame = A,
	tics = 8,
	action = A_Fall,
	var1 = 0, 
	var2 = 0,
	nextstate = S_AGGROMANEN_FLEE2
}

states[S_AGGROMANEN_FLEE2] = {
	sprite = SPR_AGGR,
	frame = A,
	tics = 8,
	action = A_BossScream,
	var1 = 0, 
	var2 = 0,
	nextstate = S_AGGROMANEN_FLEE3
}

states[S_AGGROMANEN_FLEE3] = {
	sprite = SPR_AGGR,
	frame = A,
	tics = 8,
	action = A_BossScream,
	var1 = 0, 
	var2 = 0,
	nextstate = S_AGGROMANEN_FLEE4
}

states[S_AGGROMANEN_FLEE4] = {
	sprite = SPR_AGGR,
	frame = A,
	tics = 8,
	action = A_BossScream,
	var1 = 0, 
	var2 = 0,
	nextstate = S_AGGROMANEN_FLEE5
}

states[S_AGGROMANEN_FLEE5] = {
	sprite = SPR_AGGR,
	frame = A,
	tics = 8,
	action = A_BossScream,
	var1 = 0, 
	var2 = 0,
	nextstate = S_AGGROMANEN_FLEE6
}

states[S_AGGROMANEN_FLEE6] = {
	sprite = SPR_AGGR,
	frame = A,
	tics = -1,
	action = A_BossDeath,
	var1 = 0, 
	var2 = 0
}

states[S_AGGROMANEN_RAISE] = {
	sprite = SPR_AGGR,
	frame = A,
	tics = 2,
	action = A_Boss1Spikeballs,
	var1 = 0, 
	var2 = 3,
	nextstate = S_AGGROMANEN_RAISE2
}

states[S_AGGROMANEN_RAISE2] = {
	sprite = SPR_AGGR,
	frame = A,
	tics = 1,
	action = nil,
	var1 = 0, 
	var2 = 0,
	nextstate = S_AGGROMANEN_RAISE3
}

states[S_AGGROMANEN_RAISE3] = {
	sprite = SPR_AGGR,
	frame = A,
	tics = 2,
	action = A_Boss1Spikeballs,
	var1 = 1, 
	var2 = 3,
	nextstate = S_AGGROMANEN_RAISE4
}

states[S_AGGROMANEN_RAISE4] = {
	sprite = SPR_AGGR,
	frame = A,
	tics = 1,
	action = nil,
	var1 = 0, 
	var2 = 0,
	nextstate = S_AGGROMANEN_RAISE5
}

states[S_AGGROMANEN_RAISE5] = {
	sprite = SPR_AGGR,
	frame = A,
	tics = 2,
	action = A_Boss1Spikeballs,
	var1 = 2, 
	var2 = 3,
	nextstate = S_AGGROMANEN_RAISE6
}

states[S_AGGROMANEN_RAISE6] = {
	sprite = SPR_AGGR,
	frame = A,
	tics = 17,
	action = A_BossZoom,
	var1 = 0,
	var2 = 0,
	nextstate = S_AGGROMANEN_IDLE
}

mobjinfo[MT_AGGROMANEN] = {
	spawnhealth = 8,
	spawnstate = S_AGGROMANEN_IDLE,
	seestate = S_AGGROMANEN_IDLE,
	painstate = S_AGGROMANEN_PAIN,
	painsound = sfx_dmpain,
	meleestate = S_AGGROMANEN_SPIKEBALL,
	missilestate = S_AGGROMANEN_LASER,
	deathstate = S_AGGROMANEN_FLEE,
	xdeathstate = S_AGGROMANEN_FLEE,
	deathsound = sfx_cybdth,
	activesound = sfx_telept,
	raisestate = S_AGGROMANEN_RAISE,
	reactiontime = 45,
	painchance = MT_THOK,
	speed = 4,
	radius = 24*FRACUNIT,
	height = 76*FRACUNIT,
	damage = 3,
	flags = MF_SPECIAL|MF_SHOOTABLE|MF_FLOAT|MF_NOGRAVITY|MF_BOSS
}

addHook("MobjThinker", function(egg)
	for p in players.iterate do
		if not (p.mo and p.mo.valid) then return end
		if p.mo.skin ~= "specki" and p.mo.skin ~= "mechaspecki" then return end
		if not egg and egg.valid then return end
		if not egg.health then return end
		local aggro = P_SpawnMobj(egg.x, egg.y, egg.z, MT_AGGROMANEN)
		aggro.flags = egg.flags
		aggro.flags2 = egg.flags2|MF2_BOSSNOTRAP
		aggro.eflags = egg.eflags
		aggro.health = egg.health
		aggro.scale = egg.scale
		aggro.angle = egg.angle
		if mapheaderinfo[gamemap].musname == "VSBOSS" then
			S_ChangeMusic("VSOBOS", true)
		end
		P_RemoveMobj(egg)
		return
	end
end, MT_EGGMOBILE)

addHook("MobjThinker", function(mobj)
	if (mobj.flags2 & MF2_FRET) and states[mobj.state].nextstate == mobj.info.spawnstate and mobj.tics == 1 then
		mobj.flags2 = $ & ~(MF2_FRET|MF2_SKULLFLY)
		mobj.momx = 0
		mobj.momy = 0
		mobj.momz = 0
	end

	if (not mobj.tracer) then
		A_BossJetFume(mobj, 0)
	end

	if (not mobj.target or not (mobj.target.flags & MF_SHOOTABLE)) then
		if (mobj.target and mobj.target.health 
		and mobj.target.type == MT_EGGMOBILE_TARGET) // Oh, we're just firing our laser.
		then
			return // It's okay, then.
		end

		if (mobj.health <= 0) then
			return
		end

		// look for a new target
		if (P_BossTargetPlayer(mobj, false) and mobj.info.seesound)
			S_StartSound(mobj, mobj.info.seesound)
		end

		return
	end

	if (mobj.flags2 & MF2_SKULLFLY) then
		local dist = (mobj.eflags & MFE_VERTICALFLIP) and ((mobj.ceilingz-(2*mobj.height)) - (mobj.z+mobj.height)) or (mobj.z - (mobj.floorz+(2*mobj.height)))
		if (dist > 0 and P_MobjFlip(mobj)*mobj.momz > 0) then
			mobj.momz = FixedMul(mobj.momz, FRACUNIT - (dist>>12))
		end
	elseif (mobj.state ~= mobj.info.spawnstate and mobj.health > 0 and mobj.flags & MF_FLOAT) then
		mobj.momz = FixedMul(mobj.momz,7*FRACUNIT/8)
	end

	if (mobj.state == mobj.info.meleestate
		or (mobj.state == mobj.info.missilestate
		and mobj.health > mobj.info.damage))
	then
		mobj.angle = R_PointToAngle2(mobj.x, mobj.y, mobj.target.x, mobj.target.y)
	end
end, MT_AGGROMANEN)