// TGF Deton (AKA "Heat-Seeking Bomb!") - Ported by MIDIMan

freeslot(
	"MT_TGFDETON",
	"S_TGFDETON_LOOK",
	"S_TGFDETON_LOOK2",
	"S_TGFDETON_LOOK3",
	"S_TGFDETON_LOOK4",
	"S_TGFDETON_CHASE",
	"S_TGFDETON_CHASE2",
	"S_TGFDETON_CHASE3",
	"S_TGFDETON_CHASE4",
	"S_TGFDETON_EXPLODE",
	"SPR_TDTN"
)

// Imitate the vanilla Deton's explosions
function A_TGFDetonExplode(actor, var1, var2)
	if not (actor and actor.valid) then return end
	
	P_RadiusAttack(actor, actor, actor.info.damage, 0, true)
	for i = 0, 3 do
		local explosion = P_SpawnMobjFromMobj(actor, 0, 0, 0, MT_EXPLODE)
		local thrust = explosion.scale/8
		local randomMax = 32
		local xSign = 1
		local ySign = 1
		
		if i > 2
			randomMax = 96
			xSign = -1
			ySign = -1
		elseif i > 1
			randomMax = 128
			xSign = -1
		elseif i > 0
			randomMax = 64
			ySign = -1
		end
		
		explosion.momx = $+(xSign * (P_RandomByte() % randomMax) * thrust)
		explosion.momy = $+(ySign * (P_RandomByte() % randomMax) * thrust)
	end
end

// Version of A_BuzzFly that follows the player even if they lose sight
local function TGF_DetonChase(actor, var1, var2)
	if not (actor and actor.valid) then return end
	
	if (actor.flags2 & MF2_AMBUSH) then return end
	if actor.reactiontime then actor.reactiontime = $-1 end
	
	local target = actor.target
	
	if actor.threshold then
		if not (target and target.valid) or target.health <= 0 then
			actor.threshold = 0
		else
			actor.threshold = $-1
		end
	end
	
	if not (target and target.valid and (target.flags & MF_SHOOTABLE)) then
		// If a new target is spotted, end the function
		if P_LookForPlayers(actor, 0, true) then return end
		
		// "Reset" the deton if a new target is not found
		actor.momx = 0
		actor.momy = 0
		actor.momz = 0
		actor.state = actor.info.spawnstate
		return
	end
	
	// Make the deton face its target
	actor.angle = R_PointToAngle2(actor.x, actor.y, target.x, target.y)
	
	if target.health <= 0 then
		// Find another player to target if in a netgame or multiplayer game
		if (multiplayer or netgame) and P_LookForPlayers(actor, 3072*actor.scale, true) then return end
		
		// "Reset" the deton if a new target is not found
		actor.momx = 0
		actor.momy = 0
		actor.momz = 0
		actor.state = actor.info.spawnstate
		return
	end
	
	// If the targetted player is too far from the deton, look for another player
	if FixedHypot(FixedHypot(target.x - actor.x, target.y - actor.y), target.z - actor.z) > 3072*actor.scale then
		if multiplayer or netgame then
			P_LookForPlayers(actor, 3072*actor.scale, true)
		end
		
		return
	end
	
	// Chase the targetted player
	local speed = FixedMul(actor.info.speed, actor.scale)
	local dist = FixedHypot(FixedHypot(target.x - actor.x, target.y - actor.y), target.z - actor.z)
	
	if dist < 1 then dist = 1 end
	
	actor.momx = FixedMul(FixedDiv(target.x - actor.x, dist), speed)
	actor.momy = FixedMul(FixedDiv(target.y - actor.y, dist), speed)
	actor.momz = FixedMul(FixedDiv(target.z - actor.z, dist), speed)
end

mobjinfo[MT_TGFDETON] = {
	//$Name "TGF Deton"
	//$Sprite TDTNA0
	//$Category TGF/Concept Enemies
	doomednum = 161,
	spawnstate = S_TGFDETON_LOOK,
	spawnhealth = 1,
	seestate = S_TGFDETON_CHASE,
	seesound = sfx_s3k86,
	deathstate = S_TGFDETON_EXPLODE,
	deathsound = sfx_pop,
	speed = 6*FRACUNIT,
	radius = 20*FRACUNIT,
	height = 44*FRACUNIT,
	damage = 96*FRACUNIT,
	flags = MF_ENEMY|MF_SPECIAL|MF_SHOOTABLE|MF_NOGRAVITY|MF_MISSILE
}

states[S_TGFDETON_LOOK] =		{SPR_TDTN,	A,	1,	A_Look,				(1024<<16)+1,	0,	S_TGFDETON_LOOK2}
states[S_TGFDETON_LOOK2] =		{SPR_TDTN,	B,	1,	A_Look,				(1024<<16)+1,	0,	S_TGFDETON_LOOK3}
states[S_TGFDETON_LOOK3] =		{SPR_TDTN,	C,	1,	A_Look,				(1024<<16)+1,	0,	S_TGFDETON_LOOK4}
states[S_TGFDETON_LOOK4] =		{SPR_TDTN,	B,	1,	A_Look,				(1024<<16)+1,	0,	S_TGFDETON_LOOK}
states[S_TGFDETON_CHASE] =		{SPR_TDTN,	A,	1,	TGF_DetonChase,		0,				0,	S_TGFDETON_CHASE2}
states[S_TGFDETON_CHASE2] =		{SPR_TDTN,	B,	1,	TGF_DetonChase,		0,				0,	S_TGFDETON_CHASE3}
states[S_TGFDETON_CHASE3] =		{SPR_TDTN,	C,	1,	TGF_DetonChase,		0,				0,	S_TGFDETON_CHASE4}
states[S_TGFDETON_CHASE4] =		{SPR_TDTN,	B,	1,	TGF_DetonChase,		0,				0,	S_TGFDETON_CHASE}
states[S_TGFDETON_EXPLODE] =	{SPR_TDTN,	A,	0,	A_TGFDetonExplode,	0,				0,	S_XPLD_FLICKY}
