-- Spawns drift sparks when waterrunning too
-- It used to be air drift sparks script, but after i changed waterrun script
-- to modify P_IsObjectOnGround, airdriftsparks.lua stopped working (which is 
-- fine by me, makes it easier to avoid script overlaps or stuff like that.
-- The only thing that is not fine is code duplication, but this basically is
-- duplication of a hardcode function anyway :p)

local cv_driftsparkpulse
local cv_sparkroll

local DRIFTSPARKGROWTICS = 8

local driftsparkGrowTimer = {}

for i = 0, #players-1 do
    driftsparkGrowTimer[i] = 0
end

local function K_SpawnDriftSparks(player)
	if leveltime % 2 == 1 then
		return
    end

	if not player.kartstuff[k_drift] or player.kartstuff[k_driftcharge] < K_GetKartDriftSparkValue(player) then
		return
    end

	local travelangle = player.mo.angle-(ANGLE_45/5)*player.kartstuff[k_drift]

	for i = 0, 1 do
		local driftExtraScale = 0
		local newx = player.mo.x + P_ReturnThrustX(player.mo, travelangle + ((i&1) and -1 or 1)*ANGLE_135, FixedMul(32*FRACUNIT, player.mo.scale))
		local newy = player.mo.y + P_ReturnThrustY(player.mo, travelangle + ((i&1) and -1 or 1)*ANGLE_135, FixedMul(32*FRACUNIT, player.mo.scale))
		local spark = P_SpawnMobj(newx, newy, player.mo.z, MT_DRIFTSPARK)

		spark.target = player.mo
		spark.angle = travelangle-(ANGLE_45/5)*player.kartstuff[k_drift]

		-- scale increase while driftspark level gained timer is running

		driftExtraScale = FixedDiv(driftsparkGrowTimer[#player], DRIFTSPARKGROWTICS)

		spark.destscale = FixedMul(player.mo.scale, FRACUNIT + FixedMul(driftExtraScale, cv_driftsparkpulse.value))
		P_SetScale(spark, FixedMul(player.mo.scale, FRACUNIT + FixedMul(driftExtraScale, cv_driftsparkpulse.value)))

		spark.momx = player.mo.momx/2
		spark.momy = player.mo.momy/2
		--spark.momz = player.mo.momz/2

		-- rotate the sparks based on pitch and roll it just looks neat
		if cv_sparkroll.value == 1 then
			spark.slopepitch = player.mo.slopepitch
			spark.sloperoll = player.mo.sloperoll
        end

		if player.kartstuff[k_driftcharge] >= K_GetKartDriftSparkValue(player)*4 then
			spark.color = (1 + (leveltime % (MAXSKINCOLORS-1)))
		elseif player.kartstuff[k_driftcharge] >= K_GetKartDriftSparkValue(player)*2 then
			if player.kartstuff[k_driftcharge] <= (K_GetKartDriftSparkValue(player)*2)+(24*3) then
				spark.color = SKINCOLOR_RASPBERRY -- transition
			else
				spark.color = SKINCOLOR_KETCHUP
            end
		else
			spark.color = SKINCOLOR_SAPPHIRE
        end

		if (player.kartstuff[k_drift] > 0 and player.cmd.driftturn > 0) -- Inward drifts
			or (player.kartstuff[k_drift] < 0 and player.cmd.driftturn < 0) then

			if player.kartstuff[k_drift] < 0 and (i & 1)
				or (player.kartstuff[k_drift] > 0 and !(i & 1)) then

				spark.state = S_DRIFTSPARK_A1
			elseif (player.kartstuff[k_drift] < 0 and !(i & 1))
				or (player.kartstuff[k_drift] > 0 and (i & 1)) then

				spark.state = S_DRIFTSPARK_C1
            end
		elseif (player.kartstuff[k_drift] > 0 and player.cmd.driftturn < 0) -- Outward drifts
			or (player.kartstuff[k_drift] < 0 and player.cmd.driftturn > 0) then

			if (player.kartstuff[k_drift] < 0 and (i & 1))
				or (player.kartstuff[k_drift] > 0 and !(i & 1)) then
				spark.state = S_DRIFTSPARK_C1
			elseif (player.kartstuff[k_drift] < 0 and !(i & 1))
				or (player.kartstuff[k_drift] > 0 and (i & 1)) then

				spark.state = S_DRIFTSPARK_A1
            end
        end

		K_MatchGenericExtraFlags(spark, player.mo)
    end
end

local function between(min, val, max)
    return val >= min and val <= max
end

addHook("PlayerThink", function(player)
    if not (player.playerstate == PST_LIVE and player.mo and player.mo.waterrunning) then
        return
    end

    if not cv_driftsparkpulse then
        cv_driftsparkpulse = CV_FindVar("driftsparkpulse") or { value = FRACUNIT }
        cv_sparkroll = CV_FindVar("sparkroll") or { value = 0 }
    end

    K_SpawnDriftSparks(player)
end)


addHook("PlayerThink", function(player)
    if not player.waterrun_lastdriftcharge then
        player.waterrun_lastdriftcharge = player.kartstuff[k_driftcharge]
        return
    end

    local dsone = K_GetKartDriftSparkValue(player)
	local dstwo = dsone*2
	local dsthree = dstwo*2

    if player.waterrun_lastdriftcharge ~= player.kartstuff[k_driftcharge] and
        (between(player.waterrun_lastdriftcharge, dsone, player.kartstuff[k_driftcharge])
        or between(player.waterrun_lastdriftcharge, dstwo, player.kartstuff[k_driftcharge])
        or between(player.waterrun_lastdriftcharge, dsthree, player.kartstuff[k_driftcharge])) then

        driftsparkGrowTimer[#player] = DRIFTSPARKGROWTICS
    else
        driftsparkGrowTimer[#player] = max($ - 1, 0)
    end

    player.waterrun_lastdriftcharge = player.kartstuff[k_driftcharge]
end)
