// 2.1 Eggmobile - Ported from 2.1.25

freeslot(
	// Sprites
	"SPR_21EM",
	"SPR_OUNI",
	// Objects
	"MT_21EGGMOBILE",
	"MT_21EGGMOBILE_BALL",
	"MT_OLDLASER",
	"MT_21EGGMOBILE_FIRE",
	"MT_21EGGMOBILE_TARGET",
	// States
	"S_21EGGMOBILE_STND",
	"S_21EGGMOBILE_LATK1",
	"S_21EGGMOBILE_LATK2",
	"S_21EGGMOBILE_LATK3",
	"S_21EGGMOBILE_LATK4",
	"S_21EGGMOBILE_LATK5",
	"S_21EGGMOBILE_LATK6",
	"S_21EGGMOBILE_LATK7",
	"S_21EGGMOBILE_LATK8",
	"S_21EGGMOBILE_LATK9",
	"S_21EGGMOBILE_LATK10",
	"S_21EGGMOBILE_RATK1",
	"S_21EGGMOBILE_RATK2",
	"S_21EGGMOBILE_RATK3",
	"S_21EGGMOBILE_RATK4",
	"S_21EGGMOBILE_RATK5",
	"S_21EGGMOBILE_RATK6",
	"S_21EGGMOBILE_RATK7",
	"S_21EGGMOBILE_RATK8",
	"S_21EGGMOBILE_RATK9",
	"S_21EGGMOBILE_RATK10",
	"S_21EGGMOBILE_PANIC1",
	"S_21EGGMOBILE_PANIC2",
	"S_21EGGMOBILE_PANIC3",
	"S_21EGGMOBILE_PANIC4",
	"S_21EGGMOBILE_PANIC5",
	"S_21EGGMOBILE_PANIC6",
	"S_21EGGMOBILE_PANIC7",
	"S_21EGGMOBILE_PANIC8",
	"S_21EGGMOBILE_PANIC9",
	"S_21EGGMOBILE_PANIC10",
	"S_21EGGMOBILE_PAIN",
	"S_21EGGMOBILE_PAIN2",
	"S_21EGGMOBILE_DIE1",
	"S_21EGGMOBILE_DIE2",
	"S_21EGGMOBILE_DIE3",
	"S_21EGGMOBILE_DIE4", // Originally went up to 14
	"S_21EGGMOBILE_FLEE1",
	"S_21EGGMOBILE_FLEE2",
	"S_21EGGMOBILE_BALL",
	"S_21EGGMOBILE_TARGET",
	"S_OLDLASER"
	// Add states for MT_EGGMOBILE_FIRE, if SPR_SFLM changes in the future
	/*
	"S_21SPINFIRE1",
	"S_21SPINFIRE2",
	"S_21SPINFIRE3",
	"S_21SPINFIRE4",
	"S_21SPINFIRE5",
	"S_21SPINFIRE6"
	*/
	)

// A_Boss1Laser ported from 2.1.25
function A_21Boss1Laser(actor, var1, var2)
	local x, y, z, floorz, speed
	local i
	local angle
	local point
	
	if not actor.target
		return true
	end

	if var2 == 0
		x = actor.x + P_ReturnThrustX(actor, actor.angle+ANGLE_90, FixedMul(43*FRACUNIT, actor.scale))
		y = actor.y + P_ReturnThrustY(actor, actor.angle+ANGLE_90, FixedMul(43*FRACUNIT, actor.scale))
		if (actor.eflags & MFE_VERTICALFLIP)
			z = actor.z + actor.height - FixedMul(56*FRACUNIT, actor.scale) - mobjinfo[var1].height
		else
			z = actor.z + FixedMul(56*FRACUNIT, actor.scale)
		end
		//break
	elseif var2 == 1
		x = actor.x + P_ReturnThrustX(actor, actor.angle-ANGLE_90, FixedMul(43*FRACUNIT, actor.scale))
		y = actor.y + P_ReturnThrustY(actor, actor.angle-ANGLE_90, FixedMul(43*FRACUNIT, actor.scale))
		if (actor.eflags & MFE_VERTICALFLIP)
			z = actor.z + actor.height - FixedMul(56*FRACUNIT, actor.scale) - mobjinfo[var1].height
		else
			z = actor.z + FixedMul(56*FRACUNIT, actor.scale)
		end
		//break
	else
		x = actor.x
		y = actor.y
		z = actor.z + actor.height/2
		//break
	end
	
	if not (actor.firing)
		actor.angle = R_PointToAngle2(x, y, actor.target.x, actor.target.y)
		if mobjinfo[var1].seesound
			S_StartSound(actor, mobjinfo[var1].seesound)
		end
		if not (actor.spawnpoint and (actor.spawnpoint.options & MTF_AMBUSH))
			point = P_SpawnMobj(x + P_ReturnThrustX(actor, actor.angle, actor.radius), y + P_ReturnThrustY(actor, actor.angle, actor.radius), actor.z - actor.height / 2, MT_21EGGMOBILE_TARGET) // Replace with MT_21EGGMOBILE_TARGET if necessary
			point.fuse = actor.tics+1
			point.target = actor.target
			actor.target = point
			point.followPlayer = true // Let it follow the player
		else // Don't aim for the player, aim for the target
			point = P_SpawnMobj(actor.target.x, actor.target.y, actor.target.z, MT_21EGGMOBILE_TARGET) // Replace with MT_21EGGMOBILE_TARGET if necessary
			point.fuse = actor.tics+1
			point.target = actor.target
			actor.target = point
		end
	elseif actor.target// and not (actor.spawnpoint and (actor.spawnpoint.options & MTF_AMBUSH))
		actor.angle = R_PointToAngle2(x, y, actor.target.x, actor.target.y)
	end
	
	// Make sure the actor points to the target and not the player
	if not actor.laserTarget or not actor.laserTarget.valid
		actor.laserTarget = point
	end
	
	if actor.spawnpoint and (actor.spawnpoint.options & MTF_AMBUSH)
		angle = FixedAngle(FixedDiv(actor.tics*160*FRACUNIT, states[actor.state].tics*FRACUNIT) + 10*FRACUNIT)
	else
		angle = R_PointToAngle2(z + (mobjinfo[var1].height / 2), 0, actor.target.z, R_PointToDist2(x, y, actor.target.x, actor.target.y))
	end
	point = P_SpawnMobj(x, y, z, var1)
	point.target = actor
	point.angle = actor.angle
	speed = point.radius*2
	point.momz = FixedMul(cos(angle), speed)
	point.momx = FixedMul(sin(angle), FixedMul(cos(point.angle), speed))
	point.momy = FixedMul(sin(angle), FixedMul(sin(point.angle), speed))
	
	for i=0, 256, 1 do
		local mo = P_SpawnMobj(point.x, point.y, point.z, point.type)
		mo.angle = point.angle
		//P_UnsetThingPosition(mo)
		mo.flags = MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_SCENERY
		//P_SetThingPosition(mo)
		
		x = point.x
		y = point.y
		z = point.z
		
		if P_RailThinker(point)
			break
		end
	end
	
	floorz = P_FloorzAtPos(x, y, z, mobjinfo[MT_21EGGMOBILE_FIRE].height) // Relace MT_EGGMOBILE_FIRE with MT_21EGGMOBILE_FIRE if necessary
	if (z - floorz < mobjinfo[MT_21EGGMOBILE_FIRE].height / 2)
		point = P_SpawnMobj(x, y, floorz+1, MT_21EGGMOBILE_FIRE)
		point.target = actor
		point.destscale = 3*FRACUNIT
		point.scalespeed = FRACUNIT / (2^2)
		point.fuse = TICRATE
	end
	
	if actor.tics > 1
		actor.firing = true
	else
		actor.firing = false
	end
end

function A_21FocusTarget(actor, var1, var2)
	if actor.target and actor.followPlayer
		local speed = FixedMul(actor.info.speed, actor.scale)
		local dist = R_PointToDist2(actor.x, actor.y, actor.target.x, actor.target.y)
		local vangle = R_PointToAngle2(actor.z, 0, actor.target.z + (actor.target.height / 2), dist)
		local hangle = R_PointToAngle2(actor.x, actor.y, actor.target.x, actor.target.y)
		if var1 == 0
			actor.momx = $ - actor.momx / (2^4)
			actor.momy = $ - actor.momy / (2^4)
			actor.momz = $ - actor.momz / (2^4)
			actor.momz = $ + FixedMul(cos(vangle), speed)
			actor.momx = $ + FixedMul(sin(vangle), FixedMul(cos(hangle), speed))
			actor.momy = $ + FixedMul(sin(vangle), FixedMul(sin(hangle), speed))
		elseif var1 == 1
			if dist > speed
				actor.momz = FixedMul(cos(vangle), speed)
				actor.momx = FixedMul(sin(vangle), FixedMul(cos(hangle), speed))
				actor.momy = FixedMul(sin(vangle), FixedMul(sin(hangle), speed))
			else
				actor.momx = 0
				actor.momy = 0
				actor.momz = 0
				P_TeleportMove(actor, actor.x, actor.y, actor.target.z + (actor.target.height / 2))
				P_TryMove(actor, actor.target.x, actor.target.y, true)
			end
		end
	end
end

function A_21Boss1Spikeballs(actor, var1, var2)
	local ball = P_SpawnMobj(actor.x, actor.y, actor.z, MT_21EGGMOBILE_BALL)
	ball.target = actor
	ball.movedir = FixedAngle(FixedMul(FixedDiv(var1*(2^FRACBITS), var2*(2^FRACBITS)), 360*(2^FRACBITS)))
	ball.threshold = ball.radius + actor.radius + ball.info.painchance
	
	S_StartSound(ball, ball.info.seesound)
end

addHook("MapThingSpawn", function(mobj, mapthing)
	local offset
	
	if mapthing.z != 0
		offset = mapthing.z
	else
		offset = 128*FRACUNIT
	end
	
	if (mapthing.options & MTF_OBJECTFLIP)
		if offset != 0
			mobj.z = mobj.z - offset
		else
			mobj.z = mobj.ceilingz
		end
	else
		if offset != 0
			mobj.z = mobj.z + offset
		else
			mobj.z = mobj.ceilingz
		end
	end
	
end, MT_21EGGMOBILE)

addHook("MobjSpawn", function(mobj)
	mobj.laserTarget = nil
	// The following variable is used to get around some hardcoded nonsense regarding MF2_FIRING,
	// specifically in terms of it automatically changing the angle of the mobj.
	// Change this if the aforementioned "hardcoded nonsense" has been taken care of 
	mobj.firing = false
end, MT_21EGGMOBILE)

addHook("MobjSpawn", function(mobj)
	mobj.followPlayer = false
end, MT_21EGGMOBILE_TARGET)

// Prevent the 2.1 Egg Mobile from stopping when it approaches the player in its panic state
addHook("MobjMoveCollide", function(tmthing, thing)
	return false
end, MT_21EGGMOBILE)

// Prevents the 2.1 Egg Mobile from bouncing off of the walls when
addHook("MobjMoveBlocked", function(mobj)
	mobj.flags2 = $ & ~MF2_SKULLFLY
	mobj.momx = 0
	mobj.momy = 0
	mobj.momz = 0
	return true
end, MT_21EGGMOBILE)

addHook("MobjDamage", function(target, inflictor, source)
	if (target.flags2 & MF2_SKULLFLY)
		target.flags2 = $ & ~MF2_SKULLFLY
	end
	if target.firing
		target.firing = false
	end
end, MT_21EGGMOBILE)

// Ported BossThinker behavior for 2.1 Eggmobile from 2.1.25
addHook("BossThinker", function(mobj)
	
	if mobj.health < mobj.info.damage+1 and (leveltime & 1) and mobj.health > 0
		P_SpawnMobj(mobj.x, mobj.y, mobj.z, MT_SMOKE) // Replace MT_SMOKE with MT_21SMOKE if necessary
	end
	if mobj.flags2 & MF2_SKULLFLY
		P_SpawnGhostMobj(mobj)
		
		/*
		local spawnmobj
		spawnmobj = P_SpawnMobj(mobj.x, mobj.y, mobj.z, mobj.info.painchance)
		spawnmobj.target = mobj
		spawnmobj.color = SKINCOLOR_GREY
		*/
	end
	
	// P_Boss1Thinker ported from 2.1.25 with some fixups from 2.2
	if ((mobj.flags2 & MF2_FRET) and mobj.state == mobj.info.spawnstate)
		mobj.flags2 = $ & ~(MF2_FRET|MF2_SKULLFLY)
		mobj.momx = 0
		mobj.momy = 0
		mobj.momz = 0
	end
	
	if not mobj.tracer
		A_21BossJetFume(mobj, 0, 0)
	end
	
	if not mobj.target or not (mobj.target.flags & MF_SHOOTABLE)
		if mobj.target and mobj.target.health and mobj.target.type == MT_21EGGMOBILE_TARGET // Oh, we're just firing our laser.
			return true // It's okay, then.
		end
		
		if mobj.health <= 0
			if P_BossTargetPlayer(mobj, false) and mobj.info.mass // Bid farewell!
				S_StartSound(mobj, mobj.info.mass)
			end
			
			return true
		end
		
		// look for a new target
		if P_BossTargetPlayer(mobj, false) and mobj.info.seesound
			S_StartSound(mobj, mobj.info.seesound)
			
			return true
		end
	end
	
	if mobj.state != mobj.info.spawnstate and mobj.health > 0 and (mobj.flags & MF_FLOAT) and not (mobj.flags2 & MF2_SKULLFLY)
		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)
		mobj.angle = R_PointToAngle2(mobj.x, mobj.y, mobj.target.x, mobj.target.y)
	end
	
	// Prevent the 2.1 Egg Mobile from floating downwards when the player gets too close
	if not (mobj.flags2 & MF2_INFLOAT)
		mobj.flags2 = $|MF2_INFLOAT
	end
	
	return true
end, MT_21EGGMOBILE)

addHook("BossDeath", function(mo)
	A_21BossDeath(mo)
	return true
end, MT_21EGGMOBILE)

addHook("MobjThinker", function(mobj)
	if mobj.laserTarget and mobj.laserTarget.valid
		mobj.target = mobj.laserTarget
	end
	
	// Continuously run A_21Boss1Laser when it is called
	if (mobj.firing) and mobj.target and mobj.health > 0
		if states[mobj.state].action == A_21Boss1Laser
			A_21Boss1Laser(mobj, states[mobj.state].var1, states[mobj.state].var2)
		end
	end
end, MT_21EGGMOBILE)

addHook("MobjThinker", function(mobj)
	if mobj.scale == mobj.destscale
		mobj.destscale = FRACUNIT
		mobj.scalespeed = FRACUNIT / 8
	end
end, MT_21EGGMOBILE_FIRE)

mobjinfo[MT_21EGGMOBILE] = {
	//$Name 2.1 Eggmobile
	//$Sprite 21EMA1
	//$Category Bosses
	doomednum = 4040,
	spawnstate = S_21EGGMOBILE_STND,
	spawnhealth = 8,
	seestate = S_21EGGMOBILE_STND,
	reactiontime = 45,
	painstate = S_21EGGMOBILE_PAIN,
	painchance = MT_THOK,
	painsound = sfx_odmpai,
	meleestate = S_21EGGMOBILE_LATK1,
	missilestate = S_21EGGMOBILE_RATK1,
	deathstate = S_21EGGMOBILE_DIE1,
	xdeathstate = S_21EGGMOBILE_FLEE1,
	deathsound = sfx_cybdth,
	speed = 4,
	radius = 24*FRACUNIT,
	height = 76*FRACUNIT,
	damage = 3,
	activesound = sfx_telept,
	flags = MF_SPECIAL|MF_SHOOTABLE|MF_FLOAT|MF_NOGRAVITY|MF_BOSS,
	raisestate = S_21EGGMOBILE_PANIC1
}

states[S_21EGGMOBILE_STND] = {
	sprite = SPR_21EM,
	frame = A,
	tics = 1,
	action = A_Boss1Chase,
	nextstate = S_21EGGMOBILE_STND
}

states[S_21EGGMOBILE_LATK1] = {
	sprite = SPR_21EM,
	frame = B,
	tics = 3,
	action = A_FaceTarget,
	nextstate = S_21EGGMOBILE_LATK2
}

states[S_21EGGMOBILE_LATK2] = {
	sprite = SPR_21EM,
	frame = C,
	tics = 15,
	nextstate = S_21EGGMOBILE_LATK3
}

states[S_21EGGMOBILE_LATK3] = {
	sprite = SPR_21EM,
	frame = D,
	tics = 2,
	action = A_FaceTarget,
	nextstate = S_21EGGMOBILE_LATK4
	}

states[S_21EGGMOBILE_LATK4] = {
	sprite = SPR_21EM,
	frame = E,
	tics = 1,
	nextstate = S_21EGGMOBILE_LATK5
}

states[S_21EGGMOBILE_LATK5] = {
	sprite = SPR_21EM,
	frame = F,
	tics = 1,
	nextstate = S_21EGGMOBILE_LATK6
}

states[S_21EGGMOBILE_LATK6] = {
	sprite = SPR_21EM,
	frame = G,
	tics = 1,
	nextstate = S_21EGGMOBILE_LATK7
}

states[S_21EGGMOBILE_LATK7] = {
	sprite = SPR_21EM,
	frame = H,
	tics = 1,
	nextstate = S_21EGGMOBILE_LATK8
}

states[S_21EGGMOBILE_LATK8] = {
	sprite = SPR_21EM,
	frame = I,
	tics = 45,
	action = A_21Boss1Laser,
	var1 = MT_OLDLASER,
	var2 = 0,
	nextstate = S_21EGGMOBILE_LATK9
}

states[S_21EGGMOBILE_LATK9] = {
	sprite = SPR_21EM,
	frame = J,
	tics = 10,
	nextstate = S_21EGGMOBILE_LATK10
}

states[S_21EGGMOBILE_LATK10] = {
	sprite = SPR_21EM,
	frame = K,
	tics = 2,
	action = A_FaceTarget,
	nextstate = S_21EGGMOBILE_STND
}

states[S_21EGGMOBILE_RATK1] = {
	sprite = SPR_21EM,
	frame = L,
	tics = 3,
	action = A_FaceTarget,
	nextstate = S_21EGGMOBILE_RATK2
}

states[S_21EGGMOBILE_RATK2] = {
	sprite = SPR_21EM,
	frame = M,
	tics = 15,
	nextstate = S_21EGGMOBILE_RATK3
}

states[S_21EGGMOBILE_RATK3] = {
	sprite = SPR_21EM,
	frame = N,
	tics = 2,
	action = A_FaceTarget,
	nextstate = S_21EGGMOBILE_RATK4
}

states[S_21EGGMOBILE_RATK4] = {
	sprite = SPR_21EM,
	frame = O,
	tics = 1,
	nextstate = S_21EGGMOBILE_RATK5
}

states[S_21EGGMOBILE_RATK5] = {
	sprite = SPR_21EM,
	frame = P,
	tics = 1,
	nextstate = S_21EGGMOBILE_RATK6
}

states[S_21EGGMOBILE_RATK6] = {
	sprite = SPR_21EM,
	frame = Q,
	tics = 1,
	nextstate = S_21EGGMOBILE_RATK7
}

states[S_21EGGMOBILE_RATK7] = {
	sprite = SPR_21EM,
	frame = R,
	tics = 1,
	nextstate = S_21EGGMOBILE_RATK8
}

states[S_21EGGMOBILE_RATK8] = {
	sprite = SPR_21EM,
	frame = S,
	tics = 45,
	action = A_21Boss1Laser,
	var1 = MT_OLDLASER,
	var2 = 1,
	nextstate = S_21EGGMOBILE_RATK9
}

states[S_21EGGMOBILE_RATK9] = {
	sprite = SPR_21EM,
	frame = T,
	tics = 10,
	nextstate = S_21EGGMOBILE_RATK10
}

states[S_21EGGMOBILE_RATK10] = {
	sprite = SPR_21EM,
	frame = U,
	tics = 2,
	action = A_FaceTarget,
	nextstate = S_21EGGMOBILE_STND
}

states[S_21EGGMOBILE_PANIC1] = {
	sprite = SPR_21EM,
	frame = D,
	tics = 12,
	nextstate = S_21EGGMOBILE_PANIC2
}

states[S_21EGGMOBILE_PANIC2] = {
	sprite = SPR_21EM,
	frame = E,
	tics = 4,
	action = A_21Boss1Spikeballs,
	var1 = 0,
	var2 = 4,
	nextstate = S_21EGGMOBILE_PANIC3
}

states[S_21EGGMOBILE_PANIC3] = {
	sprite = SPR_21EM,
	frame = D,
	tics = 5,
	nextstate = S_21EGGMOBILE_PANIC4
}

states[S_21EGGMOBILE_PANIC4] = {
	sprite = SPR_21EM,
	frame = E,
	tics = 4,
	action = A_21Boss1Spikeballs,
	var1 = 1,
	var2 = 4,
	nextstate = S_21EGGMOBILE_PANIC5
}

states[S_21EGGMOBILE_PANIC5] = {
	sprite = SPR_21EM,
	frame = D,
	tics = 5,
	nextstate = S_21EGGMOBILE_PANIC6
}

states[S_21EGGMOBILE_PANIC6] = {
	sprite = SPR_21EM,
	frame = E,
	tics = 4,
	action = A_21Boss1Spikeballs,
	var1 = 2,
	var2 = 4,
	nextstate = S_21EGGMOBILE_PANIC7
}

states[S_21EGGMOBILE_PANIC7] = {
	sprite = SPR_21EM,
	frame = D,
	tics = 5,
	nextstate = S_21EGGMOBILE_PANIC8
}

states[S_21EGGMOBILE_PANIC8] = {
	sprite = SPR_21EM,
	frame = E,
	tics = 4,
	action = A_21Boss1Spikeballs,
	var1 = 3,
	var2 = 4,
	nextstate = S_21EGGMOBILE_PANIC9
}

states[S_21EGGMOBILE_PANIC9] = {
	sprite = SPR_21EM,
	frame = D,
	tics = 5,
	nextstate = S_21EGGMOBILE_PANIC10
}

states[S_21EGGMOBILE_PANIC10] = {
	sprite = SPR_21EM,
	frame = A,
	tics = 35,
	action = A_SkullAttack,
	var1 = 0,
	var2 = 0,
	nextstate = S_21EGGMOBILE_STND
}

states[S_21EGGMOBILE_PAIN] = {
	sprite = SPR_21EM,
	frame = V,
	tics = 24,
	action = A_Pain,
	nextstate = S_21EGGMOBILE_PAIN2
}

states[S_21EGGMOBILE_PAIN2] = {
	sprite = SPR_21EM,
	frame = V,
	tics = 16,
	action = A_SkullAttack,
	var1 = 1,
	var2 = 1,
	nextstate = S_21EGGMOBILE_STND
}

states[S_21EGGMOBILE_DIE1] = {
	sprite = SPR_21EM,
	frame = W,
	tics = 8,
	action = A_Fall,
	nextstate = S_21EGGMOBILE_DIE2
}

states[S_21EGGMOBILE_DIE2] = {
	sprite = SPR_21EM,
	frame = W,
	tics = 8,
	action = A_BossScream,
	var1 = 0,
	var2 = MT_BOSSEXPLODE,
	nextstate = S_21EGGMOBILE_DIE3
}

states[S_21EGGMOBILE_DIE3] = {
	sprite = SPR_21EM,
	frame = W,
	tics = 0,
	action = A_Repeat,
	var1 = 12,
	var2 = S_21EGGMOBILE_DIE2,
	nextstate = S_21EGGMOBILE_DIE4
}

states[S_21EGGMOBILE_DIE4] = {
	sprite = SPR_21EM,
	frame = W,
	tics = -1,
	action = A_BossDeath
}

states[S_21EGGMOBILE_FLEE1] = {
	sprite = SPR_21EM,
	frame = X,
	tics = 5,
	nextstate = S_21EGGMOBILE_FLEE2
}

states[S_21EGGMOBILE_FLEE2] = {
	sprite = SPR_21EM,
	frame = Y,
	tics = 5,
	nextstate = S_21EGGMOBILE_FLEE1
}

mobjinfo[MT_21EGGMOBILE_BALL] = {
	doomednum = -1,
	spawnstate = S_21EGGMOBILE_BALL,
	spawnhealth = 1,
	seesound = sfx_cannon,
	reactiontime = 1,
	painchance = 40*FRACUNIT,
	speed = 2*FRACUNIT,
	radius = 13*FRACUNIT,
	height = 26*FRACUNIT,
	damage = 8*FRACUNIT,
	flags = MF_PAIN|MF_NOGRAVITY|MF_NOCLIPHEIGHT // MF_NOCLIP and MF_NOCLIPTHING (present in 2.1's spikeball) result in this object being intangible when attached to a boss
}

states[S_21EGGMOBILE_BALL] = {
	sprite = SPR_OUNI,
	frame = B,
	tics = 1,
	action = A_UnidusBall, // Replace this with a 2.1 variant, if necenssary
	var1 = 2,
	var2 = 0,
	nextstate = S_21EGGMOBILE_BALL
}

mobjinfo[MT_21EGGMOBILE_TARGET] = {
	doomednum = -1,
	spawnstate = S_21EGGMOBILE_TARGET,
	spawnhealth = 1,
	speed = 2*FRACUNIT,
	flags = MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY
}

states[S_21EGGMOBILE_TARGET] = {
	sprite = SPR_NULL,
	tics = 1,
	action = A_21FocusTarget,
	nextstate = S_21EGGMOBILE_TARGET
}

// 2.1 Egg Mobile Laser

mobjinfo[MT_OLDLASER] = {
	doomednum = -1,
	spawnstate = S_OLDLASER,
	spawnhealth = 1000,
	seesound = sfx_orlaun,
	reactiontime = 8,
	speed = 20*FRACUNIT,
	radius = 11*FRACUNIT,
	height = 8*FRACUNIT,
	mass = 100,
	damage = 20,
	flags = MF_NOBLOCKMAP|MF_MISSILE|MF_NOGRAVITY
}

states[S_OLDLASER] = {
	sprite = SPR_MISL,
	frame = A|FF_FULLBRIGHT,
	tics = 2
}

// 2.1 Egg Mobile Laser Fire
mobjinfo[MT_21EGGMOBILE_FIRE] = {
	doomednum = -1,
	spawnstate = S_SPINFIRE1,
	spawnhealth = 1,
	reactiontime = 8,
	radius = 8*FRACUNIT,
	height = 14*FRACUNIT,
	mass = 100,
	damage = 1,
	flags = MF_NOBLOCKMAP|MF_NOGRAVITY|MF_FIRE|MF_PAIN
}
