Villagegen: Initialize double doors correctly

This commit is contained in:
Wuzzy 2022-10-29 18:01:04 +02:00
parent 03ea8abd5e
commit 213b614930
4 changed files with 79 additions and 9 deletions

View File

@ -137,6 +137,8 @@ This is the list of all groups used for nodes. Note: If no number/rating is spec
* `path`: A path node like the Dirt Path (1 = normal path, 2 = path slab)
* `door`: Any door
* `door_wood`: Wooden door
* `door_state`: Door segment, internal state (1 or 2) (see `rp_door` mod)
* `door_position`: Door segment, position (1 = bottom, 2 = top)
* `fence`: Fence
* `sign`: Sign
* `bed`: Bed segment

View File

@ -28,3 +28,18 @@ Also adds a craftitem (with identifier `name`) which the players can use.
* `selection_box_top`: Custom selection box table for top door segment (optional)
* `selection_box_bottom`: Custom selection box table for bottom door segment (optional)
### `door.init_segment(pos, is_open)`
This initializes a door segment to set the correct internal state.
You only need this function is the door segment was generated
procedurally (e.g. via VManip or a schematic). Doors placed
by the player don't need this function.
This currently sets the correct hinge state which is required
for this mod to know about the open/close state.
* `pos`: Position of door segment
* `is_open`: (optional) `true` if this door segment is open,
`false` otherwise (default: `false`)

View File

@ -6,6 +6,16 @@ local S = minetest.get_translator("rp_door")
door = {}
-- Mark the door segment at pos as having a right hinge.
-- This function assumes that there is a door segment at pos.
local function set_segment_hinge_right(pos)
local meta = minetest.get_meta(pos)
-- the meta key "right" stores the door hinge:
-- * 0: hinge is left
-- * 1: hinge is right
meta:set_int("right", 1)
end
-- Registers a door
function door.register_door(name, def)
@ -100,11 +110,8 @@ function door.register_door(name, def)
else
minetest.set_node(pt, {name=name.."_b_2", param2=p2})
minetest.set_node(pt2, {name=name.."_t_2", param2=p2})
-- the meta key "right" stores the door hinge:
-- * 0: hinge is left
-- * 1: hinge is right
minetest.get_meta(pt):set_int("right", 1)
minetest.get_meta(pt2):set_int("right", 1)
set_segment_hinge_right(pt)
set_segment_hinge_right(pt2)
end
if def.sounds and def.sounds.place then
minetest.sound_play(def.sounds.place, {pos=pt}, true)
@ -178,6 +185,23 @@ function door.register_door(name, def)
local groups_node = table.copy(def.groups)
groups_node.not_in_creative_inventory = 1
local groups_node_b_1 = table.copy(groups_node)
-- door position: 1 = bottom, 2 = top
groups_node_b_1.door_position = 1
groups_node_b_1.door_state = 1
local groups_node_b_2 = table.copy(groups_node)
groups_node_b_2.door_position = 1
groups_node_b_2.door_state = 2
local groups_node_t_1 = table.copy(groups_node)
groups_node_t_1.door_position = 2
groups_node_t_1.door_state = 1
local groups_node_t_2 = table.copy(groups_node)
groups_node_t_2.door_position = 2
groups_node_t_2.door_state = 2
-- Door segment: bottom, state 1
minetest.register_node(
name.."_b_1",
@ -198,7 +222,7 @@ function door.register_door(name, def)
fixed = def.selection_box_bottom
},
groups = groups_node,
groups = groups_node_b_1,
on_rightclick = function(pos, node, clicker)
if check_player_priv(pos, clicker) then
@ -238,7 +262,7 @@ function door.register_door(name, def)
type = "fixed",
fixed = def.selection_box_top
},
groups = groups_node,
groups = groups_node_t_1,
on_rightclick = function(pos, node, clicker)
if check_player_priv(pos, clicker) then
@ -278,7 +302,7 @@ function door.register_door(name, def)
type = "fixed",
fixed = def.selection_box_bottom
},
groups = groups_node,
groups = groups_node_b_2,
on_rightclick = function(pos, node, clicker)
if check_player_priv(pos, clicker) then
@ -318,7 +342,7 @@ function door.register_door(name, def)
type = "fixed",
fixed = def.selection_box_top
},
groups = groups_node,
groups = groups_node_t_2,
on_rightclick = function(pos, node, clicker)
if check_player_priv(pos, clicker) then
@ -341,6 +365,20 @@ function door.register_door(name, def)
end
function door.init_segment(pos, is_open)
local node = minetest.get_node(pos)
local state = minetest.get_item_group(node.name, "door_state")
if state == 0 then
return
end
if is_open == nil then
is_open = false
end
if (state == 2 and is_open == false) or (state == 1 and is_open == true) then
set_segment_hinge_right(pos)
end
end
door.register_door(
"rp_door:door_wood",
{

View File

@ -1275,6 +1275,18 @@ local function village_modify_lock_chests(upos, upos2, pr)
end
end
-- Village modifier: Inizialize doors
local function village_modify_init_doors(upos, upos2, pr)
util.nodefunc(
upos, upos2,
"group:door",
function(pos)
-- The `is_open` parameter is false because we assume all
-- doors in the village chunks are closed
door.init_segment(pos, false)
end, true)
end
local function after_village_area_emerged(blockpos, action, calls_remaining, params)
local done = action == minetest.EMERGE_GENERATED or action == minetest.EMERGE_FROM_DISK or action == minetest.EMERGE_FROM_MEMORY
if not done or calls_remaining > 0 then
@ -1534,6 +1546,9 @@ local function after_village_area_emerged(blockpos, action, calls_remaining, par
-- Force on_construct to be called on all nodes
util.reconstruct(upos, upos2, pr)
-- Initialize doors (required by rp_doors mod)
village_modify_init_doors(upos, upos2, pr)
-- Fill containers with goodies
village_modify_populate_containers(upos, upos2, pr, {chunktype=chunktype})