Add takable detectors

master
Wuzzy 2022-01-09 00:56:44 +01:00
parent 33dcc0dc76
commit 9046210545
2 changed files with 67 additions and 9 deletions

View File

@ -95,6 +95,22 @@ end
-- Update the whole playfield after placing or digging a laser node
local full_update = function()
lzr_laser.full_laser_update(lzr_globals.PLAYFIELD_START, lzr_globals.PLAYFIELD_END)
local done = lzr_laser.check_level_won()
if done then
lzr_levels.next_level()
end
end
-- Same as above, but special case after a detector was placed.
-- This is hack to tell check_level_won that there one detector in the player
-- inventory has to be ignored because after_dig_node is called BEFORE
-- the inventory change after placing the node.
local full_update_detector_placed = function()
lzr_laser.full_laser_update(lzr_globals.PLAYFIELD_START, lzr_globals.PLAYFIELD_END)
local done = lzr_laser.check_level_won(true)
if done then
lzr_levels.next_level()
end
end
local after_rotate = function()
@ -103,7 +119,11 @@ end
local register_element = function(subname, def, options)
local def_core = table.copy(def)
def_core.after_place_node = full_update
if options.is_detector then
def_core.after_place_node = full_update_detector_placed
else
def_core.after_place_node = full_update
end
def_core.after_dig_node = full_update
def_core._after_rotate = after_rotate
def_core._lzr_active = "lzr_laser:"..subname.."_on"
@ -302,7 +322,7 @@ register_element("emitter", {
nname = "lzr_laser:emitter_takable"
end
minetest.swap_node(pos, {name=nname, param2=node.param2})
lzr_laser.full_laser_update(lzr_globals.PLAYFIELD_START, lzr_globals.PLAYFIELD_END)
full_update()
end,
groups = { laser_block = 1 },
sounds = lzr_sounds.node_sound_wood_defaults(),
@ -312,6 +332,22 @@ register_element("detector", {
description = S("Detector"),
paramtype2 = "facedir",
tiles_off = {
"lzr_laser_detector.png^lzr_laser_fixed.png",
"lzr_laser_detector.png^lzr_laser_fixed.png",
"lzr_laser_detector.png^lzr_laser_fixed.png",
"lzr_laser_detector.png^lzr_laser_fixed.png",
"lzr_laser_detector.png^lzr_laser_fixed.png",
"lzr_laser_detector_front.png^lzr_laser_fixed.png",
},
tiles_on = {
"lzr_laser_detector_on.png^lzr_laser_fixed.png",
"lzr_laser_detector_on.png^lzr_laser_fixed.png",
"lzr_laser_detector_on.png^lzr_laser_fixed.png",
"lzr_laser_detector_on.png^lzr_laser_fixed.png",
"lzr_laser_detector_on.png^lzr_laser_fixed.png",
"lzr_laser_detector_on_front.png^lzr_laser_fixed.png",
},
tiles_takable_off = {
"lzr_laser_detector.png",
"lzr_laser_detector.png",
"lzr_laser_detector.png",
@ -319,7 +355,7 @@ register_element("detector", {
"lzr_laser_detector.png",
"lzr_laser_detector_front.png",
},
tiles_on = {
tiles_takable_on = {
"lzr_laser_detector_on.png",
"lzr_laser_detector_on.png",
"lzr_laser_detector_on.png",
@ -329,5 +365,5 @@ register_element("detector", {
},
groups = { laser_block = 1 },
sounds = lzr_sounds.node_sound_wood_defaults(),
})
}, { allow_take = true, is_detector = true })

View File

@ -213,6 +213,33 @@ function lzr_laser.check_detectors_in_area(pos1, pos2)
return true
end
-- Returns true if player has no detectors in inventory
function lzr_laser.check_inventory_detectors(player, detector_placed)
local inv = player:get_inventory()
local count = 0
for i=1, inv:get_size("main") do
local item = inv:get_stack("main", i):get_name()
if minetest.get_item_group(item, "detector") ~= 0 then
count = count + 1
if (detector_placed and count > 1) or (not detector_placed) then
return false
end
end
end
return true
end
-- Returns true if current level is won
function lzr_laser.check_level_won(detector_placed)
local cond_area = lzr_laser.check_detectors_in_area(lzr_globals.PLAYFIELD_START, lzr_globals.PLAYFIELD_END)
local cond_inventory = true
local player = minetest.get_player_by_name("singleplayer")
if player then
cond_inventory = lzr_laser.check_inventory_detectors(player, detector_placed)
end
return cond_area and cond_inventory
end
-- Completely recalculate all lasers
function lzr_laser.full_laser_update(pos1, pos2)
local benchmark_time_1 = minetest.get_us_time()
@ -230,11 +257,6 @@ function lzr_laser.full_laser_update(pos1, pos2)
vmanip:set_param2_data(vdata_p2)
vmanip:write_to_map()
local done = lzr_laser.check_detectors_in_area(lzr_globals.PLAYFIELD_START, lzr_globals.PLAYFIELD_END)
if done then
lzr_levels.next_level()
end
-- Print benchmark time
local benchmark_time_2 = minetest.get_us_time()
local diff = benchmark_time_2 - benchmark_time_1