//comet dash lua

local function comet(player)
	local center = P_SpawnMobj(player.mo.x, player.mo.y, player.mo.z+player.mo.height/2, MT_THOK)
	center.target = player.mo
	center.scale = player.mo.scale/3
	center.color = player.mo.color
	local radiusx = P_ReturnThrustX(player.mo, player.mo.angle, -player.mo.radius)
	local radiusy = P_ReturnThrustY(player.mo, player.mo.angle, -player.mo.radius)
	local factorx = P_ReturnThrustX(player.mo, player.mo.angle+ANGLE_90, FRACUNIT)
	local factory = P_ReturnThrustY(player.mo, player.mo.angle+ANGLE_90, FRACUNIT)
	local i = -1
	while (i < 2)
		local offseth = i*P_ReturnThrustX(player.mo, ANG20*leveltime, player.mo.radius)
		local offsetv = i*P_ReturnThrustY(player.mo, ANG20*leveltime, player.mo.radius)
		local x = player.mo.x + radiusx + FixedMul(offseth, factorx)
		local y = player.mo.y + radiusy + FixedMul(offseth, factory)
		local z = player.mo.z + (player.mo.height >> 1) + offsetv
		local trail = P_SpawnMobj(x, y, z, MT_THOK)
		trail.target = player.mo
		trail.scale = player.mo.scale/3
		trail.color = player.mo.color
		i = $+2
	end
end

addHook("PlayerThink", function(player)
	if (player.playerstate != PST_LIVE) or not (player.mo)
		return
	end
	if (player.mo.skin == "sonic")
		if P_IsObjectOnGround(player.mo) or player.powers[pw_carry] or (player.mo.eflags & MFE_SPRUNG) or P_PlayerInPain(player) or (player.playerstate != PST_LIVE)
			player.cometdashtimer = 0
			player.cometdashwall = 0
			player.cometdashspeedstore = 0
			player.cometdashextra = 0
			if (player.pflags & PF_DRILLING) and (player.powers[pw_carry] != CR_NIGHTSMODE)
				player.pflags = $ & ~PF_DRILLING
			end
			return
		end
		if (player.cometdashtimer)
			player.cometdashtimer = $-1
			player.drawangle = player.mo.angle
			player.mo.momz = $-P_GetMobjGravity(player.mo)<<1
			comet(player)
			if (player.cometdashtimer == 1) and (player.speed) and (player.cometdashspeedstore)
				P_InstaThrust(player.mo, R_PointToAngle2(0, 0, player.rmomx, player.rmomy), player.cometdashspeedstore)
				player.cometdashspeedstore = 0
				player.cometdashextra = 7
				player.pflags = $ & ~PF_DRILLING
			end
		elseif (player.cometdashextra)
			player.cometdashextra = $-1
		end
		if player.cometdashwall
			player.mo.flags = $ & ~MF_BOUNCE
			if (player.cometdashwall < 8)
				player.cometdashwall = $+1
				comet(player)
			else
				player.cometdashwall = 0
				player.pflags = $ & ~PF_THOKKED & ~PF_DRILLING
				if (player.secondjump == 4)
					P_ResetPlayer(player)
					player.mo.state = S_PLAY_FALL
				end
			end
		end
	end
end)

addHook("AbilitySpecial", function(player)
	if (player.pflags & PF_THOKKED)
		return false
	end
	if (player.mo.skin == "sonic")
		if not (player.cometdashtimer) and not (player.cometdashwall)
			local realspeed = FixedHypot(player.rmomx, player.rmomy)
			S_StartSound(player.mo, sfx_s3kb6)
			if player.powers[pw_super]
				if (player.mo.eflags & MFE_UNDERWATER)
					player.cometdashspeedstore = max(FixedMul(27<<FRACBITS, player.mo.scale), realspeed)
					P_InstaThrust(player.mo, player.mo.angle, max(FixedMul(41<<FRACBITS, player.mo.scale), realspeed))
				else
					player.cometdashspeedstore = max(FixedMul(51<<FRACBITS, player.mo.scale), realspeed)
					P_InstaThrust(player.mo, player.mo.angle, max(FixedMul(76<<FRACBITS, player.mo.scale), realspeed))
				end
			else
				if (player.mo.eflags & MFE_UNDERWATER)
					player.cometdashspeedstore = max(FixedMul(21<<FRACBITS, player.mo.scale), realspeed)
					P_InstaThrust(player.mo, player.mo.angle, max(FixedMul(31<<FRACBITS, player.mo.scale), realspeed))
				else
					player.cometdashspeedstore = max(FixedMul(41<<FRACBITS, player.mo.scale), realspeed)
					P_InstaThrust(player.mo, player.mo.angle, max(FixedMul(61<<FRACBITS, player.mo.scale), realspeed))
				end
			end
			if (P_MobjFlip(player.mo)*player.mo.momz < 1)
				A_ZThrust(player.mo, 1, FRACUNIT)
			end
			player.cometdashtimer = 12
			player.pflags = $|PF_JUMPED|PF_THOKKED|PF_DRILLING & ~PF_SPINNING
		end
		return true
	end
end)

addHook("MobjMoveBlocked", function(comet, object, line)
	if not line or not comet.player
		return
	end
	if line.valid
		if (line.frontsector) and (line.frontsector.ceilingheight == line.frontsector.floorheight) and (comet.z > line.frontsector.ceilingheight)
			return
		end
		if (line.backsector) and (line.backsector.ceilingheight == line.backsector.floorheight) and (comet.z > line.backsector.ceilingheight)
			return
		end
	end
	if (comet.player.cometdashtimer) or (comet.player.cometdashextra)
		comet.player.cometdashtimer = 0
		comet.player.cometdashextra = 0
		S_StartSound(comet, sfx_s3k49)
		comet.flags = $|MF_BOUNCE
		if (comet.eflags & MFE_UNDERWATER)
			P_SetObjectMomZ(comet, FixedMul(7<<FRACBITS, comet.scale), false)
		else
			P_SetObjectMomZ(comet, FixedMul(12<<FRACBITS, comet.scale), false)
		end
		comet.player.cometdashwall = 1
		if (comet.player.secondjump)
			comet.player.secondjump = 4
		elseif not (comet.player.powers[pw_super])
			comet.player.secondjump = 3
		end
	end
end, MT_PLAYER)
