fireworkz/init.lua

429 lines
12 KiB
Lua

fireworkz = {}
--Variables
local modname = "fireworkz"
local modpath = minetest.get_modpath(modname)
local S = minetest.get_translator(minetest.get_current_modname())
--Settings
fireworkz.settings = {}
local settings = Settings(modpath .. "/fireworkz.conf")
fireworkz.settings.igniter = settings:get("igniter") or "default:torch"
fireworkz.settings.ignition_time = tonumber(settings:get("ignition_time")) or 3
fireworkz.settings.max_hear_distance_fuse = tonumber(settings:get("max_hear_distance_fuse")) or 5
fireworkz.settings.max_hear_distance_launch = tonumber(settings:get("max_hear_distance_launch")) or 13
fireworkz.settings.max_hear_distance_bang = tonumber(settings:get("max_hear_distance_bang")) or 90
local variant_list = {
--{colour = "default", figure = "", form = "", desc = ""},
{colour = "red", figure = "default", form = "", desc = S("Red")},
{colour = "green", figure = "default", form = "", desc = S("Green")},
{colour = "blue", figure = "default", form = "", desc = S("Blue")},
{colour = "yellow", figure = "default", form = "", desc = S("Yellow")},
{colour = "white", figure = "default", form = "", desc = S("White")},
{colour = "red", figure = "ball", form = "", desc = S("Red")},
{colour = "green", figure = "ball", form = "", desc = S("Green")},
{colour = "blue", figure = "ball", form = "", desc = S("Blue")},
{colour = "yellow", figure = "ball", form = "", desc = S("Yellow")},
{colour = "white", figure = "ball", form = "", desc = S("White")},
{colour = "red", figure = "custom", form = "love", desc = S("Red")},
{colour = "blue_white_red", figure = "ball_default_love", form = "", desc = S("Blue-White-Love"),
rdt = {
{color = "blue", figure = "ball", form = ""},
{color = "yellow", figure = "default", form = ""},
--{color = "red", figure = "custom", form = "love"},
}
},
{colour = "green_yellow_red", figure = "ball_default_love", form = "", desc = S("Green-Yellow-Love"),
rdt = {
{color = "green", figure = "ball", form = ""},
{color = "yellow", figure = "default", form = ""},
{color = "red", figure = "custom", form = "love"},
}
},
}
--Functions
local function default_figure(r)
local tab = {}
local num = 1
for x=-r, r, 0.02 do
for y=-r, r, 0.02 do
for z=-r, r, 0.02 do
if x*x + y*y + z*z <= r*r then
local v = math.random(21,35) --velocity
if math.random(1,2) > 1 then
local xrand = math.random(-5, 5) * 0.001
local yrand = math.random(-5, 5) * 0.001
local zrand = math.random(-5, 5) * 0.001
tab[num] = {x=x+xrand, y=y+yrand, z=z+zrand, v=v}
end
num = num + 1
end
end
end
end
return tab
end
local function 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 function custom_figure(form)
local tab = {}
if form == "love" then
tab[1] = {x=0,y=0,z=0,v=60}
tab[2] = {x=0,y=0,z=-0.02,v=60}
tab[3] = {x=0.01,y=0,z=-0.03,v=60}
tab[4] = {x=0.02,y=0,z=-0.04,v=60}
tab[5] = {x=0.03,y=0,z=-0.04,v=60}
tab[6] = {x=0.04,y=0,z=-0.03,v=60}
tab[7] = {x=0.05,y=0,z=-0.02,v=60}
tab[8] = {x=0.05,y=0,z=-0.01,v=60}
tab[9] = {x=0.04,y=0,z=0,v=60}
tab[10] = {x=0.04,y=0,z=0.01,v=60}
tab[11] = {x=0.03,y=0,z=0.02,v=60}
tab[12] = {x=0.02,y=0,z=0.03,v=60}
tab[13] = {x=0.01,y=0,z=0.04,v=60}
tab[14] = {x=0,y=0,z=0.05,v=60}
tab[15] = {x=-0.01,y=0,z=0.04,v=60}
tab[16] = {x=-0.02,y=0,z=0.03,v=60}
tab[17] = {x=-0.03,y=0,z=0.02,v=60}
tab[18] = {x=-0.04,y=0,z=0.01,v=60}
tab[19] = {x=-0.04,y=0,z=0,v=60}
tab[20] = {x=-0.05,y=0,z=-0.01,v=60}
tab[21] = {x=-0.05,y=0,z=-0.02,v=60}
tab[22] = {x=-0.04,y=0,z=-0.03,v=60}
tab[23] = {x=-0.03,y=0,z=-0.04,v=60}
tab[24] = {x=-0.02,y=0,z=-0.04,v=60}
tab[25] = {x=-0.01,y=0,z=-0.03,v=60}
else
tab[1] = {x=0,y=0,z=0,v=0}
end
return tab
end
-- 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,
--collision_removal = false,
vertical = false,
animation = {type="vertical_frames", aspect_w=9, aspect_h=9, length = 3.5,},
glow = 30,
texture = "anim_"..colour.."_star.png",
})
end
end
-- Entity Definition
local rocket = {
physical = true, --collides with things
wield_image = "rocket_default.png",
collisionbox = {0, -0.5 ,0 ,0 ,0.5 ,0},
visual = "sprite",
textures = {"rocket_default.png"},
timer = 0,
rocket_firetime = 0,
rocket_flytime = 0,
rdt = {} -- rocket data table
}
--Entity Registration
minetest.register_entity("fireworkz:rocket", rocket)
function rocket:on_activate(staticdata)
minetest.sound_play("fireworkz_rocket", {pos=self.object:getpos(), max_hear_distance = fireworkz.settings.max_hear_distance_launch, gain = 1,})
self.rocket_flytime = math.random(13,15)/10
self.object:setvelocity({x=0, y=9, z=0})
self.object:setacceleration({x= math.random(-5, 5), y= 33, z= math.random(-5, 5)})
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:getpos()
self.rocket_firetime = 0
local xrand = 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
if #self.rdt > 0 then
minetest.sound_play("fireworkz_bang", {pos= self.object:get_pos(), max_hear_distance = fireworkz.settings.max_hear_distance_bang, gain = 3,})
for _, i in pairs(self.rdt) do
local pos = self.object:getpos()
if i.figure == "ball" then
partcl_gen(pos, ball_figure(0.1), 4, 4, i.color)
elseif i.figure == "default" then
partcl_gen(pos, default_figure(0.1), 2, 4, i.color)
elseif i.figure == "custom" then
partcl_gen(pos, custom_figure(i.form), 7, 7, i.color)
end
end
end
self.object:remove()
end
end
--Nodes
for _, i in pairs(variant_list) do
local figure_desc = ""
if i.figure == "default" then
figure_desc = S("Default")
elseif i.figure == "ball" then
figure_desc = S("Ball")
elseif i.figure == "ball_default_love" then
figure_desc = S("Love Ball")
elseif i.figure == "custom" then
figure_desc = S("Custom")
end
local inv_image = "rocket_"
if not(i.figure == "") then
inv_image = inv_image .. i.figure .. "_"
end
inv_image = inv_image .. i.colour .. ".png"
local rdt = i.rdt or {{color = i.colour, figure = i.figure, form = i.form},}
minetest.register_node("fireworkz:rocket_"..i.figure.."_"..i.colour, {
description = S("Rocket").." (".. i.desc .. "|"..figure_desc..")",
drawtype = "plantlike",
light_source = 5,
inventory_image = inv_image,
tiles = {"rocket_default.png"},
wield_image = "rocket_default.png",
paramtype = "light",
sunlight_propagates = true,
walkable = false,
is_ground_content = false,
groups = {choppy = 3, explody = 1, firework = 1},
on_rightclick = function(pos, node, clicker, itemstack, pointed_thing)
local wielded_item = clicker:get_wielded_item()
local wielded_item_name = wielded_item:get_name()
if wielded_item_name == fireworkz.settings.igniter then
minetest.sound_play("fireworkz_fuse", {pos= pos, fireworkz.settings.max_hear_distance_fuse, gain = 1,})
minetest.after(fireworkz.settings.ignition_time, function(node, pos)
local rocket_node = minetest.get_node(pos)
if rocket_node.name == node.name then
minetest.remove_node(pos)
fireworkz.launch(pos, rdt)
end
end, node, pos)
end
end,
on_use = function(itemstack, user, pointed_thing)
local pos = minetest.get_pointed_thing_position(pointed_thing, true)
if pos then
fireworkz.launch(pos, rdt)
end
end,
on_construct = function(pos)
local meta = minetest.get_meta(pos)
meta:set_string("firework:rdt", minetest.serialize(rdt))
end,
})
end
fireworkz.launch = function(pos, rdt)
local obj = minetest.add_entity(pos, "fireworkz:rocket") --activate
local obj_ent = obj:get_luaentity()
obj_ent.rdt = rdt
end
-- Craffitems
minetest.register_craft({
output = "fireworkz:rocket_default",
recipe = {
{"tnt:gunpowder"},
{"default:paper"},
{"default:coal_lump"}
},
})
minetest.register_craft({
output = "fireworkz:rocket_default_red",
recipe = {
{"default:tin_lump", "tnt:gunpowder", "dye:red"},
{"", "default:paper", ""},
{"", "default:coal_lump", ""}
},
})
minetest.register_craft({
output = "fireworkz:rocket_default_green",
recipe = {
{"default:tin_lump", "tnt:gunpowder", "dye:green"},
{"", "default:paper", ""},
{"", "default:coal_lump", ""}
},
})
minetest.register_craft({
output = "fireworkz:rocket_default_blue",
recipe = {
{"default:tin_lump", "tnt:gunpowder", "dye:blue"},
{"", "default:paper", ""},
{"", "default:coal_lump", ""}
},
})
minetest.register_craft({
output = "fireworkz:rocket_default_yellow",
recipe = {
{"default:tin_lump", "tnt:gunpowder", "dye:yellow"},
{"", "default:paper", ""},
{"", "default:coal_lump", ""}
},
})
minetest.register_craft({
output = "fireworkz:rocket_default_white",
recipe = {
{"default:tin_lump", "tnt:gunpowder", "dye:white"},
{"", "default:paper", ""},
{"", "default:coal_lump", ""}
},
})
minetest.register_craft({
output = "fireworkz:rocket_ball_red",
recipe = {
{"default:iron_lump", "tnt:gunpowder", "dye:red"},
{"", "default:paper", ""},
{"", "default:coal_lump", ""}
},
})
minetest.register_craft({
output = "fireworkz:rocket_ball_green",
recipe = {
{"default:iron_lump", "tnt:gunpowder", "dye:green"},
{"", "default:paper", ""},
{"", "default:coal_lump", ""}
},
})
minetest.register_craft({
output = "fireworkz:rocket_ball_blue",
recipe = {
{"default:iron_lump", "tnt:gunpowder", "dye:blue"},
{"", "default:paper", ""},
{"", "default:coal_lump", ""}
},
})
minetest.register_craft({
output = "fireworkz:rocket_ball_yellow",
recipe = {
{"default:iron_lump", "tnt:gunpowder", "dye:yellow"},
{"", "default:paper", ""},
{"", "default:coal_lump", ""}
},
})
minetest.register_craft({
output = "fireworkz:rocket_ball_white",
recipe = {
{"default:iron_lump", "tnt:gunpowder", "dye:white"},
{"", "default:paper", ""},
{"", "default:coal_lump", ""}
},
})
minetest.register_craft({
output = "fireworkz:rocket_ball_default_love_blue_white_red",
recipe = {
{"default:mese_crystal", "tnt:gunpowder", "dye:blue"},
{"dye:white", "default:paper", ""},
{"", "default:coal_lump", ""}
},
})
minetest.register_craft({
output = "fireworkz:rocket_ball_default_love_green_yellow_red",
recipe = {
{"default:diamond", "tnt:gunpowder", "dye:green"},
{"dye:yellow", "default:paper", "dye:red"},
{"", "default:coal_lump", ""}
},
})
--Mesecons Support
if minetest.get_modpath("mesecons") ~= nil then
minetest.register_node("fireworkz:launcher", {
description = S("Firework Rocket Launcher"),
tiles = {"fireworkz_rocket_launcher.png"},
is_ground_content = false,
groups = {cracky = 2, stone = 1},
sounds = default.node_sound_stone_defaults(),
mesecons = {effector = {
action_on = function (pos, node)
pos.y = pos. y + 1
local node = minetest.get_node_or_nil(pos)
if node then
if node.name:sub(1, 16) == "fireworkz:rocket" then
local meta = minetest.get_meta(pos)
local rdt = minetest.deserialize(meta:get_string("firework:rdt"))
minetest.remove_node(pos)
fireworkz.launch(pos, rdt)
end
end
end,
}}
})
minetest.register_craft({
output = "fireworkz:launcher",
type = "shaped",
recipe = {
{"", "tnt:gunpowder", ""},
{"", "default:mese", ""},
{"", "default:steelblock", ""}
},
})
end