diff --git a/mods/lzr_laser/physics.lua b/mods/lzr_laser/physics.lua index f1ad9fe..4d86cff 100644 --- a/mods/lzr_laser/physics.lua +++ b/mods/lzr_laser/physics.lua @@ -105,11 +105,13 @@ function lzr_laser.add_laser(pos, dir, varea, vdata) if detected then local def = minetest.registered_nodes[nodename] local active = def._lzr_active - -- Activate node - vdata[vi] = minetest.get_content_id(active) - local done = lzr_laser.check_detectors_in_area(lzr_globals.PLAYFIELD_START, lzr_globals.PLAYFIELD_END) - if done then - lzr_levels.next_level() + if active then + -- Activate node + vdata[vi] = minetest.get_content_id(active) + local done = lzr_laser.check_detectors_in_area(lzr_globals.PLAYFIELD_START, lzr_globals.PLAYFIELD_END) + if done then + lzr_levels.next_level() + end end end -- Laser ends here @@ -164,37 +166,30 @@ function lzr_laser.travel_laser(pos, dir, varea, vdata) end -- Remove all lasers in area and disable all laser blocks -function lzr_laser.clear_lasers_in_area(pos1, pos2, ignore_emitters) - -- Remove lasers - local lasers = minetest.find_nodes_in_area(pos1, pos2, {"group:laser"}) - minetest.bulk_set_node(lasers, {name="air"}) - - -- Disable laser blocks (mirror, etc.) - local laser_blocks = minetest.find_nodes_in_area(pos1, pos2, {"group:laser_block"}) - for b=1, #laser_blocks do - local block_pos = laser_blocks[b] - local block = minetest.get_node(block_pos) - local def = minetest.registered_nodes[block.name] - local is_ignored_emitter = false - if ignore_emitters ~= true then - is_ignored_emitter = minetest.get_item_group(block.name, "emitter") > 0 - end - if def and not is_ignored_emitter then - local inactive = def._lzr_inactive - if inactive then - minetest.set_node(block_pos, {name=inactive, param2=block.param2}) +function lzr_laser.clear_lasers_in_area(pos1, pos2, ignore_emitters, varea, vdata) + for vi=1, #vdata do + local cid = vdata[vi] + local nodename = minetest.get_name_from_content_id(cid) + if minetest.get_item_group(nodename, "laser") ~= 0 then + vdata[vi] = minetest.CONTENT_AIR + elseif minetest.get_item_group(nodename, "laser_block") ~= 0 then + local def = minetest.registered_nodes[nodename] + local is_ignored_emitter = false + if ignore_emitters ~= true then + is_ignored_emitter = minetest.get_item_group(nodename, "emitter") > 0 + end + if def and not is_ignored_emitter then + local inactive = def._lzr_inactive + if inactive then + vdata[vi] = minetest.get_content_id(inactive) + end end end end end -- Emit lasers from all active emitters -function lzr_laser.emit_lasers_in_area(pos1, pos2) - local vmanip = minetest.get_voxel_manip(pos1, pos2) - local vpos1, vpos2 = vmanip:get_emerged_area() - local varea = VoxelArea:new({MinEdge = vpos1, MaxEdge = vpos2}) - local vdata = vmanip:get_data() - local vdata_p2 = vmanip:get_param2_data() +function lzr_laser.emit_lasers_in_area(pos1, pos2, varea, vdata, vdata_p2) local emitters = minetest.find_nodes_in_area(pos1, pos2, {"group:emitter"}) for e=1, #emitters do local epos = emitters[e] @@ -206,10 +201,6 @@ function lzr_laser.emit_lasers_in_area(pos1, pos2) lzr_laser.emit_laser(emitters[e], varea, vdata, vdata_p2) end end - - vmanip:set_data(vdata) - vmanip:set_param2_data(vdata_p2) - vmanip:write_to_map() end -- Return true if all detectors in area are on (including if no detector) @@ -228,6 +219,16 @@ end -- Completely recalculate all lasers function lzr_laser.full_laser_update(pos1, pos2) - lzr_laser.clear_lasers_in_area(pos1, pos2) - lzr_laser.emit_lasers_in_area(pos1, pos2) + local vmanip = minetest.get_voxel_manip(pos1, pos2) + local vpos1, vpos2 = vmanip:get_emerged_area() + local varea = VoxelArea:new({MinEdge = vpos1, MaxEdge = vpos2}) + local vdata = vmanip:get_data() + local vdata_p2 = vmanip:get_param2_data() + + lzr_laser.clear_lasers_in_area(pos1, pos2, nil, varea, vdata) + lzr_laser.emit_lasers_in_area(pos1, pos2, varea, vdata, vdata_p2) + + vmanip:set_data(vdata) + vmanip:set_param2_data(vdata_p2) + vmanip:write_to_map() end