autocrafter, init, keypad, light, machines_configuration: allow change autocrafter recipe / light param2 with keypad
recycler: update no_recycle_list, variable fuel cost
This commit is contained in:
waxtatect 2023-01-02 19:11:30 +01:00
parent ee2831cd3b
commit 1f5c28d9b9
7 changed files with 115 additions and 52 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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]" ..

View File

@ -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 "<i> <mode>".@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<index>".=
@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.=

View File

@ -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 \"<i> <mode>\".\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<index>\".")) 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." ..

View File

@ -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