/*
Magnet point
	by Lach
*/

// To prevent duplicate freeslots
local function SafeFreeslot(...)
	for _, item in ipairs({...})
		if rawget(_G, item) == nil
			freeslot(item)
		end
	end
end

SafeFreeslot("SPR_MGNP", "S_MAGNETPOINT", "MT_MAGNETPOINT")

states[S_MAGNETPOINT] = {
	sprite = SPR_MGNP,
	frame = FF_ANIMATE|FF_FULLBRIGHT,
	var1 = 4,
	var2 = 1,
}

mobjinfo[MT_MAGNETPOINT] = {
	doomednum = 2788,
	spawnstate = S_MAGNETPOINT,
	height = FRACUNIT,
	radius = FRACUNIT,
	speed = 3*FRACUNIT,
	painchance = 512*FRACUNIT,
	flags = MF_NOCLIP|MF_NOGRAVITY|MF_SCENERY
}

local function DoMagnetPoint(mo, point)
	if not point.valid
	or point.type ~= MT_MAGNETPOINT
		return
	end
	
	local current = {mo.x, mo.y, mo.z + (mo.height >> 1)}
	local goal = {point.x, point.y, point.z}
	local x = goal[1] - current[1]
	local y = goal[2] - current[2]
	local z = goal[3] - current[3]
	local hdist = FixedHypot(x, y)
	local dist = FixedHypot(hdist, z)
	if dist > point.info.painchance
		return
	end
	
	local hangle = R_PointToAngle2(current[1], current[2], goal[1], goal[2])
	local vangle = R_PointToAngle2(0, current[3], hdist, goal[3])
	P_Thrust(mo, hangle, FixedMul(point.info.speed, cos(vangle)))
	mo.momz = $ + FixedMul(point.info.speed, sin(vangle))
	
	local viewangle = R_PointToAngle(mo.x, mo.y) - hangle
	if viewangle < 0
		vangle = -$
	end
	
	local n = (dist >> FRACBITS)/64
	for i = 1, n - 1
		local thok = P_SpawnMobj(mo.x + i*x/n, mo.y + i*y/n, mo.z + i*z/n, MT_THOK)
		thok.state = S_SHOCKWAVE1
		thok.fuse = 1
		thok.frame = P_RandomKey(8) | FF_PAPERSPRITE | FF_FULLBRIGHT
		thok.color = SKINCOLOR_GOLD
		thok.colorized = true
		thok.angle = hangle
		thok.rollangle = vangle
	end
end

addHook("ThinkFrame", do
	for player in players.iterate
		if (player.powers[pw_shield] & SH_PROTECTELECTRIC) == 0
			continue
		end
		local mo = player.mo
		searchBlockmap("objects", DoMagnetPoint, mo,
			mo.x - mobjinfo[MT_MAGNETPOINT].painchance, mo.x + mobjinfo[MT_MAGNETPOINT].painchance,
			mo.y - mobjinfo[MT_MAGNETPOINT].painchance, mo.y + mobjinfo[MT_MAGNETPOINT].painchance)
	end
end)
			