-- particle.lua
-- @date 2022-02-20
-- @author MrRare
-- @brief Enhanced fire and smoke particle spawner, based on ThiccSmoke & ThiccFire (I am the author of that mod :P).

Particle_Randomness =  0.8
Particle_TypeFire = {3, 5, 5, 13, 14, 8}
Particle_TypeSmoke = {3, 5, 3, 5, 3, 5}
Particle_Duplicator = 1
Particle_SmokeFadeIn = 0
Particle_SmokeFadeOut = 5
Particle_FireFadeIn = 1
Particle_FireFadeOut = 1
Particle_FireEmissive = 6
Particle_Embers = "OFF"

Particle_Fire = {
    color={r=0.93,g=0.25,b=0.10,a=1},
    lifetime=5,
    size=1,
    gravity=6,
    speed=1,
    drag=0.5,
    variation=0.1,
	location_random=0.5,
    custom_direction=nil
}

Particle_Smoke = {
    color={r=0.08,g=0.08,b=0.08,a=1},
    lifetime=8,
    size=1,
    gravity=8,
    speed=2,
    drag=0.3,
    variation=0.3,
	location_random=3,
    custom_direction=nil
}

Particle_Fire_Expl = {
    color={r=0.93,g=0.25,b=0.10,a=1},
    lifetime=4,
    size=1,
    gravity=8,
    speed=8,
    drag=0.8,
    variation=0.3,
	location_random=4,
    custom_direction=nil
}

Particle_Smoke_Expl = {
    color={r=0,g=0,b=0,a=1},
    lifetime=8,
    size=1,
    gravity=8,
    speed=10,
    drag=1,
    variation=0.1,
	location_random=4,
    custom_direction=nil
}

Particle_FireGradient = {
    {-0.2, -0.3, -0.3},
    {0, -0.2, -0.2},
    {-0.2, -0.1, -0.1},
    {-0.3, 0, 0},
    {-0.3, 0.1, 0.2}
}


Particle_SpawningFire = true
function Particle_FireSmoke(fire_emitter, smoke_emitter,fire_intensity, smoke_intensity, location)
	if Particle_SpawningFire then
		Particle_EmitParticle(fire_emitter, location, "fire", fire_intensity)
		Particle_SpawningFire = false
	else
		Particle_EmitParticle(smoke_emitter, location, "smoke", smoke_intensity)
		Particle_SpawningFire = true
	end
end

function Particle_EmitParticle(emitter, location, particle, fire_intensity)

	local radius = emitter["size"]
	local life = emitter["lifetime"]
	local vel = emitter["speed"]
	local drag = emitter["drag"]
	local gravity = emitter["gravity"]
	-- Fire color
	local red = emitter["color"]["r"]
	local green = emitter["color"]["g"]
	local blue = emitter["color"]["b"]
	local alpha = emitter["color"]["a"]
	local variation = emitter["variation"]
    local custom_direction = emitter["custom_direction"]
    local location_random = emitter["location_random"]
	alpha = alpha +  Generic_rnd( -variation, variation)
	-- gravity = gravity + Generic_rnd(gravity / 2 , gravity * 2)
	if alpha > 1 then
		alpha = 1
	end

	if alpha < 0 then
		alpha = 0
	end

	drag = ((drag / (100 / 1.5)) * fire_intensity)
	radius = ((radius / (100 / 1.5)) * fire_intensity)
	gravity = ((gravity / (75 / 1.5)) * fire_intensity)

	--Set up the particle state
	ParticleReset()
	ParticleType("smoke")
	ParticleDrag(drag)
	ParticleCollide(1, 1, "constant", 0.01)
	local iterator = Particle_Duplicator
	local rand = Generic_rndInt(1, #Particle_TypeFire)
	if particle == "fire" then
		local particle_type = Particle_TypeFire[rand]
		ParticleTile(particle_type)

		local s_random = Particle_FireGradient[Generic_rndInt(1, #Particle_FireGradient)]
		local s_red =  0.8 + s_random[1]
		local s_green = 0.6 + s_random[2]
		local s_blue =  0.3 + s_random[3]
		-- 3 - 5 - 13 -  14
		-- 8 = fire embers
		life = life + Generic_rnd(-life / 2, life / 2)
		if life < 0.5 then
			life = 0.5
		end


		ParticleColor (s_red, s_green, s_blue, red, green, blue)
		ParticleStretch(0, Generic_rnd(1, Particle_Randomness * 2))
		ParticleAlpha(alpha, 0, "smooth",  life * (Particle_FireFadeIn / 100),  life * (Particle_FireFadeOut / 100))	-- Ramp up fast, ramp down after 50%

		if particle_type == 5 then
			local emissive = Generic_rnd(Particle_FireEmissive, Particle_FireEmissive * 2)
			ParticleEmissive(emissive, 2, "easeout", 0, (Particle_FireFadeIn / 100) * Generic_rnd(variation , variation * 3))
			ParticleRadius(radius, radius / 4, "easein", life *(Particle_FireFadeIn / 100), life * (Particle_FireFadeOut / 100))
			-- life = radius * life * 2
		elseif particle_type == 8 then
			gravity = gravity +  Generic_rnd(1, 3)
			vel = vel + Generic_rnd(2 , 4)
			ParticleStretch(1, 10)
			local emissive = Generic_rnd(Particle_FireEmissive / 2, Particle_FireEmissive * 2)
			ParticleEmissive(emissive, 2, "easeout")
			ParticleRadius(radius , radius / 2, "easein")
		else
			-- life = radius * life * 2
			local emissive = Generic_rnd(Particle_FireEmissive / 2, Particle_FireEmissive * 2)
			ParticleEmissive(emissive, 2, "easeout", 0, (Particle_FireFadeIn / 100) * Generic_rnd(variation , variation * 3))
			ParticleRadius(radius, radius / 4, "easeout")
		end
		iterator = 1
	else
		local particle_type = Particle_TypeSmoke[rand]
		ParticleTile(particle_type)
		ParticleAlpha(alpha, alpha / 2, "easein", (life / 100) * Particle_SmokeFadeIn, (life / 100) * Particle_SmokeFadeOut)
		ParticleRadius(radius * 0.75, radius, "constant")
		ParticleColor(red, green, blue, red + 0.2, green + 0.2, blue + 0.2)
	end

	for d=1, iterator do
		ParticleGravity(Generic_rnd(gravity / 2, gravity))		-- Slightly randomized gravity looks better
		ParticleRotation(Generic_rnd(-vel / 2 , vel / 2), Generic_rnd(-vel / 4 , vel / 4), "smooth")
		--Emit particles
        local v = custom_direction
        if  v == nil then
            v = {Generic_rnd(-vel, vel),Generic_rnd(0, vel),Generic_rnd(-vel, vel)}
        end

		--Spawn particle into the world
		SpawnParticle(VecAdd(location, Generic_rndVec(location_random)), v, life)
	end
end
