//comet dash lua

freeslot("S_COMETDASH","SPR_RZSP")

states[S_COMETDASH] = {SPR_RZSP,FF_SEMIBRIGHT|FF_ADD|TR_TRANS60,3,nil,A,1,S_NULL}

local function comet(player)
	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.state = S_COMETDASH
		trail.target = player.mo
		trail.scale = player.mo.scale/2
		trail.color = player.mo.color
		trail.blendmode = AST_MODULATE
		i = $+2
	end
	local effect = P_SpawnMobjFromMobj(player.mo, 0, 0, 0, MT_THOK)
	effect.state = S_COMETDASH
	effect.color = player.mo.color
end

addHook("PlayerThink", function(player)
	if not (player.mo)
		return
	end
	if (player.mo.skin == "sonic")
		if 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.cometdashextra = 0
			player.cometdashspeedstore = 0
			player.pflags = $ & ~PF_DRILLING
			return
		elseif (player.cometdashtimer) and P_IsObjectOnGround(player.mo)
			player.cometdashtimer = 0
			player.cometdashwall = 0
			player.cometdashextra = 0
			P_InstaThrust(player.mo, R_PointToAngle2(0, 0, player.rmomx, player.rmomy), player.cometdashspeedstore)
			player.powers[pw_justsprung] = 0
			player.pflags = $ & ~PF_DRILLING
			return
		end
		if (player.cometdashtimer)
			player.cometdashtimer = $-1
			player.mo.momz = $-(P_GetMobjGravity(player.mo)*2/3)
			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.powers[pw_justsprung] = 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 == 1)
				P_InstaThrust(player.mo, R_PointToAngle2(0, 0, player.rmomx, player.rmomy), player.cometdashspeedstore>>1)
				player.powers[pw_justsprung] = 8
				player.powers[pw_noautobrake] = 0
			end
			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)
			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), player.speed)
					P_InstaThrust(player.mo, player.mo.angle, max(FixedMul(41<<FRACBITS, player.mo.scale), player.speed))
				else
					player.cometdashspeedstore = max(FixedMul(51<<FRACBITS, player.mo.scale), player.speed)
					P_InstaThrust(player.mo, player.mo.angle, max(FixedMul(76<<FRACBITS, player.mo.scale), player.speed))
				end
			else
				if (player.mo.eflags & MFE_UNDERWATER)
					player.cometdashspeedstore = max(FixedMul(21<<FRACBITS, player.mo.scale), player.speed)
					P_InstaThrust(player.mo, player.mo.angle, max(FixedMul(31<<FRACBITS, player.mo.scale), player.speed))
				else
					player.cometdashspeedstore = max(FixedMul(41<<FRACBITS, player.mo.scale), player.speed)
					P_InstaThrust(player.mo, player.mo.angle, max(FixedMul(61<<FRACBITS, player.mo.scale), player.speed))
				end
			end
			if (P_MobjFlip(player.mo)*player.mo.momz < 1)
				A_ZThrust(player.mo, 1, FRACUNIT)
			end
			player.cometdashtimer = 12
			player.powers[pw_justsprung] = 12
			player.powers[pw_noautobrake] = 12
			player.sonictrick = 0
			player.pflags = $|PF_JUMPED|PF_THOKKED|PF_DRILLING & ~PF_SPINNING
		end
		return true
	end
end)

addHook("MobjMoveBlocked", function(comet, object, line)
	if (comet.skin != "sonic") or not comet.player
		return
	end
	if line and line.valid
		local failed = false
		if (comet.eflags & MFE_VERTICALFLIP)
			if (line.frontsector) and (line.frontsector.floorpic == "F_SKY1") and (comet.z < line.frontsector.floorheight)
				failed = true
			end
			if (line.backsector) and (line.backsector.floorpic == "F_SKY1") and (comet.z < line.backsector.floorheight)
				failed = true
			end
		else
			if (line.frontsector) and (line.frontsector.ceilingpic == "F_SKY1") and (comet.z > line.frontsector.ceilingheight)
				failed = true
			end
			if (line.backsector) and (line.backsector.ceilingpic == "F_SKY1") and (comet.z > line.backsector.ceilingheight)
				failed = true
			end
		end
		if (failed)
			comet.player.cometdashtimer = 0
			comet.player.cometdashextra = 0
			return
		end
	else
		comet.player.cometdashtimer = 0
		comet.player.cometdashextra = 0
		return
	end
	if (comet.player.cometdashtimer or comet.player.cometdashextra)
		comet.player.cometdashtimer = 0
		comet.player.cometdashextra = 0
		if (comet.state != S_PLAY_JUMP) or not (comet.player.pflags & PF_JUMPDOWN)
			return
		end
		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)
