// 2.1 Boss Commonalities - Ported from 2.1.25

freeslot(
	// Sprites
	"SPR_OJTF",
	"SPR_PRPL", // Replace this with SPR_OPRL if it gets used in the future
	"SPR_OEFR",
	// Sounds
	"sfx_odmpai",
	"sfx_orlaun",
	"sfx_osprin",
	// Objects
	"MT_21JETFUME1",
	"MT_PROPELLER", // Replace this with MT_OLDPROPELLER if it gets used in the future
	"MT_21JETFLAME",
	// States
	"S_21JETFUME1",
	"S_21JETFUME2",
	"S_PROPELLER1",
	"S_PROPELLER2",
	"S_PROPELLER3",
	"S_PROPELLER4",
	"S_PROPELLER5",
	"S_PROPELLER6",
	"S_PROPELLER7",
	"S_21JETFLAME1",
	"S_21JETFLAME2"
)

sfxinfo[sfx_odmpai].caption = "Legacy machine damage"
sfxinfo[sfx_orlaun].caption = "Legacy firing"
sfxinfo[sfx_osprin].caption = "Legacy spring"

// A_BossDeath portion ported from 2.1.25
function A_21BossDeath(actor)
	// Stop exploding and prepare to run.
	actor.state = actor.info.xdeathstate
	if not actor.valid
		return
	end
	
	actor.target = nil
	
	// Flee! Flee! Find a point to escape to! If none, just shoot upward!
	// scan the thinkers to find the runaway point
	for th in mobjs.iterate()
		if th.type == MT_BOSSFLYPOINT
			// If this one's closer then the last one, go for it
			if not actor.target or
				FixedHypot(FixedHypot(actor.x - th.x, actor.y - th.y), actor.z - th.z) <
				FixedHypot(FixedHypot(actor.x - actor.target.x, actor.y - actor.target.y), actor.z - actor.target.z)
					actor.target = th
			end
			// Otherwise... Don't!
		end
	end
	
	actor.flags = $|MF_NOGRAVITY|MF_NOCLIP
	actor.flags = $|MF_NOCLIPHEIGHT
	
	if actor.target
		actor.angle = R_PointToAngle2(actor.x, actor.y, actor.target.x, actor.target.y)
		actor.flags2 = $|MF2_BOSSFLEE
		actor.momz = FixedMul(FixedDiv(actor.target.z - actor.z, FixedHypot(actor.x-actor.target.x,actor.y-actor.target.y)), FixedMul(2*FRACUNIT, actor.scale))
	else
		actor.momz = FixedMul(2*FRACUNIT, actor.scale)
	end
end

// A_BossJetFume ported from 2.1.25
function A_21BossJetFume(actor, var1, var2)
	local filler
	
	if var1 == 0 // Boss1 jet fumes
		local jetx, jety, jetz
		
		jetx = actor.x + P_ReturnThrustX(actor, actor.angle, -FixedMul(64*FRACUNIT, actor.scale))
		jety = actor.y + P_ReturnThrustY(actor, actor.angle, -FixedMul(64*FRACUNIT, actor.scale))
		if (actor.eflags & MFE_VERTICALFLIP)
			jetz = actor.z + actor.height - FixedMul(38*FRACUNIT + mobjinfo[MT_21JETFUME1].height, actor.scale)
		else
			jetz = actor.z + FixedMul(38*FRACUNIT, actor.scale)
		end
		
		filler = P_SpawnMobj(jetx, jety, jetz, MT_21JETFUME1)
		filler.target = actor
		filler.destscale = actor.scale
		P_SetScale(filler, filler.destscale)
		if (actor.eflags & MFE_VERTICALFLIP)
			filler.flags2 = $|MF2_OBJECTFLIP
		end
		filler.fuse = 56
		
		if (actor.eflags & MFE_VERTICALFLIP)
			jetz = actor.z + actor.height - FixedMul(38*FRACUNIT + mobjinfo[MT_21JETFUME1].height, actor.scale)
		else
			jetz = actor.z + FixedMul(38*FRACUNIT, actor.scale)
		end
		
		filler = P_SpawnMobj(jetx + P_ReturnThrustX(actor, actor.angle-ANGLE_90, FixedMul(24*FRACUNIT, actor.scale)),
							jety + P_ReturnThrustY(actor, actor.angle-ANGLE_90, FixedMul(24*FRACUNIT, actor.scale)),
							jetz, MT_21JETFUME1)
		filler.target = actor
		filler.destscale = actor.scale
		P_SetScale(filler, filler.destscale)
		if (actor.eflags & MFE_VERTICALFLIP)
			filler.flags2 = $|MF2_OBJECTFLIP
		end
		filler.fuse = 57
		
		filler = P_SpawnMobj(jetx + P_ReturnThrustX(actor, actor.angle+ANGLE_90, FixedMul(24*FRACUNIT, actor.scale)),
							jety + P_ReturnThrustY(actor, actor.angle+ANGLE_90, FixedMul(24*FRACUNIT, actor.scale)),
							jetz, MT_21JETFUME1)
		filler.target = actor
		filler.destscale = actor.scale
		P_SetScale(filler, filler.destscale)
		if (actor.eflags & MFE_VERTICALFLIP)
			filler.flags2 = $|MF2_OBJECTFLIP
		end
		filler.fuse = 58
		
		actor.tracer = filler
	elseif var1 == 1 // Boss 3 propeller
		local jetx, jety, jetz
		
		jetx = actor.x + P_ReturnThrustX(actor, actor.angle, -FixedMul(60*FRACUNIT, actor.scale))
		jety = actor.y + P_ReturnThrustY(actor, actor.angle, -FixedMul(60*FRACUNIT, actor.scale))
		if (actor.eflags & MFE_VERTICALFLIP)
			jetz = actor.z + actor.height - FixedMul(17*FRACUNIT + mobjinfo[MT_PROPELLER].height, actor.scale)
		else
			jetz = actor.z + FixedMul(17*FRACUNIT, actor.scale)
		end
		
		filler = P_SpawnMobj(jetx, jety, jetz, MT_PROPELLER)
		filler.target = actor
		filler.destscale = actor.scale
		P_SetScale(filler, filler.destscale)
		if (actor.eflags & MFE_VERTICALFLIP)
			filler.flags2 = $|MF2_OBJECTFLIP
		end
		filler.angle = actor.angle - ANGLE_180
		
		actor.tracer = filler
	elseif var1 == 2 // Metal Sonic jet fumes
		filler = P_SpawnMobj(actor.x, actor.y, actor.z, MT_21JETFUME1)
		filler.target = actor
		filler.fuse = 59
		actor.tracer = filler
		filler.destscale = actor.scale/2
		P_SetScale(filler, filler.destscale)
		if (actor.eflags & MFE_VERTICALFLIP)
			filler.flags2 = $|MF2_OBJECTFLIP
		end
	elseif var1 == 3 // Boss 4 jet flame
		local jetz
		if (actor.eflags & MFE_VERTICALFLIP)
			jetz = actor.z + actor.height + FixedMul(50*FRACUNIT - mobjinfo[MT_21JETFLAME].height, actor.scale)
		else
			jetz = actor.z - FixedMul(50*FRACUNIT, actor.scale)
		end
		filler = P_SpawnMobj(actor.x, actor.y, jetz, MT_21JETFLAME)
		filler.target = actor
		// Boss 4 already uses its tracer for other things
		filler.destscale = actor.scale
		P_SetScale(filler, filler.destscale)
		if (actor.eflags & MFE_VERTICALFLIP)
			filler.flags2 = $|MF2_OBJECTFLIP
		end
	end
end

// 2.0-2.1 Jet Fume

addHook("MobjThinker", function(mobj)
	local jetx, jety, jetz
	
	if not mobj.target // if you have no target
		or (not (mobj.target.flags & MF_BOSS) and mobj.target.health <= 0) // or your target isn't a boss and it's popped now
		// then remove yourself as well!
		P_RemoveMobj(mobj)
		return
	end
	
	jetx = mobj.target.x + P_ReturnThrustX(mobj.target, mobj.target.angle, FixedMul(-64*FRACUNIT, mobj.target.scale))
	jety = mobj.target.y + P_ReturnThrustY(mobj.target, mobj.target.angle, FixedMul(-64*FRACUNIT, mobj.target.scale))
	
	if mobj.fuse == 56 // First one
		if (mobj.target.eflags & MFE_VERTICALFLIP)
			jetz = mobj.target.z + mobj.target.height - mobj.height - FixedMul(38*FRACUNIT, mobj.target.scale)
		else
			jetz = mobj.target.z + FixedMul(38*FRACUNIT, mobj.target.scale)
		end
		P_TeleportMove(mobj, jetx, jety, jetz)
		//mobj.floorz = mobj.z
		//mobj.ceilingz = mobj.z+mobj.height
	elseif mobj.fuse == 57
		if (mobj.target.eflags & MFE_VERTICALFLIP)
			jetz = mobj.target.z + mobj.target.height - mobj.height - FixedMul(12*FRACUNIT, mobj.target.scale)
		else
			jetz = mobj.target.z + FixedMul(12*FRACUNIT, mobj.target.scale)
		end
		P_TeleportMove(mobj, jetx + P_ReturnThrustX(mobj.target, mobj.target.angle-ANGLE_90, FixedMul(24*FRACUNIT, mobj.target.scale)),
							jety + P_ReturnThrustY(mobj.target, mobj.target.angle-ANGLE_90, FixedMul(24*FRACUNIT, mobj.target.scale)),
							jetz)
		//mobj.floorz = mobj.z
		//mobj.ceilingz = mobj.z+mobj.height
	elseif mobj.fuse == 58
		if (mobj.target.eflags & MFE_VERTICALFLIP)
			jetz = mobj.target.z + mobj.target.height - mobj.height - FixedMul(12*FRACUNIT, mobj.target.scale)
		else
			jetz = mobj.target.z + FixedMul(12*FRACUNIT, mobj.target.scale)
		end
		P_TeleportMove(mobj, jetx + P_ReturnThrustX(mobj.target, mobj.target.angle+ANGLE_90, FixedMul(24*FRACUNIT, mobj.target.scale)),
							jety + P_ReturnThrustY(mobj.target, mobj.target.angle+ANGLE_90, FixedMul(24*FRACUNIT, mobj.target.scale)),
							jetz)
		//mobj.floorz = mobj.z
		//mobj.ceilingz = mobj.z+mobj.height
	elseif mobj.fuse == 59
		jetx = mobj.target.x + P_ReturnThrustX(mobj.target, mobj.target.angle, -mobj.target.radius)
		jety = mobj.target.y + P_ReturnThrustY(mobj.target, mobj.target.angle, -mobj.target.radius)
		if (mobj.target.eflags & MFE_VERTICALFLIP)
			jetz = mobj.target.z + mobj.target.height/2 + mobj.height/2
		else
			jetz = mobj.target.z + mobj.target.height/2 - mobj.height/2
		end
		P_TeleportMove(mobj, jetx, jety, jetz)
		//mobj.floorz = mobj.z
		//mobj.ceilingz = mobj.z+mobj.height
	end
	mobj.fuse = $+1
	
	mobj.momz = 0 // Prevent the jetfume from moving vertically
end, MT_21JETFUME1)

mobjinfo[MT_21JETFUME1] = {
	doomednum = -1,
	spawnstate = S_21JETFUME1,
	spawnhealth = 1000,
	reactiontime = 8,
	speed = 1,
	radius = 8*FRACUNIT,
	height = 16*FRACUNIT,
	mass = 4,
	flags = MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOCLIP|MF_NOCLIPHEIGHT
}

states[S_21JETFUME1] = {
	sprite = SPR_OJTF,
	frame = A|FF_FULLBRIGHT,
	tics = 1,
	nextstate = S_21JETFUME2
}

states[S_21JETFUME2] = {
	sprite = SPR_NULL,
	tics = 1,
	nextstate = S_21JETFUME1
}

// 2.0-2.1 Propeller

addHook("MobjThinker", function(mobj)
	local jetx, jety	
	
	if not mobj.target // if you have no target
	or (not (mobj.target.flags & MF_BOSS) and mobj.target.health <= 0) // or your target isn't a boss and it's popped now
	// then remove yourself as well!
		P_RemoveMobj(mobj)
		return
	end
	
	jetx = mobj.target.x + P_ReturnThrustX(mobj.target, mobj.target.angle, FixedMul(-60*FRACUNIT, mobj.target.scale))
	jety = mobj.target.y + P_ReturnThrustY(mobj.target, mobj.target.angle, FixedMul(-60*FRACUNIT, mobj.target.scale))
	
	P_TeleportMove(mobj, jetx, jety, mobj.target.z + FixedMul(17*FRACUNIT, mobj.target.scale))
	mobj.angle = mobj.target.angle - ANGLE_180
	//mobj.floorz = mobj.z
	//mobj.ceilingz = mobj.z+mobj.height
end, MT_PROPELLER)

mobjinfo[MT_PROPELLER] = {
	doomednum = -1,
	spawnstate = S_PROPELLER1,
	spawnhealth = 1000,
	reactiontime = 8,
	speed = 1,
	radius = 4*FRACUNIT,
	height = 4*FRACUNIT,
	mass = 4,
	flags = MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOCLIP|MF_NOCLIPHEIGHT
}

states[S_PROPELLER1] = {
	sprite = SPR_PRPL,
	frame = A,
	tics = 1,
	nextstate = S_PROPELLER2
}

states[S_PROPELLER2] = {
	sprite = SPR_PRPL,
	frame = B,
	tics = 1,
	nextstate = S_PROPELLER3
}

states[S_PROPELLER3] = {
	sprite = SPR_PRPL,
	frame = C,
	tics = 1,
	nextstate = S_PROPELLER4
}

states[S_PROPELLER4] = {
	sprite = SPR_PRPL,
	frame = D,
	tics = 1,
	nextstate = S_PROPELLER5
}

states[S_PROPELLER5] = {
	sprite = SPR_PRPL,
	frame = E,
	tics = 1,
	nextstate = S_PROPELLER6
}

states[S_PROPELLER6] = {
	sprite = SPR_PRPL,
	frame = F,
	tics = 1,
	nextstate = S_PROPELLER7
}

states[S_PROPELLER7] = {
	sprite = SPR_PRPL,
	frame = G,
	tics = 1,
	nextstate = S_PROPELLER1
}

// 2.1 Jet Flame (for Eggscalibur)

addHook("MobjThinker", function(mobj)
	if not mobj.target // if you have no target
	or (not (mobj.target.flags & MF_BOSS) and mobj.target.health <=0)
		P_RemoveMobj(mobj)
		return
	end
	
	P_TeleportMove(mobj, mobj.target.x, mobj.target.y, mobj.target.z - FixedMul(50*FRACUNIT, mobj.target.scale))
end, MT_21JETFLAME)

mobjinfo[MT_21JETFLAME] = {
	doomednum = -1,
	spawnstate = S_21JETFLAME1,
	spawnhealth = 1000,
	reactiontime = 8,
	speed = 1,
	radius = 20*FRACUNIT,
	height = 32*FRACUNIT,
	mass = DMG_FIRE,
	flags = MF_NOGRAVITY|MF_PAIN|MF_FIRE|MF_NOCLIPHEIGHT
}

states[S_21JETFLAME1] = {
	sprite = SPR_OEFR,
	frame = FF_FULLBRIGHT|A,
	tics = 1,
	nextstate = S_21JETFLAME2
}

states[S_21JETFLAME2] = {
	sprite = SPR_OEFR,
	frame = FF_FULLBRIGHT|B,
	tics = 1,
	nextstate = S_21JETFLAME1
}
