Make barricade burn on laser contact
10
CREDITS.md
|
@ -10,8 +10,9 @@ External mods used:
|
|||
---
|
||||
|
||||
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)
|
||||
- Barricade made by jp (CC0)
|
||||
- Crosshair, wieldhand, `smoke_puff.png`: trivial textures by Wuzzy (CC0)
|
||||
- Emitter, detector textures: Derivate works of xdecor textures by jp (CC0)
|
||||
- Mirror textures: by Wuzzy (CC0)
|
||||
|
@ -84,6 +85,13 @@ Sounds:
|
|||
- by Fourier <https://opengameart.org/content/forward-button-press-ui-sound>
|
||||
- Edit by Wuzzy (shortened)
|
||||
- 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`:
|
||||
- by Wuzzy
|
||||
- License: MIT License
|
||||
|
|
|
@ -45,15 +45,6 @@ register_pane("wood_frame", S("Wood Frame"), {
|
|||
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", {
|
||||
description = S("Bonfire"),
|
||||
walkable = false,
|
||||
|
|
|
@ -32,6 +32,8 @@ local mirror_out = {
|
|||
[23] = {0,0,1},
|
||||
}
|
||||
|
||||
local movement_gravity = tonumber(minetest.settings:get("movement_gravity")) or 9.81
|
||||
|
||||
lzr_laser.get_detector_dir = function(param2)
|
||||
local dir_input = minetest.facedir_to_dir(param2)
|
||||
if not dir_input then
|
||||
|
@ -132,6 +134,29 @@ local after_rotate = function()
|
|||
full_update()
|
||||
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 def_core = table.copy(def)
|
||||
if not options then options = {} end
|
||||
|
@ -153,28 +178,8 @@ local register_element = function(subname, def, options)
|
|||
end
|
||||
def_core.groups.breakable = 1
|
||||
def_core.groups[subname] = 1
|
||||
def_core.can_dig = function()
|
||||
return lzr_gamestate.get_state() ~= lzr_gamestate.LEVEL_COMPLETE
|
||||
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
|
||||
def_core.can_dig = element_can_dig
|
||||
def_core.on_place = element_on_place
|
||||
|
||||
minetest.register_node("lzr_laser:"..subname, def_core)
|
||||
|
||||
|
@ -439,3 +444,78 @@ register_element("detector", {
|
|||
sounds = lzr_sounds.node_sound_wood_defaults(),
|
||||
}, { 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",
|
||||
})
|
||||
|
||||
|
||||
|
|
|
@ -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
|
|
@ -1,6 +1,9 @@
|
|||
-- Max. number of steps in the laser travel algorithm
|
||||
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`.
|
||||
-- Dir is a direction vector, and only one direction must be set
|
||||
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 content_id = vdata[vi]
|
||||
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
|
||||
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 dirstring = lzr_laser.dirs_to_dirstring(dirs)
|
||||
vdata[vi] = minetest.get_content_id("lzr_laser:laser_"..dirstring)
|
||||
pos = vector.add(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)
|
||||
elseif minetest.get_item_group(nodename, "laser") > 0 then
|
||||
local dirnum = minetest.get_item_group(nodename, "laser")
|
||||
|
@ -244,6 +258,8 @@ end
|
|||
function lzr_laser.full_laser_update(pos1, pos2)
|
||||
local benchmark_time_1 = minetest.get_us_time()
|
||||
|
||||
burning_cache = {}
|
||||
|
||||
local vmanip = minetest.get_voxel_manip(pos1, pos2)
|
||||
local vpos1, vpos2 = vmanip:get_emerged_area()
|
||||
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: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
|
||||
local benchmark_time_2 = minetest.get_us_time()
|
||||
local diff = benchmark_time_2 - benchmark_time_1
|
||||
|
|
After Width: | Height: | Size: 256 B |
After Width: | Height: | Size: 913 B |
After Width: | Height: | Size: 304 B |
After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 258 B After Width: | Height: | Size: 258 B |
After Width: | Height: | Size: 258 B |