//This lua was made by Flame. This is for pick up objects. It was adjusted a little.
addHook("ThinkFrame", do
    for p in players.iterate
		if p.mo.skin == "semut" -- Added: to detect Si Semut
        	if not p.pickedup
				p.pickedup = false
        	end
		end
    end
end)

-- 
-- lookforitem
-- Created by Flame
-- Date: 12-20-19
--
-- Description:
-- Looks for the closest Mobj to you.
--

local function lookforitem(mo)
    -- Make sure that our mobj is valid, and that we're a real player
    if not (mo and mo.valid and mo.player and mo.player.valid) then
        --CONS_Printf(mo.player,"NOT VALID")
        return -- If we're not, don't run the function.
    end
    
    local closestmo -- The closest mobj. We don't know what it is yet, so nil
    local closestdist = mo.radius*5 -- Maximum possible distance, *something* has to be closer..
    for i_mo in mobjs.iterate() do -- i_mo is "iterating mo", random crap i made up
        -- Check to see if the mobj is us
		if (i_mo == mo)
			continue -- Ignore it
		end

		-- Health Check
		if (i_mo.health <= 0)
			continue -- I'm dead
		end

		-- Mobj Check
		if  (i_mo.type >= 4) and (i_mo.type <= 5) -- Player overlays
		or (i_mo.type >= 107)
		and (i_mo.type <= 127) -- Collectables
		or (i_mo.type >= 453)
		and (i_mo.type <= 532) -- Elemental Shields, Animals, Environmentals, Game Indicators, Ambient sounds
		or (i_mo.type >= 536)
		and (i_mo.type <= 549) -- Weapon ring pickups
		-- NOTICE THE EXPLICIT EXCLUSION FOR THROWN RINGS, YOU CAN TRY TO CATCH THESE >:)
		or (i_mo.type >= 572)
		and (i_mo.type <= 598) -- Nights
		or (i_mo.type >= 614)
		and (i_mo.type <= 652) -- Misc
			continue -- Skip these.
		end
		
		---- Flags check
		--if (i_mo.flags & MF_SCENERY) -- Already a scenery object
		--	continue -- Skip any type with this flag
		--end

		----State Check
		--if not i_mo.state == S_INVISIBLE -- Dissappearing state?
		--	continue -- Skip it
		--end

		-- This mobj's 3D distance from the player.
		local dist = abs(P_AproxDistance(P_AproxDistance(mo.x - i_mo.x, mo.y - i_mo.y), mo.z - i_mo.z))
		
		--CONS_Printf(mo.player, "i_mo X position is: "..i_mo.x/FRACUNIT.."\n")
		--CONS_Printf(mo.player, "mo X position is: "..mo.x/FRACUNIT.."\n")
		--CONS_Printf(mo.player, "i_mo y position is: "..i_mo.y/FRACUNIT.."\n")
		--CONS_Printf(mo.player, "mo Y position is: "..mo.y/FRACUNIT.."\n")
		--CONS_Printf(mo.player, "i_mo Z position is: "..i_mo.z/FRACUNIT.."\n")
		--CONS_Printf(mo.player, "mo Z position is: "..mo.z/FRACUNIT.."\n\n")
		
		if dist < closestdist then -- If this mobj is closer than the closest one..
			closestmo = i_mo -- Then we're the real closest mobj!
			closestdist = dist -- And this is our distance!
		end
    end
    return closestmo -- Returns the closest mobj to us.
end

-- 
-- FlameMobjPickup
-- Created by Flame
-- Date: 12-20-19
--
-- Description:
-- Pick up a Mobj close to you
--
-- Variables:
-- picker = you
-- pickup = mobj being picked up (Also picker.holding)
--
-- picker.pickedup = true/false
-- true:
-- You are holding an object. It floats in front of you.
-- false:
-- You are not holding an object and ready to pick one up, if close to you.
--

local function FlameMobjPickup(picker)

	local pickup = picker.holding

	if picker and picker.player and (picker.spectator or (picker.player.pflags & PF_STASIS) or (picker.player.powers[pw_nocontrol])) -- If you currently have no control over your character...
		return -- You can't do anything!
	end

	if picker.weapondelay -- Delay timer
		picker.weapondelay = $ - 1
	end
	
	if picker.pickedup and not pickup.valid -- Pickup dissappeared for some reason?
		picker.pickedup = false -- Allow yourself to pick up another one!
		return -- Stop processing additional rules
	end
	
	--if pickup and picker.pickedup and ((leveltime % 30) == 0)
	--	CONS_Printf(picker.player,"You have a pickup, what are you picking up?")
	--	CONS_Printf(picker.player,mobjTypeToString[pickup.type])
	--	CONS_Printf(picker.player,pickup.type)
	--end

	-- Are you already holding the pickup?
	if picker and picker.player
	and pickup and picker.pickedup and pickup.valid
	and not picker.weapondelay
	and (pickup.flags & MF_SCENERY)
	and (picker.player.cmd.buttons & BT_CUSTOM2) -- Did you just press the button?
		--CONS_Printf(picker.player,"Toss me!")
		
		-- LETS TOSS THIS MOBJ
		picker.weapondelay = TICRATE/2
		
		-- First set it's position to yours!
		if (picker.flags2 & MF2_TWOD) -- In 2D, make the item hover above your head. 
			P_TeleportMove(pickup, 
							picker.x, 
							picker.y, 
							picker.z + 65*FRACUNIT)
			-- Aaand TOSS!
			P_Thrust(pickup, picker.angle, 4*FRACUNIT)
		elseif not (picker.flags2 & MF2_TWOD) -- In 3D, make the item slightly in front of you
			P_TeleportMove(pickup, 
							picker.x + pickup.momx + P_ReturnThrustX(picker, picker.angle, picker.radius*4), 
							picker.y + pickup.momy + P_ReturnThrustY(picker, picker.angle, picker.radius*4), 
							picker.z + 40*FRACUNIT)
			-- Aaand TOSS!
			P_Thrust(pickup, picker.angle, 8*FRACUNIT)
			-- Your speed affects how far you throw the object
			pickup.momx = $ + picker.momx
			pickup.momy = $ + picker.momy
		end
		
		-- Your Z movement also affects how high you throw the object
		if not picker.momz
			pickup.momz = 6*FRACUNIT
		else
			pickup.momz = $ + (6*FRACUNIT + picker.momz)
		end
		
		pickup.flags = pickup.savedflags -- Reapply the flags of the Mobj.
		if (pickup.flags & MF_SPRING) -- Special check for all springs.
			pickup.flags = $ & ~MF_NOGRAVITY
		end
		
		pickup.target = picker
		picker.pickedup = false
		pickup = nil
		return -- Don't process anything else
	end
	
	-- Are you already holding the pickup?
	if picker and picker.player
	and pickup and picker.pickedup and pickup.valid
	and (pickup.flags & MF_SCENERY)
	and not (picker.player.cmd.buttons & BT_CUSTOM2)
		-- Set it's position to yours!
		if (picker.flags2 & MF2_TWOD) -- In 2D, make the item hover above your head. 
			P_TeleportMove(pickup, 
							picker.x, 
							picker.y, 
							picker.z + 65*FRACUNIT)
		elseif not (picker.flags2 & MF2_TWOD) -- In 3D, make the item slightly in front of you
			P_TeleportMove(pickup, 
							picker.x + pickup.momx + P_ReturnThrustX(picker, picker.angle, picker.radius*4), 
							picker.y + pickup.momy + P_ReturnThrustY(picker, picker.angle, picker.radius*4), 
							picker.z + 40*FRACUNIT)
		end
		pickup.angle = picker.angle
		return -- Don't process anything else
	end
	
	--Are you not holding anything?
	if picker and picker.player
	and not (picker.player.pflags & PF_FINISHED) -- Can't pick up if you're finished with a level.
	and not (picker.player.panim == PA_RIDE) -- Can't pickup when you're being carried.
	and not (pickup and picker.weapondelay) -- Can't pickup if you're in cooldown.
	and (picker.player.cmd.buttons & BT_CUSTOM2) -- Did you just press the button?
		picker.holding = lookforitem(picker)
		pickup = picker.holding

		if (pickup)
			pickup.target = picker
			picker.weapondelay = TICRATE/2
			-- Flag Checks:
			pickup.savedflags = pickup.flags -- Save the pickup's current flags.
			
			-- And make sure you can HOLD the pickup without it HURTING YOU
			pickup.flags = $ | MF_SCENERY
			
			if (pickup.flags & MF_SOLID)
				pickup.flags = $ & ~MF_SOLID
			end
			if (pickup.flags & MF_MONITOR)
				pickup.flags = $ & ~MF_MONITOR
			end
			if (pickup.flags & MF_SPRING)
				pickup.flags = $ & ~MF_SPRING
			end
			if not (pickup.flags & MF_NOGRAVITY)
				pickup.flags = $ | MF_NOGRAVITY
			end
			if not (pickup.flags & MF_NOCLIP)
				pickup.flags = $ | MF_NOCLIP
			end
			if (pickup.flags & MF_SPECIAL)
				pickup.flags = $ & ~MF_SPECIAL
			end
			if pickup.type == 3 -- Pickup is another player?
				pickup.player.pflags = $ | PF_JUMPED
				pickup.state = S_PLAY_ROLL
			end
			picker.pickedup = true
			--CONS_Printf(picker.player,"the player should have just picked up an object!")
		end
		return  -- Don't process anything else
	end
end

addHook("MobjThinker", FlameMobjPickup, MT_PLAYER)