Make barricade burn on laser contact

This commit is contained in:
Wuzzy 2022-02-15 05:42:50 +01:00
parent df63bd7937
commit 8bfa7e7e21
16 changed files with 179 additions and 33 deletions

View File

@ -10,8 +10,9 @@ External mods used:
--- ---
Textures: Textures:
- Water, wood, tree, stone, tools, hand, gold block, ship lightbox, player textures, crates, seaweed, purple coral, crab grass come from “PixelBOX” texture pack by jp (CC0) - Water, wood, tree, stone, tools, hand, gold block, ship lightbox, player textures, crates, seaweed, purple coral, crab grass, fire come from “PixelBOX” texture pack by jp (CC0)
- Textures in `lzr_decor` mod made by jp (CC0) - Textures in `lzr_decor` mod made by jp (CC0)
- Barricade made by jp (CC0)
- Crosshair, wieldhand, `smoke_puff.png`: trivial textures by Wuzzy (CC0) - Crosshair, wieldhand, `smoke_puff.png`: trivial textures by Wuzzy (CC0)
- Emitter, detector textures: Derivate works of xdecor textures by jp (CC0) - Emitter, detector textures: Derivate works of xdecor textures by jp (CC0)
- Mirror textures: by Wuzzy (CC0) - Mirror textures: by Wuzzy (CC0)
@ -84,6 +85,13 @@ Sounds:
- by Fourier <https://opengameart.org/content/forward-button-press-ui-sound> - by Fourier <https://opengameart.org/content/forward-button-press-ui-sound>
- Edit by Wuzzy (shortened) - Edit by Wuzzy (shortened)
- License: CC BY 3.0 - License: CC BY 3.0
- `lzr_laser_quickburn.*.ogg`:
- Original by florianreichelt <https://freesound.org/people/florianreichelt/sounds/563012/>
- Shortened for gameplay reasons
- License: CC0
- `lzr_laser_barricade_break.ogg`:
- By kevinkace <https://freesound.org/people/kevinkace/sounds/66780/>
- License: CC0
- `lzr_sounds_footstep_stone.*.ogg`, `default_dirt_footstep.*.ogg`, `lzr_sounds_footstep_leaves.*.ogg`, `lzr_sounds_dug_grass.*.ogg`: - `lzr_sounds_footstep_stone.*.ogg`, `default_dirt_footstep.*.ogg`, `lzr_sounds_footstep_leaves.*.ogg`, `lzr_sounds_dug_grass.*.ogg`:
- by Wuzzy - by Wuzzy
- License: MIT License - License: MIT License

View File

@ -45,15 +45,6 @@ register_pane("wood_frame", S("Wood Frame"), {
groups = {breakable = 1, rotatable = 3, pane = 1}, groups = {breakable = 1, rotatable = 3, pane = 1},
}) })
minetest.register_node("lzr_decor:barricade", {
description = S("Barricade"),
drawtype = "plantlike",
paramtype = "light",
inventory_image = "xdecor_baricade.png",
tiles = {"xdecor_baricade.png"},
groups = {breakable = 1},
})
minetest.register_node("lzr_decor:bonfire", { minetest.register_node("lzr_decor:bonfire", {
description = S("Bonfire"), description = S("Bonfire"),
walkable = false, walkable = false,

View File

@ -32,6 +32,8 @@ local mirror_out = {
[23] = {0,0,1}, [23] = {0,0,1},
} }
local movement_gravity = tonumber(minetest.settings:get("movement_gravity")) or 9.81
lzr_laser.get_detector_dir = function(param2) lzr_laser.get_detector_dir = function(param2)
local dir_input = minetest.facedir_to_dir(param2) local dir_input = minetest.facedir_to_dir(param2)
if not dir_input then if not dir_input then
@ -132,6 +134,29 @@ local after_rotate = function()
full_update() full_update()
end end
local element_can_dig = function()
return lzr_gamestate.get_state() ~= lzr_gamestate.LEVEL_COMPLETE
end
local element_on_place = function(itemstack, placer, pointed_thing)
if lzr_gamestate.get_state() == lzr_gamestate.LEVEL_COMPLETE then
-- Prevent node placement when in 'level complete' state
return itemstack
else
-- node's on_rightclick action takes precedence
if pointed_thing.type == "node" and placer then
local node = minetest.get_node(pointed_thing.under)
local def = minetest.registered_nodes[node.name]
local sneak = placer:get_player_control().sneak
if def and def.on_rightclick and not sneak then
def.on_rightclick(pointed_thing.under, node, placer, itemstack, pointed_thing)
return itemstack
end
end
-- Default node placement behavior
return minetest.item_place_node(itemstack, placer, pointed_thing)
end
end
local register_element = function(subname, def, options) local register_element = function(subname, def, options)
local def_core = table.copy(def) local def_core = table.copy(def)
if not options then options = {} end if not options then options = {} end
@ -153,28 +178,8 @@ local register_element = function(subname, def, options)
end end
def_core.groups.breakable = 1 def_core.groups.breakable = 1
def_core.groups[subname] = 1 def_core.groups[subname] = 1
def_core.can_dig = function() def_core.can_dig = element_can_dig
return lzr_gamestate.get_state() ~= lzr_gamestate.LEVEL_COMPLETE def_core.on_place = element_on_place
end
def_core.on_place = function(itemstack, placer, pointed_thing)
if lzr_gamestate.get_state() == lzr_gamestate.LEVEL_COMPLETE then
-- Prevent node placement when in 'level complete' state
return itemstack
else
-- node's on_rightclick action takes precedence
if pointed_thing.type == "node" and placer then
local node = minetest.get_node(pointed_thing.under)
local def = minetest.registered_nodes[node.name]
local sneak = placer:get_player_control().sneak
if def and def.on_rightclick and not sneak then
def.on_rightclick(pointed_thing.under, node, placer, itemstack, pointed_thing)
return itemstack
end
end
-- Default node placement behavior
return minetest.item_place_node(itemstack, placer, pointed_thing)
end
end
minetest.register_node("lzr_laser:"..subname, def_core) minetest.register_node("lzr_laser:"..subname, def_core)
@ -439,3 +444,78 @@ register_element("detector", {
sounds = lzr_sounds.node_sound_wood_defaults(), sounds = lzr_sounds.node_sound_wood_defaults(),
}, { allow_take = true, is_detector = true }) }, { allow_take = true, is_detector = true })
minetest.register_node("lzr_laser:barricade", {
description = S("Barricade"),
drawtype = "mesh",
mesh = "lzr_laser_burning.obj",
paramtype = "light",
inventory_image = "xdecor_baricade.png",
wield_image = "xdecor_baricade.png",
tiles = {"blank.png","xdecor_baricade.png"},
use_texture_alpha = "clip",
groups = { breakable = 1, laser_destroys = 2 },
sounds = lzr_sounds.node_sound_wood_defaults({
dug = {name="lzr_laser_barricade_break", gain=1.0},
}),
on_place = element_on_place,
can_dig = element_can_dig,
_lzr_active = "lzr_laser:barricade_on",
})
minetest.register_node("lzr_laser:barricade_on", {
description = S("Burning Barricade"),
drawtype = "mesh",
paramtype = "light",
light_source = 12,
mesh = "lzr_laser_burning.obj",
inventory_image = "lzr_laser_baricade_burning.png",
wield_image = "lzr_laser_baricade_burning.png",
use_texture_alpha = "clip",
tiles = {
{ name="fire_basic_flame_animated.png", animation={
type = "vertical_frames",
aspect_w = 16,
aspect_h = 16,
length = 1.0,
},},
{ name="lzr_laser_baricade_burning_animated.png", animation={
type = "vertical_frames",
aspect_w = 16,
aspect_h = 16,
length = 1.0,
},},
},
groups = { breakable = 1, not_in_creative_inventory = 1 },
sounds = lzr_sounds.node_sound_wood_defaults({
dug = {name="lzr_laser_barricade_break", gain=1.0},
}),
on_timer = function(pos)
-- spawn a few particles for the removed node
minetest.add_particlespawner({
amount = 16,
time = 0.001,
minpos = vector.subtract(pos, vector.new(0.5, 0.5, 0.5)),
maxpos = vector.add(pos, vector.new(0.5, 0.5, 0.5)),
minvel = vector.new(-0.5, -0.5, -0.5),
maxvel = vector.new(0.5, 0.2, 0.5),
minacc = vector.new(0, -movement_gravity, 0),
maxacc = vector.new(0, -movement_gravity, 0),
minsize = 0.1,
maxsize = 0.5,
node = {name="lzr_laser:barricade"},
})
-- Play randomly-pitched break sound
local pitch = 1.0+math.random(-100, 100)*0.001 -- 0.9..1.1
minetest.sound_play({name="lzr_laser_barricade_break", gain=1.0}, {gain=1.0, pitch=pitch, pos=pos}, true)
-- remove node
minetest.remove_node(pos)
full_update()
end,
drop = "",
on_place = element_on_place,
can_dig = element_can_dig,
_lzr_inactive = "lzr_laser:barricade",
})

Binary file not shown.

View File

@ -0,0 +1,44 @@
# Blender v3.1.0 Alpha OBJ File: 'lzr_plants_burning.blend'
# www.blender.org
mtllib lzr_plants_burning.mtl
v 0.495000 0.500000 0.495000
v 0.495000 -0.500000 0.495000
v -0.495000 0.500000 0.495000
v -0.495000 -0.500000 0.495000
v 0.495000 0.500000 -0.495000
v 0.495000 -0.500000 -0.495000
v -0.495000 0.500000 -0.495000
v -0.495000 -0.500000 -0.495000
vt 1.000000 0.000000
vt 1.000000 1.000000
vt 0.000000 1.000000
vt 0.000000 0.000000
vt 1.000000 0.000000
vt 1.000000 1.000000
vt 0.000000 1.000000
vt 0.000000 0.000000
vt 1.000000 0.000000
vt 1.000000 1.000000
vt 0.000000 1.000000
vt 0.000000 0.000000
vt 1.000000 0.000000
vt 1.000000 1.000000
vt 0.000000 1.000000
vt 0.000000 0.000000
vn -1.0000 0.0000 0.0000
vn 0.0000 0.0000 -1.0000
vn 0.0000 0.0000 1.0000
vn 1.0000 0.0000 0.0000
vn -0.7071 0.0000 -0.7071
vn -0.7071 0.0000 0.7071
g Fire_Cube_Fire
usemtl Fire
s off
f 4/1/1 3/2/1 7/3/1 8/4/1
f 8/5/2 7/6/2 5/7/2 6/8/2
f 2/9/3 1/10/3 3/11/3 4/12/3
f 6/13/4 5/14/4 1/15/4 2/16/4
g Fire_Cube_Object
usemtl Object
f 4/1/5 3/2/5 5/7/5 6/8/5
f 2/9/6 1/10/6 7/3/6 8/4/6

View File

@ -1,6 +1,9 @@
-- Max. number of steps in the laser travel algorithm -- Max. number of steps in the laser travel algorithm
local MAX_LASER_ITERATIONS = 10000 local MAX_LASER_ITERATIONS = 10000
-- TODO: Don't use this variable, instead transport it between functions
local burning_cache = {}
-- Add a laser node to pos with the direction `dir`. -- Add a laser node to pos with the direction `dir`.
-- Dir is a direction vector, and only one direction must be set -- Dir is a direction vector, and only one direction must be set
function lzr_laser.add_laser(pos, dir, varea, vdata) function lzr_laser.add_laser(pos, dir, varea, vdata)
@ -13,13 +16,24 @@ function lzr_laser.add_laser(pos, dir, varea, vdata)
local vi = varea:indexp(pos) local vi = varea:indexp(pos)
local content_id = vdata[vi] local content_id = vdata[vi]
local nodename = minetest.get_name_from_content_id(content_id) local nodename = minetest.get_name_from_content_id(content_id)
local ld = minetest.get_item_group(nodename, "laser_destroys")
-- Laser through air or destroyable block -- Laser through air or destroyable block
if content_id == minetest.CONTENT_AIR or minetest.get_item_group(nodename, "laser_destroys") > 0 then if content_id == minetest.CONTENT_AIR or ld == 1 then
local dirs = lzr_laser.vector_to_dirs(dir) local dirs = lzr_laser.vector_to_dirs(dir)
local dirstring = lzr_laser.dirs_to_dirstring(dirs) local dirstring = lzr_laser.dirs_to_dirstring(dirs)
vdata[vi] = minetest.get_content_id("lzr_laser:laser_"..dirstring) vdata[vi] = minetest.get_content_id("lzr_laser:laser_"..dirstring)
pos = vector.add(pos, dir) pos = vector.add(pos, dir)
return {{pos, dir}} return {{pos, dir}}
elseif ld == 2 then
local def = minetest.registered_nodes[nodename]
local active = def._lzr_active
if active then
vdata[vi] = minetest.get_content_id(active)
table.insert(burning_cache, pos)
else
minetest.log("error", "[lzr_laser] Node definition of "..nodename.." has laser_destroys=2 but no _lzr_active")
end
return false
-- Laser through laser (laser intersection) -- Laser through laser (laser intersection)
elseif minetest.get_item_group(nodename, "laser") > 0 then elseif minetest.get_item_group(nodename, "laser") > 0 then
local dirnum = minetest.get_item_group(nodename, "laser") local dirnum = minetest.get_item_group(nodename, "laser")
@ -244,6 +258,8 @@ end
function lzr_laser.full_laser_update(pos1, pos2) function lzr_laser.full_laser_update(pos1, pos2)
local benchmark_time_1 = minetest.get_us_time() local benchmark_time_1 = minetest.get_us_time()
burning_cache = {}
local vmanip = minetest.get_voxel_manip(pos1, pos2) local vmanip = minetest.get_voxel_manip(pos1, pos2)
local vpos1, vpos2 = vmanip:get_emerged_area() local vpos1, vpos2 = vmanip:get_emerged_area()
local varea = VoxelArea:new({MinEdge = vpos1, MaxEdge = vpos2}) local varea = VoxelArea:new({MinEdge = vpos1, MaxEdge = vpos2})
@ -257,6 +273,13 @@ function lzr_laser.full_laser_update(pos1, pos2)
vmanip:set_param2_data(vdata_p2) vmanip:set_param2_data(vdata_p2)
vmanip:write_to_map() vmanip:write_to_map()
for b=1, #burning_cache do
local timer = minetest.get_node_timer(burning_cache[b])
minetest.sound_play({name="lzr_laser_quickburn", gain=1.0}, {pos=burning_cache[b]}, true)
timer:start(1)
end
burning_cache = {}
-- Print benchmark time -- Print benchmark time
local benchmark_time_2 = minetest.get_us_time() local benchmark_time_2 = minetest.get_us_time()
local diff = benchmark_time_2 - benchmark_time_1 local diff = benchmark_time_2 - benchmark_time_1

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 256 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 913 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 304 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

Before

Width:  |  Height:  |  Size: 258 B

After

Width:  |  Height:  |  Size: 258 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 258 B