Remove windows

This commit is contained in:
Wuzzy 2024-10-18 14:31:28 +02:00
parent 641b8cebbd
commit 68c761c06b
4 changed files with 45 additions and 91 deletions

View File

@ -20,8 +20,7 @@ in the “Level settings” in your inventory menu.
The level boundaries need to be specified as itemstrings like
`lzr_core:wood`. Invalid values will be automatically replaced
by a default. The special “window node” will appear at the
wall 2 blocks above the floor, each spaced 2 blocks apart.
by a default.
**WARNING**: Reducing the level size will remove all nodes
that would no longer fit into the level!
@ -268,10 +267,10 @@ Each record contains multiple values, in this order:
Border list is a list of nodes used for the level border.
It contains 1-4 node names, separated by `|`. The border nodes are, in this order:
* Wall|Window|Floor|Ceiling
* Wall|Ignored|Floor|Ceiling
Wall is mandatory, the rest is optional. If window, floor or ceiling are missing,
they will the same as wall.
Wall is mandatory, the rest is optional. Ignored can be any text and will be
ignored. If floor or ceiling are missing, they will the same as wall.
Note: The same syntax is also used for the `.csv` files created by the level
editor, the only difference is that these files only contain 1 CSV record,

View File

@ -52,7 +52,6 @@ local INITIAL_LEVEL_STATE = {
file_name = "",
size = lzr_globals.DEFAULT_LEVEL_SIZE,
wall = lzr_globals.DEFAULT_WALL_NODE,
window = lzr_globals.DEFAULT_WINDOW_NODE,
ceiling = lzr_globals.DEFAULT_CEILING_NODE,
floor = lzr_globals.DEFAULT_FLOOR_NODE,
ambient = lzr_ambience.DEFAULT_AMBIENCE,
@ -261,7 +260,9 @@ local save_level = function(level_name, is_autosave)
local csv_contents = lzr_csv.write_csv({{
level_name..".mts",
level_state.name,
level_state.wall .. "|" .. level_state.window .. "|" .. level_state.floor .. "|" .. level_state.ceiling,
-- level boundaries syntax: wall|<unused>|floor|ceiling
-- (the <unused> used to be a node, but it has been removed from the game)
level_state.wall .. "||" .. level_state.floor .. "|" .. level_state.ceiling,
level_state.ambient,
level_state.sky,
npc_texts_csv,
@ -377,7 +378,6 @@ local load_level = function(level_name, player)
local exploded_bounds = string.split(bounds, "|")
if exploded_bounds then
level_state.wall = exploded_bounds[1]
level_state.window = exploded_bounds[2]
level_state.floor = exploded_bounds[3]
level_state.ceiling = exploded_bounds[4]
end
@ -413,7 +413,6 @@ local load_level = function(level_name, player)
level_state.size = lzr_world.get_level_size()
level_state.name = level_state.name or ""
level_state.wall = level_state.wall or lzr_globals.DEFAULT_WALL_NODE
level_state.window = level_state.window or lzr_globals.DEFAULT_WINDOW_NODE
level_state.ceiling = level_state.ceiling or lzr_globals.DEFAULT_CEILING_NODE
level_state.floor = level_state.floor or lzr_globals.DEFAULT_FLOOR_NODE
level_state.ambient = level_state.ambient or lzr_ambience.DEFAULT_AMBIENCE
@ -435,7 +434,6 @@ local load_level = function(level_name, player)
local bounding_nodes = {
node_wall = level_state.wall,
node_window = level_state.window,
node_ceiling = level_state.ceiling,
node_floor = level_state.floor,
}
@ -663,7 +661,7 @@ local show_settings_dialog = function(player, settings_state)
end
local form = "formspec_version[7]"..
"size[9,13.1]"..
"size[9,11.7]"..
"box[0,0;9,0.8;#00000080]"..
"label[0.4,0.4;"..FS("Level settings").."]"..
"field[0.5,1.3;8,0.6;level_name;"..FS("Name")..";"..F(settings_state.name).."]"..
@ -672,33 +670,31 @@ local show_settings_dialog = function(player, settings_state)
"field[2.62,2.3;1,0.6;level_size_y;"..FS("Y")..";"..F(tostring(settings_state.size.y)).."]"..
"field[3.63,2.3;1,0.6;level_size_z;"..FS("Z")..";"..F(tostring(settings_state.size.z)).."]"..
"field[0.5,3.3;7,0.6;level_wall;"..FS("Wall node")..";"..F(settings_state.wall).."]"..
"field[0.5,4.3;7,0.6;level_window;"..FS("Window node")..";"..F(settings_state.window).."]"..
"field[0.5,5.3;7,0.6;level_floor;"..FS("Floor node")..";"..F(settings_state.floor).."]"..
"field[0.5,6.3;7,0.6;level_ceiling;"..FS("Ceiling node")..";"..F(settings_state.ceiling).."]"..
"field[0.5,4.3;7,0.6;level_floor;"..FS("Floor node")..";"..F(settings_state.floor).."]"..
"field[0.5,5.3;7,0.6;level_ceiling;"..FS("Ceiling node")..";"..F(settings_state.ceiling).."]"..
boundary_button("wall", settings_state.wall, 3.3)..
boundary_button("window", settings_state.window, 4.3)..
boundary_button("floor", settings_state.floor, 5.3)..
boundary_button("ceiling", settings_state.ceiling, 6.3)..
boundary_button("floor", settings_state.floor, 4.3)..
boundary_button("ceiling", settings_state.ceiling, 5.3)..
"field[0.5,7.3;8,0.6;level_npc_goldie;"..FS("Information block text")..";"..F(settings_state.npc_texts.goldie).."]"..
"field[0.5,6.3;8,0.6;level_npc_goldie;"..FS("Information block text")..";"..F(settings_state.npc_texts.goldie).."]"..
"label[0.5,8.1;"..FS("Music").."]"..
"dropdown[0.5,8.3;8,0.6;level_ambient;"..ambient_list..";"..current_ambient..";true]"..
"label[0.5,7.1;"..FS("Music").."]"..
"dropdown[0.5,7.3;8,0.6;level_ambient;"..ambient_list..";"..current_ambient..";true]"..
"label[0.5,9.2;"..FS("Sky").."]"..
"dropdown[0.5,9.4;3.5,0.6;level_sky;"..sky_list..";"..current_sky..";true]"..
"label[0.5,8.2;"..FS("Sky").."]"..
"dropdown[0.5,8.4;3.5,0.6;level_sky;"..sky_list..";"..current_sky..";true]"..
"label[5,9.2;"..FS("Weather").."]"..
"dropdown[5,9.4;3.5,0.6;level_weather;"..weather_list..";"..current_weather..";true]"..
"label[5,8.2;"..FS("Weather").."]"..
"dropdown[5,8.4;3.5,0.6;level_weather;"..weather_list..";"..current_weather..";true]"..
"label[0.5,10.3;"..FS("Backdrop").."]"..
"dropdown[0.5,10.5;3.5,0.6;level_backdrop;"..backdrop_list..";"..current_backdrop..";true]"
"label[0.5,9.3;"..FS("Backdrop").."]"..
"dropdown[0.5,9.5;3.5,0.6;level_backdrop;"..backdrop_list..";"..current_backdrop..";true]"
-- backdrop_pos is only relevant for islands backdrop
if settings_state.backdrop == "islands" then
form = form .. "field[5,10.5;1,0.6;level_backdrop_pos_x;"..FS("X")..";"..F(tostring(settings_state.backdrop_pos.x)).."]"..
"field[6.02,10.5;1,0.6;level_backdrop_pos_y;"..FS("Y")..";"..F(tostring(settings_state.backdrop_pos.y)).."]"..
"field[7.04,10.5;1,0.6;level_backdrop_pos_z;"..FS("Z")..";"..F(tostring(settings_state.backdrop_pos.z)).."]"..
form = form .. "field[5,9.5;1,0.6;level_backdrop_pos_x;"..FS("X")..";"..F(tostring(settings_state.backdrop_pos.x)).."]"..
"field[6.02,9.5;1,0.6;level_backdrop_pos_y;"..FS("Y")..";"..F(tostring(settings_state.backdrop_pos.y)).."]"..
"field[7.04,9.5;1,0.6;level_backdrop_pos_z;"..FS("Z")..";"..F(tostring(settings_state.backdrop_pos.z)).."]"..
"tooltip[level_backdrop_pos_x;"..FS("X coordinate of backdrop position").."]"..
"tooltip[level_backdrop_pos_y;"..FS("Y coordinate of backdrop position").."]"..
"tooltip[level_backdrop_pos_z;"..FS("Z coordinate of backdrop position").."]"
@ -708,8 +704,7 @@ local show_settings_dialog = function(player, settings_state)
"tooltip[level_size_x;"..FS("Level size along the X axis").."]"..
"tooltip[level_size_y;"..FS("Level size along the Y axis").."]"..
"tooltip[level_size_z;"..FS("Level size along the Z axis").."]"..
"tooltip[level_wall;"..FS("Itemstring of node to be placed on the left, front, back and right level borders, except windows").."]"..
"tooltip[level_window;"..FS("Itemstring of node to be placed as window in the level walls").."]"..
"tooltip[level_wall;"..FS("Itemstring of node to be placed on the left, front, back and right level borders").."]"..
"tooltip[level_floor;"..FS("Itemstring of node to be placed at the bottom of the level").."]"..
"tooltip[level_ceiling;"..FS("Itemstring of node to be placed at the top of the level").."]"..
"tooltip[level_npc_goldie;"..FS("Text to be shown when player interacts with the information block").."]"..
@ -718,8 +713,8 @@ local show_settings_dialog = function(player, settings_state)
"tooltip[level_weather;"..FS("Visual weather effects (no audio)").."]"..
"tooltip[level_backdrop;"..FS("The world that surrounds the level").."]"..
"button_exit[0.5,11.9;3.5,0.7;level_ok;"..FS("OK").."]"..
"button_exit[5,11.9;3.5,0.7;level_cancel;"..FS("Cancel").."]"..
"button_exit[0.5,10.5;3.5,0.7;level_ok;"..FS("OK").."]"..
"button_exit[5,10.5;3.5,0.7;level_cancel;"..FS("Cancel").."]"..
"field_close_on_enter[level_ok;true]"
minetest.show_formspec(player:get_player_name(), "lzr_editor:level_settings", form)
end
@ -977,7 +972,6 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
target_table.size.z = fields.level_size_z or target_table.size.z
target_table.floor = fields.level_floor or target_table.floor
target_table.window = fields.level_window or target_table.window
target_table.ceiling = fields.level_ceiling or target_table.ceiling
target_table.wall = fields.level_wall or target_table.wall
if fields.level_npc_goldie then
@ -1043,7 +1037,7 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
if not fields.level_cancel and not fields.quit and not fields.level_ok then
-- select_item button clicked
if fields.level_wall_select or fields.level_window_select or fields.level_ceiling_select or fields.level_floor_select then
if fields.level_wall_select or fields.level_ceiling_select or fields.level_floor_select then
parse_settings_fields(temp_settings_state, fields)
local state = table.copy(level_state)
merge_settings(state, temp_settings_state)
@ -1053,8 +1047,6 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
local bname
if fields.level_wall_select then
bname = "wall"
elseif fields.level_window_select then
bname = "window"
elseif fields.level_ceiling_select then
bname = "ceiling"
elseif fields.level_floor_select then
@ -1085,7 +1077,6 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
local old_level_pos = table.copy(lzr_world.get_level_pos())
local old_level_size = table.copy(lzr_world.get_level_size())
local old_floor = level_state.floor
local old_window = level_state.window
local old_ceiling = level_state.ceiling
local old_wall = level_state.wall
@ -1111,10 +1102,9 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
local rebuild_room, relocate_room = false, false
local nodes = {}
nodes.node_floor = level_state.floor
nodes.node_window = level_state.window
nodes.node_ceiling = level_state.ceiling
nodes.node_wall = level_state.wall
if old_floor ~= nodes.node_floor or old_window ~= nodes.node_window or old_ceiling ~= nodes.node_ceiling or old_wall ~= nodes.node_wall then
if old_floor ~= nodes.node_floor or old_ceiling ~= nodes.node_ceiling or old_wall ~= nodes.node_wall then
for k,v in pairs(nodes) do
if not minetest.registered_nodes[v] then
nodes[k] = lzr_globals.DEFAULT_WALL_NODE
@ -1389,7 +1379,6 @@ minetest.register_chatcommand("editor_clear", {
local size = lzr_world.get_level_size()
local bounding_nodes = {
node_wall = level_state.wall,
node_window = level_state.window,
node_ceiling = level_state.ceiling,
node_floor = level_state.floor,
}

View File

@ -14,11 +14,9 @@ lzr_globals.MIN_LEVEL_SIZE = vector.new(2, 5, 2)
-- Default level size. New level editor levels start with this size
lzr_globals.DEFAULT_LEVEL_SIZE = vector.new(10, 6, 10)
-- Default level boundary: ceiling
lzr_globals.DEFAULT_CEILING_NODE = "lzr_core:wood"
lzr_globals.DEFAULT_CEILING_NODE = "lzr_core:barrier"
-- Default level boundary: wall (the 4 horizontal level boundaries)
lzr_globals.DEFAULT_WALL_NODE = "lzr_core:wood"
-- Default level boundary: window (holes in wall)
lzr_globals.DEFAULT_WINDOW_NODE = "lzr_decor:woodframed_glass"
-- Default level boundary: floor
lzr_globals.DEFAULT_FLOOR_NODE = "lzr_core:wood"
-- Default NPC texts table. The table uses NPC identifiers

View File

@ -7,9 +7,6 @@ lzr_levels = {}
-- the level name and NPC text locale files
local PRINT_TRANSLATABLE_LEVEL_STRINGS = false
local WINDOW_HEIGHT = 3
local WINDOW_DIST = 3
-- Time the level title/complete message is shown (seconds)
local LEVEL_CAPTION_TIME = 3.0
local FINAL_LEVEL_CAPTION_TIME = 5.0
@ -179,7 +176,6 @@ lzr_levels.create_fallback_level_data = function(level, levels_path)
node_wall = lzr_globals.DEFAULT_WALL_NODE,
node_floor = lzr_globals.DEFAULT_FLOOR_NODE,
node_ceiling = lzr_globals.DEFAULT_CEILING_NODE,
node_window = lzr_globals.DEFAULT_WINDOW_NODE,
ambience = lzr_ambience.DEFAULT_AMBIENCE,
sky = lzr_globals.DEFAULT_SKY,
npc_texts = lzr_globals.DEFAULT_NPC_TEXTS,
@ -205,8 +201,9 @@ Syntax of a single record in the CSV file:
<File name>,<Title>,<Border nodes>,<Ambience>,<Sky>,<NPC texts>,<Weather>,<Backdrop>,<Node meta>
Border nodes is a list of nodenames for the level border, separated by the pipe symbol (|), in this order:
wall, window, floor, ceiling
wall, ignored, floor, ceiling
wall is mandatory, the rest is optional (will default to the wall node)
ignored can be any string and will just be ignored (this was the window in old versions)
Ambience is an ambience ID for the background noise (see lzr_ambience).
Sky and weather are IDs for sky and weather (see lzr_sky, lzr_weather).
NPC texts is a *single* text used by NPC like the information block.
@ -272,10 +269,15 @@ lzr_levels.analyze_levels = function(level_list_path, levels_path)
local node_matches = string.split(nodes, "|")
local node_wall = node_matches[1]
local node_window = node_matches[2] or node_wall
local node_legacy_window = node_matches[2]
local node_floor = node_matches[3] or node_wall
local node_ceiling = node_matches[4] or node_wall
table.insert(local_level_data, {filename=filename, name=lname, node_wall=node_wall, node_window=node_window, node_floor=node_floor, node_ceiling=node_ceiling, ambience=ambience, sky=sky, npc_texts=npc_texts, weather=weather, backdrop=backdrop, backdrop_pos=backdrop_pos, triggers=triggers})
-- If the level uses a legacy window, force the ceiling to
-- be a barrier so that light can enter the level
if node_legacy_window == "lzr_decor:woodframed_glass" then
node_ceiling = "lzr_core:barrier"
end
table.insert(local_level_data, {filename=filename, name=lname, node_wall=node_wall, node_floor=node_floor, node_ceiling=node_ceiling, ambience=ambience, sky=sky, npc_texts=npc_texts, weather=weather, backdrop=backdrop, backdrop_pos=backdrop_pos, triggers=triggers})
if PRINT_TRANSLATABLE_LEVEL_STRINGS then
if lname and lname ~= "" then
@ -315,14 +317,9 @@ end
local set_room_nodes = function(pos, size, nodes)
local psize = size
local posses_border = {}
local windows = {}
local posses_floor = {}
local posses_ceiling = {}
local size = vector.add(psize, {x=1,y=1,z=1})
local rotate_windows = false
if minetest.get_item_group(nodes.node_window, "pane") ~= 0 then
rotate_windows = true
end
lzr_world.set_level_size(psize)
for x=0,size.x do
for z=0,size.z do
@ -332,24 +329,6 @@ local set_room_nodes = function(pos, size, nodes)
local lpos = vector.add(pos, offset)
local node = minetest.get_node(lpos)
if node.name == "air" or minetest.get_item_group(node.name, "water") ~= 0 or minetest.get_item_group(node.name, "plant") ~= 0 then
if y == WINDOW_HEIGHT and ((x >= 1 and x < size.x and x % WINDOW_DIST == 0) or (z >= 1 and z < size.z and z % WINDOW_DIST == 0)) then
-- Set param2 if the window node is a pane
if rotate_windows then
local param2 = 0
if (z == 0) then
param2 = 2
elseif (z == size.z) then
param2 = 0
elseif (x == 0) then
param2 = 3
elseif (x == size.x) then
param2 = 1
end
table.insert(windows, { pos = lpos, param2 = param2 })
else
table.insert(windows, lpos)
end
else
if y == 0 then
table.insert(posses_floor, lpos)
elseif y == size.y then
@ -362,18 +341,9 @@ local set_room_nodes = function(pos, size, nodes)
end
end
end
end
minetest.bulk_set_node(posses_floor, {name=nodes.node_floor})
minetest.bulk_set_node(posses_border, {name=nodes.node_wall})
minetest.bulk_set_node(posses_ceiling, {name=nodes.node_ceiling})
if rotate_windows then
-- Set windows individually because their param2 differs
for w=1, #windows do
minetest.set_node(windows[w].pos, {name=nodes.node_window, param2=windows[w].param2})
end
else
minetest.bulk_set_node(windows, {name=nodes.node_window})
end
end
local get_singleplayer = function()
@ -661,7 +631,7 @@ end
-- - level: level ID (for builtin level)
-- - schematic: Path to schematic
-- - nodes (optional): Table containing node names of level border nodes:
-- - node_floor, node_ceiling, node_wall, node_window
-- - node_floor, node_ceiling, node_wall
function lzr_levels.build_room(room_data)
lzr_laser.clear_out_of_bounds_lasers()
if not room_data.nodes then
@ -669,7 +639,6 @@ function lzr_levels.build_room(room_data)
node_floor = lzr_globals.DEFAULT_FLOOR_NODE,
node_wall = lzr_globals.DEFAULT_WALL_NODE,
node_ceiling = lzr_globals.DEFAULT_CEILING_NODE,
node_window = lzr_globals.DEFAULT_WINDOW_NODE,
}
end
prepare_room(room_data)
@ -689,7 +658,6 @@ function lzr_levels.prepare_and_build_level(level, level_data, spawn_pos, yaw, o
node_floor = level_data[level].node_floor,
node_wall = level_data[level].node_wall,
node_ceiling = level_data[level].node_ceiling,
node_window = level_data[level].node_window,
}
local lpos
if level_data[level].backdrop == "ocean" then