// 2.1 Eggmobile - Ported from 2.1.25
// PLEASE LOAD LUA_CMMN, LUA_OJTF AND LUA_EMCM BEFORE THIS

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)
	if not (actor and actor.valid) then return end
	
	local x, y, z, floorz, speed
	local i
	local angle
	local point
	
	if not (actor.target and actor.target.valid) then return true end

	if var2 == 0 then
		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) then
			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 then
		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) then
			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) then
		actor.angle = R_PointToAngle2(x, y, actor.target.x, actor.target.y)
		if mobjinfo[var1].seesound then
			S_StartSound(actor, mobjinfo[var1].seesound)
		end
		if not (actor.spawnpoint and (actor.spawnpoint.options & MTF_AMBUSH)) then
			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 then// 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 and actor.laserTarget.valid) then
		actor.laserTarget = point
	end
	
	if actor.spawnpoint and (actor.spawnpoint.options & MTF_AMBUSH) then
		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) then 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) then
		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 then
		actor.firing = true
	else
		actor.firing = false
	end
end

function A_21FocusTarget(actor, var1, var2)
	if not (actor and actor.valid) then return end
	
	if actor.target and actor.target.valid and actor.followPlayer then
		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 then
			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 then
			if dist > speed then
				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_MoveOrigin(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)
	if not (actor and actor.valid) then return end
	
	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

// Make the 2.1 Egg Mobile spawn 128 FRACUNITS off the ground if its map thing's z-position hasn't been set
addHook("MapThingSpawn", function(mobj, mapthing)
	if not (mobj and mobj.valid
	and mapthing and mapthing.valid) then
		return
	end
	
	local offset
	
	if mapthing.z ~= 0 then
		offset = mapthing.z
	else
		offset = 128*FRACUNIT
	end
	
	if (mapthing.options & MTF_OBJECTFLIP) then
		if offset ~= 0 then
			mobj.z = mobj.z - offset
		else
			mobj.z = mobj.ceilingz
		end
	else
		if offset ~= 0 then
			mobj.z = mobj.z + offset
		else
			mobj.z = mobj.floorz
		end
	end
end, MT_21EGGMOBILE)

// Initializes variables for the 2.1 Egg Mobile
addHook("MobjSpawn", function(mobj)
	if not (mobj and mobj.valid) then return end
	
	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)
	if not (mobj and mobj.valid) then return end
	mobj.followPlayer = false
end, MT_21EGGMOBILE_TARGET)

// Prevents the 2.1 Egg Mobile from stopping when it approaches the player in its panic state
addHook("MobjMoveCollide", function(tmthing, thing)
	if not (tmthing and tmthing.valid
	and thing and thing.valid) then
		return
	end
	
	// Only go through objects if the 2.0 Egg Mobile is in "SKULLFLY" mode
	if not (tmthing.flags2 & MF2_SKULLFLY) then return end
	
	return false
end, MT_21EGGMOBILE)

// Prevents the 2.1 Egg Mobile from bouncing off of the walls in "SKULLFLY" mode
addHook("MobjMoveBlocked", function(mobj)
	if not (mobj and mobj.valid) then return end
	
	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 not (target and target.valid) then return end
	
	if (target.flags2 & MF2_SKULLFLY) then
		target.flags2 = $ & ~MF2_SKULLFLY
	end
	if target.firing then
		target.firing = false
	end
end, MT_21EGGMOBILE)

// Ported BossThinker behavior for 2.1 Eggmobile from 2.1.25
addHook("BossThinker", function(mobj)
	if not (mobj and mobj.valid) then return end
	
	if mobj.health < mobj.info.damage+1 and (leveltime & 1) and mobj.health > 0 then
		P_SpawnMobj(mobj.x, mobj.y, mobj.z, MT_SMOKE) // Replace MT_SMOKE with MT_21SMOKE if necessary
	end
	if mobj.flags2 & MF2_SKULLFLY then
		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) then
		mobj.flags2 = $ & ~(MF2_FRET|MF2_SKULLFLY)
		mobj.momx = 0
		mobj.momy = 0
		mobj.momz = 0
	end
	
	if not (mobj.tracer and mobj.tracer.valid) then A_OldBossJetFumes(mobj, 0, 0) end
	
	if not (mobj.target and mobj.target.valid and (mobj.target.flags & MF_SHOOTABLE)) then
		if mobj.target and mobj.target.valid and mobj.target.health and mobj.target.type == MT_21EGGMOBILE_TARGET then // Oh, we're just firing our laser.
			return true // It's okay, then.
		end
		
		if mobj.health <= 0 then
			if P_BossTargetPlayer(mobj, false) and mobj.info.mass then // 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 then
			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) 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
	
	// Prevents the 2.1 Egg Mobile from floating downwards when the player gets too close
	if not (mobj.flags2 & MF2_INFLOAT) then
		mobj.flags2 = $|MF2_INFLOAT
	end
	
	return true
end, MT_21EGGMOBILE)

addHook("BossDeath", function(mo)
	if not (mo and mo.valid) then return end
	A_21BossDeath(mo)
	return true
end, MT_21EGGMOBILE)

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

addHook("MobjThinker", function(mobj)
	if not (mobj and mobj.valid) then return end
	
	if mobj.scale == mobj.destscale then
		mobj.destscale = FRACUNIT
		mobj.scalespeed = FRACUNIT/8
	end
end, MT_21EGGMOBILE_FIRE)

mobjinfo[MT_21EGGMOBILE] = {
	//$Name 2.1 Eggmobile
	//$Sprite 21EMA1
	//$Category Bosses
	//$Flags4Text End level on death
	//$Flags8Text Alternate laser attack
	doomednum = 224,
	spawnstate = S_21EGGMOBILE_STND,
	spawnhealth = 8,
	seestate = S_21EGGMOBILE_STND,
	reactiontime = 45,
	painstate = S_21EGGMOBILE_PAIN,
	painchance = MT_THOK,
	painsound = sfx_dmpain,
	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] =	{SPR_21EM,	A,	1,	A_Boss1Chase,	0,	0,	S_21EGGMOBILE_STND}

states[S_21EGGMOBILE_LATK1] =	{SPR_21EM,	B,	3,	A_FaceTarget,	0,				0,	S_21EGGMOBILE_LATK2}
states[S_21EGGMOBILE_LATK2] =	{SPR_21EM,	C,	15,	nil,			0,				0,	S_21EGGMOBILE_LATK3}
states[S_21EGGMOBILE_LATK3] =	{SPR_21EM,	D,	2,	A_FaceTarget,	0,				0,	S_21EGGMOBILE_LATK4}
states[S_21EGGMOBILE_LATK4] =	{SPR_21EM,	E,	1,	nil,			0,				0,	S_21EGGMOBILE_LATK5}
states[S_21EGGMOBILE_LATK5] =	{SPR_21EM,	F,	1,	nil,			0,				0,	S_21EGGMOBILE_LATK6}
states[S_21EGGMOBILE_LATK6] =	{SPR_21EM,	G,	1,	nil,			0,				0,	S_21EGGMOBILE_LATK7}
states[S_21EGGMOBILE_LATK7] =	{SPR_21EM,	H,	1,	nil,			0,				0,	S_21EGGMOBILE_LATK8}
states[S_21EGGMOBILE_LATK8] =	{SPR_21EM,	I,	45,	A_21Boss1Laser,	MT_OLDLASER,	0,	S_21EGGMOBILE_LATK9}
states[S_21EGGMOBILE_LATK9] =	{SPR_21EM,	J,	10,	nil,			0,				0,	S_21EGGMOBILE_LATK10}
states[S_21EGGMOBILE_LATK10] =	{SPR_21EM,	K,	2,	A_FaceTarget,	0,				0,	S_21EGGMOBILE_STND}

states[S_21EGGMOBILE_RATK1] =	{SPR_21EM,	L,	3,	A_FaceTarget,	0,				0,	S_21EGGMOBILE_RATK2}
states[S_21EGGMOBILE_RATK2] =	{SPR_21EM,	M,	15,	nil,			0,				0,	S_21EGGMOBILE_RATK3}
states[S_21EGGMOBILE_RATK3] =	{SPR_21EM,	N,	2,	A_FaceTarget,	0,				0,	S_21EGGMOBILE_RATK4}
states[S_21EGGMOBILE_RATK4] =	{SPR_21EM,	O,	1,	nil,			0,				0,	S_21EGGMOBILE_RATK5}
states[S_21EGGMOBILE_RATK5] =	{SPR_21EM,	P,	1,	nil,			0,				0,	S_21EGGMOBILE_RATK6}
states[S_21EGGMOBILE_RATK6] =	{SPR_21EM,	Q,	1,	nil,			0,				0,	S_21EGGMOBILE_RATK7}
states[S_21EGGMOBILE_RATK7] =	{SPR_21EM,	R,	1,	nil,			0,				0,	S_21EGGMOBILE_RATK8}
states[S_21EGGMOBILE_RATK8] =	{SPR_21EM,	S,	45,	A_21Boss1Laser,	MT_OLDLASER,	1,	S_21EGGMOBILE_RATK9}
states[S_21EGGMOBILE_RATK9] =	{SPR_21EM,	T,	10,	nil,			0,				0,	S_21EGGMOBILE_RATK10}
states[S_21EGGMOBILE_RATK10] =	{SPR_21EM,	U,	2,	A_FaceTarget,	0,				0,	S_21EGGMOBILE_STND}

states[S_21EGGMOBILE_PANIC1] =	{SPR_21EM,	D,	12,	nil,					0,	0,	S_21EGGMOBILE_PANIC2}
states[S_21EGGMOBILE_PANIC2] =	{SPR_21EM,	E,	4,	A_21Boss1Spikeballs,	0,	4,	S_21EGGMOBILE_PANIC3}
states[S_21EGGMOBILE_PANIC3] =	{SPR_21EM,	D,	5,	nil,					0,	0,	S_21EGGMOBILE_PANIC4}
states[S_21EGGMOBILE_PANIC4] =	{SPR_21EM,	E,	4,	A_21Boss1Spikeballs,	1,	4,	S_21EGGMOBILE_PANIC5}
states[S_21EGGMOBILE_PANIC5] =	{SPR_21EM,	D,	5,	nil,					0,	0,	S_21EGGMOBILE_PANIC6}
states[S_21EGGMOBILE_PANIC6] =	{SPR_21EM,	E,	4,	A_21Boss1Spikeballs,	2,	4,	S_21EGGMOBILE_PANIC7}
states[S_21EGGMOBILE_PANIC7] =	{SPR_21EM,	D,	5,	nil,					0,	0,	S_21EGGMOBILE_PANIC8}
states[S_21EGGMOBILE_PANIC8] =	{SPR_21EM,	E,	4,	A_21Boss1Spikeballs,	3,	4,	S_21EGGMOBILE_PANIC9}
states[S_21EGGMOBILE_PANIC9] =	{SPR_21EM,	D,	5,	nil,					0,	0,	S_21EGGMOBILE_PANIC10}
states[S_21EGGMOBILE_PANIC10] =	{SPR_21EM,	A,	35,	A_SkullAttack,			0,	0,	S_21EGGMOBILE_STND}

states[S_21EGGMOBILE_PAIN] =	{SPR_21EM,	V,	24,	A_Pain,			0,	0,	S_21EGGMOBILE_PAIN2}
states[S_21EGGMOBILE_PAIN2] =	{SPR_21EM,	V,	16,	A_SkullAttack,	1,	1,	S_21EGGMOBILE_STND}

// 2.1 Egg Mobile Spikeball

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,
	mass = DMG_SPIKE,
	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
}

// Replace A_UnidusBall with a 2.1 variant, if it changes in the future
states[S_21EGGMOBILE_BALL] = {SPR_OUNI, B, 1, A_UnidusBall, 2, 0, S_21EGGMOBILE_BALL}

// 2.1 Egg Mobile Target (required for the laser to function properly)

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] = {SPR_NULL, 0, 1, A_21FocusTarget, 0, 0, S_21EGGMOBILE_TARGET}

// 2.1 Egg Mobile Laser

mobjinfo[MT_OLDLASER] = {
	doomednum = -1,
	spawnstate = S_OLDLASER,
	spawnhealth = 1000,
	seesound = sfx_rlaunc,
	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] = {SPR_MISL, A|FF_FULLBRIGHT, 2, nil, 0, 0, S_NULL}

// 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
}
