-- New Fireworks by googol
-- https://forum.minetest.net/viewtopic.php?f=9&t=16721
-- License: LGPLv2.1+
-- Modified by Talas for colourhop

new_fireworks = {}

local rocket = {
	physical = false,
	collisionbox = {0, -0.5, 0, 0, 0.5, 0},
	visual = "sprite",
	textures = {"rocket_low.png"},
	timer = 0,
	rocket_firetime = 0,
	glow = 30,
	static_save = false,
}

local function calc_ball_figure(r)
	local tab = {}
	local num = 1
	for x=-r,r,0.01 do
		for y=-r,r,0.01 do
			for z=-r,r,0.01 do
				if x*x+y*y+z*z <= r*r and x*x+y*y+z*z >= (r-0.005)*(r-0.005) then
					if math.random(1,4) > 1 then
						local xrand = math.random(-3, 3) * 0.001
						local yrand = math.random(-3, 3) * 0.001
						local zrand = math.random(-3, 3) * 0.001
						tab[num] = {x=x+xrand, y=y+yrand, z=z+zrand, v=43}
					end
					num = num + 1
				end
			end
		end
	end
	return tab
end

local ball_figure = calc_ball_figure(0.1)


-- Activate fireworks
local function partcl_gen(pos, tab, size_min, size_max, colour)
	for _,i in pairs(tab) do
		minetest.add_particle({
			pos = {x=pos.x, y=pos.y, z=pos.z},
			velocity = {x=i.x*i.v, y=i.y*i.v, z=i.z*i.v},
			acceleration = {x=0, y=-1.5, z=0},
			expirationtime = 3,
			size = math.random(size_min, size_max),
			collisiondetection = true,
			vertical = false,
			animation = {type = "vertical_frames", aspect_w = 9, aspect_h = 9, length = 3.5},
			glow = 30,
			texture = "anim_"..colour.."_star.png",
		})
	end
end

function rocket:on_activate(staticdata)
	local tmp = minetest.deserialize(staticdata)
	self.colour = tmp["colour"]
	self.high = tmp["high"]
	self.shield = tmp["shield"]
	minetest.sound_play("simple_fireworks_rocket", {pos=self.object:get_pos(),
							 max_hear_distance = 13, gain = 1})
	self.rocket_flytime = math.random(13, 14)/10
	self.object:set_velocity({x=0, y=9, z=0})
	if self.high then
		self.rocket_flytime = self.rocket_flytime * 1.1
		self.object:set_properties({ textures = {"rocket_high.png"} })
		self.object:set_acceleration({x=math.random(-4, 4), y=37, z=math.random(-4, 4)})
	elseif self.shield then
		self.object:set_properties({ textures = {"rocket_shield.png"} })
		self.object:set_acceleration({x=math.random(-5, 5), y=22, z=math.random(-5, 5)})
	else
		self.object:set_acceleration({x=math.random(-5, 5), y=19, z=math.random(-5, 5)})
	end
end

-- Called periodically
function rocket:on_step(dtime)
	self.timer = self.timer + dtime
	self.rocket_firetime = self.rocket_firetime + dtime
	if self.rocket_firetime > 0.1 then
		local pos = self.object:get_pos()
		self.rocket_firetime = 0
		local xrand = math.random(-15, 15) / 10
		local zrand = math.random(-15, 15) / 10
		minetest.add_particle({
			pos = {x=pos.x, y=pos.y-0.4, z=pos.z},
			velocity = {x=xrand, y=-3, z=xrand},
			acceleration = {x=0, y=0, z=0},
			expirationtime = 1.5,
			size = 3,
			collisiondetection = true,
			vertical = false,
			animation = {type="vertical_frames", aspect_w = 9, aspect_h = 9, length = 1.6},
			glow = 10,
			texture = "anim_white_star.png",
		})
	end
	if self.timer > self.rocket_flytime then
		minetest.sound_play("simple_fireworks_bang", {pos=self.object:get_pos(),
								 max_hear_distance = 90, gain = 3})
		partcl_gen(self.object:get_pos(), ball_figure, 4, 4, self.colour)
		draconis.check_fireworks_hit(self.object:get_pos(), self.shield)
		self.object:remove()
	end
end

minetest.register_entity("new_fireworks:rocket", rocket)

new_fireworks.launch = function(pos, colour, high_altitude, shield_breaker)
	local tmp = minetest.serialize({colour = colour, high = high_altitude, shield = shield_breaker})
	local obj = minetest.add_entity(pos, "new_fireworks:rocket", tmp)
	return obj
end
