mirror of
https://git.minetest.land/MineClone2/MineClone2.git
synced 2025-01-01 14:17:29 +01:00
Merge pull request 'Fireworks update' (#4724) from fireworks_update into master
Reviewed-on: https://git.minetest.land/VoxeLibre/VoxeLibre/pulls/4724
This commit is contained in:
commit
8d3f3b4715
@ -184,3 +184,37 @@ tt.register_snippet(function(itemstring, _, itemstack)
|
||||
end
|
||||
return s:trim()
|
||||
end)
|
||||
|
||||
|
||||
-- Fireworks info
|
||||
tt.register_snippet(function(itemstring, _, itemstack)
|
||||
if not itemstack then return end
|
||||
local def = itemstack:get_definition()
|
||||
if not def then return end
|
||||
|
||||
if not def._vl_fireworks_tt then return end
|
||||
|
||||
local s = ""
|
||||
local meta = itemstack:get_meta()
|
||||
local stars = meta:get("vl_fireworks:stars") or core.serialize({})
|
||||
s = s .. def._vl_fireworks_tt(meta:get_float("vl_fireworks:duration"),
|
||||
core.deserialize(stars))
|
||||
|
||||
return s:trim()
|
||||
end)
|
||||
tt.register_snippet(function(itemstring, _, itemstack)
|
||||
if not itemstack then return end
|
||||
local def = itemstack:get_definition()
|
||||
if not def then return end
|
||||
|
||||
if not def.groups.firework_star or def.groups.firework_star == 0 then return end
|
||||
|
||||
local s = ""
|
||||
local meta = itemstack:get_meta()
|
||||
local effect = meta:get("vl_fireworks:star_effect") or core.serialize({fn="generic"})
|
||||
if effect then
|
||||
s = vl_fireworks.star_tt(core.deserialize(effect))
|
||||
end
|
||||
|
||||
return s
|
||||
end)
|
||||
|
@ -72,6 +72,8 @@ minetest.register_on_mods_loaded(function()
|
||||
|
||||
-- Is set to true if it was added in any category besides misc
|
||||
local nonmisc = false
|
||||
-- Is set to true if it has already been added to the "all" category (special handler)
|
||||
local all_handled = false
|
||||
if def.groups.building_block then
|
||||
table.insert(inventory_lists["blocks"], name)
|
||||
nonmisc = true
|
||||
@ -113,6 +115,22 @@ minetest.register_on_mods_loaded(function()
|
||||
table.insert(inventory_lists["matr"], name)
|
||||
nonmisc = true
|
||||
end
|
||||
if def._vl_fireworks_std_durs_forces then
|
||||
local generic = core.serialize({{fn="generic"}})
|
||||
for i, tbl in ipairs(def._vl_fireworks_std_durs_forces) do
|
||||
local stack = ItemStack(name)
|
||||
local meta = stack:get_meta()
|
||||
meta:set_float("vl_fireworks:duration", tbl[1])
|
||||
meta:set_int("vl_fireworks:force", tbl[2])
|
||||
table.insert(inventory_lists["misc"], stack:to_string())
|
||||
table.insert(inventory_lists["all"], stack:to_string())
|
||||
meta:set_string("vl_fireworks:stars", generic)
|
||||
table.insert(inventory_lists["misc"], stack:to_string())
|
||||
table.insert(inventory_lists["all"], stack:to_string())
|
||||
end
|
||||
nonmisc = true
|
||||
all_handled = true
|
||||
end
|
||||
-- Misc. category is for everything which is not in any other category
|
||||
if not nonmisc then
|
||||
table.insert(inventory_lists["misc"], name)
|
||||
@ -133,7 +151,9 @@ minetest.register_on_mods_loaded(function()
|
||||
table.insert(inventory_lists["brew"], stack:to_string())
|
||||
table.insert(inventory_lists["all"], stack:to_string())
|
||||
end
|
||||
else
|
||||
end
|
||||
|
||||
if not all_handled then
|
||||
table.insert(inventory_lists["all"], name)
|
||||
end
|
||||
|
||||
@ -190,12 +210,11 @@ local function set_inv_search(filter, player)
|
||||
local inv = minetest.get_inventory({ type = "detached", name = "creative_" .. playername })
|
||||
local creative_list = {}
|
||||
local lang = minetest.get_player_information(playername).lang_code
|
||||
for name, def in pairs(minetest.registered_items) do
|
||||
if (not def.groups.not_in_creative_inventory or def.groups.not_in_creative_inventory == 0) and def.description and
|
||||
def.description ~= "" then
|
||||
if filter_item(string.lower(def.name), def.description, lang, filter) then
|
||||
table.insert(creative_list, name)
|
||||
end
|
||||
for _, str in pairs(inventory_lists["all"]) do
|
||||
local stack = ItemStack(str)
|
||||
if filter_item(stack:get_name(), minetest.strip_colors(stack:get_description()), lang, filter)
|
||||
and stack:get_name() ~= "mcl_enchanting:book_enchanted" then
|
||||
table.insert(creative_list, stack:to_string())
|
||||
end
|
||||
end
|
||||
for ench, def in pairs(mcl_enchanting.enchantments) do
|
||||
|
@ -8,6 +8,8 @@ local ROCKET_TIMEOUT = 1
|
||||
|
||||
local YAW_OFFSET = -math.pi/2
|
||||
|
||||
local particle_explosion = vl_fireworks.particle_explosion
|
||||
|
||||
local function damage_explosion(self, damagemulitplier, pos)
|
||||
if self._harmless then return end
|
||||
|
||||
@ -27,194 +29,6 @@ local function damage_explosion(self, damagemulitplier, pos)
|
||||
end
|
||||
end
|
||||
|
||||
local function particle_explosion(pos)
|
||||
if pos.object then pos = pos.object:get_pos() end
|
||||
local particle_pattern = math.random(1, 3)
|
||||
local fpitch
|
||||
local type = math.random(1, 2)
|
||||
local size = math.random(1, 3)
|
||||
local colors = {"red", "yellow", "blue", "green", "white"}
|
||||
local this_colors = {colors[math.random(#colors)], colors[math.random(#colors)], colors[math.random(#colors)]}
|
||||
|
||||
if size == 1 then
|
||||
fpitch = math.random(200, 300)
|
||||
elseif size == 2 then
|
||||
fpitch = math.random(100, 130)
|
||||
else
|
||||
fpitch = math.random(60, 70)
|
||||
end
|
||||
|
||||
if type == 1 then
|
||||
core.sound_play("mcl_bows_firework", {
|
||||
pos = pos,
|
||||
max_hear_distance = 100,
|
||||
gain = 3.0,
|
||||
pitch = fpitch/100
|
||||
}, true)
|
||||
else
|
||||
core.sound_play("mcl_bows_firework_soft", {
|
||||
pos = pos,
|
||||
max_hear_distance = 100,
|
||||
gain = 4.0,
|
||||
pitch = fpitch/100
|
||||
}, true)
|
||||
end
|
||||
|
||||
if particle_pattern == 1 then
|
||||
core.add_particlespawner({
|
||||
amount = 400 * size,
|
||||
time = 0.0001,
|
||||
minpos = pos,
|
||||
maxpos = pos,
|
||||
minvel = vector.new(-7 * size,-7 * size,-7 * size),
|
||||
maxvel = vector.new(7 * size,7 * size,7 * size),
|
||||
minexptime = .6 * size / 2,
|
||||
maxexptime = .9 * size / 2,
|
||||
minsize = 2 * size,
|
||||
maxsize = 3 * size,
|
||||
collisiondetection = false,
|
||||
vertical = false,
|
||||
texture = "mcl_bows_firework_"..this_colors[1]..".png",
|
||||
glow = 14,
|
||||
})
|
||||
core.add_particlespawner({
|
||||
amount = 400 * size,
|
||||
time = 0.0001,
|
||||
minpos = pos,
|
||||
maxpos = pos,
|
||||
minvel = vector.new(-2 * size,-2 * size,-2 * size),
|
||||
maxvel = vector.new(2 * size,2 * size,2 * size),
|
||||
minexptime = .6 * size / 2,
|
||||
maxexptime = .9 * size / 2,
|
||||
minsize = 2 * size,
|
||||
maxsize = 3 * size,
|
||||
collisiondetection = false,
|
||||
vertical = false,
|
||||
texture = "mcl_bows_firework_"..this_colors[2]..".png",
|
||||
glow = 14,
|
||||
})
|
||||
core.add_particlespawner({
|
||||
amount = 100 * size,
|
||||
time = 0.0001,
|
||||
minpos = pos,
|
||||
maxpos = pos,
|
||||
minvel = vector.new(-14 * size,-14 * size,-14 * size),
|
||||
maxvel = vector.new(14 * size,14 * size,14 * size),
|
||||
minexptime = .6 * size / 2,
|
||||
maxexptime = .9 * size / 2,
|
||||
minsize = 2 * size,
|
||||
maxsize = 3 * size,
|
||||
collisiondetection = false,
|
||||
vertical = false,
|
||||
texture = "mcl_bows_firework_"..this_colors[3]..".png",
|
||||
glow = 14,
|
||||
})
|
||||
elseif particle_pattern == 2 then
|
||||
|
||||
core.add_particlespawner({
|
||||
amount = 240 * size,
|
||||
time = 0.0001,
|
||||
minpos = pos,
|
||||
maxpos = pos,
|
||||
minvel = vector.new(-5 * size,-5 * size,-5 * size),
|
||||
maxvel = vector.new(5 * size,5 * size,5 * size),
|
||||
minexptime = .6 * size / 2,
|
||||
maxexptime = .9 * size / 2,
|
||||
minsize = 2 * size,
|
||||
maxsize = 3 * size,
|
||||
collisiondetection = false,
|
||||
vertical = false,
|
||||
texture = "mcl_bows_firework_"..this_colors[1]..".png",
|
||||
glow = 14,
|
||||
})
|
||||
core.add_particlespawner({
|
||||
amount = 500 * size,
|
||||
time = 0.0001,
|
||||
minpos = pos,
|
||||
maxpos = pos,
|
||||
minvel = vector.new(-2 * size,-2 * size,-2 * size),
|
||||
maxvel = vector.new(2 * size,2 * size,2 * size),
|
||||
minexptime = .6 * size / 2,
|
||||
maxexptime = .9 * size / 2,
|
||||
minsize = 2 * size,
|
||||
maxsize = 3 * size,
|
||||
collisiondetection = false,
|
||||
vertical = false,
|
||||
texture = "mcl_bows_firework_"..this_colors[2]..".png",
|
||||
glow = 14,
|
||||
})
|
||||
core.add_particlespawner({
|
||||
amount = 350 * size,
|
||||
time = 0.0001,
|
||||
minpos = pos,
|
||||
maxpos = pos,
|
||||
minvel = vector.new(-3 * size,-3 * size,-3 * size),
|
||||
maxvel = vector.new(3 * size,3 * size,3 * size),
|
||||
minexptime = .6 * size / 2,
|
||||
maxexptime = .9 * size / 2,
|
||||
minsize = 2 * size,
|
||||
maxsize = 3 * size,
|
||||
collisiondetection = false,
|
||||
vertical = false,
|
||||
texture = "mcl_bows_firework_"..this_colors[3]..".png",
|
||||
glow = 14,
|
||||
})
|
||||
elseif particle_pattern == 3 then
|
||||
|
||||
core.add_particlespawner({
|
||||
amount = 400 * size,
|
||||
time = 0.0001,
|
||||
minpos = pos,
|
||||
maxpos = pos,
|
||||
minvel = vector.new(-6 * size,-4 * size,-6 * size),
|
||||
maxvel = vector.new(6 * size,4 * size,6 * size),
|
||||
minexptime = .6 * size,
|
||||
maxexptime = .9 * size,
|
||||
minsize = 2 * size,
|
||||
maxsize = 3 * size,
|
||||
collisiondetection = false,
|
||||
vertical = false,
|
||||
texture = "mcl_bows_firework_"..this_colors[1]..".png",
|
||||
glow = 14,
|
||||
})
|
||||
core.add_particlespawner({
|
||||
amount = 120 * size,
|
||||
time = 0.0001,
|
||||
minpos = pos,
|
||||
maxpos = pos,
|
||||
minvel = vector.new(-8 * size,6 * size,-8 * size),
|
||||
maxvel = vector.new(8 * size,6 * size,8 * size),
|
||||
minexptime = .6 * size,
|
||||
maxexptime = .9 * size,
|
||||
minsize = 2 * size,
|
||||
maxsize = 3 * size,
|
||||
collisiondetection = false,
|
||||
vertical = false,
|
||||
texture = "mcl_bows_firework_"..this_colors[2]..".png",
|
||||
glow = 14,
|
||||
})
|
||||
core.add_particlespawner({
|
||||
amount = 130 * size,
|
||||
time = 0.0001,
|
||||
minpos = pos,
|
||||
maxpos = pos,
|
||||
minvel = vector.new(-3 * size,3 * size,-3 * size),
|
||||
maxvel = vector.new(3 * size,3 * size,3 * size),
|
||||
minexptime = .6 * size,
|
||||
maxexptime = .9 * size,
|
||||
minsize = 2 * size,
|
||||
maxsize = 3 * size,
|
||||
collisiondetection = false,
|
||||
vertical = false,
|
||||
texture = "mcl_bows_firework_"..this_colors[3]..".png",
|
||||
glow = 14,
|
||||
})
|
||||
end
|
||||
|
||||
return size
|
||||
|
||||
end
|
||||
|
||||
core.register_craftitem("mcl_bows:rocket", {
|
||||
description = S("Arrow"),
|
||||
_tt_help = S("Ammunition").."\n"..S("Damage from bow: 1-10").."\n"..S("Damage from dispenser: 3"),
|
||||
@ -283,7 +97,7 @@ if core.get_modpath("mcl_core") and core.get_modpath("mcl_mobitems") then
|
||||
output = "mcl_bows:rocket 1",
|
||||
recipe = {
|
||||
{"mcl_core:paper"},
|
||||
{"mcl_fireworks:rocket_2"},
|
||||
{"vl_fireworks:rocket_2"},
|
||||
{"mcl_bows:arrow"},
|
||||
}
|
||||
})
|
||||
|
@ -1,17 +0,0 @@
|
||||
minetest.register_craft({
|
||||
type = "shapeless",
|
||||
output = "mcl_fireworks:rocket_1 3",
|
||||
recipe = {"mcl_core:paper", "mcl_mobitems:gunpowder"},
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
type = "shapeless",
|
||||
output = "mcl_fireworks:rocket_2 3",
|
||||
recipe = {"mcl_core:paper", "mcl_mobitems:gunpowder", "mcl_mobitems:gunpowder"},
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
type = "shapeless",
|
||||
output = "mcl_fireworks:rocket_3 3",
|
||||
recipe = {"mcl_core:paper", "mcl_mobitems:gunpowder", "mcl_mobitems:gunpowder", "mcl_mobitems:gunpowder"},
|
||||
})
|
@ -1,4 +0,0 @@
|
||||
local path = minetest.get_modpath("mcl_fireworks")
|
||||
|
||||
dofile(path .. "/register.lua")
|
||||
dofile(path .. "/crafting.lua")
|
@ -1,28 +0,0 @@
|
||||
local S = minetest.get_translator(minetest.get_current_modname())
|
||||
|
||||
local tt_help = S("Flight Duration:")
|
||||
local description = S("Firework Rocket")
|
||||
|
||||
local function register_rocket(n, duration, force)
|
||||
minetest.register_craftitem("mcl_fireworks:rocket_" .. n, {
|
||||
description = description,
|
||||
_tt_help = tt_help .. " " .. duration,
|
||||
inventory_image = "mcl_fireworks_rocket.png",
|
||||
stack_max = 64,
|
||||
on_use = function(itemstack, user, pointed_thing)
|
||||
local elytra = mcl_playerplus.elytra[user]
|
||||
if elytra.active and elytra.rocketing <= 0 then
|
||||
elytra.rocketing = duration
|
||||
if not minetest.is_creative_enabled(user:get_player_name()) then
|
||||
itemstack:take_item()
|
||||
end
|
||||
minetest.sound_play("mcl_fireworks_rocket", {pos = user:get_pos()})
|
||||
end
|
||||
return itemstack
|
||||
end,
|
||||
})
|
||||
end
|
||||
|
||||
register_rocket(1, 2.2, 10)
|
||||
register_rocket(2, 4.5, 20)
|
||||
register_rocket(3, 6, 30)
|
@ -313,8 +313,7 @@ minetest.register_craftitem("mcl_mobitems:nether_star", {
|
||||
_doc_items_longdesc = S("A nether star is dropped when the Wither dies. Place it in an item frame to show the world how hardcore you are! Or just as decoration."),
|
||||
wield_image = "mcl_mobitems_nether_star.png",
|
||||
inventory_image = "mcl_mobitems_nether_star.png",
|
||||
-- TODO: Reveal item when it's useful
|
||||
groups = { craftitem = 1, not_in_creative_inventory = 1 },
|
||||
groups = { craftitem = 1 },
|
||||
stack_max = 64,
|
||||
})
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
Firework mod for VoxeLibre
|
||||
|
||||
by NO11 and and some parts by j45
|
||||
by Herowl and teknomunk, based on the old version by NO11 and j45
|
||||
|
||||
Sound credits:
|
||||
|
95
mods/ITEMS/vl_fireworks/crafting.lua
Normal file
95
mods/ITEMS/vl_fireworks/crafting.lua
Normal file
@ -0,0 +1,95 @@
|
||||
-- Firework Star
|
||||
core.register_craft({ -- temporary
|
||||
type = "shapeless",
|
||||
output = "vl_fireworks:firework_star",
|
||||
recipe = {"mcl_mobitems:gunpowder", "mcl_core:clay_lump"}
|
||||
})
|
||||
core.register_craft({ -- temporary
|
||||
type = "shapeless",
|
||||
output = "vl_fireworks:firework_star",
|
||||
recipe = {"mcl_mobitems:gunpowder", "mcl_core:clay_lump", "mcl_fire:fire_charge"}
|
||||
})
|
||||
core.register_craft({ -- temporary
|
||||
type = "shapeless",
|
||||
output = "vl_fireworks:firework_star",
|
||||
recipe = {"mcl_mobitems:gunpowder", "mcl_core:clay_lump", "mcl_end:crystal"}
|
||||
})
|
||||
|
||||
local function craft_star(itemstack, player, old_grid)
|
||||
if itemstack:get_name() ~= "vl_fireworks:firework_star" then return end
|
||||
local size = 1
|
||||
|
||||
-- analyze the recipe used
|
||||
for _, item in pairs(old_grid) do
|
||||
if item:get_name() == "mcl_fire:fire_charge" then
|
||||
size = 2
|
||||
break
|
||||
end
|
||||
if item:get_name() == "mcl_end:crystal" then
|
||||
size = 3
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
local effect = {
|
||||
fn = "generic",
|
||||
size = size
|
||||
}
|
||||
itemstack:get_meta():set_string("vl_fireworks:star_effect", core.serialize(effect))
|
||||
tt.reload_itemstack_description(itemstack)
|
||||
return itemstack
|
||||
end
|
||||
core.register_craft_predict(craft_star)
|
||||
core.register_on_craft(craft_star)
|
||||
|
||||
-- Firework Rocket
|
||||
local function register_firework_crafts()
|
||||
local r1 = {"mcl_core:paper"}
|
||||
local r2 = table.copy(r1)
|
||||
table.insert(r2, "vl_fireworks:firework_star") -- TODO replace with a loop or such to allow more stars
|
||||
for i=1, 3 do
|
||||
table.insert(r1, "mcl_mobitems:gunpowder")
|
||||
table.insert(r2, "mcl_mobitems:gunpowder")
|
||||
core.register_craft({
|
||||
type = "shapeless",
|
||||
output = "vl_fireworks:rocket 3",
|
||||
recipe = r1,
|
||||
})
|
||||
core.register_craft({
|
||||
type = "shapeless",
|
||||
output = "vl_fireworks:rocket 3",
|
||||
recipe = r2,
|
||||
})
|
||||
end
|
||||
end
|
||||
register_firework_crafts()
|
||||
|
||||
local function craft_firework(itemstack, player, old_grid)
|
||||
if itemstack:get_name() ~= "vl_fireworks:rocket" then return end
|
||||
local gp = 0 -- gunpowder
|
||||
local stars = {}
|
||||
|
||||
-- analyze the recipe used
|
||||
for _, item in pairs(old_grid) do
|
||||
if item:get_name() == "mcl_mobitems:gunpowder" then gp = gp + 1 end
|
||||
if item:get_name() == "vl_fireworks:firework_star" then
|
||||
local effect = item:get_meta():get("vl_fireworks:star_effect")
|
||||
or core.serialize({fn="generic"})
|
||||
table.insert(stars, effect)
|
||||
end
|
||||
end
|
||||
|
||||
-- determine duration and force from the amount of gunpowder used
|
||||
local tbl = vl_fireworks.firework_def._vl_fireworks_std_durs_forces[gp]
|
||||
local meta = itemstack:get_meta()
|
||||
meta:set_float("vl_fireworks:duration", tbl[1])
|
||||
meta:set_int("vl_fireworks:force", tbl[2])
|
||||
|
||||
-- write star effects into metadata
|
||||
meta:set_string("vl_fireworks:stars", core.serialize(stars))
|
||||
|
||||
tt.reload_itemstack_description(itemstack)
|
||||
return itemstack
|
||||
end
|
||||
core.register_craft_predict(craft_firework)
|
||||
core.register_on_craft(craft_firework)
|
196
mods/ITEMS/vl_fireworks/init.lua
Normal file
196
mods/ITEMS/vl_fireworks/init.lua
Normal file
@ -0,0 +1,196 @@
|
||||
local path = minetest.get_modpath("vl_fireworks")
|
||||
|
||||
vl_fireworks = {}
|
||||
|
||||
local colors = {"red", "yellow", "blue", "green", "white"}
|
||||
|
||||
|
||||
function vl_fireworks.generic_particle_explosion(pos, size)
|
||||
if pos.object then pos = pos.object:get_pos() end
|
||||
local particle_pattern = math.random(1, 3)
|
||||
local fpitch
|
||||
local type = math.random(1, 2)
|
||||
local size = size or math.random(1, 3)
|
||||
local this_colors = {colors[math.random(#colors)], colors[math.random(#colors)], colors[math.random(#colors)]}
|
||||
|
||||
if size == 1 then
|
||||
fpitch = math.random(200, 300)
|
||||
elseif size == 2 then
|
||||
fpitch = math.random(100, 130)
|
||||
else
|
||||
fpitch = math.random(60, 70)
|
||||
end
|
||||
|
||||
if type == 1 then
|
||||
core.sound_play("mcl_bows_firework", {
|
||||
pos = pos,
|
||||
max_hear_distance = 100,
|
||||
gain = 3.0,
|
||||
pitch = fpitch/100
|
||||
}, true)
|
||||
else
|
||||
core.sound_play("mcl_bows_firework_soft", {
|
||||
pos = pos,
|
||||
max_hear_distance = 100,
|
||||
gain = 4.0,
|
||||
pitch = fpitch/100
|
||||
}, true)
|
||||
end
|
||||
|
||||
if particle_pattern == 1 then
|
||||
core.add_particlespawner({
|
||||
amount = 400 * size,
|
||||
time = 0.0001,
|
||||
minpos = pos,
|
||||
maxpos = pos,
|
||||
minvel = vector.new(-7 * size,-7 * size,-7 * size),
|
||||
maxvel = vector.new(7 * size,7 * size,7 * size),
|
||||
minexptime = .6 * size / 2,
|
||||
maxexptime = .9 * size / 2,
|
||||
minsize = 2 * size,
|
||||
maxsize = 3 * size,
|
||||
collisiondetection = false,
|
||||
vertical = false,
|
||||
texture = "mcl_bows_firework_"..this_colors[1]..".png",
|
||||
glow = 14,
|
||||
})
|
||||
core.add_particlespawner({
|
||||
amount = 400 * size,
|
||||
time = 0.0001,
|
||||
minpos = pos,
|
||||
maxpos = pos,
|
||||
minvel = vector.new(-2 * size,-2 * size,-2 * size),
|
||||
maxvel = vector.new(2 * size,2 * size,2 * size),
|
||||
minexptime = .6 * size / 2,
|
||||
maxexptime = .9 * size / 2,
|
||||
minsize = 2 * size,
|
||||
maxsize = 3 * size,
|
||||
collisiondetection = false,
|
||||
vertical = false,
|
||||
texture = "mcl_bows_firework_"..this_colors[2]..".png",
|
||||
glow = 14,
|
||||
})
|
||||
core.add_particlespawner({
|
||||
amount = 100 * size,
|
||||
time = 0.0001,
|
||||
minpos = pos,
|
||||
maxpos = pos,
|
||||
minvel = vector.new(-14 * size,-14 * size,-14 * size),
|
||||
maxvel = vector.new(14 * size,14 * size,14 * size),
|
||||
minexptime = .6 * size / 2,
|
||||
maxexptime = .9 * size / 2,
|
||||
minsize = 2 * size,
|
||||
maxsize = 3 * size,
|
||||
collisiondetection = false,
|
||||
vertical = false,
|
||||
texture = "mcl_bows_firework_"..this_colors[3]..".png",
|
||||
glow = 14,
|
||||
})
|
||||
elseif particle_pattern == 2 then
|
||||
|
||||
core.add_particlespawner({
|
||||
amount = 240 * size,
|
||||
time = 0.0001,
|
||||
minpos = pos,
|
||||
maxpos = pos,
|
||||
minvel = vector.new(-5 * size,-5 * size,-5 * size),
|
||||
maxvel = vector.new(5 * size,5 * size,5 * size),
|
||||
minexptime = .6 * size / 2,
|
||||
maxexptime = .9 * size / 2,
|
||||
minsize = 2 * size,
|
||||
maxsize = 3 * size,
|
||||
collisiondetection = false,
|
||||
vertical = false,
|
||||
texture = "mcl_bows_firework_"..this_colors[1]..".png",
|
||||
glow = 14,
|
||||
})
|
||||
core.add_particlespawner({
|
||||
amount = 500 * size,
|
||||
time = 0.0001,
|
||||
minpos = pos,
|
||||
maxpos = pos,
|
||||
minvel = vector.new(-2 * size,-2 * size,-2 * size),
|
||||
maxvel = vector.new(2 * size,2 * size,2 * size),
|
||||
minexptime = .6 * size / 2,
|
||||
maxexptime = .9 * size / 2,
|
||||
minsize = 2 * size,
|
||||
maxsize = 3 * size,
|
||||
collisiondetection = false,
|
||||
vertical = false,
|
||||
texture = "mcl_bows_firework_"..this_colors[2]..".png",
|
||||
glow = 14,
|
||||
})
|
||||
core.add_particlespawner({
|
||||
amount = 350 * size,
|
||||
time = 0.0001,
|
||||
minpos = pos,
|
||||
maxpos = pos,
|
||||
minvel = vector.new(-3 * size,-3 * size,-3 * size),
|
||||
maxvel = vector.new(3 * size,3 * size,3 * size),
|
||||
minexptime = .6 * size / 2,
|
||||
maxexptime = .9 * size / 2,
|
||||
minsize = 2 * size,
|
||||
maxsize = 3 * size,
|
||||
collisiondetection = false,
|
||||
vertical = false,
|
||||
texture = "mcl_bows_firework_"..this_colors[3]..".png",
|
||||
glow = 14,
|
||||
})
|
||||
elseif particle_pattern == 3 then
|
||||
|
||||
core.add_particlespawner({
|
||||
amount = 400 * size,
|
||||
time = 0.0001,
|
||||
minpos = pos,
|
||||
maxpos = pos,
|
||||
minvel = vector.new(-6 * size,-4 * size,-6 * size),
|
||||
maxvel = vector.new(6 * size,4 * size,6 * size),
|
||||
minexptime = .6 * size,
|
||||
maxexptime = .9 * size,
|
||||
minsize = 2 * size,
|
||||
maxsize = 3 * size,
|
||||
collisiondetection = false,
|
||||
vertical = false,
|
||||
texture = "mcl_bows_firework_"..this_colors[1]..".png",
|
||||
glow = 14,
|
||||
})
|
||||
core.add_particlespawner({
|
||||
amount = 120 * size,
|
||||
time = 0.0001,
|
||||
minpos = pos,
|
||||
maxpos = pos,
|
||||
minvel = vector.new(-8 * size,6 * size,-8 * size),
|
||||
maxvel = vector.new(8 * size,6 * size,8 * size),
|
||||
minexptime = .6 * size,
|
||||
maxexptime = .9 * size,
|
||||
minsize = 2 * size,
|
||||
maxsize = 3 * size,
|
||||
collisiondetection = false,
|
||||
vertical = false,
|
||||
texture = "mcl_bows_firework_"..this_colors[2]..".png",
|
||||
glow = 14,
|
||||
})
|
||||
core.add_particlespawner({
|
||||
amount = 130 * size,
|
||||
time = 0.0001,
|
||||
minpos = pos,
|
||||
maxpos = pos,
|
||||
minvel = vector.new(-3 * size,3 * size,-3 * size),
|
||||
maxvel = vector.new(3 * size,3 * size,3 * size),
|
||||
minexptime = .6 * size,
|
||||
maxexptime = .9 * size,
|
||||
minsize = 2 * size,
|
||||
maxsize = 3 * size,
|
||||
collisiondetection = false,
|
||||
vertical = false,
|
||||
texture = "mcl_bows_firework_"..this_colors[3]..".png",
|
||||
glow = 14,
|
||||
})
|
||||
end
|
||||
|
||||
return size
|
||||
end
|
||||
|
||||
dofile(path .. "/star.lua")
|
||||
dofile(path .. "/rockets.lua")
|
||||
dofile(path .. "/crafting.lua")
|
@ -1,2 +1,3 @@
|
||||
name = mcl_fireworks
|
||||
description = Adds fun fireworks to the game which players can use.
|
||||
name = vl_fireworks
|
||||
description = Adds fun fireworks to the game which players can use.
|
||||
depends = vl_projectile
|
30
mods/ITEMS/vl_fireworks/models/vl_fireworks_rocket.obj
Normal file
30
mods/ITEMS/vl_fireworks/models/vl_fireworks_rocket.obj
Normal file
@ -0,0 +1,30 @@
|
||||
# Blender 3.6.7
|
||||
# www.blender.org
|
||||
o Plane
|
||||
v -0.500000 1.000000 0.500000
|
||||
v 0.500000 1.000000 0.500000
|
||||
v -0.500000 1.000000 -0.500000
|
||||
v 0.500000 1.000000 -0.500000
|
||||
v -0.300517 0.000000 0.300517
|
||||
v 0.300517 0.000000 -0.300517
|
||||
v -0.300517 1.500000 0.300517
|
||||
v 0.300517 1.500000 -0.300517
|
||||
v 0.300517 0.000000 0.300517
|
||||
v -0.300517 0.000000 -0.300517
|
||||
v 0.300517 1.500000 0.300517
|
||||
v -0.300517 1.500000 -0.300517
|
||||
vn -0.0000 1.0000 -0.0000
|
||||
vn 0.7071 -0.0000 0.7071
|
||||
vn 0.7071 -0.0000 -0.7071
|
||||
vt 0.562500 0.562500
|
||||
vt 1.000000 0.562500
|
||||
vt 1.000000 1.000000
|
||||
vt 0.562500 1.000000
|
||||
vt -0.000000 0.125000
|
||||
vt 0.437500 0.125000
|
||||
vt 0.437500 0.937500
|
||||
vt -0.000000 0.937500
|
||||
s 0
|
||||
f 1/1/1 2/2/1 4/3/1 3/4/1
|
||||
f 5/5/2 6/6/2 8/7/2 7/8/2
|
||||
f 9/5/3 10/6/3 12/7/3 11/8/3
|
201
mods/ITEMS/vl_fireworks/rockets.lua
Normal file
201
mods/ITEMS/vl_fireworks/rockets.lua
Normal file
@ -0,0 +1,201 @@
|
||||
local S = core.get_translator(core.get_current_modname())
|
||||
|
||||
local tt_help = S("Flight Duration:")
|
||||
local description = S("Firework Rocket")
|
||||
|
||||
local TAU = 2*math.pi
|
||||
|
||||
local function explode(self, pos, stars)
|
||||
mcl_mobs.mob_class.safe_boom(self, pos, 1)
|
||||
if not stars then return end
|
||||
for _, effect in pairs(stars) do
|
||||
if type(effect) == "string" then effect = core.deserialize(effect) end
|
||||
if effect.fn == "generic" then
|
||||
vl_fireworks.generic_particle_explosion(pos, effect.size or 1)
|
||||
end
|
||||
-- TODO implement other handlers
|
||||
end
|
||||
end
|
||||
|
||||
local firework_entity = {
|
||||
physical = true,
|
||||
pointable = false,
|
||||
visual = "mesh",
|
||||
visual_size = {x=3, y=3},
|
||||
mesh = "vl_fireworks_rocket.obj",
|
||||
textures = {"vl_fireworks_entity.png"},
|
||||
backface_culling = false,
|
||||
collisionbox = {-0.1, 0, -0.1, 0.1, 0.5, 0.1},
|
||||
collide_with_objects = false,
|
||||
liquid_drag = true,
|
||||
_fire_damage_resistant = true,
|
||||
|
||||
_save_fields = {
|
||||
"last_pos", "vl_projectile", "dir", "rot_axis", "force", "stars"
|
||||
},
|
||||
|
||||
_vector_save_fields = {
|
||||
last_pos = true, dir = true, rot_axis = true, force = true
|
||||
},
|
||||
|
||||
_damage=1, -- Damage on impact
|
||||
_blocked = false,
|
||||
_viscosity=0, -- Viscosity of node the arrow is currently in
|
||||
|
||||
_vl_projectile = {
|
||||
ignore_gravity = true,
|
||||
survive_collision = false,
|
||||
damages_players = true,
|
||||
maximum_time = 3,
|
||||
pitch_offset = -math.pi / 2,
|
||||
damage_groups = function(self)
|
||||
return { fleshy = vector.length(self.object:get_velocity()) }
|
||||
end,
|
||||
tracer_texture = "mobs_mc_arrow_particle.png",
|
||||
behaviors = {
|
||||
vl_projectile.burns,
|
||||
vl_projectile.has_tracer,
|
||||
|
||||
function(self, dtime)
|
||||
if self._vl_projectile.extra then
|
||||
local e = self._vl_projectile.extra
|
||||
self._force = e.force/10 + 5
|
||||
self._vl_projectile.maximum_time = e.dur
|
||||
self._rot_axis = e.rot_axis
|
||||
self._dir = self.object:get_velocity():normalize()
|
||||
self._stars = e.stars
|
||||
self._vl_projectile.extra = nil
|
||||
end
|
||||
if not self._dir then return end
|
||||
if self._last_pos and (self._last_pos - self.object:get_pos()):length() < (10*dtime) then
|
||||
self._rot_axis = -self._rot_axis
|
||||
end
|
||||
self._dir = self._dir:rotate_around_axis(self._rot_axis, dtime/3)
|
||||
local obj = self.object
|
||||
obj:set_velocity((obj:get_velocity():length() + self._force*dtime) * self._dir)
|
||||
end,
|
||||
|
||||
vl_projectile.collides_with_solids,
|
||||
vl_projectile.raycast_collides_with_entities,
|
||||
},
|
||||
allow_punching = function(self, entity_def, projectile_def, object)
|
||||
local lua = object:get_luaentity()
|
||||
if lua and lua.name == "mobs_mc:rover" then return false end
|
||||
-- TODO at some point make it so impact depends on collision speed? (see next line)
|
||||
--if (self.object:get_velocity() + object:get_velocity()).length() < 5 then return end
|
||||
|
||||
return true
|
||||
end,
|
||||
},
|
||||
|
||||
get_staticdata = function(self)
|
||||
local out = {}
|
||||
local save_fields = self._save_fields
|
||||
for i = 1,#save_fields do
|
||||
local field = save_fields[i]
|
||||
out[field] = self["_"..field]
|
||||
end
|
||||
out.timer = self.timer
|
||||
|
||||
-- Preserve entity properties
|
||||
out.properties = self.object:get_properties()
|
||||
|
||||
return core.serialize(out)
|
||||
end,
|
||||
on_activate = function(self, staticdata, dtime_s)
|
||||
self.object:set_armor_groups({ immortal = 1 })
|
||||
|
||||
self._time_in_air = 1.0
|
||||
local data = core.deserialize(staticdata)
|
||||
if not data then return end
|
||||
|
||||
-- Restore entity properties
|
||||
if data.properties then
|
||||
self.object:set_properties(data.properties)
|
||||
data.properties = nil
|
||||
end
|
||||
self.timer = data.timer
|
||||
|
||||
-- Restore rocket state
|
||||
local save_fields = self._save_fields
|
||||
local vecs = self._vector_save_fields
|
||||
for i = 1,#save_fields do
|
||||
local field = save_fields[i]
|
||||
local d = data[field]
|
||||
if type(d) == "table" and vecs[field] then
|
||||
d = vector.new(d.x, d.y, d.z)
|
||||
end
|
||||
self["_"..field] = d
|
||||
end
|
||||
|
||||
if not self._vl_projectile then
|
||||
self._vl_projetile = {}
|
||||
end
|
||||
end,
|
||||
|
||||
_on_remove = function(self)
|
||||
explode(self, self.object:get_pos(), self._stars)
|
||||
end,
|
||||
}
|
||||
|
||||
vl_projectile.register("vl_fireworks:rocket", firework_entity)
|
||||
|
||||
function vl_fireworks.shoot_firework(itemstack, pos, dir)
|
||||
local meta = itemstack:get_meta()
|
||||
local rot_axis = vector.new(1,0,0)
|
||||
rot_axis = rot_axis:rotate_around_axis(vector.new(0,1,0), math.random()*TAU)
|
||||
local stars = meta:get("vl_fireworks:stars") or core.serialize({})
|
||||
vl_projectile.create("vl_fireworks:rocket", {
|
||||
pos = pos,
|
||||
dir = dir or vector.new(0,1,0),
|
||||
velocity = 1 + meta:get_int("vl_fireworks:force")/10,
|
||||
extra = {
|
||||
dur = meta:get_float("vl_fireworks:duration"),
|
||||
force = meta:get_float("vl_fireworks:force"),
|
||||
rot_axis = rot_axis,
|
||||
stars = core.deserialize(stars)
|
||||
}
|
||||
})
|
||||
end
|
||||
|
||||
local firework_def = {
|
||||
description = description,
|
||||
inventory_image = "vl_fireworks_rocket.png",
|
||||
stack_max = 64,
|
||||
on_use = function(itemstack, user, pointed_thing)
|
||||
local elytra = mcl_playerplus.elytra[user]
|
||||
if elytra.active and elytra.rocketing <= 0 then
|
||||
elytra.rocketing = meta:get_float("vl_fireworks:duration")
|
||||
if not core.is_creative_enabled(user:get_player_name()) then
|
||||
itemstack:take_item()
|
||||
end
|
||||
core.sound_play("vl_fireworks_rocket", {pos = user:get_pos()})
|
||||
end
|
||||
return itemstack
|
||||
end,
|
||||
on_place = function(itemstack, user, pointed_thing)
|
||||
local pos = pointed_thing.above
|
||||
vl_fireworks.shoot_firework(itemstack, pos)
|
||||
if mcl_gamemode.get_gamemode(user) ~= "creative" then
|
||||
itemstack:take_item()
|
||||
return itemstack
|
||||
end
|
||||
end,
|
||||
_on_dispense = function(dropitem, pos, droppos, dropnode, dropdir)
|
||||
vl_fireworks.shoot_firework(dropitem, pos, dropdir)
|
||||
end,
|
||||
_vl_fireworks_std_durs_forces = { {2.2, 10}, {4.5, 20}, {6, 30} },
|
||||
_vl_fireworks_tt = function(duration, stars)
|
||||
local retval = tt_help .. " " .. duration
|
||||
|
||||
for _, effect in pairs(stars) do
|
||||
if type(effect) == "string" then effect = core.deserialize(effect) end
|
||||
retval = retval .. "\n\n" .. vl_fireworks.star_tt(effect)
|
||||
end
|
||||
|
||||
return retval
|
||||
end,
|
||||
}
|
||||
vl_fireworks.firework_def = table.copy(firework_def)
|
||||
|
||||
core.register_craftitem("vl_fireworks:rocket", firework_def)
|
23
mods/ITEMS/vl_fireworks/star.lua
Normal file
23
mods/ITEMS/vl_fireworks/star.lua
Normal file
@ -0,0 +1,23 @@
|
||||
local S = minetest.get_translator(minetest.get_current_modname())
|
||||
|
||||
minetest.register_craftitem("vl_fireworks:firework_star", {
|
||||
description = S("Firework Star"),
|
||||
_doc_items_longdesc = S("A firework star is the key component of a firework rocket which is responsible for the visible explosion."),
|
||||
wield_image = "vl_fireworks_star.png",
|
||||
inventory_image = "vl_fireworks_star.png",
|
||||
groups = { craftitem = 1, firework_star = 1 },
|
||||
stack_max = 64,
|
||||
})
|
||||
|
||||
function vl_fireworks.star_tt(effect)
|
||||
local s = ""
|
||||
if effect.fn == "generic" then
|
||||
s = S("Generic Firework Star")
|
||||
end
|
||||
if effect.size then
|
||||
s = s .. "\n" .. S("Size:") .. " " .. effect.size
|
||||
end
|
||||
return s:trim()
|
||||
end
|
||||
|
||||
-- TODO image handlers
|
BIN
textures/vl_fireworks_entity.png
Normal file
BIN
textures/vl_fireworks_entity.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 199 B |
Before Width: | Height: | Size: 195 B After Width: | Height: | Size: 195 B |
BIN
textures/vl_fireworks_star.png
Normal file
BIN
textures/vl_fireworks_star.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 241 B |
Loading…
Reference in New Issue
Block a user