From 1f5c28d9b91d34bbd44be8d60f229825e9217c83 Mon Sep 17 00:00:00 2001 From: waxtatect <52937829+waxtatect@users.noreply.github.com> Date: Mon, 2 Jan 2023 19:11:30 +0100 Subject: [PATCH] increase autocrafter, init, keypad, light, machines_configuration: allow change autocrafter recipe / light param2 with keypad recycler: update no_recycle_list, variable fuel cost --- autocrafter.lua | 2 ++ init.lua | 2 ++ keypad.lua | 53 ++++++++++++++++++++++++++--------- light.lua | 57 +++++++++++++++++++++++++------------- locale/template | 8 ++++-- machines_configuration.lua | 16 +++++++---- recycler.lua | 29 +++++++++++-------- 7 files changed, 115 insertions(+), 52 deletions(-) diff --git a/autocrafter.lua b/autocrafter.lua index 24d8f7d..a9ffeba 100644 --- a/autocrafter.lua +++ b/autocrafter.lua @@ -123,6 +123,8 @@ local function on_output_change(pos, inventory, stack) after_recipe_change(pos, inventory) end +basic_machines.change_autocrafter_recipe = on_output_change + local function autocraft(inventory, craft) if not craft then return end local output_item = craft.output.item diff --git a/init.lua b/init.lua index 61e83a3..8f80dfe 100644 --- a/init.lua +++ b/init.lua @@ -64,6 +64,8 @@ basic_machines = { end return table.concat(player_inv) end, + -- autocrafter + change_autocrafter_recipe = function() end, -- distributor get_distributor_form = function() end, -- enviro diff --git a/keypad.lua b/keypad.lua index a81d496..63714ed 100644 --- a/keypad.lua +++ b/keypad.lua @@ -3,7 +3,6 @@ local machines_TTL = basic_machines.properties.machines_TTL local machines_minstep = basic_machines.properties.machines_minstep local machines_timer = basic_machines.properties.machines_timer local byte = string.byte -local use_signs_lib = minetest.global_exists("signs_lib") local signs = { -- when activated with keypad these will be "punched" to update their text too ["basic_signs:sign_wall_glass"] = true, ["basic_signs:sign_wall_locked"] = true, @@ -20,6 +19,8 @@ local signs = { -- when activated with keypad these will be "punched" to update ["default:sign_wall_steel"] = true, ["default:sign_wall_wood"] = true } +local use_signs_lib = minetest.global_exists("signs_lib") +local use_unifieddyes = minetest.global_exists("unifieddyes") -- position, time to live (how many times can signal travel before vanishing to prevent infinite recursion), -- do we want to stop repeating @@ -50,7 +51,7 @@ basic_machines.use_keypad = function(pos, ttl, reset, reset_msg) return end - local iter = meta:get_int("iter") + local iter = meta:get_int("iter"); if iter == 0 then return end local count = 0 -- counts repeats if iter > 1 then @@ -121,7 +122,7 @@ basic_machines.use_keypad = function(pos, ttl, reset, reset_msg) local tpos = vector.add(pos, {x = meta:get_int("x0"), y = meta:get_int("y0"), z = meta:get_int("z0")}) local node = minetest.get_node_or_nil(tpos); if not node then return end -- error - local name, tmeta = node.name, minetest.get_meta(tpos) + local name = node.name if name ~= "basic_machines:keypad" and not vector.equals(pos, tpos) then if count < 2 then @@ -132,6 +133,7 @@ basic_machines.use_keypad = function(pos, ttl, reset, reset_msg) end if signs[name] then -- update text on signs with signs_lib + local tmeta = minetest.get_meta(tpos) tmeta:set_string("infotext", text) tmeta:set_string("text", text) if use_signs_lib and signs_lib.update_sign then @@ -141,20 +143,22 @@ basic_machines.use_keypad = function(pos, ttl, reset, reset_msg) -- target is keypad, special functions: @, % that output to target keypad text elseif name == "basic_machines:keypad" then -- special modify of target keypad text and change its target - if bit == 64 then -- target keypad's text starts with @ (ascii code 64) -> character replacement + local tmeta = minetest.get_meta(tpos) + + if bit == 64 then -- target keypad's text starts with '@' (ascii code 64) -> character replacement text = text:sub(2); if text == "" then tmeta:set_string("text", ""); return end -- clear target keypad text -- read words [j] from blocks above keypad: local j = 0 local function replace() j = j + 1; return minetest.get_meta({x = pos.x, y = pos.y + j, z = pos.z}):get_string("infotext") end - text = text:gsub("@", replace) -- replace every @ in text with string on blocks above + text = text:gsub("@", replace) -- replace every '@' in text with string on blocks above -- set target keypad's text tmeta:set_string("text", text) - elseif bit == 37 then -- target keypad's text starts with % (ascii code 37) -> word extraction + elseif bit == 37 then -- target keypad's text starts with '%' (ascii code 37) -> word extraction local ttext = minetest.get_meta({x = pos.x, y = pos.y + 1, z = pos.z}):get_string("infotext") - local i = tonumber(text:sub(2, 2)) or 1 -- read the number following the % + local i = tonumber(text:sub(2, 2)) or 1 -- read the number following the '%' -- extract i - th word from text local j = 0 for word in ttext:gmatch("%S+") do @@ -169,14 +173,16 @@ basic_machines.use_keypad = function(pos, ttl, reset, reset_msg) end elseif name == "basic_machines:detector" then -- change filter on detector - if bit == 64 then -- if text starts with @ clear the filter - tmeta:set_string("node", "") + if bit == 64 then -- if text starts with '@' -> clear the filter + minetest.get_meta(tpos):set_string("node", "") else - tmeta:set_string("node", text) + minetest.get_meta(tpos):set_string("node", text) end elseif name == "basic_machines:mover" then -- change filter on mover - if bit == 64 then -- if text starts with @ clear the filter + local tmeta = minetest.get_meta(tpos) + + if bit == 64 then -- if text starts with '@' -> clear the filter tmeta:set_string("prefer", "") tmeta:get_inventory():set_list("filter", {}) else @@ -196,12 +202,33 @@ basic_machines.use_keypad = function(pos, ttl, reset, reset_msg) local ti = tonumber(text:sub(1, i - 1)) or 1 local tm = tonumber(text:sub(i + 1)) or 1 if ti >= 1 and ti <= 16 and tm >= -2 and tm <= 2 then - tmeta:set_int("active" .. ti, tm) + minetest.get_meta(tpos):set_int("active" .. ti, tm) end end + elseif name == "basic_machines:autocrafter" then + local tmeta = minetest.get_meta(tpos) + + if bit == 64 then -- if text starts with '@' -> clear the recipe + basic_machines.change_autocrafter_recipe(tpos, tmeta:get_inventory(), nil) + elseif minetest.registered_items[text] then + basic_machines.change_autocrafter_recipe(tpos, tmeta:get_inventory(), ItemStack(text)) + else + tmeta:set_string("infotext", text:gsub("^ +$", "")) + end + + elseif use_unifieddyes and name:find("basic_machines:light") then + if bit == 105 then -- text starts with 'i' -> set param2 + local idx = tonumber(text:sub(2)) or 0 + if idx ~= node.param2 and idx % 8 == 0 then -- colorwallmounted palette + node.param2 = idx; minetest.swap_node(tpos, node) + end + else + minetest.get_meta(tpos):set_string("infotext", text:gsub("^ +$", "")) + end + else - tmeta:set_string("infotext", text:gsub("^ +$", "")) -- else just set text + minetest.get_meta(tpos):set_string("infotext", text:gsub("^ +$", "")) -- else just set text end else diff --git a/light.lua b/light.lua index 3cade05..fe31e78 100644 --- a/light.lua +++ b/light.lua @@ -1,27 +1,39 @@ local F, S = basic_machines.F, basic_machines.S -local def = { - groups = {cracky = 3}, - light_on_actions = {action_on = function(pos, _) - local meta = minetest.get_meta(pos) - local count = tonumber(meta:get_string("infotext")) or 0 - meta:set_string("infotext", count + 1) -- increase activate count - end} -} +local def = {groups = {cracky = 3}} if minetest.global_exists("unifieddyes") then def.groups.ud_param2_colorable = 1 def.palette = "unifieddyes_palette_colorwallmounted.png" def.paramtype2 = "color" - def.light_on_actions.action_off = function(pos, _) - local node = minetest.get_node_or_nil(pos) - if node and node.name == "basic_machines:light_on" then - minetest.swap_node(pos, {name = "basic_machines:light_off", param2 = node.param2}) + def.light_on_actions = { + action_on = function(pos, _) + local meta = minetest.get_meta(pos) + if meta:get_float("deactivate") == 99 then + local node = minetest.get_node_or_nil(pos) + if node and node.name == "basic_machines:light_on" then + node.param2 = node.param2 + 8; if node.param2 > 248 then node.param2 = 0 end + minetest.swap_node(pos, node) + end + else + local count = tonumber(meta:get_string("infotext")) or 0 + meta:set_string("infotext", count + 1) -- increase activate count + end + end, + action_off = function(pos, _) + local node = minetest.get_node_or_nil(pos) + if node and node.name == "basic_machines:light_on" then + minetest.swap_node(pos, {name = "basic_machines:light_off", param2 = node.param2}) + end end - end + } def.light_off_action = {action_on = function(pos, _) local node = minetest.get_node_or_nil(pos) if node and node.name == "basic_machines:light_off" then + local deactivate = minetest.get_meta(pos):get_float("deactivate") + if deactivate == 99 then + node.param2 = node.param2 + 8; if node.param2 > 248 then node.param2 = 0 end + minetest.swap_node(pos, node); return + end minetest.swap_node(pos, {name = "basic_machines:light_on", param2 = node.param2}) - local deactivate = minetest.get_meta(pos):get_int("deactivate") if deactivate > 0 then minetest.after(deactivate, function() minetest.swap_node(pos, node) -- turn off again @@ -30,12 +42,19 @@ if minetest.global_exists("unifieddyes") then end end} else - def.light_on_actions.action_off = function(pos, _) - minetest.swap_node(pos, {name = "basic_machines:light_off"}) - end + def.light_on_actions = { + action_on = function(pos, _) + local meta = minetest.get_meta(pos) + local count = tonumber(meta:get_string("infotext")) or 0 + meta:set_string("infotext", count + 1) -- increase activate count + end, + action_off = function(pos, _) + minetest.swap_node(pos, {name = "basic_machines:light_off"}) + end + } def.light_off_action = {action_on = function(pos, _) minetest.swap_node(pos, {name = "basic_machines:light_on"}) - local deactivate = minetest.get_meta(pos):get_int("deactivate") + local deactivate = minetest.get_meta(pos):get_float("deactivate") if deactivate > 0 then minetest.after(deactivate, function() minetest.swap_node(pos, {name = "basic_machines:light_off"}) -- turn off again @@ -67,7 +86,7 @@ minetest.register_node("basic_machines:light_on", { if fields.OK then if minetest.is_protected(pos, sender:get_player_name()) then return end local deactivate = tonumber(fields.deactivate) or 0 - if deactivate > -1 and deactivate < 601 then + if deactivate >= 0 and deactivate <= 600 then local meta = minetest.get_meta(pos) deactivate = basic_machines.twodigits_float(deactivate) meta:set_string("formspec", "formspec_version[4]size[2.5,2.5]" .. diff --git a/locale/template b/locale/template index b421f9d..1bf9cd6 100644 --- a/locale/template +++ b/locale/template @@ -175,14 +175,14 @@ DISTRIBUTOR: Target set.= KEYPAD: Punched position is protected. Aborting.= KEYPAD: Punch closer to keypad. Resetting.= Punch keypad to use it.= -KEYPAD: Target set with coordinates @1,@2,@3.= +KEYPAD: Target set with coordinates @1, @2, @3.= DETECTOR: Punch closer to detector. Aborting.= DETECTOR: Now punch the target machine.= DETECTOR: Punch something else. Aborting.= DETECTOR: Setup complete.= MOVER: Position is protected. Aborting.= MOVER: All coordinates must be between @1 and @2. For increased range set up positions by punching.= -Mover block. Set up with source coordinates @1,@2,@3 -> @4,@5,@6 and target coordinates @7,@8,@9. Put charged battery next to it and start it with keypad.= +Mover block. Set up with source coordinates @1, @2, @3 -> @4, @5, @6 and target coordinates @7, @8, @9. Put charged battery next to it and start it with keypad.= MOVER: Battery found - displaying mark 1= MOVER: Please put battery nearby= Mover help= @@ -205,9 +205,11 @@ KEYPAD: Password too long.= Sounds (@1):= Keypad help= Mode: 0@=IDLE, 1@=OFF, 2@=ON, 3@=TOGGLE, control the way how the target is activated.@n@nRepeat: Number to control how many times activation is repeated after initial punch.@n@nPassword: Enter password and press OK. Password will be encrypted. Next time you use keypad you will need to enter correct password to gain access.@n@nText: If set then text on target node will be changed. In case target is detector/mover, filter settings will be changed. Can be used for special operations.@n@nTarget: Coordinates (x, y, z) relative to the keypad. (0, 0, 0) is keypad itself, (0, 1, 0) is one node above, (0, -1, 0) one node below. X coordinate axes goes from east to west, Y from down to up, Z from south to north.= -@n@nSetup: Just punch (left click) keypad, then the target block will be activated.@nTo set text on other nodes (text shows when you look at node) just target the node and set nonempty text. Upon activation text will be set. When target node is another keypad, its "text" field will be set. When targets is mover/detector, its "filter" field will be set. To clear "filter" set text to "@@". When target is distributor, you can change i-th target of distributor mode with "i mode".@n@nKeyboard: To use keypad as keyboard for text input write "@@" in "text" field and set any password. Next time keypad is used it will work as text input device.@n@nDisplaying messages to nearby players (up to 5 blocks around keypad's target): Set text to "!text". Upon activation player will see "text" in their chat.@n@nPlaying sound to nearby players: set text to "$sound_name", optionally followed by a space and pitch value: 0.01 to 10. Can choose a sound with sounds menu.= @n@nAdvanced:@nText replacement: Suppose keypad A is set with text "@@Some @@. text @@!" and there are blocks on top of keypad A with infotext '1' and '2'. Suppose we target B with A and activate A. Then text of keypad B will be set to "some 1. text 2!".@nWord extraction: Suppose similar setup but now keypad A is set with text "%1". Then upon activation text of keypad B will be set to 1.st word of infotext.= ACCESS DENIED. WRONG PASSWORD.= +@n@nSetup: Right click or punch (left click) the keypad, then follow instructions.@n@nTo set text on other nodes (text shows when you look at node) just target the node and set nonempty text. Upon activation text will be set:@nWhen target node is keypad, its "text" field will be set.@nWhen target is detector/mover, its "filter" field will be set. To clear "filter" set text to "@@".@nWhen target is distributor, you can change i-th target of distributor mode with " ".@nWhen target is autocrafter, the recipe will be set. To clear the recipe set text to "@@".= +@nWhen target is light, you can change the index value (a multiple of 8) with "i".= +@n@nKeyboard: To use keypad as keyboard for text input write "@@" in "text" field and set any password. Next time keypad is used it will work as text input device.@n@nDisplaying messages to nearby players (up to 5 blocks around keypad's target): Set text to "!text". Upon activation player will see "text" in their chat.@n@nPlaying sound to nearby players: set text to "$sound_name", optionally followed by a space and pitch value: 0.01 to 10. Can choose a sound with sounds menu.= ACCESS GRANTED= Operation aborted by user. Punch to activate.= DETECTOR: Position is protected. Aborting.= diff --git a/machines_configuration.lua b/machines_configuration.lua index 4bc1020..afbd4db 100644 --- a/machines_configuration.lua +++ b/machines_configuration.lua @@ -364,6 +364,8 @@ local connectables = { ["basic_machines:mover"] = true } +local use_unifieddyes = minetest.global_exists("unifieddyes") + minetest.register_on_player_receive_fields(function(player, formname, fields) local formname_sub, pos = check_fname(formname); if not formname_sub or pos == "" then return end local name = player:get_player_name(); if name == "" then return end @@ -777,12 +779,14 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) "\n\nTarget: Coordinates (x, y, z) relative to the keypad." .. " (0, 0, 0) is keypad itself, (0, 1, 0) is one node above, (0, -1, 0) one node below." .. " X coordinate axes goes from east to west, Y from down to up, Z from south to north.")) .. - F(S("\n\nSetup: Just punch (left click) keypad, then the target block will be activated.\n" .. - "To set text on other nodes (text shows when you look at node) just target the node and set nonempty text." .. - " Upon activation text will be set. When target node is another keypad, its \"text\" field will be set." .. - " When targets is mover/detector, its \"filter\" field will be set. To clear \"filter\" set text to \"@@\"." .. - " When target is distributor, you can change i-th target of distributor mode with \"i mode\"." .. - "\n\nKeyboard: To use keypad as keyboard for text input write \"@@\" in \"text\" field and set any password." .. + F(S("\n\nSetup: Right click or punch (left click) the keypad, then follow instructions." .. + "\n\nTo set text on other nodes (text shows when you look at node) just target the node and set nonempty text." .. + " Upon activation text will be set:\nWhen target node is keypad, its \"text\" field will be set.\n" .. + "When target is detector/mover, its \"filter\" field will be set. To clear \"filter\" set text to \"@@\".\n" .. + "When target is distributor, you can change i-th target of distributor mode with \" \".\n" .. + "When target is autocrafter, the recipe will be set. To clear the recipe set text to \"@@\".")) .. + (use_unifieddyes and F(S("\nWhen target is light, you can change the index value (a multiple of 8) with \"i\".")) or "") .. + F(S("\n\nKeyboard: To use keypad as keyboard for text input write \"@@\" in \"text\" field and set any password." .. " Next time keypad is used it will work as text input device." .. "\n\nDisplaying messages to nearby players (up to 5 blocks around keypad's target): Set text to \"!text\"." .. " Upon activation player will see \"text\" in their chat." .. diff --git a/recycler.lua b/recycler.lua index f3b2a11..abdcece 100644 --- a/recycler.lua +++ b/recycler.lua @@ -8,13 +8,17 @@ local F, S = basic_machines.F, basic_machines.S local machines_minstep = basic_machines.properties.machines_minstep local twodigits_float = basic_machines.twodigits_float local no_recycle_list = { -- prevent unrealistic recycling - ["default:bronze_ingot"] = 1, ["default:gold_ingot"] = 1, - ["default:copper_ingot"] = 1, ["default:steel_ingot"] = 1, - ["dye:black"] = 1, ["dye:blue"] = 1, ["dye:brown"] = 1, ["dye:cyan"] = 1, - ["dye:dark_green"] = 1, ["dye:dark_grey"] = 1, ["dye:green"] = 1, - ["dye:grey"] = 1, ["dye:magenta"] = 1, ["dye:orange"] = 1, - ["dye:pink"] = 1, ["dye:red"] = 1, ["dye:violet"] = 1, - ["dye:white"] = 1, ["dye:yellow"] = 1 + ["default:bronze_ingot"] = 1, ["default:coal_lump"] = 1, + ["default:copper_ingot"] = 1, ["default:diamond"] = 1, + ["default:gold_ingot"] = 1, ["default:mese_crystal"] = 1, + ["default:mese_crystal_fragment"] = 1, ["default:steel_ingot"] = 1, + ["default:tin_ingot"] = 1, + ["dye:black"] = 1, ["dye:blue"] = 1, ["dye:brown"] = 1, + ["dye:cyan"] = 1, ["dye:dark_green"] = 1, ["dye:dark_grey"] = 1, + ["dye:green"] = 1, ["dye:grey"] = 1, ["dye:magenta"] = 1, + ["dye:orange"] = 1, ["dye:pink"] = 1, ["dye:red"] = 1, + ["dye:violet"] = 1, ["dye:white"] = 1, ["dye:yellow"] = 1, + ["moreores:mithril_ingot"] = 1, ["moreores:silver_ingot"] = 1 } local function recycler_update_form(meta) @@ -37,15 +41,18 @@ end local function recycler_process(pos) local meta = minetest.get_meta(pos) - local inv = meta:get_inventory(); local msg + local inv = meta:get_inventory() + local stack, msg -- FUEL CHECK - local fuel_req; local fuel = meta:get_float("fuel") + local fuel_req + local fuel = meta:get_float("fuel") if meta:get_int("admin") == 1 then fuel_req = 0 else - fuel_req = 1 + stack = inv:get_stack("src", 1) + fuel_req = (stack:to_string():len() + 5) * 0.16 if fuel < fuel_req then -- we need new fuel local fuellist = inv:get_list("fuel"); if not fuellist then return end @@ -74,7 +81,7 @@ local function recycler_process(pos) end -- RECYCLING: check out inserted items - local stack = inv:get_stack("src", 1) + stack = stack or inv:get_stack("src", 1) if stack:is_empty() then if msg then meta:set_string("infotext", msg) end; return end -- nothing to do local src_item = stack:get_name() -- take first word to determine what item was