--Egg Reverie Zone Super Sonic by Frostiikin. Feel free to use & edit this anywhere as long as you give the proper credits.
--Bug Fixes, comments, and code cleanup courtesy of Dabir, Thanks for cleaning up my shoddy code lmfao
freeslot(
"sfx_spdash")
sfxinfo[sfx_spdash].caption = "Super Dash"
addHook("PlayerThink",  function(p)
    -- Only Sonic can be Super Sonic
    if not (p.mo and p.mo.valid and p.mo.skin == "jasonfox")
        return
    end
   
    -- Only Super people can be Super Sonic
    if not p.powers[pw_super]
        -- Take your old ability back, normie, we're done here
        if p.eggoldability != nil
            p.charability = p.eggoldability
            p.eggoldability = nil
        end
        -- Non-super people can't be super-flying
        p.eggsuperflying = false
        return
    end
   
    -- Can't go flying if you're in a minecart or a zoom tube
    if p.mo.state == S_PLAY_RIDE or p.powers[pw_carry] == CR_ZOOMTUBE
        return
    end
   
    -- Definitely flying, so initialise/confirm flying-related variables
    p.eggsuperflying = $ or false  -- Boolean for whether Super Sonic is flying
    p.eggflystart = $ or false -- Boolean for whether Super Sonic just started flying
    p.eggflyboost = $ or false  -- Boolean for whether Super Sonic can boost this tic
    p.eggboostcost = 5  -- How many rings it costs to boost
    p.eggmaxvert = 22*FRACUNIT  -- Maximum vertical flying speed in either direction
    p.eggoldability = $ or CA_NONE -- Storage for non-super jump ability
   
    -- If you still have a jump ability, take it away and remember what it was
    if p.charability != CA_NONE
        p.charability, p.eggoldability = CA_NONE, $1
    end
   
    -- You stop flying when you touch the ground
    if P_IsObjectOnGround(p.mo)
        p.eggsuperflying = false
    else
    -- Prevent rolling when holding spin and touching ground while flying.
        p.pflags = $ | PF_THOKKED
    end
   
    -- If you're not flying right now, we're done here.
    if not p.eggsuperflying
        return
    end
   
    -- Gravity doesn't apply when you're flying
    p.mo.momz = $-P_GetMobjGravity(p.mo)
   
    -- You can't fall when you're flying
    if p.mo.state == S_PLAY_FALL
        p.mo.state = S_PLAY_FLOAT
    end
   
    -- You're not jumping or spinning when you're flying
	p.pflags = $ & ~PF_JUMPED & ~PF_SPINNING
   
    -- You have to let go of jump after you start floating before you can ascend
    if not (p.cmd.buttons & BT_JUMP)
        p.eggflystart = false
    end
	
	--Prevent stored momentum when initiating hover
	if p.eggflystart == true and p.eggflymode == 1 
		P_SetObjectMomZ(p.mo, 0*FRACUNIT)
	end
   
    -- You have to let go of either jump or spin after boosting before you can boost again
    if not (p.cmd.buttons & BT_USE) or not (p.cmd.buttons & BT_JUMP)
        p.eggflyboost = true
    end
   
    -- If you're holding jump and not spin, accelerate up
    if (p.cmd.buttons & BT_JUMP) and not (p.cmd.buttons & BT_USE) and not p.eggflystart or (p.cmd.buttons & BT_JUMP) and not (p.cmd.buttons & BT_USE) and p.eggflymode == 2
        P_SetObjectMomZ(p.mo, 1*FRACUNIT, true) -- Accelerate up
    end
   
    -- If you're holding spin and not jump, accelerate down
    if (p.cmd.buttons & BT_USE) and not (p.cmd.buttons & BT_JUMP)
        P_SetObjectMomZ(p.mo, -1*FRACUNIT, true)
    end
   
    -- Cap the max flying speed at both ends
    p.mo.momz = max(min(p.eggmaxvert, p.mo.momz), 0-p.eggmaxvert)
   
    -- If you're holding both, and you're allowed to boost, and you can pay for it, boost
    if (p.cmd.buttons & BT_JUMP) and (p.cmd.buttons & BT_USE)
    and p.eggflyboost and p.rings >= p.eggboostcost
        p.rings = $ - p.eggboostcost
        P_InstaThrust(p.mo, p.mo.angle, 110*FRACUNIT)
        S_StartSound(p.mo, sfx_spdash)
        p.eggflyboost = false -- Can't boost if you've just boosted
    end
   
    -- If you're holding neither, come to a halt
    if not (p.cmd.buttons & BT_JUMP) and not (p.cmd.buttons & BT_USE)
        p.mo.momz = abs($)>FRACUNIT and $*9/10 or 0
    end
end)
 
addHook("AbilitySpecial", function(p)
    if p.mo.skin == "jasonfox" and p.mo and p.mo.valid
    and p.powers[pw_super] and not p.eggsuperflying
        p.eggsuperflying = true
        p.eggflystart = true
        p.mo.state = S_PLAY_FLOAT
        return true
    end
    return false
end)