/////////////////////////
// SPECCYHUGS - V1.0.0 //
/////////////////////////
// Reused for like all of my mods, I might as well just allow for public use.
// Made by Spectra (speccyspec) and Rosy.iso (rosy.iso) on Discord.
// Change line 134, probably. It should say the skinname.
// also you might want to keep these credits
// pwease ;w;

if not SpeccyHugs then
	freeslot("S_PLAY_SPECCYHUGS", "SPR2_HUG_")
	states[S_PLAY_SPECCYHUGS] = {SPR_PLAY, SPR2_HUG_, -1, nil, 0, 0, S_PLAY_STND}
	rawset(_G, "SpeccyHugs", {})

	local function CheckObject(refmo, foundmo)
		local p2 = foundmo.player

		-- Make sure the player exists.
		if not p2 or not p2.valid then return end

		local p = refmo.player

		-- Make sure we're on the floor.
		if not P_IsObjectOnGround(refmo) or not P_IsObjectOnGround(foundmo) then return end

		-- No NiGHTS.
		if (p.powers[pw_carry] & CR_NIGHTSMODE) return end

		-- Make sure the player is alive.
		if p2.playerstate ~= PST_LIVE return end

		-- No hugging the enemy!
		if p.ctfteam ~= p2.ctfteam return end

		-- Distance check.
		local dist = P_AproxDistance(P_AproxDistance(foundmo.x - refmo.x, foundmo.y - refmo.y), foundmo.z - refmo.z)

		if dist <= 48*refmo.scale then
			P_SpawnLockOn(p, foundmo, S_LOCKON2)

			if (p.cmd.buttons & BT_TOSSFLAG) then
				p.tossflagbtn = $ and $+1 or 1
			else
				p.tossflagbtn = nil
			end

			if p.tossflagbtn == 1 then
				if not p.hugging then
					p.hugging = {p2}
				else
					p.hugging[#p.hugging + 1] = p2
				end
				p2.hugged = p
				S_StartSound(refmo, sfx_s3k4a)
				S_StartSound(refmo, sfx_cdpcm6)
			end
		end
	end

	addHook("PlayerThink", function(p)
		-- lmao.
		if not p.mo or not p.mo.valid then return end

		-- There would be nobody to hug.
		if not multiplayer then return end

		-- Only do this for characters that support it.
		if not SpeccyHugs[p.mo.skin] then return end

		if p.hugging then
			local p2, cancel

			for i = 1, #p.hugging do
				p2 = p.hugging[i]
				p2.hugged = p

				-- Force to look at eachother.
				p.drawangle = R_PointToAngle2(p.mo.x, p.mo.y, p2.mo.x, p2.mo.y)

				-- Stop movement.
				p.powers[pw_nocontrol] = 5
				p2.powers[pw_nocontrol] = 5
				p.pflags = $|PF_STASIS -- Recognise as
				p2.pflags = $|PF_STASIS -- a hug.
				p.mo.momx, p.mo.momy = 0, 0
				p2.mo.momx, p2.mo.momy = 0, 0

				-- Force state.
				if p.mo.state ~= S_PLAY_SPECCYHUGS then p.mo.state = S_PLAY_SPECCYHUGS end
				p.mo.frame = A

				-- Cancel Hug.
				if (p.cmd.buttons & BT_JUMP) or (p2.cmd.buttons & BT_JUMP) or P_PlayerInPain(p) or p.mo.dying or not P_IsObjectOnGround(p.mo) then
					cancel = true
				end
			end

			-- The hug was cancelled.
			if cancel then
				for i = 1, #p.hugging do
					p2 = p.hugging[i]
					p2.hugged = nil
					p2.pflags = $ & ~PF_STASIS
				end

				p.hugging = nil
				p.pflags = $ & ~PF_STASIS
				p.mo.state = S_PLAY_STND
			end

			return
		end

		searchBlockmap("objects", CheckObject, p.mo)
	end)

	addHook("MapChange", function()
		for p in players.iterate do
			if p.hugging then
				for i = 1, #p.hugging do
					p2 = p.hugging[i]
					p2.hugged = nil
					p2.pflags = $ & ~PF_STASIS
				end

				p.hugging = nil
				p.pflags = $ & ~PF_STASIS
				p.mo.state = S_PLAY_STND
			end
		end
	end)
end

SpeccyHugs.sparrow = true