Use VManip for laser update
parent
1138bc4eb8
commit
5f65950bf4
|
@ -1,7 +1,7 @@
|
||||||
lzr_globals = {}
|
lzr_globals = {}
|
||||||
|
|
||||||
lzr_globals.PLAYFIELD_START = { x = -50, y = 0, z = -50 }
|
lzr_globals.PLAYFIELD_START = { x = -5, y = 0, z = -5 }
|
||||||
lzr_globals.PLAYFIELD_SIZE = { x = 100, y = 100, z = 100 }
|
lzr_globals.PLAYFIELD_SIZE = { x = 20, y = 20, z = 20 }
|
||||||
lzr_globals.PLAYFIELD_END = vector.add(lzr_globals.PLAYFIELD_START, lzr_globals.PLAYFIELD_SIZE)
|
lzr_globals.PLAYFIELD_END = vector.add(lzr_globals.PLAYFIELD_START, lzr_globals.PLAYFIELD_SIZE)
|
||||||
lzr_globals.LEVEL_POS = { x = 0, y = 0, z = 0 }
|
lzr_globals.LEVEL_POS = { x = 0, y = 0, z = 0 }
|
||||||
lzr_globals.MENU_SHIP_POS = { x = -500, y = -4, z = -500 }
|
lzr_globals.MENU_SHIP_POS = { x = -500, y = -4, z = -500 }
|
||||||
|
|
|
@ -3,44 +3,46 @@ local MAX_LASER_ITERATIONS = 10000
|
||||||
|
|
||||||
-- Add a laser node to pos with the direction `dir`.
|
-- Add a laser node to pos with the direction `dir`.
|
||||||
-- Dir is a direction vector, and only one direction must be set
|
-- Dir is a direction vector, and only one direction must be set
|
||||||
function lzr_laser.add_laser(pos, dir)
|
function lzr_laser.add_laser(pos, dir, varea, vdata)
|
||||||
-- Check if laser is still within the playfield
|
-- Check if laser is still within the playfield
|
||||||
if pos.x < lzr_globals.PLAYFIELD_START.x or pos.x > lzr_globals.PLAYFIELD_END.x or
|
if pos.x < lzr_globals.PLAYFIELD_START.x or pos.x > lzr_globals.PLAYFIELD_END.x or
|
||||||
pos.y < lzr_globals.PLAYFIELD_START.y or pos.y > lzr_globals.PLAYFIELD_END.y or
|
pos.y < lzr_globals.PLAYFIELD_START.y or pos.y > lzr_globals.PLAYFIELD_END.y or
|
||||||
pos.z < lzr_globals.PLAYFIELD_START.z or pos.z > lzr_globals.PLAYFIELD_END.z then
|
pos.z < lzr_globals.PLAYFIELD_START.z or pos.z > lzr_globals.PLAYFIELD_END.z then
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
local node = minetest.get_node(pos)
|
local vi = varea:indexp(pos)
|
||||||
|
local content_id = vdata[vi]
|
||||||
|
local nodename = minetest.get_name_from_content_id(content_id)
|
||||||
-- Laser through air
|
-- Laser through air
|
||||||
if node.name == "air" then
|
if content_id == minetest.CONTENT_AIR then
|
||||||
local dirs = lzr_laser.vector_to_dirs(dir)
|
local dirs = lzr_laser.vector_to_dirs(dir)
|
||||||
local dirstring = lzr_laser.dirs_to_dirstring(dirs)
|
local dirstring = lzr_laser.dirs_to_dirstring(dirs)
|
||||||
minetest.set_node(pos, {name="lzr_laser:laser_"..dirstring})
|
vdata[vi] = minetest.get_content_id("lzr_laser:laser_"..dirstring)
|
||||||
pos = vector.add(pos, dir)
|
pos = vector.add(pos, dir)
|
||||||
return {{pos, dir}}
|
return {{pos, dir}}
|
||||||
-- Laser through laser (laser intersection)
|
-- Laser through laser (laser intersection)
|
||||||
elseif minetest.get_item_group(node.name, "laser") > 0 then
|
elseif minetest.get_item_group(nodename, "laser") > 0 then
|
||||||
local dirnum = minetest.get_item_group(node.name, "laser")
|
local dirnum = minetest.get_item_group(nodename, "laser")
|
||||||
local dirstring_old = lzr_laser.dec2bin(dirnum, 3)
|
local dirstring_old = lzr_laser.dec2bin(dirnum, 3)
|
||||||
|
|
||||||
local dirs_new = lzr_laser.vector_to_dirs(dir)
|
local dirs_new = lzr_laser.vector_to_dirs(dir)
|
||||||
local dirstring_new = lzr_laser.dirs_to_dirstring(dirs_new)
|
local dirstring_new = lzr_laser.dirs_to_dirstring(dirs_new)
|
||||||
|
|
||||||
local place_dirstring = lzr_laser.bitwise_or(dirstring_old, dirstring_new)
|
local place_dirstring = lzr_laser.bitwise_or(dirstring_old, dirstring_new)
|
||||||
minetest.set_node(pos, {name="lzr_laser:laser_"..place_dirstring})
|
vdata[vi] = minetest.get_content_id("lzr_laser:laser_"..place_dirstring)
|
||||||
pos = vector.add(pos, dir)
|
pos = vector.add(pos, dir)
|
||||||
return {{pos, dir}}
|
return {{pos, dir}}
|
||||||
-- Mirror laser
|
-- Mirror laser
|
||||||
elseif minetest.get_item_group(node.name, "mirror") > 0 then
|
elseif minetest.get_item_group(nodename, "mirror") > 0 then
|
||||||
local mirror_dir = lzr_laser.get_mirrored_laser_dir(pos, dir)
|
local mirror_dir = lzr_laser.get_mirrored_laser_dir(pos, dir)
|
||||||
if mirror_dir then
|
if mirror_dir then
|
||||||
local def = minetest.registered_nodes[node.name]
|
local def = minetest.registered_nodes[nodename]
|
||||||
local active = def._lzr_active
|
local active = def._lzr_active
|
||||||
if not active then
|
if not active then
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
-- Activate mirror node
|
-- Activate mirror node
|
||||||
minetest.set_node(pos, {name=def._lzr_active, param2 = node.param2})
|
vdata[vi] = minetest.get_content_id(def._lzr_active)
|
||||||
-- Set new pos and dir
|
-- Set new pos and dir
|
||||||
pos = vector.add(pos, mirror_dir)
|
pos = vector.add(pos, mirror_dir)
|
||||||
dir = mirror_dir
|
dir = mirror_dir
|
||||||
|
@ -49,16 +51,16 @@ function lzr_laser.add_laser(pos, dir)
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
-- Mirror and split laser
|
-- Mirror and split laser
|
||||||
elseif minetest.get_item_group(node.name, "transmissive_mirror") > 0 then
|
elseif minetest.get_item_group(nodename, "transmissive_mirror") > 0 then
|
||||||
local mirror_dir = lzr_laser.get_mirrored_laser_dir(pos, dir)
|
local mirror_dir = lzr_laser.get_mirrored_laser_dir(pos, dir)
|
||||||
if mirror_dir then
|
if mirror_dir then
|
||||||
local def = minetest.registered_nodes[node.name]
|
local def = minetest.registered_nodes[nodename]
|
||||||
local active = def._lzr_active
|
local active = def._lzr_active
|
||||||
if not active then
|
if not active then
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
-- Activate mirror node
|
-- Activate mirror node
|
||||||
minetest.set_node(pos, {name=active, param2 = node.param2})
|
vdata[vi] = minetest.get_content_id(active)
|
||||||
-- Set new pos and dir
|
-- Set new pos and dir
|
||||||
local pos_straight = vector.add(pos, dir)
|
local pos_straight = vector.add(pos, dir)
|
||||||
local dir_straight = dir
|
local dir_straight = dir
|
||||||
|
@ -69,14 +71,14 @@ function lzr_laser.add_laser(pos, dir)
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
-- Spread laser to all directions
|
-- Spread laser to all directions
|
||||||
elseif minetest.get_item_group(node.name, "crystal") > 0 then
|
elseif minetest.get_item_group(nodename, "crystal") > 0 then
|
||||||
local def = minetest.registered_nodes[node.name]
|
local def = minetest.registered_nodes[nodename]
|
||||||
local active = def._lzr_active
|
local active = def._lzr_active
|
||||||
if not active then
|
if not active then
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
-- Activate node
|
-- Activate node
|
||||||
minetest.set_node(pos, {name=active, param2 = node.param2})
|
vdata[vi] = minetest.get_content_id(active)
|
||||||
-- Set dirs
|
-- Set dirs
|
||||||
local dirs = {
|
local dirs = {
|
||||||
{ x = 0, y = -1, z = 0 },
|
{ x = 0, y = -1, z = 0 },
|
||||||
|
@ -98,13 +100,13 @@ function lzr_laser.add_laser(pos, dir)
|
||||||
end
|
end
|
||||||
return output
|
return output
|
||||||
-- Detector
|
-- Detector
|
||||||
elseif minetest.get_item_group(node.name, "detector") > 0 then
|
elseif minetest.get_item_group(nodename, "detector") > 0 then
|
||||||
local detected = lzr_laser.check_detector(pos, dir)
|
local detected = lzr_laser.check_detector(pos, dir)
|
||||||
if detected then
|
if detected then
|
||||||
local def = minetest.registered_nodes[node.name]
|
local def = minetest.registered_nodes[nodename]
|
||||||
local active = def._lzr_active
|
local active = def._lzr_active
|
||||||
-- Activate node
|
-- Activate node
|
||||||
minetest.set_node(pos, {name=active, param2 = node.param2})
|
vdata[vi] = minetest.get_content_id(active)
|
||||||
local done = lzr_laser.check_detectors_in_area(lzr_globals.PLAYFIELD_START, lzr_globals.PLAYFIELD_END)
|
local done = lzr_laser.check_detectors_in_area(lzr_globals.PLAYFIELD_START, lzr_globals.PLAYFIELD_END)
|
||||||
if done then
|
if done then
|
||||||
lzr_levels.next_level()
|
lzr_levels.next_level()
|
||||||
|
@ -118,19 +120,24 @@ function lzr_laser.add_laser(pos, dir)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function lzr_laser.emit_laser(pos)
|
function lzr_laser.emit_laser(pos, varea, vdata, vdata_p2)
|
||||||
local node = minetest.get_node(pos)
|
local vi = varea:indexp(pos)
|
||||||
if minetest.get_item_group(node.name, "emitter") == 0 then
|
local content_id = vdata[vi]
|
||||||
|
local nodename = minetest.get_name_from_content_id(content_id)
|
||||||
|
if minetest.get_item_group(nodename, "emitter") == 0 then
|
||||||
minetest.log("error", "[lzr_laser] lzr_laser.emit_laser was called at invalid pos!")
|
minetest.log("error", "[lzr_laser] lzr_laser.emit_laser was called at invalid pos!")
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
local dir = minetest.facedir_to_dir(node.param2)
|
local param2 = vdata_p2[vi]
|
||||||
|
|
||||||
|
local dir = minetest.facedir_to_dir(param2)
|
||||||
dir = vector.multiply(dir, -1)
|
dir = vector.multiply(dir, -1)
|
||||||
local i_pos = vector.add(pos, dir)
|
local i_pos = vector.add(pos, dir)
|
||||||
lzr_laser.travel_laser(i_pos, dir)
|
lzr_laser.travel_laser(i_pos, dir, varea, vdata)
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function lzr_laser.travel_laser(pos, dir)
|
function lzr_laser.travel_laser(pos, dir, varea, vdata)
|
||||||
local i_pos = table.copy(pos)
|
local i_pos = table.copy(pos)
|
||||||
local cond = true
|
local cond = true
|
||||||
local next_lasers = {{i_pos, dir}}
|
local next_lasers = {{i_pos, dir}}
|
||||||
|
@ -143,7 +150,7 @@ function lzr_laser.travel_laser(pos, dir)
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
local next_laser = next_lasers[1]
|
local next_laser = next_lasers[1]
|
||||||
local add_laser_result = lzr_laser.add_laser(next_laser[1], next_laser[2])
|
local add_laser_result = lzr_laser.add_laser(next_laser[1], next_laser[2], varea, vdata)
|
||||||
table.remove(next_lasers, 1)
|
table.remove(next_lasers, 1)
|
||||||
if add_laser_result ~= false then
|
if add_laser_result ~= false then
|
||||||
for a=1, #add_laser_result do
|
for a=1, #add_laser_result do
|
||||||
|
@ -183,15 +190,26 @@ end
|
||||||
|
|
||||||
-- Emit lasers from all active emitters
|
-- Emit lasers from all active emitters
|
||||||
function lzr_laser.emit_lasers_in_area(pos1, pos2)
|
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()
|
||||||
local emitters = minetest.find_nodes_in_area(pos1, pos2, {"group:emitter"})
|
local emitters = minetest.find_nodes_in_area(pos1, pos2, {"group:emitter"})
|
||||||
for e=1, #emitters do
|
for e=1, #emitters do
|
||||||
local epos = emitters[e]
|
local epos = emitters[e]
|
||||||
local emitter = minetest.get_node(epos)
|
local vi = varea:indexp(epos)
|
||||||
local is_active = minetest.get_item_group(emitter.name, "emitter") == 2
|
local emitter_cid = vdata[vi]
|
||||||
|
local emittername = minetest.get_name_from_content_id(emitter_cid)
|
||||||
|
local is_active = minetest.get_item_group(emittername, "emitter") == 2
|
||||||
if is_active then
|
if is_active then
|
||||||
lzr_laser.emit_laser(emitters[e])
|
lzr_laser.emit_laser(emitters[e], varea, vdata, vdata_p2)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
vmanip:set_data(vdata)
|
||||||
|
vmanip:set_param2_data(vdata_p2)
|
||||||
|
vmanip:write_to_map()
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Return true if all detectors in area are on (including if no detector)
|
-- Return true if all detectors in area are on (including if no detector)
|
||||||
|
|
Loading…
Reference in New Issue