freeslot(
"sfx_tjm1",
"sfx_tjm2",
"sfx_tjm3",
"sfx_putfst",
"S_PLAY_FEELTWIRL",
"S_PLAY_FEELFLY",
"S_PLAY_FEELFLY2",
"S_PLAY_FEELVICT1",
"S_PLAY_FEELVICT2",
"MT_FEELS_CAPE"
)
sfxinfo[sfx_tjm1].caption = "Triple Jump: 1"
sfxinfo[sfx_tjm2].caption = "Triple Jump: 2"
sfxinfo[sfx_tjm3].caption = "Triple Jump: 3"
sfxinfo[sfx_putfst].caption = "/"

mobjinfo[MT_FEELS_CAPE] = {
	spawnstate = S_INVISIBLE,
	spawnhealth = 1000,
	radius = 8*FRACUNIT,
	height = 8*FRACUNIT,
	dispoffset = 2,
	flags = MF_SCENERY|MF_NOGRAVITY|MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPTHING|MF_NOCLIPHEIGHT
}

local FLYNUM = 69 //secondjump value for flight
local MOMNUM = 70 //secondjump value for Boundgust
local MOMTIME = TICRATE*2/3 //Amount of time Boundgust lasts for

//Custom jumping function for Triple Jumps
addHook("JumpSpecial", function(player)
	if not (player.mo and player.mo.valid and player.mo.skin == "feelsonic")
	or P_PlayerInPain(player)
	or (player.pflags & PF_SLIDING)
	or player.exiting != 0
	or player.powers[pw_carry]
	or player.spectator
	or player.playerstate
	or not player.mo.health
	or (player.panim == PA_PAIN and not (player.pflags&PF_JUMPED))
	or player.powers[pw_super] == 1
	or player.iseggrobo
	or player.isjettysyn
	or player.guard
	or player.actionstate
	or player.powers[pw_nocontrol] > 0
	or player.pflags&PF_JUMPSTASIS
	or player.pflags&PF_JUMPDOWN
	return end
	
	if (P_IsObjectOnGround(player.mo) or player.mo.eflags&MFE_JUSTHITFLOOR)
	and not (player.pflags&PF_JUMPED)
		//Set the triple to the next one in the list
		if player.tjcount <= 1
		or player.speed >= player.mo.scale*15 and player.tjcount < 3
			player.tjcount = $+1
		else
			player.tjcount = 0
		end
		
		//Normal Jump
		if player.tjcount <= 1
			player.jumpfactor = skins[player.mo.skin].jumpfactor
			P_DoJump(player, false)
			player.mo.state = S_PLAY_JUMP
		//Double Jump
		elseif player.tjcount == 2
			player.jumpfactor = skins[player.mo.skin].jumpfactor + FRACUNIT/3
			P_DoJump(player, false)
			player.mo.state = S_PLAY_FEELTWIRL
			player.panim = PA_JUMP
		//Triple Jump
		elseif player.tjcount >= 3
			player.jumpfactor = skins[player.mo.skin].jumpfactor + 4*FRACUNIT/5
			P_DoJump(player, false)
			player.mo.state = S_PLAY_ROLL
			player.pflags = $&~PF_NOJUMPDAMAGE
		end
		
		//Hyper boost
		if (player.powers[pw_super] and player.hyper and player.hyper.capable)
			player.mo.momz = $*3/2
		end
		
		S_StartSound(player.mo, sfx_tjm1+min(max(player.tjcount-1,0),2))
		
		player.tjcounttime = 5
		return true
		
	//AbilitySpecial
	elseif not (P_IsObjectOnGround(player.mo) or player.mo.eflags&MFE_JUSTHITFLOOR)
	and player.pflags&PF_JUMPED and not (player.pflags & PF_THOKKED)
		//Flight
		if player.tjcount == 3
			player.pflags = $|PF_STARTJUMP
			P_InstaThrust(player.mo, player.mo.angle, FixedHypot(player.rmomx,player.rmomy)*2/3)
			P_SetObjectMomZ(player.mo, 12*FRACUNIT, false)
			S_StartSound(player.mo, sfx_putfst)
			player.tjcount = 0
			player.secondjump = FLYNUM
			player.mo.state = S_PLAY_FEELFLY
			
		//Boundgust
		else
			player.pflags = $|PF_THOKKED&~PF_NOJUMPDAMAGE
			S_StartSound(player.mo, sfx_cdfm51)
			S_StopSoundByID(player.mo, sfx_putput)
			S_StopSoundByID(player.mo, sfx_putfst)
			player.secondjump = MOMNUM+MOMTIME
			player.mo.state = S_PLAY_ROLL
			P_InstaThrust(player.mo, player.mo.angle,
			FixedHypot(player.rmomx,player.rmomy) + FixedMul(player.normalspeed/3, player.mo.scale))
			player.rmomx = player.mo.momx
			player.rmomy = player.mo.momy
			player.feelsangle = player.mo.angle
		end
	end
end)

addHook("SpinSpecial", function(player)
	if player.mo and player.mo.valid and player.mo.skin == "feelsonic"
	and not (player.pflags&PF_SPINDOWN) and player.secondjump == FLYNUM
		player.secondjump = 0
		player.mo.state = S_PLAY_FALL
		S_StopSoundByID(player.mo, sfx_putput)
		S_StopSoundByID(player.mo, sfx_putfst)
		return true
	end
end)

//Main Think Code
addHook("PlayerThink", function(player)
	if not (player.mo and player.mo.valid and player.mo.skin == "feelsonic") return end
	
	if P_IsObjectOnGround(player.mo)
		//Triple jump grace period
		if player.tjcounttime
			player.tjcounttime = $-1
		else
			player.tjcount = 0
		end
		
		//Winning
		if player.exiting > 0 and player.mo.state != S_PLAY_FEELVICT1
		and player.mo.state != S_PLAY_FEELVICT2
			player.mo.state = S_PLAY_FEELVICT1
		end
	end
	
	//Flight
	if player.secondjump == FLYNUM
		if not (leveltime%10)
			S_StartSound(player.mo, sfx_putput)
		end
		if player.mo.momz*P_MobjFlip(player.mo) <= -6*player.mo.scale
			P_SetObjectMomZ(player.mo, -6*FRACUNIT, false)
		end
		if not P_IsObjectInGoop(player.mo)
			player.mo.momz = $-P_GetMobjGravity(player.mo)/2
		end
		
	//Boundgust
	elseif player.secondjump > MOMNUM and player.mo.state == S_PLAY_ROLL
		player.secondjump = $ - 1
		if player.secondjump > MOMNUM+MOMTIME/3
			P_InstaThrust(player.mo, player.feelsangle, FixedHypot(player.rmomx,player.rmomy))
			player.mo.momz = 0
			
			if leveltime % 2 == 0
				local fuckwit = P_SpawnGhostMobj(player.mo)
				fuckwit.colorized = true
			end
			
			local diff = (player.mo.angle - player.feelsangle)
            local factor = 8
            if diff
                if (diff > ANGLE_180)
                    diff = InvAngle(InvAngle(diff)/factor)
                else
                    diff = $/factor
                end
                player.feelsangle = $+diff
            end
			
			if not (player.cmd.buttons&BT_JUMP)
				player.secondjump = MOMNUM+MOMTIME/3
			end
		elseif player.secondjump <= MOMNUM+1
			player.pflags = $|PF_NOJUMPDAMAGE
			player.mo.state = S_PLAY_FALL
			player.secondjump = 0
		end
	end
end)

addHook("FollowMobj", function(player, mobj)
	if not mobj.skin
		mobj.skin = "feelsonic"
	end
	A_CapeChase(mobj, 21*FRACUNIT+1, -10*FRACUNIT)
	if player.powers[pw_super] > 1
		mobj.state = S_TAILSOVERLAY_STAND
	else
		mobj.state = S_INVISIBLE
	end
	return true
end, MT_FEELS_CAPE)