From 6e8d9ab4198c4ebcc38411bd16c24e651bb35bab Mon Sep 17 00:00:00 2001 From: Wuzzy Date: Sun, 15 Dec 2024 14:20:32 +0100 Subject: [PATCH] Add warnings for bad doors in level --- GROUPS.md | 5 +++ mods/lzr_doors/init.lua | 4 +++ mods/lzr_editor/init.lua | 72 +++++++++++++++++++++++++++++++++++++++- 3 files changed, 80 insertions(+), 1 deletion(-) diff --git a/GROUPS.md b/GROUPS.md index b94fb039..ce950049 100644 --- a/GROUPS.md +++ b/GROUPS.md @@ -101,6 +101,11 @@ a special event to happen. * `water=3`: Water * `liquid=3`: Node is a liquid in a semantic sense * `pane=1`: Pane (flat window-like block) +* `door`: Door segment + * `1`: Bottom segment + * `2`: Top segment +* `door_exit=1`: Exit door segment +* `door_locked=1`: Locked door segment * `stair`: Stair * `1`: Normal stair * `2`: Inner stair diff --git a/mods/lzr_doors/init.lua b/mods/lzr_doors/init.lua index f0f5a3c5..9a2660e1 100644 --- a/mods/lzr_doors/init.lua +++ b/mods/lzr_doors/init.lua @@ -78,6 +78,7 @@ lzr_doors.register_door = function(basename, modname, def) sounds = def.sounds or lzr_sounds.node_sound_wood_defaults(), element_group = "laser_element_door_"..basename.."_exit_top", on_punch = on_punch_exit, + groups = { door = 2, door_exit = 1 }, }) lzr_panes.register_pane(modname..":door_"..basename.."_exit_bottom", { description = S("@1 (bottom segment, exit)", def.base_description), @@ -88,6 +89,7 @@ lzr_doors.register_door = function(basename, modname, def) sounds = lzr_sounds.node_sound_wood_defaults(), element_group = "laser_element_door_"..basename.."_exit_bottom", on_punch = on_punch_exit, + groups = { door = 1, door_exit = 1 }, }) lzr_panes.register_pane(modname..":door_"..basename.."_locked_top", { @@ -99,6 +101,7 @@ lzr_doors.register_door = function(basename, modname, def) sounds = def.sounds or lzr_sounds.node_sound_wood_defaults(), element_group = "laser_element_door_"..basename.."_locked_top", on_punch = on_punch_locked, + groups = { door = 2, door_locked = 1 }, }) lzr_panes.register_pane(modname..":door_"..basename.."_locked_bottom", { description = S("@1 (bottom segment, locked)", def.base_description), @@ -109,6 +112,7 @@ lzr_doors.register_door = function(basename, modname, def) sounds = lzr_sounds.node_sound_wood_defaults(), element_group = "laser_element_door_"..basename.."_locked_bottom", on_punch = on_punch_locked, + groups = { door = 1, door_locked = 1 }, }) end diff --git a/mods/lzr_editor/init.lua b/mods/lzr_editor/init.lua index 67b6e12e..f52fe906 100644 --- a/mods/lzr_editor/init.lua +++ b/mods/lzr_editor/init.lua @@ -85,11 +85,18 @@ local error_warning_texts = { plant_on_ground = S("Rooted plant in level area"), too_many_parrot_spawners = S("More than one parrot spawner"), too_many_hidden_parrot_spawners = S("More than one hidden parrot spawner"), - bad_hidden_parrot_spawner = S("Bad param2 for hidden parrot spawner"), + --~ param2 is an internal value used by blocks to store some state + bad_hidden_parrot_spawner = S("Bad param2 value for hidden parrot spawner"), trigger_out_of_bounds = S("Trigger is out of bounds"), trigger_moved = S("Trigger ID does not match location"), laser_incompatible = S("Laser-incompatible node found"), no_treasures = S("No treasures to collect"), + --~ Warning shown when a level has an incomplete door + half_door = S("Incomplete door"), + --~ Warning shown when a level has an invalid door. param2 is an internal value used by blocks to store some state + incompatible_door_segments_param2 = S("Mismatching param2 value for door segments"), + --~ Warning shown when a level has an invalid door + incompatible_door_segments_type = S("Mismatching type for door segments"), } -- Add error messages from lzr_triggers as well for id, text in pairs(lzr_triggers.CHECK_ERROR_TEXTS) do @@ -858,6 +865,20 @@ lzr_editor.check_level_errors = function() end end + local hidden_parrot_spawners = minetest.find_nodes_in_area(minpos, maxpos, "lzr_parrot_npc:hidden_parrot_spawner") + if #hidden_parrot_spawners > 1 then + table.insert(errors, "too_many_hidden_parrot_spawners") + end + for h=1, #hidden_parrot_spawners do + local node = minetest.get_node(hidden_parrot_spawners[h]) + local num = (node.param2 % 4) + 1 + local parrot_name = lzr_parrot_npc.get_hidden_parrot_name(num) + if not parrot_name then + table.insert(errors, "bad_hidden_parrot_spawner") + break + end + end + -- Test: Trigger validity check from lzr_triggers local trigger_check_ok, trigger_errors = lzr_triggers.check_triggers(true) if not trigger_check_ok then @@ -902,6 +923,55 @@ lzr_editor.check_level_warnings = function() table.insert(warnings, "laser_incompatible") end + -- Test: Incompatible door segments + local doors = minetest.find_nodes_in_area(minpos, maxpos, "group:door") + if #doors > 0 then + local half_door, inc_p2, inc_type = false, false, false + for d=1, #doors do + local dpos = doors[d] + local dnode = minetest.get_node(dpos) + local ddir = minetest.facedir_to_dir(dnode.param2) + -- Only test upright door segments. Door segments that lie flat + -- don't trigger warnings. + if ddir.y == 0 then + local altpos + local g = minetest.get_item_group(dnode.name, "door") + if g == 1 then + altpos = vector.offset(dpos, 0, 1, 0) + elseif g == 2 then + altpos = vector.offset(dpos, 0, -1, 0) + else + minetest.log("error", "[lzr_editor] Door node '"..dnode.name.."' has bad door group rating: "..g) + break + end + local altnode = minetest.get_node(altpos) + local ga = minetest.get_item_group(altnode.name, "door") + if ga == 0 then + half_door = true + elseif altnode.param2 ~= dnode.param2 then + inc_p2 = true + else + local g_exit = minetest.get_item_group(dnode.name, "door_exit") + local ga_exit = minetest.get_item_group(altnode.name, "door_exit") + local g_locked = minetest.get_item_group(dnode.name, "door_locked") + local ga_locked = minetest.get_item_group(altnode.name, "door_locked") + if g_exit ~= ga_exit or g_locked ~= ga_locked then + inc_type = true + end + end + end + end + if half_door then + table.insert(warnings, "half_door") + end + if inc_p2 then + table.insert(warnings, "incompatible_door_segments_param2") + end + if inc_type then + table.insert(warnings, "incompatible_door_segments_type") + end + end + -- Test: No treasures to collect (should have at least 1). -- The level is still playable, but it will be an instant win. local no_treasures = true