-- Flame
-- A small Homing Attack mockup.
-- Multi Target

addHook("ThinkFrame", do
	for p in players.iterate
		if not p.mo then return end
		local mo = p.mo

		-- Always be on the lookout for a target if not homing.
		if not p.flhoming then
			mo.htable = L_Look4TargetTable(mo, 3*RING_DIST/4) -- Homing Table
		end
		
		-- Table count is larger than 0?
		if (#mo.htable > 0) then
			for i = 1, #mo.htable do -- Lets go through the table!
				if not (mo.htable[i] and mo.htable[i].valid) then continue end
				if not mo.htable[i].health then continue end -- Enemy in Homing Table has no health.

				if (p == consoleplayer) then -- Only show the marker for YOU
					P_SpawnLockOn(p, mo.htable[i], S_LOCKON1)
				end
			end
		end

		-- Homing Action
		p.flhoming = $ or 0
		if (p.flhoming > 0)
			mo.spritexscale = max(FRACUNIT * 3/4, min($ - FRACUNIT/95, FRACUNIT))
			mo.spriteyscale = max(FRACUNIT, min($ + FRACUNIT/95, FRACUNIT*4/3))
			
			-- Decrease tic timer by one
			p.flhoming = $ - 1
			
			-- Homing but prematurely hit the floor?
			if P_IsObjectOnGround(mo) 
			or (mo.eflags & MFE_JUSTHITFLOOR) 
			or (mo.z <= mo.floorz) then 
				p.flhoming = 0 -- I guess you shouldn't be homing anymore.
			end
			
			-- Home in on the first 'seen' target
			if mo.htable[1] and mo.htable[1].valid
			and (mo.htable[1].health > 0) then
				local target = mo.htable[1]
				L_HomingAttackXY(mo, target) -- Home in
				P_SetObjectMomZ(mo, -3*gravity, true)
				P_SpawnGhostMobj(mo) -- Spawn a ghost trail behind you
			elseif (mo.htable[2] and mo.htable[2].valid) then -- Enemy in homing table no longer valid, but there's still an enemy in the table?
				-- Move on to the next target
				table.remove(mo.htable, 1) -- Shift the table up by one
				local target = mo.htable[1]
				p.flhoming = 2*TICRATE -- Reset the homing timer
				mo.momz = $>>1 -- Reset z momentum
				mo.spritexscale = FRACUNIT
				mo.spriteyscale = FRACUNIT
				local dist = abs(FixedHypot(target.x - mo.x, target.y - mo.y))/25
				P_SetObjectMomZ(mo, dist, false) -- Bounce!
				p.flhoming = 2*TICRATE
			else
				mo.momz = $>>1
				p.flhoming = 0
			end
		else
			-- Unsquish the sprite. Don't make the math too complex...
			mo.spritexscale = ($ < FRACUNIT) and $ + FRACUNIT/25 or FRACUNIT
			mo.spriteyscale = ($ > FRACUNIT) and $ - FRACUNIT/25 or FRACUNIT
		end
	end
end)

addHook("AbilitySpecial", function(p)
	if not p.mo then return end
	local mo = p.mo

	if not (p.charability == CA_THOK)
	and not (p.charability == CA_HOMINGTHOK) 
	and not (p.charability == CA_DOUBLEJUMP) then return false end -- Not an ability we want to override
	
	if (#mo.htable > 0) then -- Not a valid tracer from the previous tic	
		if p.flhoming then return true end -- Not already homing in on a target
		-- We actually don't want the player to do anything if they're already homing
		
		-- Homing trigger
		local target = mo.htable[1]
		if (target.health <= 0) then return true end -- Object is dying, hold off for a sec
		if not (mo.state == S_PLAY_ROLL) then mo.state = S_PLAY_ROLL end
		S_StartSoundAtVolume(mo, sfx_s3k47, 170)
		S_StartSoundAtVolume(mo, sfx_zoom, 140)
		local dist = abs(FixedHypot(target.x - mo.x, target.y - mo.y))/20
		P_SetObjectMomZ(mo, dist, false)
		
		-- Start homing in!
		p.flhoming = 2*TICRATE -- Only home in for 2 seconds before getting 'tired'
		--p.pflags = $ | PF_THOKKED
		return true
	else
		return false
	end
end)