hades_revisited/mods/hades_doors/api.lua

1304 lines
41 KiB
Lua
Raw Normal View History

2022-04-25 17:53:49 -07:00
local S = minetest.get_translator("hades_doors")
2022-04-25 17:53:49 -07:00
hades_doors = { }
2021-10-08 08:05:24 -07:00
local config = {}
config.autoclose_timeout = 2.5
2021-10-09 12:46:22 -07:00
-- Set this true to enable HIDDEN NODE DEBUG.
-- This makes the hidden nodes visible and diggable.
local HIDDEN_DEBUG = false
2022-04-25 17:53:49 -07:00
hades_doors.LOCKING_MODE_UNDEFINED = 0
hades_doors.LOCKING_MODE_UNLOCKED = 1
hades_doors.LOCKING_MODE_LOCKED = 2
hades_doors.LOCKING_MODE_SHARED = 3
hades_doors.CLOSING_MODE_UNDEFINED = 0
hades_doors.CLOSING_MODE_MANUAL = 1
hades_doors.CLOSING_MODE_AUTOCLOSE = 2
hades_doors.CLOSING_MODE_HOLDOPEN = 3
hades_doors.ADJUST_LOCKING = 1
hades_doors.ADJUST_CLOSING = 2
hades_doors.CHECK_LOCKING = 3
hades_doors.CHECK_CLOSING = 4
2021-10-09 11:56:08 -07:00
local hidden_tiles = { "blank.png" }
2021-10-09 12:22:03 -07:00
local hidden_drawtype = "airlike"
2021-10-09 12:46:22 -07:00
local hidden_pointable = false
local hidden_diggable = false
local hidden_can_dig = function() return false end
2021-10-09 12:46:22 -07:00
local hidden_groups = { not_in_creative_inventory = 1 }
2021-10-09 11:56:08 -07:00
if HIDDEN_DEBUG then
hidden_tiles = { "default_stone.png" }
2021-10-09 12:22:03 -07:00
hidden_drawtype = "nodebox"
2021-10-09 12:46:22 -07:00
hidden_pointable = true
hidden_diggable = true
hidden_can_dig = nil
2021-10-09 12:46:22 -07:00
hidden_groups.dig_immediate = 3
2021-10-09 11:56:08 -07:00
end
2021-10-09 02:37:39 -07:00
local offset_y = function ( pos, y )
return { x = pos.x, y = pos.y + ( y or 1 ), z = pos.z }
end
2021-10-09 12:08:56 -07:00
--[[ Hidden door segments are used to occupy the other nodes of doors to
make sure no nodes overlap with the door.
2021-10-09 12:22:03 -07:00
All hidden door segments are defined in such a way that they effectively
"block" other nodes from occupying the same space.
2021-10-09 12:08:56 -07:00
The "standard" offset door (open and closed) uses 1 hidden door segment
2022-04-25 17:53:49 -07:00
* hades_doors:hidden for the upper segment.
2021-10-09 12:08:56 -07:00
The closed center door uses 1 hidden door segment:
2022-04-25 17:53:49 -07:00
* hades_doors:hidden_center (1×) for the upper door segment
2021-10-09 12:08:56 -07:00
The open center door uses 3 hidden door segments:
2022-04-25 17:53:49 -07:00
* hades_doors:hidden_center (1×) for the upper door segment
* hades_doors:hidden (2×) for the lower and upper and lower
door segments of the door's neighbors
The "neighbors" of the center door are the 2 nodes into which the
center door opens. ]]
2021-10-09 12:08:56 -07:00
2022-04-25 17:53:49 -07:00
minetest.register_node( "hades_doors:hidden", {
2021-10-09 12:22:03 -07:00
-- This node is walkable to stop falling nodes.
-- The nodebox is chosen in such a way
-- that it is inside the overlapping nodebox
-- of the main door node, but it still needs
-- to be rotated.
2021-10-09 12:08:56 -07:00
description = S("Shared Hidden Door Segment"),
2022-04-25 17:53:49 -07:00
inventory_image = "hades_doors_hidden_inv.png",
wield_image = "hades_doors_hidden_inv.png",
2021-10-09 12:22:03 -07:00
drawtype = hidden_drawtype,
tiles = hidden_tiles,
use_texture_alpha = "clip",
paramtype = "light",
paramtype2 = "facedir",
sunlight_propagates = true,
walkable = true,
2021-10-09 12:46:22 -07:00
pointable = hidden_pointable,
diggable = hidden_diggable,
can_dig = hidden_can_dig,
buildable_to = false,
floodable = false,
drop = "",
2021-10-09 12:46:22 -07:00
groups = hidden_groups,
on_blast = function( ) end,
node_box = {
type = "fixed",
fixed = { -15/32, 13/32, -15/32, -13/32, 1/2, -13/32 },
},
} )
2022-04-25 17:53:49 -07:00
minetest.register_node( "hades_doors:hidden_center", {
-- Basically the same as hades_doors:hidden, but
2021-10-09 12:22:03 -07:00
-- for center doors instead.
description = S("Hidden Center Door Segment"),
2022-04-25 17:53:49 -07:00
inventory_image = "hades_doors_hidden_center_inv.png",
wield_image = "hades_doors_hidden_center_inv.png",
2021-10-09 12:22:03 -07:00
drawtype = hidden_drawtype,
2021-10-09 11:56:08 -07:00
tiles = hidden_tiles,
use_texture_alpha = "clip",
2021-10-09 12:22:03 -07:00
drawtype = "airlike",
paramtype = "light",
paramtype2 = "facedir",
sunlight_propagates = true,
walkable = true,
2021-10-09 12:46:22 -07:00
pointable = hidden_pointable,
diggable = hidden_diggable,
can_dig = hidden_can_dig,
buildable_to = false,
floodable = false,
drop = "",
2021-10-09 12:46:22 -07:00
groups = hidden_groups,
on_blast = function( ) end,
can_dig = function( ) end,
node_box = {
type = "fixed",
fixed = { -15/32, 13/32, -1/32, -13/32, 1/2, 1/32 },
},
} )
-- table used to aid door opening/closing
-- tier 1 = hand, tier 2 = face, and tier 3 = is_open
local offset_transform = {
left = {
{ [false] = { suffix = "_a", param2 = 3 }, [true] = { suffix = "_b", param2 = 1 } },
{ [false] = { suffix = "_a", param2 = 0 }, [true] = { suffix = "_b", param2 = 2 } },
{ [false] = { suffix = "_a", param2 = 1 }, [true] = { suffix = "_b", param2 = 3 } },
{ [false] = { suffix = "_a", param2 = 2 }, [true] = { suffix = "_b", param2 = 0 } },
},
right = {
{ [false] = { suffix = "_b", param2 = 1 }, [true] = { suffix = "_a", param2 = 3 } },
{ [false] = { suffix = "_b", param2 = 2 }, [true] = { suffix = "_a", param2 = 0 } },
{ [false] = { suffix = "_b", param2 = 3 }, [true] = { suffix = "_a", param2 = 1 } },
{ [false] = { suffix = "_b", param2 = 0 }, [true] = { suffix = "_a", param2 = 2 } },
},
}
local center_transform = {
left = {
{ [false] = { suffix = "_c", param2 = 2 }, [true] = { suffix = "_d", param2 = 2 } },
{ [false] = { suffix = "_c", param2 = 3 }, [true] = { suffix = "_d", param2 = 3 } },
{ [false] = { suffix = "_c", param2 = 0 }, [true] = { suffix = "_d", param2 = 0 } },
{ [false] = { suffix = "_c", param2 = 1 }, [true] = { suffix = "_d", param2 = 1 } },
},
right = {
{ [false] = { suffix = "_c", param2 = 0 }, [true] = { suffix = "_e", param2 = 0 } },
{ [false] = { suffix = "_c", param2 = 1 }, [true] = { suffix = "_e", param2 = 1 } },
{ [false] = { suffix = "_c", param2 = 2 }, [true] = { suffix = "_e", param2 = 2 } },
{ [false] = { suffix = "_c", param2 = 3 }, [true] = { suffix = "_e", param2 = 3 } },
},
}
local center_neighbor = {
left = {
[0] = { x = 0, y = 0, z = 1 },
[1] = { x = 1, y = 0, z = 0 },
[2] = { x = 0, y = 0, z = -1 },
[3] = { x = -1, y = 0, z = 0 },
},
right = {
[0] = { x = 0, y = 0, z = -1 },
[1] = { x = -1, y = 0, z = 0 },
[2] = { x = 0, y = 0, z = 1 },
[3] = { x = 1, y = 0, z = 0 },
},
}
---------------------------------
-- get_door_properties( )
---------------------------------
local function get_door_properties( state, param2 )
local is_open = state % 2 == 1
local type = state < 4 and "offset" or "center"
local hand = math.floor( state / 2 ) % 2 == 0 and "left" or "right"
local face = param2 + 1
return is_open, type, hand, face
end
---------------------------------
-- get_door_transform( )
---------------------------------
local function get_door_transform( state, param2, toggle_open, switch_type, switch_hand, rotate_face )
local is_open, type, hand, face = get_door_properties( state, param2 )
-- NB: lots of nightmarish state calculations in order to maintain
-- backwards compatibility, so venture forward at your own risk :)
if toggle_open then
state = is_open and state - 1 or state + 1 -- add 1 for open, subtract 1 for close
is_open = not is_open
end
if switch_type then
state = type == "offset" and state + 4 or state - 4 -- add 4 for center, substract 4 for offset
type = type == "offset" and "center" or "offset"
-- need to rotate for seamless switch (also avoid face index overflow)
local face_translation = {
center = { [false] = 1, [true] = 2 },
offset = { [false] = 0, [true] = 1 },
}
face = ( face + face_translation[ type ][ is_open ] ) % 4 + 1
end
if switch_hand then
state = hand == "left" and state + 2 or state - 2 -- add 2 for left, subtract 2 for right
hand = hand == "left" and "right" or "left"
-- need to rotate for seamless switch (also avoid face index overflow)
local face_translation = {
center = { left = 3, right = 1 },
offset = { left = 0, right = 2 },
}
if is_open and type == "center" then -- hack to correct open center doors :P
face = face + 2
end
face = ( face + face_translation[ type ][ hand ] ) % 4 + 1
end
if rotate_face then
face = face % 4 + 1
end
return is_open, state, type == "offset" and
offset_transform[ hand ][ face ][ is_open ] or
center_transform[ hand ][ face ][ is_open ]
end
---------------------------------
-- is_door_protected( )
---------------------------------
local function is_door_protected( pos, ndef, player_name )
local owner = minetest.get_meta( pos ):get_string( "doors_owner" )
if minetest.get_player_privs( player_name ).protection_bypass then return false end
return ndef.protected and player_name ~= owner
end
---------------------------------
-- is_door_locked( )
---------------------------------
local function is_door_locked( pos, ndef, player_name )
local meta = minetest.get_meta( pos )
local locking_mode = meta:get_int( "locking_mode" )
local owner = meta:get_string( "doors_owner" )
if minetest.get_player_privs( player_name ).protection_bypass then return false end
2022-04-25 17:53:49 -07:00
if locking_mode == hades_doors.LOCKING_MODE_UNDEFINED then
if ndef.protected and player_name ~= owner then
return true
end
2022-04-25 17:53:49 -07:00
elseif locking_mode == hades_doors.LOCKING_MODE_LOCKED then
if ndef.protected and player_name ~= owner or not ndef.protected then
return true
end
2022-04-25 17:53:49 -07:00
elseif locking_mode == hades_doors.LOCKING_MODE_SHARED then
if minetest.is_protected( pos, player_name ) then
return true
end
end
return false
end
local is_trapdoor_locked = is_door_locked
---------------------------------
-- toggle_door( )
---------------------------------
local function toggle_door( pos, node, player )
local meta = minetest.get_meta( pos )
local ndef = minetest.registered_nodes[ node.name ]
local closing_mode = meta:get_int( "closing_mode" )
if player and is_door_locked( pos, ndef, player:get_player_name( ) ) then
2021-10-09 05:06:41 -07:00
minetest.sound_play( ndef.sound_locked, { pos = pos, gain = 0.3, max_hear_distance = 10 }, true )
return false
end
local state = meta:get_int( "state" )
local _, statetype, hand = get_door_properties( state, node.param2 )
local is_open, state, transform = get_door_transform( state, node.param2, true, false, false )
local new_name = ndef.base_name .. transform.suffix
local new_param2 = transform.param2
2022-04-25 17:53:49 -07:00
if not is_open and closing_mode == hades_doors.CLOSING_MODE_HOLDOPEN then
2021-10-09 15:43:26 -07:00
minetest.sound_play( ndef.sound_held_open, { pos = pos, gain = 0.8, max_hear_distance = 10 }, true )
return false -- abort since this door does not close
end
if statetype == "center" then
local nhand = hand
if not is_open and hand == "left" then
nhand = "right"
end
local neighbor = center_neighbor[nhand][node.param2]
local neighbor_bottom = vector.add(pos, neighbor)
local neighbor_top = offset_y(neighbor_bottom, 1)
local nb1 = minetest.get_node(neighbor_bottom)
local nb2 = minetest.get_node(neighbor_top)
local nb1d = minetest.registered_nodes[nb1.name]
local nb2d = minetest.registered_nodes[nb2.name]
if is_open then
-- Open center door, place hidden nodes to prevent node overlap
if nb1d and nb2d and nb1d.buildable_to and nb2d.buildable_to then
local np2
if hand == "left" then
np2 = node.param2
else
np2 = (node.param2 + 1) % 4
end
2022-04-25 17:53:49 -07:00
minetest.set_node(neighbor_bottom, {name="hades_doors:hidden", param2=np2})
minetest.set_node(neighbor_top, {name="hades_doors:hidden", param2=np2})
else
-- It's blocked, can't open
2021-10-09 15:43:26 -07:00
minetest.sound_play( ndef.sound_held_open, { pos = pos, gain = 0.8, max_hear_distance = 10 }, true )
return false
end
else
-- Close center door, remove place hidden nodes again
2022-04-25 17:53:49 -07:00
if nb1.name == "hades_doors:hidden" then
minetest.remove_node(neighbor_bottom)
end
2022-04-25 17:53:49 -07:00
if nb2.name == "hades_doors:hidden" then
minetest.remove_node(neighbor_top)
minetest.check_for_falling(neighbor_top)
end
end
end
2022-04-25 17:53:49 -07:00
if is_open and closing_mode == hades_doors.CLOSING_MODE_AUTOCLOSE then
2021-10-09 13:39:00 -07:00
local timer = minetest.get_node_timer( pos )
timer:start( config.autoclose_timeout )
end
if is_open then
-- if opened, play open sound
minetest.sound_play( ndef.sound_open, {
pos = pos, gain = 0.3, max_hear_distance = 10
2021-10-09 05:06:41 -07:00
}, true )
else
-- if closed, play close sound
minetest.sound_play( ndef.sound_close, {
pos = pos, gain = 0.3, max_hear_distance = 10
2021-10-09 05:06:41 -07:00
}, true )
end
minetest.swap_node( pos, { name = new_name, param2 = new_param2 } )
meta:set_int( "state", state )
end
---------------------------------
-- toggle_trapdoor( )
---------------------------------
function toggle_trapdoor( pos, node, player )
local meta = minetest.get_meta( pos )
local ndef = minetest.registered_nodes[ node.name ]
local closing_mode = meta:get_int( "closing_mode" )
if player and is_trapdoor_locked( pos, ndef, player:get_player_name( ) ) then
2021-10-09 05:06:41 -07:00
minetest.sound_play( ndef.sound_locked, { pos = pos, gain = 0.3, max_hear_distance = 10 }, true )
return false
end
if node.name == ndef.base_name then
local new_name = ndef.base_name .. "_open"
2022-04-25 17:53:49 -07:00
if closing_mode == hades_doors.CLOSING_MODE_AUTOCLOSE then
2021-10-09 13:39:00 -07:00
local timer = minetest.get_node_timer( pos )
timer:start( config.autoclose_timeout )
end
2021-10-09 05:06:41 -07:00
minetest.sound_play( ndef.sound_open, { pos = pos, gain = 0.3, max_hear_distance = 10 }, true )
minetest.swap_node( pos, { name = new_name, param1 = node.param1, param2 = node.param2 } )
else
local new_name = ndef.base_name
2022-04-25 17:53:49 -07:00
if closing_mode == hades_doors.CLOSING_MODE_HOLDOPEN then
2021-10-09 15:43:26 -07:00
minetest.sound_play( ndef.sound_held_open, { pos = pos, gain = 0.8, max_hear_distance = 10 }, true )
return false -- abort since this trapdoor does not close
end
2021-10-09 05:06:41 -07:00
minetest.sound_play( ndef.sound_close, { pos = pos, gain = 0.3, max_hear_distance = 10 }, true )
minetest.swap_node( pos, { name = ndef.base_name, param1 = node.param1, param2 = node.param2 } )
end
end
2021-10-09 13:49:33 -07:00
---------------------------------
-- on_timer_door( )
---------------------------------
local on_timer_door = function(pos)
-- Auto-close timeout
local node = minetest.get_node( pos )
local meta = minetest.get_meta( pos )
local state = meta:get_int( "state" )
local is_open, state, transform = get_door_transform( state, node.param2, true, false, false )
if not is_open then
toggle_door(pos, node) --pass nil player, since security doesn't matter
end
end
---------------------------------
-- on_timer_trapdoor( )
---------------------------------
local on_timer_trapdoor = function(pos)
local node = minetest.get_node(pos)
local ndef = minetest.registered_nodes[node.name]
2021-10-09 14:13:52 -07:00
if node.name == ndef.base_name .. "_open" then
2021-10-09 13:49:33 -07:00
toggle_trapdoor(pos, node) --pass nil player, since security doesn't matter
end
end
---------------------------------
-- on_adjust_door( )
---------------------------------
local function on_adjust_door( pos, node, player, mode )
local meta = minetest.get_meta( pos )
local ndef = minetest.registered_nodes[ node.name ]
local locking_mode = meta:get_int( "locking_mode" )
local closing_mode = meta:get_int( "closing_mode" )
local player_name = player:get_player_name( )
if is_door_protected( pos, ndef, player_name ) then return false end
2022-04-25 17:53:49 -07:00
if mode == hades_doors.ADJUST_LOCKING or mode == hades_doors.CHECK_LOCKING then
2021-10-09 04:25:13 -07:00
if ndef.is_lockable and locking_mode > 0 then
local mode_defs = { S("unlocked"), S("locked"), S("shared") }
2022-04-25 17:53:49 -07:00
if mode == hades_doors.ADJUST_LOCKING then
locking_mode = locking_mode % 3 + 1
meta:set_int( "locking_mode", locking_mode )
local sound
2022-04-25 17:53:49 -07:00
if locking_mode == hades_doors.LOCKING_MODE_LOCKED then
sound = ndef.sound_locking
2022-04-25 17:53:49 -07:00
elseif locking_mode == hades_doors.LOCKING_MODE_SHARED then
sound = ndef.sound_sharing
2022-04-25 17:53:49 -07:00
elseif locking_mode == hades_doors.LOCKING_MODE_UNLOCKED then
sound = ndef.sound_unlocking
end
minetest.sound_play( sound, { pos = pos, gain = 0.3, max_hear_distance = 10 }, true )
2021-10-09 05:31:24 -07:00
end
minetest.chat_send_player(player_name, minetest.colorize("#00FFFF", S("Locking mode is set to @1.", mode_defs[locking_mode])))
2021-10-09 04:25:13 -07:00
return true
else
2021-10-09 06:06:04 -07:00
minetest.chat_send_player(player_name, minetest.colorize("#FFFF00", S("This block does not provide locking adjustments.")))
2021-10-09 04:25:13 -07:00
return false
end
2022-04-25 17:53:49 -07:00
elseif mode == hades_doors.ADJUST_CLOSING or mode == hades_doors.CHECK_CLOSING then
2021-10-09 04:25:13 -07:00
if ndef.is_closable and closing_mode > 0 then
local mode_defs = { "manual", "auto-close", "hold-open" }
2022-04-25 17:53:49 -07:00
if mode == hades_doors.ADJUST_CLOSING then
closing_mode = closing_mode % 3 + 1
meta:set_int( "closing_mode", closing_mode )
minetest.sound_play( ndef.sound_closing_mode, { pos = pos, gain = 0.3, max_hear_distance = 10 }, true )
end
2021-10-09 06:06:04 -07:00
minetest.chat_send_player(player_name, minetest.colorize("#00FFFF", S("Closing mode is set to @1.", mode_defs[closing_mode])))
2021-10-09 04:25:13 -07:00
return true
else
2021-10-09 06:06:04 -07:00
minetest.chat_send_player(player_name, minetest.colorize("#FFFF00", S("This block does not provide closing adjustments.")))
2021-10-09 04:25:13 -07:00
return false
end
end
2021-10-09 04:25:13 -07:00
minetest.log("error", "[doors] Invalid mode argument in on_adjust_door! (mode="..tostring(mode)..")")
return false
end
local on_adjust_trapdoor = on_adjust_door
2021-10-09 06:06:04 -07:00
local on_adjust_fence_gate = function( pos, node, player, mode )
local player_name = player:get_player_name()
minetest.chat_send_player(player_name, minetest.colorize("#FFFF00", S("Fence gates do not provide locking or closing adjustments.")))
return false
end
---------------------------------
-- on_rotate_door( )
---------------------------------
local function on_rotate_door( pos, node, player, mode )
local ndef = minetest.registered_nodes[ node.name ]
local meta = minetest.get_meta( pos )
local state = meta:get_int( "state" )
if is_door_protected( pos, ndef, player:get_player_name( ) ) then return false end
if mode == screwdriver.ROTATE_FACE then
-- alternate hand between left <-> right
local is_open, state, transform = get_door_transform( state, node.param2, false, false, true, false )
minetest.swap_node( pos, { name = ndef.base_name .. transform.suffix, param2 = transform.param2 } )
local top = offset_y(pos)
local _, stype, shand = get_door_properties( state, transform.param2 )
local p2 = transform.param2
if stype == "center" then
if is_open and shand == "left" then
p2 = (p2 + 2) % 4
end
elseif (shand == "right" and not is_open) or (shand == "left" and is_open) then
p2 = (p2 + 3) % 4
end
if stype == "center" then
2022-04-25 17:53:49 -07:00
minetest.set_node( top, { name = "hades_doors:hidden_center", param2 = p2 } )
if is_open then
local neighbor = center_neighbor[shand][p2]
if shand == "right" then
p2 = (p2 + 1) % 4
end
2022-04-25 17:53:49 -07:00
minetest.set_node( vector.add( top, neighbor ), { name = "hades_doors:hidden", param2 = p2 } )
end
else
2022-04-25 17:53:49 -07:00
minetest.set_node( top, { name = "hades_doors:hidden", param2 = p2 } )
end
meta:set_int( "state", state )
return true
elseif mode == screwdriver.ROTATE_AXIS and ndef.can_center and ndef.can_offset then
-- alternate type between center <-> offset
local is_open, state, transform = get_door_transform( state, node.param2, false, true, false, false )
local top = offset_y(pos)
local _, stype, shand = get_door_properties( state, transform.param2 )
local p2 = transform.param2
if stype == "center" then
if is_open then
p2 = (p2 + 2) % 4
elseif shand == "left" then
p2 = (p2 + 1) % 4
end
elseif (shand == "right" and not is_open) or (shand == "left" and is_open) then
p2 = (p2 + 3) % 4
end
if stype == "center" then
if is_open then
if shand == "right" then
p2 = (p2 + 2) % 4
end
local neighbor = center_neighbor[shand][p2]
local neighbor_top = vector.add(top, neighbor)
local neighbor_bottom = offset_y(neighbor_top, -1)
local nnt = minetest.get_node(neighbor_top)
local nnb = minetest.get_node(neighbor_bottom)
local nntd = minetest.registered_nodes[nnt.name]
local nnbd = minetest.registered_nodes[nnb.name]
if nntd and nnbd and nntd.buildable_to and nnbd.buildable_to then
minetest.swap_node( pos, { name = ndef.base_name .. transform.suffix, param2 = transform.param2 } )
2022-04-25 17:53:49 -07:00
minetest.set_node( top, { name = "hades_doors:hidden_center", param2 = p2 } )
if shand == "right" then
p2 = (p2 + 1) % 4
end
2022-04-25 17:53:49 -07:00
minetest.set_node( neighbor_bottom, { name = "hades_doors:hidden", param2 = p2 })
minetest.set_node( neighbor_top, { name = "hades_doors:hidden", param2 = p2 })
else
return false
end
else
p2 = transform.param2
minetest.swap_node( pos, { name = ndef.base_name .. transform.suffix, param2 = transform.param2 } )
2022-04-25 17:53:49 -07:00
minetest.set_node( top, { name = "hades_doors:hidden_center", param2 = p2 } )
end
else
if shand == "right" then
p2 = (p2 + 3) % 4
end
minetest.swap_node( pos, { name = ndef.base_name .. transform.suffix, param2 = transform.param2 } )
2022-04-25 17:53:49 -07:00
minetest.set_node( top, { name = "hades_doors:hidden", param2 = p2} )
local neighbor = center_neighbor[shand][p2]
local neighbor_top = vector.add(top, neighbor)
local neighbor_bottom = offset_y(neighbor_top, -1)
local nnt = minetest.get_node(neighbor_top)
local nnb = minetest.get_node(neighbor_bottom)
2022-04-25 17:53:49 -07:00
if nnt.name == "hades_doors:hidden" then
minetest.remove_node(neighbor_top)
minetest.check_for_falling(neighbor_top)
end
2022-04-25 17:53:49 -07:00
if nnb.name == "hades_doors:hidden" then
minetest.remove_node(neighbor_bottom)
end
end
meta:set_int( "state", state )
return true
end
return false
end
2021-10-09 03:30:30 -07:00
local on_rotate_trapdoor
if minetest.get_modpath("screwdriver") then
on_rotate_trapdoor = function(pos, node, user, mode, param2)
-- Flip trapdoor vertically
if mode == screwdriver.ROTATE_AXIS then
local minor = node.param2
if node.param2 >= 20 then
minor = node.param2 - 20
if minor == 3 then
minor = 1
elseif minor == 1 then
minor = 3
end
node.param2 = minor
else
if minor == 3 then
minor = 1
elseif minor == 1 then
minor = 3
end
node.param2 = minor
node.param2 = node.param2 + 20
end
2021-10-12 04:38:24 -07:00
minetest.swap_node(pos, node)
2021-10-09 03:30:30 -07:00
return true
end
end
end
---------------------------------
2022-04-25 17:53:49 -07:00
-- hades_doors.get_door_or_nil( )
---------------------------------
2022-04-25 17:53:49 -07:00
hades_doors.get_door_or_nil = function ( pos )
local node = minetest.get_node( pos )
local meta = minetest.get_meta( pos )
local ndef = minetest.registered_nodes[ node.name ]
local self = { }
if ndef.groups.trapdoor then
2022-04-25 17:53:49 -07:00
return hades_doors.get_trapdoor_or_nil( pos )
elseif not ndef.groups.door then
return nil
end
self.get_properties = function ( )
local state = meta:get_int( "state" )
local is_open, type, hand, face = get_door_properties( state, node.param2 )
return { is_open = is_open, type = type, hand = hand, face = face }
end
self.close = function ( )
local state = meta:get_int( "state" )
local is_open, state, transform = get_door_transform( state, node.param2, true, false, false )
local new_name = ndef.base_name .. transform.suffix
local new_param2 = transform.param2
if not is_open then
2021-10-09 05:06:41 -07:00
minetest.sound_play( ndef.sound_close, { pos = pos, gain = 0.3, max_hear_distance = 10 }, true )
minetest.swap_node( pos, { name = new_name, param2 = new_param2 } )
meta:set_int( "state", state )
end
end
self.open = function ( )
local state = meta:get_int( "state" )
local is_open, state, transform = get_door_transform( state, node.param2, true, false, false )
local new_name = ndef.base_name .. transform.suffix
local new_param2 = transform.param2
if is_open then
2021-10-09 05:06:41 -07:00
minetest.sound_play( ndef.sound_open, { pos = pos, gain = 0.3, max_hear_distance = 10 }, true )
minetest.swap_node( pos, { name = new_name, param2 = new_param2 } )
meta:set_int( "state", state )
end
end
self.state = function ( ) -- for backwards compatibility
return self.get_properties( ).is_open
2020-10-28 14:59:01 -07:00
end
return self
end
2022-04-25 17:53:49 -07:00
hades_doors.get = hades_doors.get_door_or_nil -- for backwards compatibility
---------------------------------
2022-04-25 17:53:49 -07:00
-- hades_doors.get_trapdoor_or_nil( )
---------------------------------
2022-04-25 17:53:49 -07:00
hades_doors.get_trapdoor_or_nil = function ( pos )
local node = minetest.get_node( pos )
local meta = minetest.get_meta( pos )
local ndef = minetest.registered_nodes[ node.name ]
local self = { }
if not ndef.groups.trapdoor then return end
self.get_properties = function ( )
return { is_open = node.name == ndef.base_name .. "_open", face = node.param2 + 1 }
end
self.close = function ( )
if node.name == ndef.base_name .. "_open" then
local new_name = ndef.base_name
2021-10-09 05:06:41 -07:00
minetest.sound_play( ndef.sound_close, { pos = pos, gain = 0.3, max_hear_distance = 10 }, true )
minetest.swap_node( pos, { name = new_name, param2 = node.param2 } )
end
end
self.open = function ( )
if node.name == ndef.base_name then
local new_name = ndef.base_name .. "_open"
2021-10-09 05:06:41 -07:00
minetest.sound_play( ndef.sound_open, { pos = pos, gain = 0.3, max_hear_distance = 10 }, true )
minetest.swap_node( pos, { name = new_name, param2 = node.param2 } )
end
end
return self
end
----------------------------------
-- notify_on_placenode( )
----------------------------------
local function notify_on_placenode( pos, new_node, player, old_node, itemstack, pointed_thing )
for _, on_placenode in ipairs( minetest.registered_on_placenodes) do
-- clone tables since callback can modify them
local clone = {
pos = vector.new( pos ),
new_node = { name = new_node.name, param1 = new_node.param1, param2 = new_node.param2 },
old_node = { name = old_node.name, param1 = old_node.param1, param2 = old_node.param2 },
pointed_thing = {
type = pointed_thing.type,
above = vector.new( pointed_thing.above ),
under = vector.new( pointed_thing.under ),
ref = pointed_thing.ref,
}
}
on_placenode( clone.pos, clone.new_node, player, clone.old_node, itemstack, clone.pointed_thing )
end
end
---------------------------------
-- register_door_craftitem( )
---------------------------------
local function register_door_craftitem( name, def )
minetest.register_craftitem( ":" .. name, {
description = def.description,
inventory_image = def.inventory_image,
groups = { node = 1 },
on_place = function( itemstack, player, pointed_thing )
local pos
if not pointed_thing.type == "node" then
return itemstack
end
local node = minetest.get_node(pointed_thing.under)
local ndef = minetest.registered_nodes[node.name]
if ndef and ndef.on_rightclick and
not player:get_player_control().sneak then
return ndef.on_rightclick(pointed_thing.under,
node, player, itemstack, pointed_thing)
end
if ndef and ndef.buildable_to then
pos = pointed_thing.under
else
pos = pointed_thing.above
node = minetest.get_node( pos )
ndef = minetest.registered_nodes[ node.name ]
if not ndef or not ndef.buildable_to then
return itemstack
end
end
2021-10-09 02:37:39 -07:00
local top_pos = offset_y( pos )
local top_node = minetest.get_node_or_nil( top_pos )
local top_ndef = top_node and minetest.registered_nodes[ top_node.name ]
if not top_ndef or not top_ndef.buildable_to then
return itemstack
end
local player_name = player:get_player_name( )
if minetest.is_protected( pos, player_name ) or minetest.is_protected( top_pos, player_name ) then
return itemstack
end
local facedir = minetest.dir_to_facedir( player:get_look_dir( ) )
local facedir_to_pos = {
[0] = { x = -1, y = 0, z = 0 },
[1] = { x = 0, y = 0, z = 1 },
[2] = { x = 1, y = 0, z = 0 },
[3] = { x = 0, y = 0, z = -1 },
}
local look_pos = vector.add( pos, facedir_to_pos[ facedir ] )
local state = 0
-- NB: state stores door hand (left vs right) and door type (offset vs center)
-- and door is_open (true or false), while param2 stores door face (1-4).
if minetest.get_item_group( minetest.get_node( look_pos ).name, "door" ) == 1 then
state = state + 2 -- rotate 180
minetest.set_node( pos, { name = name .. "_b", param2 = facedir } )
2022-04-25 17:53:49 -07:00
minetest.set_node( top_pos, { name = "hades_doors:hidden", param2 = ( facedir + 3 ) % 4 } )
else
minetest.set_node( pos, { name = name .. "_a", param2 = facedir } )
2022-04-25 17:53:49 -07:00
minetest.set_node( top_pos, { name = "hades_doors:hidden", param2 = facedir } )
end
local meta = minetest.get_meta( pos )
meta:set_int( "state", state )
if def.protected then
meta:set_int( "oldtime", os.time( ) )
meta:set_int( "newtime", os.time( ) )
meta:set_string( "doors_owner", player_name )
meta:set_string( "infotext", "Owned by " .. player_name )
end
if def.is_lockable then
2022-04-25 17:53:49 -07:00
meta:set_string( "locking_mode", def.protected and hades_doors.LOCKING_MODE_LOCKED or hades_doors.LOCKING_MODE_UNLOCKED )
end
if def.is_closable then
2022-04-25 17:53:49 -07:00
meta:set_string( "closing_mode", hades_doors.CLOSING_MODE_MANUAL )
end
if not minetest.is_creative_enabled(player:get_player_name()) then
itemstack:take_item( )
end
2021-10-09 05:06:41 -07:00
minetest.sound_play( def.sounds.place, { pos = pos }, true )
notify_on_placenode( pos, minetest.get_node( pos ), player, node, itemstack, pointed_thing )
return itemstack
end
} )
end
---------------------------------
2022-04-25 17:53:49 -07:00
-- hades_doors.register_door( )
---------------------------------
2022-04-25 17:53:49 -07:00
function hades_doors.register_door( name, def )
register_door_craftitem( name, def )
-- define the basic properties
def.base_name = name
def.drawtype = "mesh"
def.paramtype = "light"
def.paramtype2 = "facedir"
def.walkable = true
def.is_ground_content = false
def.buildable_to = false
def.inventory_image = nil
def.drop = name
def.groups.not_in_creative_inventory = 1
def.groups.door = 1
def.groups.rotation_takes_precedence = 1
-- define the crafting recipe
if def.recipe then
minetest.register_craft( { output = name, recipe = def.recipe } )
end
def.recipe = nil
-- define the opening/closing sounds
if not def.sounds then
def.sounds = hades_sounds.node_sound_wood_defaults( )
end
if not def.sound_open then
def.sound_open = "doors_door_open"
end
if not def.sound_close then
def.sound_close = "doors_door_close"
end
2021-08-14 05:58:40 -07:00
if not def.sound_locked then
def.sound_locked = "doors_door_locked"
end
2021-10-09 05:31:24 -07:00
if not def.sound_locking then
def.sound_locking = "doors_door_locking"
end
if not def.sound_unlocking then
def.sound_unlocking = "doors_door_unlocking"
end
if not def.sound_sharing then
def.sound_sharing = "doors_door_sharing"
end
if not def.sound_held_open then
def.sound_held_open = "doors_door_held_open"
end
if not def.sound_closing_mode then
def.sound_closing_mode = "doors_door_closing_mode"
end
2021-08-14 05:58:40 -07:00
-- define the placement types
if def.can_offset == nil or not def.can_center then
def.can_offset = true
end
if def.can_center == nil then
2021-10-09 12:22:46 -07:00
def.can_center = true
end
if def.is_lockable == nil then
2021-10-09 05:52:23 -07:00
def.is_lockable = true
end
if def.is_closable == nil then
2021-10-09 05:52:23 -07:00
def.is_closable = true
end
-- define the essential callbacks
def.on_adjust = on_adjust_door
def.on_rotate = on_rotate_door
def.on_rightclick = function ( pos, node, player, itemstack, pointed_thing )
toggle_door( pos, node, player )
return itemstack
end
def.on_destruct = function( pos )
2021-10-09 02:37:39 -07:00
minetest.remove_node( offset_y( pos ) ) -- hidden node
minetest.check_for_falling( offset_y( pos ) )
end
2021-10-09 13:39:00 -07:00
def.on_timer = on_timer_door
if def.protected then
def.can_dig = function ( pos, player )
local player_name = player:get_player_name( )
if is_door_protected( pos, def, player_name ) then
minetest.record_protection_violation( pos, player_name )
return false
else
return true
end
end
def.on_blast = function( ) end
else
def.on_blast = function( pos, intensity )
minetest.remove_node( pos ) -- door node
2021-10-09 02:37:39 -07:00
minetest.remove_node( offset_y( pos ) ) -- hidden node
return { name }
end
2021-07-12 06:12:52 -07:00
end
-- register offset door nodes
2021-10-09 03:08:14 -07:00
-- Prevent steel door crafting recipe from applying to hinge nodes
-- TODO: Generalize this code
if def.groups then
def.groups.steel_door = nil
end
if def.can_offset then
def.selection_box = { type = "fixed", fixed = { -1/2, -1/2, -8/16, 1/2, 3/2, -6/16 } }
def.collision_box = { type = "fixed", fixed = { -1/2, -1/2, -8/16, 1/2, 3/2, -6/16 } }
def.mesh = "door_a.obj"
minetest.register_node( ":" .. name .. "_a", table.copy(def) )
def.mesh = "door_b.obj"
minetest.register_node( ":" .. name .. "_b", table.copy(def) )
end
-- register center door nodes
if def.can_center then
2021-10-09 11:49:02 -07:00
def.on_destruct = function( pos )
local meta = minetest.get_meta( pos )
local state = meta:get_int( "state" )
local oldnode = minetest.get_node(pos)
2021-10-09 17:24:48 -07:00
local is_open, stype, shand = get_door_properties( state, oldnode.param2 )
if is_open and stype == "center" then
2021-10-09 11:49:02 -07:00
local p2 = oldnode.param2
if shand == "left" then
p2 = (p2 + 2) % 4
end
local neighbor = center_neighbor[shand][p2]
local neighbor_bottom = vector.add(pos, neighbor)
local neighbor_top = offset_y(neighbor_bottom)
-- Remove hidden nodes of open center door
minetest.remove_node( neighbor_bottom )
minetest.remove_node( neighbor_top )
minetest.check_for_falling( neighbor_top )
end
-- Remove hidden node (upper door segment)
minetest.remove_node( offset_y( pos ) )
minetest.check_for_falling( offset_y( pos ) )
end
def.selection_box = { type = "fixed", fixed = { -1/2, -1/2, -1/16, 1/2, 3/2, 1/16 } }
def.collision_box = { type = "fixed", fixed = { -1/2, -1/2, -1/16, 1/2, 3/2, 1/16 } }
def.mesh = "door_c.obj" -- shut
minetest.register_node( ":" .. name .. "_c", table.copy(def) )
def.selection_box = { type = "fixed", fixed = { 6/16, -1/2, -15/16, 8/16, 3/2, 1/16 } }
def.collision_box = { type = "fixed", fixed = { 6/16, -1/2, -15/16, 8/16, 3/2, 1/16 } }
def.mesh = "door_d.obj" -- open left-hand
minetest.register_node( ":" .. name .. "_d", table.copy(def) )
def.selection_box = { type = "fixed", fixed = { -8/16, -1/2, -15/16, -6/16, 3/2, 1/16 } }
def.collision_box = { type = "fixed", fixed = { -8/16, -1/2, -15/16, -6/16, 3/2, 1/16 } }
def.mesh = "door_e.obj" -- open right-hand
minetest.register_node( ":" .. name .. "_e", table.copy(def) )
end
end
2022-04-25 17:53:49 -07:00
hades_doors.register = hades_doors.register_door -- for backward compatibility
---------------------------------
2022-04-25 17:53:49 -07:00
-- hades_doors.register_trapdoor( )
---------------------------------
2022-04-25 17:53:49 -07:00
function hades_doors.register_trapdoor( name, def )
-- define the basic properties
def.base_name = name
def.drawtype = "nodebox"
def.paramtype = "light"
def.paramtype2 = "facedir"
def.is_ground_content = false
def.drop = name
2021-10-09 03:22:11 -07:00
if not def.groups then
def.groups = {}
end
def.groups.trapdoor = 1
def.groups.rotation_takes_precedence = 1
-- define the opening/closing sounds
if not def.sounds then
def.sounds = hades_sounds.node_sound_wood_defaults( )
end
if not def.sound_open then
def.sound_open = "doors_door_open"
end
if not def.sound_close then
def.sound_close = "doors_door_close"
end
if not def.sound_locked then
def.sound_locked = "doors_door_locked"
end
2021-10-09 05:31:24 -07:00
if not def.sound_locking then
def.sound_locking = "doors_door_locking"
end
if not def.sound_unlocking then
def.sound_unlocking = "doors_door_unlocking"
end
if not def.sound_sharing then
def.sound_sharing = "doors_door_sharing"
end
if not def.sound_held_open then
def.sound_held_open = "doors_door_held_open"
end
if not def.sound_closing_mode then
def.sound_closing_mode = "doors_door_closing_mode"
end
-- define the placement types
if def.is_lockable == nil then
2021-10-09 05:52:23 -07:00
def.is_lockable = true
end
if def.is_closable == nil then
2021-10-09 05:52:23 -07:00
def.is_closable = true
end
-- define the essential callbacks
def.on_adjust = on_adjust_trapdoor
def.on_rightclick = function ( pos, node, player, itemstack, pointed_thing )
toggle_trapdoor( pos, node, player )
return itemstack
end
def.on_place = function(itemstack, placer, pointed_thing)
-- Place trapdoor on upper or lower side depending on where it was pointed
local p0 = pointed_thing.under
local p1 = pointed_thing.above
local param2 = 0
-- Get correct trapdoor rotation for the trapdoor "hinge"
local dir = vector.subtract(p0, p1)
if dir.y == 0 then
-- Sideways placement: Trapdoor is "hinged"
-- at this side
param2 = minetest.dir_to_facedir(dir)
else
-- Floor or ceiling placement:
-- Rotation is based on placer view dir
local placer_pos = placer:get_pos()
dir = vector.subtract(p1, placer_pos)
param2 = minetest.dir_to_facedir(dir)
end
-- Decide whether to place up or down (upper or lower half of node
-- side pointed)
local finepos = minetest.pointed_thing_to_face_pos(placer, pointed_thing)
local fpos = finepos.y % 1
if p0.y - 1 == p1.y or (fpos > 0 and fpos < 0.5)
or (fpos < -0.5 and fpos > -0.999999999) then
param2 = param2 + 20
if param2 == 21 then
param2 = 23
elseif param2 == 23 then
param2 = 21
end
end
return minetest.item_place(itemstack, placer, pointed_thing, param2)
end
2021-10-09 03:30:30 -07:00
def.on_rotate = on_rotate_trapdoor
2021-10-09 13:39:00 -07:00
def.on_timer = on_timer_trapdoor
if def.protected then
def.can_dig = function ( pos, player )
local player_name = player:get_player_name( )
if is_door_protected( pos, def, player_name ) then
minetest.record_protection_violation( pos, player_name )
return false
else
return true
end
end
def.after_place_node = function ( pos, player, itemstack, pointed_thing )
local player_name = player:get_player_name( )
local meta = minetest.get_meta( pos )
meta:set_int( "oldtime", os.time( ) )
meta:set_int( "newtime", os.time( ) )
meta:set_string( "doors_owner", player_name )
meta:set_string( "infotext", "Owned by " .. player_name )
if def.is_lockable then
2022-04-25 17:53:49 -07:00
meta:set_string( "locking_mode", def.protected and hades_doors.LOCKING_MODE_LOCKED or hades_doors.LOCKING_MODE_UNLOCKED )
end
if def.is_closable then
2022-04-25 17:53:49 -07:00
meta:set_string( "closing_mode", hades_doors.CLOSING_MODE_MANUAL )
end
return minetest.is_creative_enabled(player_name)
end
def.on_blast = function ( ) end
else
def.after_place_node = function ( pos, player, itemstack, pointed_thing )
local player_name = player:get_player_name( )
local meta = minetest.get_meta( pos )
if def.is_lockable then
2022-04-25 17:53:49 -07:00
meta:set_string( "locking_mode", def.protected and hades_doors.LOCKING_MODE_LOCKED or hades_doors.LOCKING_MODE_UNLOCKED )
end
if def.is_closable then
2022-04-25 17:53:49 -07:00
meta:set_string( "closing_mode", hades_doors.CLOSING_MODE_MANUAL )
end
return minetest.is_creative_enabled(player_name)
end
def.on_blast = function ( pos, intensity )
minetest.remove_node( pos )
return { name }
end
2021-08-14 05:58:40 -07:00
end
-- register trapdoor nodes
def.node_box = { type = "fixed", fixed = { -0.5, -0.5, -0.5, 0.5, -6/16, 0.5 } }
def.selection_box = { type = "fixed", fixed = { -0.5, -0.5, -0.5, 0.5, -6/16, 0.5 } }
def.tiles = { def.tile_front, def.tile_front .. '^[transformFY', def.tile_side, def.tile_side, def.tile_side, def.tile_side }
minetest.register_node( ":" .. name, table.copy(def) ) -- closed
2021-10-09 03:22:11 -07:00
local def_open = table.copy(def)
def_open.groups.not_in_creative_inventory = 1
def_open.node_box = { type = "fixed", fixed = { -0.5, -0.5, 6/16, 0.5, 0.5, 0.5 } }
def_open.selection_box = { type = "fixed", fixed = {-0.5, -0.5, 6/16, 0.5, 0.5, 0.5 } }
def_open.tiles = { def.tile_side, def.tile_side, def.tile_side .. '^[transform3', def.tile_side .. '^[transform1', def.tile_front .. '^[transform46', def.tile_front .. '^[transform6' }
2021-10-09 03:22:11 -07:00
minetest.register_node( ":" .. name .. "_open", def_open ) -- opened
end
---------------------------------
2022-04-25 17:53:49 -07:00
-- hades_doors.register_fencegate( )
---------------------------------
2022-04-25 17:53:49 -07:00
function hades_doors.register_fencegate( name, def )
local fence = {
description = def.description,
2021-10-09 02:44:01 -07:00
drawtype = "nodebox",
tiles = {def.texture},
paramtype = "light",
paramtype2 = "facedir",
sunlight_propagates = true,
is_ground_content = false,
drop = name .. "_closed",
connect_sides = {"left", "right"},
groups = def.groups,
sounds = def.sounds,
on_rightclick = function(pos, node, player, itemstack, pointed_thing)
local node_def = minetest.registered_nodes[node.name]
minetest.swap_node(pos, {name = node_def.gate, param2 = node.param2})
minetest.sound_play(node_def.sound, {pos = pos, gain = 0.3,
2021-10-09 05:06:41 -07:00
max_hear_distance = 8}, true)
return itemstack
end,
2021-10-09 05:58:00 -07:00
on_rotate = "simple",
}
if not fence.sounds then
fence.sounds = hades_sounds.node_sound_wood_defaults()
end
2021-10-09 06:06:04 -07:00
fence.groups.fence_gate = 1
fence.on_adjust = on_adjust_fence_gate
local fence_closed = table.copy(fence)
fence_closed.gate = name .. "_open"
fence_closed.sound = "doors_fencegate_open"
2021-10-09 02:44:01 -07:00
fence_closed.node_box = {
type = "fixed",
fixed = {
{-0.5, -6/16, -1/16, -6/16, 6/16, 1/16}, -- left end
{6/16, -6/16, -1/16, 0.5, 6/16, 1/16}, -- right end
{-2/16, -2/16, -1/16, 2/16, 2/16, 1/16}, -- middle
{-6/16, 2/16, -1/16, 6/16, 5/16, 1/16}, -- up bar
{-6/16, -5/16, -1/16, 6/16, -2/16, 1/16}, -- down bar
}
}
fence_closed.collision_box = {
type = "fixed",
2021-10-09 02:44:01 -07:00
fixed = {-1/2, -1/2, -2/16, 1/2, 1/2, 2/16},
}
2021-10-09 02:44:01 -07:00
fence_closed.selection_box = {
type = "fixed",
fixed = {-1/2, -6/16, -1/16, 1/2, 6/16, 1/16},
}
local fence_open = table.copy(fence)
fence_open.gate = name .. "_closed"
fence_open.sound = "doors_fencegate_close"
fence_open.groups.not_in_creative_inventory = 1
2021-10-09 02:44:01 -07:00
fence_open.node_box = {
type = "fixed",
fixed = {
{-0.5, -6/16, -1/16, -6/16, 6/16, 1/16}, -- left end
{6/16, -6/16, -1/16, 0.5, 6/16, 1/16}, -- right end
{-0.5, 2/16, 1/16, -6/16, 5/16, 6/16}, -- up-left bar x
{-0.5, -5/16, 1/16, -6/16, -2/16, 6/16}, -- down-left bar x
{6/16, 2/16, 1/16, 0.5, 5/16, 0.5}, -- up-right bar x
{6/16, -5/16, 1/16, 0.5, -2/16, 0.5}, -- down-right bar x
{-0.5, -5/16, 6/16, -6/16, 5/16, 0.5}, -- middle left
{6/16, -2/16, 0.5, 0.5, 2/16, 6/16}, -- middle right
},
}
fence_open.selection_box = {
type = "fixed",
fixed = {
{-1/2, -6/16, -1/16, 1/2, 6/16, 1/16},
}
}
fence_open.collision_box = {
type = "fixed",
2021-10-09 02:44:01 -07:00
fixed = {
{-0.5, -6/16, -1/16, -6/16, 6/16, 1/16}, -- left end
{6/16, -6/16, -1/16, 0.5, 6/16, 1/16}, -- right end
}
}
minetest.register_node(":" .. name .. "_closed", fence_closed)
minetest.register_node(":" .. name .. "_open", fence_open)
minetest.register_craft({
output = name .. "_closed",
recipe = {
{"hades_core:stick", def.material, "hades_core:stick"},
{"hades_core:stick", def.material, "hades_core:stick"}
}
})
end