From e222d6d7327f26b8c9bc28d252344f39ce63905e Mon Sep 17 00:00:00 2001 From: Wuzzy Date: Mon, 14 Mar 2022 02:14:55 +0100 Subject: [PATCH] Implement new transmissive mirror physics (WIP) --- mods/lzr_laser/blocks.lua | 55 +++++++++++++++++++++++++++++++------- mods/lzr_laser/physics.lua | 24 ++++++++++++++--- 2 files changed, 65 insertions(+), 14 deletions(-) diff --git a/mods/lzr_laser/blocks.lua b/mods/lzr_laser/blocks.lua index c866cba..29a303a 100644 --- a/mods/lzr_laser/blocks.lua +++ b/mods/lzr_laser/blocks.lua @@ -80,7 +80,14 @@ end -- Mirror a laser that touches a mirror at mirror_pos with a laser coming towards -- the mirror with the laser_dir direction (direction vector). --- Returns the "output direction" of the laser or false if can't get mirrored. +-- Returns , +-- 1) If the laser can be mirrored, then is the direction of +-- the mirrored laser and denotes on of the 2 possible +-- sides the laser came from: true if it came in the front side, false if +-- it came from the angled side. is useful for the +-- transmissive mirror. +-- 2) If the laser cannot be mirrored is false and +-- is nil lzr_laser.get_mirrored_laser_dir = function(mirror_pos, laser_dir) local mirror = minetest.get_node(mirror_pos) local mirror_group = minetest.get_item_group(mirror.name, "mirror") @@ -94,9 +101,9 @@ lzr_laser.get_mirrored_laser_dir = function(mirror_pos, laser_dir) return false end if vector.equals(reverse_laser_dir, mirror_dir_in) then - return mirror_dir_out + return mirror_dir_out, true elseif vector.equals(reverse_laser_dir, mirror_dir_out) then - return mirror_dir_in + return mirror_dir_in, false end return false end @@ -201,6 +208,9 @@ local register_element = function(subname, def, options) if options.not_walkable_if_off then def_core.walkable = false end + if options.allow_take then + def_core._lzr_takable = "lzr_laser:"..subname.."_takable" + end def_core.description = S("@1 (fixed)", def.description) def_core.after_dig_node = full_update @@ -214,7 +224,13 @@ local register_element = function(subname, def, options) def_core.groups = {} end def_core.groups.breakable = 1 - def_core.groups[subname] = 1 + local groupname + if options.group then + groupname = options.group + else + groupname = subname + end + def_core.groups[groupname] = 1 def_core.can_dig = element_can_dig def_core.on_place = element_on_place @@ -237,7 +253,10 @@ local register_element = function(subname, def, options) if not options.keep_state_on_take then def_core_on.drop = "lzr_laser:"..subname end - def_core_on.groups[subname] = 2 + if options.allow_take then + def_core_on._lzr_takable = "lzr_laser:"..subname.."_takable_on" + end + def_core_on.groups[groupname] = 2 def_core_on.light_source = def.light_source_on minetest.register_node("lzr_laser:"..subname.."_on", def_core_on) end @@ -246,12 +265,14 @@ local register_element = function(subname, def, options) local def_takable = table.copy(def_core) def_takable.tiles = def.tiles_takable_off def_takable.groups.takable = 1 + def_takable._lzr_untakable = "lzr_laser:"..subname def_takable.description = def.description minetest.register_node("lzr_laser:"..subname.."_takable", def_takable) if options.activate ~= false then def_takable._lzr_active = "lzr_laser:"..subname.."_takable_on" local def_takable_on = table.copy(def_core_on) + def_takable_on._lzr_untakable = "lzr_laser:"..subname.."_on" def_takable_on.tiles = def.tiles_takable_on def_takable_on.light_source = def.light_source_on def_takable_on.groups.takable = 1 @@ -326,10 +347,15 @@ local tm_def = { groups = { rotatable = 1, laser_block = 1 }, sounds = lzr_sounds.node_sound_glass_defaults({ _rotate = {name = "lzr_laser_mirror_rotate", gain = 1.0}, - }) + }), + _lzr_transmissive_mirror_00 = "lzr_laser:transmissive_mirror_00", + _lzr_transmissive_mirror_01 = "lzr_laser:transmissive_mirror_01", + _lzr_transmissive_mirror_10 = "lzr_laser:transmissive_mirror_10", + _lzr_transmissive_mirror_11 = "lzr_laser:transmissive_mirror_11", } local tm_def_off = table.copy(tm_def) +tm_def_off._lzr_transmissive_mirror_state = "00" tm_def_off.tiles_off = { {name="lzr_laser_transmissive_mirror_block.png^lzr_laser_fixed.png", backface_culling=true}, {name="lzr_laser_transmissive_mirror_mirror.png", backface_culling=true}, @@ -341,8 +367,14 @@ tm_def_off.tiles_takable_off = { {name="lzr_laser_transmissive_mirror_mirror_out.png", backface_culling=true}, } tm_def_off.mesh_off = "lzr_laser_mirror.obj" +-- Use custom fields to identify transmissive mirror states + +-- Transmissive Mirror +-- FIXME: Takable Transmissive Mirror becomes fixed after full laser update local tm_def_on_01 = table.copy(tm_def) +tm_def_on_01._lzr_transmissive_mirror_state = "01" +tm_def_on_01._lzr_inactive = "lzr_laser:transmissive_mirror_00" tm_def_on_01.description = S("Transmissive Mirror (active, 01)") tm_def_on_01.tiles_off = { {name="lzr_laser_laser_full.png", backface_culling=true}, @@ -359,17 +391,20 @@ tm_def_on_01.tiles_takable_off = { tm_def_on_01.mesh_off = "lzr_laser_mirror_on_thru1.obj" local tm_def_on_10 = table.copy(tm_def_on_01) +tm_def_on_10._lzr_transmissive_mirror_state = "10" tm_def_on_10.description = S("Transmissive Mirror (active, 10)") tm_def_on_10.mesh_off = "lzr_laser_mirror_on_thru2.obj" local tm_def_on_11 = table.copy(tm_def_on_01) +tm_def_on_11._lzr_transmissive_mirror_state = "11" tm_def_on_11.description = S("Transmissive Mirror (active, 11)") tm_def_on_11.mesh_off = "lzr_laser_mirror_on_thru3.obj" -register_element("transmissive_mirror", tm_def_off, { allow_take = true, activate = false }) -register_element("transmissive_mirror_on_01", tm_def_on_01, { allow_take = true, activate = false }) -register_element("transmissive_mirror_on_10", tm_def_on_10, { allow_take = true, activate = false }) -register_element("transmissive_mirror_on_11", tm_def_on_11, { allow_take = true, activate = false }) +local tm_options = { allow_take = true, activate = false, group = "transmissive_mirror" } +register_element("transmissive_mirror_00", tm_def_off, tm_options) +register_element("transmissive_mirror_01", tm_def_on_01, tm_options) +register_element("transmissive_mirror_10", tm_def_on_10, tm_options) +register_element("transmissive_mirror_11", tm_def_on_11, tm_options) register_element("crystal", { description = S("Crystal"), diff --git a/mods/lzr_laser/physics.lua b/mods/lzr_laser/physics.lua index 04a6213..890c872 100644 --- a/mods/lzr_laser/physics.lua +++ b/mods/lzr_laser/physics.lua @@ -83,14 +83,30 @@ function lzr_laser.add_laser(pos, dir, varea, vdata) end -- Mirror and split laser elseif minetest.get_item_group(nodename, "transmissive_mirror") > 0 then - local mirror_dir = lzr_laser.get_mirrored_laser_dir(pos, dir) + local mirror_dir, mirror_side = lzr_laser.get_mirrored_laser_dir(pos, dir) if mirror_dir then local def = minetest.registered_nodes[nodename] - local active = def._lzr_active - if not active then + local state = def._lzr_transmissive_mirror_state + if not state then + minetest.log("error", "[lzr_laser] Transmissive mirror node '"..nodename.."' does not have _lzr_transmissive_mirror_state!") return false end - -- Activate mirror node + if mirror_side == true then + state = lzr_laser.bitwise_or(state, "01") + else + state = lzr_laser.bitwise_or(state, "10") + end + local active = def["_lzr_transmissive_mirror_"..state] + if not active then + minetest.log("error", "[lzr_laser] Missing transmissive mirror node state for '"..nodename.."!") + return false + end + local is_takable = minetest.get_item_group(nodename, "takable") ~= 0 + if is_takable then + local def_active = minetest.registered_nodes[active] + active = def_active._lzr_takable + end + -- Set new transmissive node state vdata[vi] = minetest.get_content_id(active) -- Set new pos and dir local pos_straight = vector.add(pos, dir)