// 2.0 Egg Slimer - Ported from 2.0.7
// PLEASE LOAD LUA_CMMN, LUA_OJTF AND LUA_ENCM BEFORE THIS

freeslot(
	// Sprites come from LUA_ENCN
	// Objects
	"MT_20EGGMOBILE2",
	"MT_OLDGOOP",
	// States
	"S_20EGGMOBILE2_POGO1",
	"S_20EGGMOBILE2_POGO2",
	"S_20EGGMOBILE2_POGO3",
	"S_OLDGOOP1",
	"S_OLDGOOP2",
	"S_OLDGOOP3"
)

// 2.0 Egg Slimer

// Mimics the A_Boss2Chase behavior of versions pre-2.1
function A_FDBoss2Chase(actor, var1, var2)
	if not (actor and actor.valid) then return end
	
	local radius
	local reversed = false
	local speedvar = 0
	
	// When reactiontime hits zero, he will go the other way
	if actor.reactiontime then actor.reactiontime = $ - 1 end
	
	if actor.reactiontime <= 0 then
		reversed = true
		actor.reactiontime = 2*TICRATE + P_RandomByte()
	end
	
	actor.target = P_GetClosestAxis(actor)
	
	if not (actor.target and actor.target.valid) then // This should NEVER happen.
		//CONS_Printf("Error: Boss2 has not target!\n")
		print("Error: Boss2 has no target!")
		A_BossDeath(actor)
		return
	end
	
	// Use a hardcoded radius if the Egg Slimer is set to use its pre-1.09.4 behavior
	// Otherwise, use the radius of the closest axis
	if actor.oldBehavior then
		radius = 384*FRACUNIT
	else
		radius = actor.target.radius
	end
	
	if reversed then
		actor.watertop = -$
	end
	
	if not actor.oldBehavior then
		if (actor.flags2 & MF2_AMBUSH) then
			speedvar = actor.health
		else
			speedvar = actor.info.spawnhealth
		end
		
		actor.target.angle = $ + FixedAngle(
									FixedDiv(
										FixedMul(
											actor.watertop,
											actor.info.spawnhealth*(FRACUNIT/4)*3
										),
										speedvar*FRACUNIT
									)
								 ) // Don't use FixedAngleC!
	else
		actor.target.angle = $ + FixedMul(actor.watertop, ANG1)
	end
	
	local fa = actor.target.angle
	local fc = FixedMul(cos(fa), radius)
	local fs = FixedMul(sin(fa), radius)
	actor.angle = R_PointToAngle2(actor.x, actor.y, actor.target.x + fc, actor.target.y + fs)
	
	// Emulate the choppiness of the original boss
	if actor.oldBehavior and (leveltime & 1) then
		P_TeleportMove(actor, actor.target.x + fc, actor.target.y + fs, actor.target.z + 64*FRACUNIT)
	elseif not actor.oldBehavior then
		P_TeleportMove(actor, actor.target.x + fc, actor.target.y + fs, actor.z)
	end
	
	// Put goop spraying code here
	if (actor.oldBehavior and leveltime % 14 == 1)
	or (not actor.oldBehavior and leveltime % (speedvar*15/10)-1 == 0) then
		local ns = 3 * FRACUNIT
		local goop
		local fz = actor.z+actor.height+56*FRACUNIT
		local fa2
		// actor.movedir is used to determine the last
		// direction goo was sprayed in. There are 8 possible
		// directions to spray. (45-degree increments)
		
		actor.movedir = $+1
		actor.movedir = $%NUMDIRS // NUMDIRS should be 8
		fa2 = FixedAngle((actor.movedir*45)*FRACUNIT)
		
		goop = P_SpawnMobj(actor.x, actor.y, fz, actor.info.painchance)
		goop.momx = FixedMul(sin(fa2), ns)
		goop.momy = FixedMul(cos(fa2), ns)
		goop.momz = 4*FRACUNIT
		goop.fuse = 30*TICRATE+P_RandomByte()
		if actor.info.attacksound then
			S_StartSound(actor, actor.info.attacksound)
		end
		
		if (P_RandomByte() & 1) then
			goop.momx = $*2
			goop.momy = $*2
		elseif (P_RandomByte() > 128) then
			goop.momx = $*3
			goop.momy = $*3
		end
		
		actor.flags2 = $|MF2_JUSTATTACKED
	end
end

function A_FDBoss2Pogo(actor, var1, var2)
	if not (actor and actor.valid) then return end
	
	if actor.z <= actor.floorz + 8*FRACUNIT and actor.momz <= 0 then
		actor.state = actor.info.raisestate
	elseif actor.momz < 0 and actor.reactiontime then
		local ns = 3*FRACUNIT
		local goop
		local fz = actor.z + actor.height + 56*FRACUNIT
		local fa
		for i = 0, 7, 1 do
			actor.movedir = $+1
			actor.movedir = $%NUMDIRS // NUMDIRS should be 8
			fa = FixedAngle((actor.movedir*45)*FRACUNIT)
			
			goop = P_SpawnMobj(actor.x, actor.y, fz, MT_OLDGOOP)
			goop.momx = FixedMul(sin(fa), ns)
			goop.momy = FixedMul(cos(fa), ns)
			goop.momz = 4*FRACUNIT
			
			// Make the goop's fuse shorter if the Egg Slimer started the level in its pogo state
			if actor.rbPogoOnly
				goop.fuse = 15*TICRATE
			else
				goop.fuse = 30*TICRATE+P_RandomByte()
			end
		end
		actor.reactiontime = 0
		if actor.info.attacksound then
			S_StartSound(actor, actor.info.attacksound)
		end
		actor.flags2 = $|MF2_JUSTATTACKED
	end
end

addHook("MapThingSpawn", function(mobj, mapthing)
	if not (mobj and mobj.valid
	and mapthing and mapthing.valid) then
		return
	end
	
	// Make the 2.0 Egg Slimer spawn 33 FRACUNITS off the ground if its map thing's z-position hasn't been set
	local offset
	
	if mapthing.z ~= 0 then
		offset = mapthing.z
	else
		offset = 33*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
	
	// Toggle the Egg Slimer's pre-1.09.4 behavior if its map thing's extra flag has been set
	if (mapthing.options & MTF_EXTRA) then mobj.oldBehavior = true end
end, MT_20EGGMOBILE2)

// Display the 2.0 Egg Slimer's "gibs" when it dies
addHook("BossDeath", function(mo)
	if not (mo and mo.valid) then return end
	A_21BossDeath(mo)
	A_20EggSlimerGibs(mo, 0, 0)
	return true
end, MT_20EGGMOBILE2)

// Allows the Egg Slimer to move in a circular path in its first phase
addHook("MobjSpawn", function(mo)
	if not (mo and mo.valid) then return end
	
	mo.watertop = mo.info.speed
	
	// Force the Egg Slimer into its pogo state if there is no NiGHTS axis on the map
	if not P_GetClosestAxis(mo) then mo.rbPogoOnly = true end
end, MT_20EGGMOBILE2)

// Ported BossThinker behavior for 2.0 Egg Slimer from 2.0.7
addHook("BossThinker", function(mobj)
	if not (mobj and mobj.valid) then return end
	
	if mobj.movecount then mobj.movecount = $-1 end
	if not mobj.movecount then mobj.flags2 = $ & ~MF2_FRET end
	if not (mobj.tracer and mobj.tracer.valid) then A_OldBossJetFumes(mobj, 0, 0) end
	
	if mobj.health <= mobj.info.damage and (not (mobj.target and mobj.target.valid and (mobj.target.flags & MF_SHOOTABLE))) then
		if mobj.health <= 0 then
			// look for a new target
			if P_LookForPlayers(mobj, 0, true) and mobj.info.mass then // Bid farewell!
				S_StartSound(mobj, mobj.info.mass)
			end
			return
		end
		
		// look for a new target
		if P_LookForPlayers(mobj, 0, true) and mobj.info.seesound then
			S_StartSound(mobj, mobj.info.seesound)
		end
		
		return
	end
	
	// Kill the Egg Slimer if there is no axis and its map Thing parameter is set to 1
	if mobj.rbPogoOnly then
		if mobj.spawnpoint 
		and mobj.spawnpoint.type == mobj.info.doomednum 
		and mobj.spawnpoint.extrainfo == 1 then
			mobj.rbPogoOnly = false
		end
	end
	
	if mobj.state == mobj.info.spawnstate and mobj.health > mobj.info.damage 
	and not mobj.rbPogoOnly then
		A_FDBoss2Chase(mobj, 0, 0)
	elseif mobj.state == mobj.info.raisestate
	or mobj.state == S_20EGGMOBILE2_POGO2
	or mobj.state == S_20EGGMOBILE2_POGO3
	or mobj.state == S_21EGGMOBILE2_POGO4
	or mobj.state == mobj.info.spawnstate then
		mobj.flags = $ & ~MF_NOGRAVITY
		A_FDBoss2Pogo(mobj, 0, 0)
	end
	
	return true
end, MT_20EGGMOBILE2)

// Don't let the 2.0 Egg Slimer get hit while its movecount is greater than 0
addHook("TouchSpecial", function(special, toucher)
	if not (special and special.valid
	and toucher and toucher.valid) then
		return
	end
	
	if special.movecount then return true end
end, MT_20EGGMOBILE2)

// 2.0 Egg Slimer reuses states from 2.1 Egg Slimer for optimization

mobjinfo[MT_20EGGMOBILE2] = {
	//$Name 2.0 Egg Slimer
	//$Sprite 21ENA1
	//$Category Bosses
	//$Flags1Text Pre-1.09.4 behavior
	//$Flags4Text End level on death
	//$Flags8Text Speed up when hit
	doomednum = 4051,
	spawnstate = S_21EGGMOBILE2_STND,
	spawnhealth = 8,
	seestate = S_21EGGMOBILE2_STND,
	reactiontime = 8,
	attacksound = sfx_gspray,
	painstate = S_21EGGMOBILE2_PAIN,
	painchance = MT_OLDGOOP,
	painsound = sfx_dmpain,
	meleestate = S_21EGGMOBILE2_STND,
	missilestate = S_21EGGMOBILE2_STND,
	deathstate = S_21EGGMOBILE2_DIE1,
	xdeathstate = S_21EGGMOBILE2_FLEE1,
	deathsound = sfx_cybdth,
	speed = 2*FRACUNIT,
	radius = 24*FRACUNIT,
	height = 48*FRACUNIT,
	damage = 2,
	activesound = sfx_pogo,
	flags = MF_SPECIAL|MF_SHOOTABLE|MF_NOGRAVITY|MF_BOSS,
	raisestate = S_20EGGMOBILE2_POGO1
}

states[S_20EGGMOBILE2_POGO1] = {SPR_21EN,	B,	1,	nil,			0,				0,			S_20EGGMOBILE2_POGO2}
// Replace A_Boss2PogoSFX with A_21Boss2PogoSFX if it gets replaced or removed
states[S_20EGGMOBILE2_POGO2] = {SPR_21EN,	A,	1,	A_Boss2PogoSFX,	12*FRACUNIT,	5*FRACUNIT,	S_20EGGMOBILE2_POGO3}
states[S_20EGGMOBILE2_POGO3] = {SPR_21EN,	B,	1,	nil,			0,				0,			S_21EGGMOBILE2_POGO4}

// Pre-2.1 Egg Slimer Goop

addHook("MobjThinker", function(mo)
	if not (mo and mo.valid) then return end
	
	if mo.z <= mo.floorz and not (mo.state == mo.info.meleestate) then
		mo.state = mo.info.meleestate
		mo.momx = 0
		mo.momy = 0
		mo.momz = 0
		mo.z = mo.floorz
		if mo.info.painsound then
			S_StartSound(mo, mo.info.painsound)
		end
	end
end, MT_OLDGOOP)

mobjinfo[MT_OLDGOOP] = {
	doomednum = -1,
	spawnstate = S_OLDGOOP1,
	spawnhealth = 1000,
	reactiontime = 8,
	painsound = sfx_ghit,
	meleestate = S_OLDGOOP3,
	speed = 1,
	radius = 4*FRACUNIT,
	height = 4*FRACUNIT,
	mass = DMG_WATER,
	flags = MF_PAIN
}

states[S_OLDGOOP1] = {SPR_OGOP,	A|FF_FULLBRIGHT,	2,	nil,	0,	0,	S_OLDGOOP2}
states[S_OLDGOOP2] = {SPR_OGOP,	B|FF_FULLBRIGHT,	2,	nil,	0,	0,	S_OLDGOOP1}
states[S_OLDGOOP3] = {SPR_OGOP,	C|FF_FULLBRIGHT,	-1,	nil,	0,	0,	S_NULL}
