//Hi :]
local function propel()
	for player in players.iterate
        if player.mo.skin == "propeller_box" then
			if player.mo.state == S_PLAY_DEAD 
			or (player.mo.state == S_PLAY_PAIN and (not (player.pflags & PF_SLIDING))) then
				return
			end
			
			if (maptol & TOL_NIGHTS) then
				return
			end
			
			if not player.propelled then
				player.propelled = false
			end
			
			if not player.propelcount then
				player.propelcount = 0
			end
			
			if P_IsObjectOnGround(player.mo)
			or (player.powers[pw_justsprung])
			or (player.powers[pw_carry] == CR_MACESPIN) then
				player.propelled = false
				player.propelcount = 0
				player.pflags = $ & ~PF_CANCARRY
				if player.mo.state == S_PLAY_FLY then
					player.mo.state = S_PLAY_STND
				end
			end
			
			if player.mo.state == S_PLAY_FLY then
				player.pflags = $|PF_CANCARRY|PF_JUMPED
				player.pflags = $ & ~PF_STARTJUMP
				player.pflags = $ & ~PF_SPINNING
				
				
				if (not (player.mo.eflags & MFE_UNDERWATER))
				and not S_SoundPlaying(player.mo, 508) then
					S_StartSound(player.mo, 508)
				end
			end
				
			
			
			if (player.cmd.buttons & BT_JUMP) then
				if player.mo.state != S_PLAY_FLY
				and (not (player.playersearch and player.playersearch.valid)) then
					if (not (player.mo.eflags & MFE_UNDERWATER))then
						S_StartSound(player.mo, 195)
					end
					player.mo.state = S_PLAY_FLY
				end
				
				if player.propelled == false
				or player.powers[pw_super] then
					player.mo.momz = $ + 1*FRACUNIT*P_MobjFlip(player.mo)
					if player.mo.momz == 0 then
						if (player.mo.eflags & MFE_VERTICALFLIP) then
							player.mo.momz = -1*FRACUNIT
						else
							player.mo.momz = 1*FRACUNIT
						end
					end
					player.propelcount = $ + 1
					if player.propelghost and player.propelghost.valid then // Prevents the first ghost from showing, preventing weird visuals. Thanks to L_CloneFighter-v2.pk3 on Discord for helping with this.
						player.propelghost.flags2 = $ & ~MF2_DONTDRAW
					end
					player.propelghost = P_SpawnGhostMobj(player.mo) //spawns afterimages
					player.propelghost.fuse = 4 //amount of afterimages
					player.propelghost.flags2 = $|MF2_DONTDRAW // Part of preventing the first ghost from showing
					if player.propelcount == 24
					or ((player.mo.eflags & MFE_UNDERWATER) and player.propelcount == 12) then
						player.propelled = true
					end
				else
					if (player.mo.eflags & MFE_VERTICALFLIP) then
						if player.mo.momz > 1*FRACUNIT then
							player.mo.momz = $ - 1*FRACUNIT
						end
					else
						if (player.mo.momz < -1*FRACUNIT) then
							player.mo.momz = $ + 1*FRACUNIT
						end
					end
				end
			end
			
			if (player.propelcount > 0)
			and (player.mo.state == S_PLAY_FLY or player.mo.state == S_PLAY_SWIM)
			and (player.cmd.buttons & BT_USE) then
				player.mo.momz = $ - 1*FRACUNIT*P_MobjFlip(player.mo)
				if (not (player.mo.eflags & MFE_UNDERWATER))
				and not S_SoundPlaying(player.mo, 354) then
					S_StartSoundAtVolume(player.mo, 354, 100)
				end
				if player.propelghost and player.propelghost.valid then // Prevents the first ghost from showing, preventing weird visuals. Thanks to L_CloneFighter-v2.pk3 on Discord for helping with this.
					player.propelghost.flags2 = $ & ~MF2_DONTDRAW
				end
				player.propelghost = P_SpawnGhostMobj(player.mo) //spawns afterimages
				player.propelghost.fuse = 4 //amount of afterimages
				player.propelghost.flags2 = $|MF2_DONTDRAW // Part of preventing the first ghost from showing
				if player.propelcount == 20 then
					player.propelled = true
				end
			else
				S_StopSoundByID(player.mo, 354)
			end
			
		end
	end
end

addHook("ThinkFrame", propel)


//function that checks if a wall is bustable, then crumbles it, by Tatsuru
local function CheckAndCrumble(mo, sec)
  for fof in sec.ffloors()
    if not (fof.flags & FF_EXISTS) then continue end
    if not (fof.flags & FF_BUSTUP) then continue end
    
    if mo.z + mo.height < fof.bottomheight - 10*FRACUNIT - mo.momz then continue end 
    if mo.z > fof.topheight + 10*FRACUNIT - mo.momz then continue end

    EV_CrumbleChain(fof)
  end
end

//calls the function every time you launch down
addHook("PlayerThink", function(player)
  if not player.mo return end
  if (player.mo.skin != "propeller_box") and (not (player.playersearch and player.playersearch.valid)) return end
  if player.mo.state != S_PLAY_FLY and player.mo.state != S_PLAY_RIDE then return end
  if not (player.cmd.buttons & BT_USE) then return end

  CheckAndCrumble(player.mo, player.mo.subsector.sector)
end)

//also required
addHook("MobjLineCollide", function(mo, line)
  if not mo.player return end
  if mo.skin != "propeller_box" and (not (mo.player.playersearch and mo.player.playersearch.valid)) return end
  if mo.state != S_PLAY_FLY and mo.state != S_PLAY_RIDE then return end
  if not (mo.player.cmd.buttons & BT_USE) then return end

  for _, sec in ipairs({line.frontsector, line.backsector})
    CheckAndCrumble(mo, sec)
  end
end, MT_PLAYER)


		

addHook("PlayerCanDamage", function(player, mohit)
	if player.mo.skin == "propeller_box" then
		if player.mo.state == S_PLAY_FLY then
			if mohit.flags & MF_ENEMY
			or mohit.flags & MF_MONITOR
			or mohit.flags & MF_SHOOTABLE
			or mohit.flags & MF_BOSS then
				return true
			end
		end
	end
end)


//Code for picking him up
local function pickup()
	for player in players.iterate
		if not (player.cmd.buttons & BT_CUSTOM3) then
			player.custom3tapready = true
			player.custom3tapping = false
		elseif player.custom3tapready then
			player.custom3tapping = true
			player.custom3tapready = false
		else
			player.custom3tapping = false
		end
		
		if not player.holdingpbox then
			player.holdingpbox = false
		end
		
		
		if not player.propelled then
			player.propelled = false
		end
			
		if not player.propelcount then
			player.propelcount = 0
		end
			
		if P_IsObjectOnGround(player.mo)
		or (player.powers[pw_justsprung])
		or (player.powers[pw_carry] == CR_MACESPIN) then
			player.propelled = false
			player.propelcount = 0
			player.pflags = $ & ~PF_CANCARRY
		end
		
		if player.custom3tapping then
			if player.holdingpbox == false then
				local searchmo = player.mo
				searchBlockmap("objects", function(searchmo, otherplayer)
					if otherplayer and otherplayer.valid then
						if otherplayer.skin == "propeller_box" then
							if otherplayer.player.playersearch and otherplayer.player.playersearch.valid then
								return
							end
							player.playersearch = otherplayer
						end
					end	
				end, player.mo, player.mo.x - 20, player.mo.x + 20, player.mo.y - 20, player.mo.y + 20)
					
				if player.playersearch and player.playersearch.valid then
					player.holdingpbox = true
				end
			else
				player.holdingpbox = false
				player.playersearch = nil
			end
		end
				
				
		if not (player.playersearch and player.playersearch.valid) then
			player.holdingpbox = false
		end
		
		
		if player.playersearch and player.playersearch.valid
		and player.holdingpbox then
			player.playersearch.player.pflags = $ & ~PF_CANCARRY
			P_MoveOrigin(player.playersearch, player.mo.x, player.mo.y, (player.mo.z + (player.mo.height*P_MobjFlip(player.mo))))
			player.playersearch.momz = 0
			//player.playersearch.angle = player.drawangle
			player.playersearch.player.drawangle = player.drawangle
			
			if player.mo.state == S_PLAY_RIDE then
				player.pflags = $|PF_CANCARRY|PF_JUMPED
				player.pflags = $ & ~PF_STARTJUMP
				player.pflags = $ & ~PF_SPINNING
			end
			
			if P_IsObjectOnGround(player.mo) then
				if player.playersearch.state == S_PLAY_FLY then
					player.playersearch.state = S_PLAY_STND
				end
				if (player.playersearch.player.cmd.buttons & BT_JUMP) then
					player.holdingpbox = false
				end
			end
			
			if player.playersearch.state == S_PLAY_ROLL
			or player.playersearch.state == S_PLAY_DEAD
			or player.mo.state == S_PLAY_DEAD
			or player.pflags & PF_STASIS
			or player.pflags & PF_FULLSTASIS then
				player.holdingpbox = false
			end
			
			if player.mo.state == S_PLAY_STND then
				if player.playersearch.state == S_PLAY_FLY then
					player.playersearch.state = S_PLAY_STND
				end
				if (player.playersearch.player.cmd.buttons & BT_JUMP) then
					player.holdingpbox = false
				end
			end
				
			
			
			if (player.cmd.buttons & BT_JUMP) then
				if player.mo.state != S_PLAY_RIDE then
					if (not (player.mo.eflags & MFE_UNDERWATER)) then
						S_StartSound(player.mo, 195)
					end
					player.mo.state = S_PLAY_RIDE
					player.playersearch.state = S_PLAY_FLY
				end
				
				if player.propelled == false
				or player.powers[pw_super] then
					player.mo.momz = $ + 1*FRACUNIT*P_MobjFlip(player.mo)
					if player.mo.momz == 0 then
						if (player.mo.eflags & MFE_VERTICALFLIP) then
							player.mo.momz = -1*FRACUNIT
						else
							player.mo.momz = 1*FRACUNIT
						end
					end
					player.propelcount = $ + 1
					if player.propelghost and player.propelghost.valid then // Prevents the first ghost from showing, preventing weird visuals. Thanks to L_CloneFighter-v2.pk3 on Discord for helping with this.
						player.propelghost.flags2 = $ & ~MF2_DONTDRAW
					end
					player.propelghost = P_SpawnGhostMobj(player.mo) //spawns afterimages
					player.propelghost.fuse = 4 //amount of afterimages
					player.propelghost.flags2 = $|MF2_DONTDRAW // Part of preventing the first ghost from showing
					if player.propelcount == 24
					or ((player.mo.eflags & MFE_UNDERWATER) and player.propelcount == 12) then
						player.propelled = true
					end
				else
					if (player.mo.eflags & MFE_VERTICALFLIP) then
						if player.mo.momz > 1*FRACUNIT then
							player.mo.momz = $ - 1*FRACUNIT
						end
					else
						if (player.mo.momz < -1*FRACUNIT) then
							player.mo.momz = $ + 1*FRACUNIT
						end
					end
				end
			end
			
			if (player.propelcount > 0)
			and player.mo.state == S_PLAY_RIDE
			and (player.cmd.buttons & BT_USE) then
				player.mo.momz = $ - 1*FRACUNIT*P_MobjFlip(player.mo)
				if (not (player.mo.eflags & MFE_UNDERWATER))
				and not S_SoundPlaying(player.mo, 354) then
					S_StartSoundAtVolume(player.mo, 354, 100)
				end
				if player.propelghost and player.propelghost.valid then // Prevents the first ghost from showing, preventing weird visuals. Thanks to L_CloneFighter-v2.pk3 on Discord for helping with this.
					player.propelghost.flags2 = $ & ~MF2_DONTDRAW
				end
				player.propelghost = P_SpawnGhostMobj(player.mo) //spawns afterimages
				player.propelghost.fuse = 4 //amount of afterimages
				player.propelghost.flags2 = $|MF2_DONTDRAW // Part of preventing the first ghost from showing
				if player.propelcount == 20 then
					player.propelled = true
				end
			else
				S_StopSoundByID(player.mo, 354)
			end
			
		end
		
		
		
		
	end
end

addHook("ThinkFrame", pickup)

			
				
				


addHook("JumpSpecial", function(player) 
	if player.mo.skin == "propeller_box" then
		if (player.powers[pw_carry] == CR_ROLLOUT)
		or (player.powers[pw_carry] == CR_PLAYER)
		or (player.powers[pw_carry] == CR_BRAKGOOP)
		or (player.powers[pw_carry] == CR_ZOOMTUBE)
		or (player.powers[pw_carry] == CR_ROPEHANG)
		or (player.powers[pw_carry] == CR_MACESPIN)
		or (player.powers[pw_carry] == CR_MINECART)
		or (player.powers[pw_carry] == CR_PTERABYTE)
		or (player.powers[pw_carry] == CR_DUSTDEVIL)
		or (player.powers[pw_carry] == CR_GENERIC)
		or (player.powers[pw_carry] == CR_NIGHTSMODE)
		or player.mo.state == S_PLAY_ROLL 
		or player.mo.state == S_PLAY_RIDE
		or player.mo.state == S_PLAY_SPRING then
			return false
		else
			return true
		end
	else
		if player.holdingpbox then
			return true
		end
	end
end)



local function customtunes()
	for player in players.iterate
		if player.mo.skin == "propeller_box" then
			//if player.isxmomentum then //prevents these during xmomentum since it has its own supermusic that would cause lag if this tried to run too
			//	return
			//end
			
			if player.powers[pw_invulnerability] == 20*TICRATE
			and not player.powers[pw_super] then
				COM_BufInsertText(player, "tunes _minv")
			end
			
			if not player.powers[pw_invulnerability] then
				if S_MusicName() == "_minv" then
					COM_BufInsertText(player, "tunes -default")
				end
			end
		end
	end
end

addHook("ThinkFrame", customtunes)			

			
			
			
			
			
			
			
			
			
			
			
			
			
			
			
			
			
			
			
			
			
			
			