rawset(_G, "CheckCel", function(player, dist)
	local cel = player.mo.ceilingz
	local celcheck = player.mo.z >= (cel - (player.mo.height+dist))
	if P_MobjFlip(player.mo) == 1
		cel = player.mo.ceilingz
		celcheck = player.mo.z >= (cel - (player.mo.height+dist))
	else
		cel = player.mo.floorz
		celcheck = player.mo.z+player.mo.height <= (cel + (player.mo.height+dist))
	end
	if celcheck
		return true
	else
		return false
	end
end)

local function AscendToCeiling(player)
	if player.pflags & (PF_JUMPED|PF_STARTJUMP)
	and player.cmd.buttons & BT_JUMP
	and player.jumpfly
		P_SetObjectMomZ(player.mo, FRACUNIT/5*3, true)
		player.jumpfly = $ - 1
	end
end

rawset(_G, "CeilingRun", function(player)
	if P_MobjFlip(player.mo) == 1
		player.mo.eflags = $|MFE_VERTICALFLIP
		player.mo.flags2 = $|MF2_OBJECTFLIP
	else
		player.mo.eflags = $&~MFE_VERTICALFLIP
		player.mo.flags2 = $&~MF2_OBJECTFLIP
	end
	if player.speed > FRACUNIT
		if player.speed < player.runspeed
			player.mo.state = S_PLAY_WALK
		else
			player.mo.state = S_PLAY_RUN
		end	
	else
		player.mo.state = S_PLAY_STND
	end	
	S_StartSound(player.mo, sfx_cdfm50)
	player.ceilingd = true
	player.celcd = 15
end)

local function CeilingCling(player, cel)
	if CheckCel(player, FRACUNIT)
		if player.speed > FRACUNIT
			player.mo.momx = $/19*18
			player.mo.momy = $/19*18
			local ranx = FixedMul(P_RandomRange(0, 25)*FRACUNIT, cos(P_RandomRange(1, 360)*ANG1))
			local rany = FixedMul(P_RandomRange(0, 25)*FRACUNIT, sin(P_RandomRange(1, 360)*ANG1))
			local heg = player.mo.height
			if P_MobjFlip(player.mo) == 1
				heg = player.mo.height
			else
				heg = 0
			end
			local dust = P_SpawnMobjFromMobj(player.mo, 0, 0, heg, MT_DUST)
			P_InstaThrust(dust, R_PointToAngle2(0, 0, player.mo.momx, player.mo.momy) + P_RandomRange(-15, 15)*ANG1, -player.speed)
			P_SetObjectMomZ(dust, -P_RandomRange(0, 5)*FRACUNIT)
		else
			player.mo.momx = $/16*15
			player.mo.momy = $/16*15
		end
		P_SetObjectMomZ(player.mo, FRACUNIT)
		player.mo.state = S_PLAY_RIDE
		if not player.celcling
			S_StartSound(player.mo, sfx_cdfm51)
		end	
		player.celcling = 4
		player.pflags = $|PF_CANCARRY
		if player.cmd.buttons & BT_SPIN
		and player.celspin
			player.celspin = 15
		end
	else
		P_SetObjectMomZ(player.mo, FRACUNIT, true)
	end
end
for i = 1, 4
freeslot("SPR_DSCL", "S_CEL_DASH"..i)
end
states[S_CEL_DASH1] = {SPR_DSCL, A|FF_PAPERSPRITE, 2, nil, 0, 0, S_CEL_DASH2}
states[S_CEL_DASH2] = {SPR_DSCL, B|FF_PAPERSPRITE, 2, nil, 0, 0, S_CEL_DASH3}
states[S_CEL_DASH3] = {SPR_DSCL, C|FF_PAPERSPRITE, 2, nil, 0, 0, S_CEL_DASH4}
states[S_CEL_DASH4] = {SPR_DSCL, D|FF_PAPERSPRITE, 2, nil, 0, 0, S_CEL_DASH1}

local feetanim = {
[0] = S_CEL_DASH4,
[1] = S_CEL_DASH1,
[2] = S_CEL_DASH2,
[3] = S_CEL_DASH3,
[4] = S_CEL_DASH4,
[5] = S_CEL_DASH1}

local feetanim2 = {
[0] = S_CEL_DASH1,
[1] = S_CEL_DASH4,
[2] = S_CEL_DASH1,
[3] = S_CEL_DASH2,
[4] = S_CEL_DASH3,
[5] = S_CEL_DASH4}

rawset(_G, "DrawFeet", function(mo, angles, dash)
	for i = 1, 2
		local minusplus = 1
		if i == 1
			minusplus = 1
		else
			minusplus = -1
		end
		local addx = FixedMul(10*FRACUNIT,cos(angles+(ANGLE_90*minusplus)))
		local addy = FixedMul(10*FRACUNIT,sin(angles+(ANGLE_90*minusplus)))
		local anim = 1 + (leveltime%3)
		local feet = P_SpawnMobjFromMobj(mo, addx, addy, 0, MT_PARTICLE)
		feet.angle = angles
		feet.fuse = 4
		feet.colorized = true
		feet.momx = mo.momx
		feet.momy = mo.momy
		feet.momz = mo.momz
		feet.blendmode = AST_ADD
		if i == 1
			feet.state = feetanim[anim]
		else
			feet.state = feetanim2[anim]
		end	
		feet.color = P_RandomRange(1, #skincolors-1)
		if dash
			local dsh = dash
			if dash < 60
				dsh = dash
			else	
				dsh = 60
			end
			feet.spritexscale = dsh*(FRACUNIT/40)
		end
		//return feet
	end
end)

local function NotHoldingCling(player)
	if not (player.cmd.buttons & BT_JUMP)
		if player.celspin
			if player.cmd.buttons & BT_SPIN
				return false
			else
				return true
			end
		else
			return true
		end
	end
end

addHook("PlayerThink", function(player) //Fix every mistake with ceiling check
	if player.valid and player.playerstate == PST_LIVE and player.powers[pw_carry] != CR_NIGHTSMODE
	and not player.spectator
	and player.mo.skin == "goosonic"
		local cel = player.mo.ceilingz
		local secpic = player.mo.subsector.sector.ceilingpic
		local sec = player.mo.subsector.sector
		if P_MobjFlip(player.mo) == 1
			cel = player.mo.ceilingz
			if player.mo.ceilingrover
				secpic = player.mo.ceilingrover.bottompic
			else
				secpic = player.mo.subsector.sector.ceilingpic
			end	
		else
			cel = player.mo.floorz
			if player.mo.floorrover
				secpic = player.mo.floorrover.toppic
			else
				secpic = player.mo.subsector.sector.floorpic
			end	
		end
		player.celcd = $ or 0
		player.celcling = $ or 0
		player.celdash = $ or 0
		player.celdashend = $ or 0
		player.standcel = $ or 0
		player.spundash = $ or 0
		player.celspin = $ or 0
		if player.celspin
			player.celspin = $ - 1
		end
		if player.speed < FRACUNIT
		and not player.celcling
			player.fullstop = true
			player.stopangle = player.wallangle
		end
		if player.celcd
			player.celcd = $ - 1
		end
		if player.standcel
			if (player.speed <= (skins[player.mo.skin].runspeed))
				player.standcel = $ - 1
			end	
		end
		if player.celcling
			player.celcling = $ - 1
		end
		if player.celdash
			player.celdash = $ - 1
		end
		if player.celdashend
			player.celdashend = $ - 1
		end
		if player.ceilingd
			player.friction = FRACUNIT*5
		else
			player.friction = 29*FRACUNIT/32
		end
		local runsped = player.speed >= FixedMul(player.runspeed, player.mo.scale)
		if player.mo.eflags & MFE_UNDERWATER
			runsped = player.speed >= (FixedMul(player.runspeed, player.mo.scale)/2)
		else
			runsped = player.speed >= FixedMul(player.runspeed, player.mo.scale)
		end
		if player.ceilingd
			if not P_IsObjectOnGround(player.mo)
			or ((not runsped) and not player.standcel)
				if P_MobjFlip(player.mo) == 1
					player.mo.eflags = $|MFE_VERTICALFLIP
					player.mo.flags2 = $|MF2_OBJECTFLIP
				else
					player.mo.eflags = $&~MFE_VERTICALFLIP
					player.mo.flags2 = $&~MF2_OBJECTFLIP
				end
				player.ceilingd = false
				player.flipgrav = TICRATE
				if not (player.pflags & PF_JUMPED)
					player.mo.state = S_PLAY_FALL
				end
			end
			if ((not runsped) and player.standcel)
				if player.dashsped and player.dashsped > 2*TICRATE
					player.dashsped = (TICRATE + TICRATE/2)
				end
				if player.mo.state != S_PLAY_ROLL
				or player.mo.state != S_PLAY_JUMP
				or player.mo.state != S_PLAY_SPINDASH
					DrawFeet(player.mo, player.drawangle, player.standcel)
				end	
				if not (player.cmd.forwardmove or player.cmd.sidemove)
					player.celspin = 5
				end
				if not player.soundplay
					S_StartSound(player.mo, sfx_cdfm57)
				end
				player.soundplay = true
			else
				player.soundplay = false
			end
		end
		player.jumpfly = $ or 0
		if P_IsObjectOnGround(player.mo)
			player.jumpfly = TICRATE/2*3
		end
		local celcheck2 = (cel - 150*FRACUNIT)
		local whrildist = 150*FRACUNIT
		if player.powers[pw_shield] == SH_WHIRLWIND //Gotta keep it simple
			if P_MobjFlip(player.mo) == 1
				celcheck2 = (cel - 200*FRACUNIT)
			else
				celcheck2 = (cel + 200*FRACUNIT)
			end
			whrildist = 200*FRACUNIT
		else
			if P_MobjFlip(player.mo) == 1
				celcheck2 = (cel - 150*FRACUNIT)
			else
				celcheck2 = (cel + 150*FRACUNIT)
			end
			whrildist = 150*FRACUNIT
		end
		if CheckCel(player, whrildist)
		and (player.mo.momz*P_MobjFlip(player.mo)) >= 0
		and runsped
		and not player.celcd and not player.ceilingd
			if (secpic and secpic != "F_SKY1")
				AscendToCeiling(player)
			end
		end
		local flipfucknormal2 = player.mo.z
		local flipfuckheight2 = player.mo.z+player.mo.height
		local celcheck3 = flipfucknormal2 >= cel
		if P_MobjFlip(player.mo) == 1
			flipfucknormal2 = player.mo.z
			flipfuckheight2 = player.mo.z+player.mo.height
			celcheck3 = flipfuckheight2 >= cel
		else
			flipfucknormal2 = player.mo.z+player.mo.height
			flipfuckheight2 = player.mo.z
			celcheck3 = flipfuckheight2 <= cel
		end
		if CheckCel(player, FRACUNIT)
		and player.mo.momz*P_MobjFlip(player.mo) >= 0
		and (runsped
		or player.dashsped >= 2*TICRATE + 15)
		and not player.celcd and not player.ceilingd
			if (secpic and secpic != "F_SKY1")
				CeilingRun(player)
			end
		end
		local flipfucknormal = player.mo.z
		local flipfuckheight = player.mo.z+player.mo.height
		local celcheck = flipfucknormal >= (cel - ((player.mo.height+10*FRACUNIT)*P_MobjFlip(player.mo)))
		if P_MobjFlip(player.mo) == 1
			flipfucknormal = player.mo.z
			flipfuckheight = player.mo.z+player.mo.height
			celcheck = flipfuckheight >= (cel - ((10*FRACUNIT)*P_MobjFlip(player.mo)))
		else
			flipfucknormal = player.mo.z+player.mo.height
			flipfuckheight = player.mo.z
			celcheck = flipfuckheight <= (cel - ((10*FRACUNIT)*P_MobjFlip(player.mo)))
		end
		if CheckCel(player, 10*FRACUNIT)
		and player.mo.momz*P_MobjFlip(player.mo) >= -FRACUNIT
		and not player.celcd and not player.ceilingd
		and not runsped
			if (secpic and secpic != "F_SKY1")
				if player.cmd.buttons & BT_JUMP
				or (player.cmd.buttons & BT_SPIN and player.celspin)
					CeilingCling(player, cel)
				end
			end
		end
		if (NotHoldingCling(player) or not CheckCel(player, 15*FRACUNIT))
		and player.celcling
			player.pflags = $ & ~PF_THOKKED
			player.pflags = $|PF_NOJUMPDAMAGE
			player.mo.state = S_PLAY_FALL
			player.freefall = true
			if not player.firsttimenot
				player.usedspring = false
				player.firsttimenot = true
			end
		end
		if P_IsObjectOnGround(player.mo)
			player.firsttimenot = false
		end
		if player.cmd.buttons & BT_JUMP
			player.celjump = true
		else
			player.celjump = false
		end
	end
end)