c the commit
interact directly with machine blocks when marks displayed hold sneak and punch a block to abort interactive setup allow removing keypad password add place sounds for mover in normal, dig and transport modes somewhat rework player punch in space code maintenance
This commit is contained in:
parent
f8a27cef49
commit
f9431c5e09
@ -1,5 +1,5 @@
|
||||
-- (c) 2015-2016 rnd
|
||||
-- Copyright (C) 2022-2023 мтест
|
||||
-- Copyright (C) 2022-2024 мтест
|
||||
-- See README.md for license details
|
||||
|
||||
local S = basic_machines.S
|
||||
@ -42,7 +42,7 @@ minetest.register_node("basic_machines:clockgen", {
|
||||
|
||||
local name = placer:get_player_name()
|
||||
if minetest.find_node_near(pos, 15, {"basic_machines:clockgen"}) then
|
||||
minetest.set_node(pos, {name = "air"})
|
||||
minetest.remove_node(pos)
|
||||
minetest.add_item(pos, "basic_machines:clockgen")
|
||||
minetest.chat_send_player(name, S("Clock Generator: Interference from nearby clock generator detected"))
|
||||
return
|
||||
|
@ -5,7 +5,7 @@
|
||||
basic_machines = {
|
||||
F = minetest.formspec_escape,
|
||||
S = minetest.get_translator("basic_machines"),
|
||||
version = "02/27/2024 (fork)",
|
||||
version = "04/23/2024 (fork)",
|
||||
properties = {
|
||||
no_clock = false, -- if true all continuously running activities (clockgen/keypad) are disabled
|
||||
machines_TTL = 16, -- time to live for signals, how many hops before signal dissipates
|
||||
|
@ -1,6 +1,6 @@
|
||||
-- Make doors open/close with signal
|
||||
-- (c) 2015-2016 rnd
|
||||
-- Copyright (C) 2022-2023 мтест
|
||||
-- Copyright (C) 2022-2024 мтест
|
||||
-- See README.md for license details
|
||||
|
||||
-- local S = basic_machines.S
|
||||
@ -154,7 +154,7 @@ if use_doors then
|
||||
if count == 1 then
|
||||
minetest.chat_send_player(player_name, S("@1: Punch me one more time to remove me", door))
|
||||
elseif count == 2 then -- remove steel door and drop it
|
||||
minetest.set_node(pos, {name = "air"})
|
||||
minetest.remove_node(pos)
|
||||
minetest.add_item(pos, ItemStack(dropname))
|
||||
end
|
||||
end
|
||||
|
27
keypad.lua
27
keypad.lua
@ -1,5 +1,5 @@
|
||||
-- (c) 2015-2016 rnd
|
||||
-- Copyright (C) 2022-2023 мтест
|
||||
-- Copyright (C) 2022-2024 мтест
|
||||
-- See README.md for license details
|
||||
|
||||
local F, S = basic_machines.F, basic_machines.S
|
||||
@ -93,9 +93,8 @@ basic_machines.use_keypad = function(pos, ttl, reset, reset_msg)
|
||||
end
|
||||
end
|
||||
|
||||
-- set text on target
|
||||
local text = meta:get_string("text")
|
||||
if text ~= "" then
|
||||
if text ~= "" then -- text operations
|
||||
if text == "@" and meta:get_string("pass") ~= "" then -- keyboard mode, set text from input
|
||||
text = meta:get_string("input")
|
||||
meta:set_string("input", "") -- clear input
|
||||
@ -113,10 +112,10 @@ basic_machines.use_keypad = function(pos, ttl, reset, reset_msg)
|
||||
local pitch = tonumber(text_sub:sub(i + 1)) or 1
|
||||
if pitch < 0.01 or pitch > 10 then pitch = 1 end
|
||||
meta:set_string("infotext", S("Playing sound: '@1', pitch: @2", (sound_name:gsub("_", " ")), pitch))
|
||||
minetest.sound_play(sound_name, {pos = pos, gain = 1, max_hear_distance = 16, pitch = pitch}, true)
|
||||
minetest.sound_play({name = sound_name, pitch = pitch}, {pos = pos, max_hear_distance = 16}, true)
|
||||
else
|
||||
meta:set_string("infotext", S("Playing sound: '@1'", (text_sub:gsub("_", " "))))
|
||||
minetest.sound_play(text_sub, {pos = pos, gain = 1, max_hear_distance = 16}, true)
|
||||
minetest.sound_play(text_sub, {pos = pos, max_hear_distance = 16}, true)
|
||||
end
|
||||
return
|
||||
end
|
||||
@ -150,6 +149,7 @@ basic_machines.use_keypad = function(pos, ttl, reset, reset_msg)
|
||||
end
|
||||
end
|
||||
|
||||
-- set text on target
|
||||
if signs[name] then -- update text on signs
|
||||
if use_signs_lib then -- with signs_lib
|
||||
if signs_lib.update_sign then
|
||||
@ -191,12 +191,14 @@ basic_machines.use_keypad = function(pos, ttl, reset, reset_msg)
|
||||
tmeta:set_string("text", text)
|
||||
end
|
||||
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 '%'
|
||||
-- extract i-th word from text
|
||||
local j = 0
|
||||
for word in ttext:gmatch("%S+") do
|
||||
j = j + 1; if j == i then text = word; break end
|
||||
local i = tonumber(text:sub(2, 2)) or 0 -- read the number following the '%'
|
||||
if i > 0 then
|
||||
-- extract i-th word from text
|
||||
local ttext = minetest.get_meta({x = pos.x, y = pos.y + 1, z = pos.z}):get_string("infotext")
|
||||
local j = 0
|
||||
for word in ttext:gmatch("%S+") do
|
||||
j = j + 1; if j == i then text = word; break end
|
||||
end
|
||||
end
|
||||
|
||||
-- set target keypad's text
|
||||
@ -275,8 +277,7 @@ basic_machines.use_keypad = function(pos, ttl, reset, reset_msg)
|
||||
minetest.get_meta(tpos):set_string("infotext", text:gsub("^ +$", "")) -- just set text
|
||||
end
|
||||
|
||||
-- target activation
|
||||
else
|
||||
else -- target activation
|
||||
if count < 2 then
|
||||
meta:set_string("infotext", S("Keypad operation: @1 cycle left", count))
|
||||
else
|
||||
|
@ -154,6 +154,7 @@ Light off=
|
||||
Light=
|
||||
DETECTOR=
|
||||
DISTRIBUTOR=
|
||||
KEYPAD=
|
||||
MOVER=
|
||||
Enter text:=
|
||||
Enter password:=
|
||||
@ -162,6 +163,7 @@ KEYPAD: You must be able to build to set up keypad.=
|
||||
MOVER: Now punch source1, source2, end position to set up mover.=
|
||||
KEYPAD: Now punch the target block.=
|
||||
DETECTOR: Now punch the source block.=
|
||||
@1: Aborting interactive setup.=
|
||||
MOVER: Punch closer to mover. Resetting.=
|
||||
MOVER: Punch something else. Aborting.=
|
||||
MOVER: Source1 position for mover set. Punch again to set source2 position.=
|
||||
@ -188,7 +190,7 @@ Mover block. Set up with source coordinates @1, @2, @3 -> @4, @5, @6 and target
|
||||
MOVER: Battery found - displaying mark 1=
|
||||
MOVER: Please put battery nearby=
|
||||
Mover help=
|
||||
version @1@nSetup: For interactive setup punch the mover and then punch source1, source2, target node (follow instructions). Put the mover directly next to a battery. For advanced setup right click mover. Positions are defined by (x, y, z) coordinates. Mover itself is at coordinates (0, 0, 0).=
|
||||
version @1@nSetup: For interactive setup punch the mover and follow chat instructions (hold sneak and punch a block to abort setup). Put the mover directly next to a battery. For advanced setup right click mover. Positions are defined by (x, y, z) coordinates. Mover itself is at coordinates (0, 0, 0).=
|
||||
@n@nModes of operation: normal (just teleport block), dig (digs and gives you resulted node - good for harvesting farms); by setting 'filter' only selected node is moved, drop (drops node on ground), object (teleportation of players and objects) - distance between source1/2 defines teleport radius; by setting 'filter' you can specify move time - [0.2, 20] - for non players.@nAfter changing from/to object mode, you need to reconfigure sources position.@nInventory mode can exchange items between node inventories. You need to select inventory name for source/target from the dropdown list on the right.@n@nAdvanced:@nYou can reverse start/end position by setting reverse nonzero. This is useful for placing stuff at many locations-planting. If you put reverse @= 2/3 in transport mode it will disable parallel transport but will still do reverse effect with 3. If you activate mover with OFF signal it will toggle reverse.=
|
||||
@n@nFuel consumption depends on blocks to be moved, distance and temperature. For example, stone or tree is harder to move than dirt, harvesting wheat is very cheap and and moving lava is very hard. High temperature increases fuel consumption while low temperature reduces it.@n@nUpgrade mover by moving mese blocks in upgrade inventory. Each mese block increases mover range by @1, fuel consumption is divided by number of mese blocks in upgrade. Max @2 blocks are used for upgrade.@n@nActivate mover by keypad/detector signal or mese signal through mesecon adapter (if mesecons mod).=
|
||||
DISTRIBUTOR: Position @1 is protected. Aborting.=
|
||||
@ -196,7 +198,7 @@ DISTRIBUTOR: All coordinates must be between @1 and @2.=
|
||||
DISTRIBUTOR: Connected @1 targets.=
|
||||
Distributor help=
|
||||
Target: Coordinates (x, y, z) relative to the distributor.@n@nMode: -2@=only OFF, -1@=NOT input, 0/1@=input, 2@=only ON, output signal of the target.@n@nDelay: Adds delay to activations, in seconds. A negative delay activation is randomized with probability -delay/1000.=
|
||||
@n@nSetup: To select a target for activation, click "Set" button then click the target.@nYou can add more targets with "Add" button. To see where the target is click "Show" button next to it.@n4 numbers in each row represent (from left to right): first 3 numbers are target coordinates (x, y, z), last number (Mode) controls how signal is passed to target.@nFor example, to only pass OFF signal use -2, to only pass ON signal use 2, -1 negates the signal, 1 passes original signal, 0 blocks signal.@n"view" button toggles view of target names, in names view there is "scan" button which automatically scans for valid targets in a box defined by first and second target.@n@nAdvanced:@nYou can use the distributor as an event handler - it listens to events like interact attempts and chat around the distributor.@nYou need to place the distributor at a position (x, y, z), with coordinates of the form (20*i, 20*j+1, 20*k) for some integers i, j, k.@nRight click holding a distributor in the hand to show a suitable position.@nThen you need to configure first row of numbers in the distributor:@nBy putting 0 as Mode it will start to listen. First number x @= 0/1 controls if node listens to failed interact attempts around it, second number y @= -1/0/1 controls listening to chat (-1 additionally mutes chat)=
|
||||
@n@nSetup: To select a target for activation, click "Set" button then click the target (hold sneak and punch a block to abort setup).@nYou can add more targets with "Add" button. To see where the target is click "Show" button next to it.@n4 numbers in each row represent (from left to right): first 3 numbers are target coordinates (x, y, z), last number (Mode) controls how signal is passed to target.@nFor example, to only pass OFF signal use -2, to only pass ON signal use 2, -1 negates the signal, 1 passes original signal, 0 blocks signal.@n"view" button toggles view of target names, in names view there is "scan" button which automatically scans for valid targets in a box defined by first and second target.@n@nAdvanced:@nYou can use the distributor as an event handler - it listens to events like interact attempts and chat around the distributor.@nYou need to place the distributor at a position (x, y, z), with coordinates of the form (20*i, 20*j+1, 20*k) for some integers i, j, k.@nRight click holding a distributor in the hand to show a suitable position.@nThen you need to configure first row of numbers in the distributor:@nBy putting 0 as Mode it will start to listen. First number x @= 0/1 controls if node listens to failed interact attempts around it, second number y @= -1/0/1 controls listening to chat (-1 additionally mutes chat)=
|
||||
DISTRIBUTOR: Punch the position to set target @1.=
|
||||
KEYPAD: Position is protected. Aborting.=
|
||||
KEYPAD: All coordinates must be between @1 and @2.=
|
||||
@ -209,7 +211,7 @@ 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@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, set i-th recipe with "<itemname> [<i>]". To clear the recipe set text to "@@".=
|
||||
@n@nSetup: Right click or punch (left click) the keypad, then follow chat instructions (hold sneak and punch a block to abort setup).@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, set i-th recipe with "<itemname> [<i>]". 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=
|
||||
@ -217,7 +219,7 @@ Operation aborted by user. Punch to activate.=
|
||||
DETECTOR: Position is protected. Aborting.=
|
||||
DETECTOR: All coordinates must be between @1 and @2.=
|
||||
Detector help=
|
||||
Setup: Right click or punch and follow chat instructions. With a detector you can detect nodes, objects, players, items inside inventories, nodes information and light levels. If detector activates it will trigger machine (on or off) at target position.@n@nThere are 6 modes of operation - node/player/object/inventory/infotext/light detection. Inside detection filter write node/player/object name or infotext/light level. If you detect node/player/object you can specify a range of detection. If you want detector to activate target precisely when its not triggered set output signal to 1.@n@nFor example, to detect empty space write air, to detect tree write default:tree, to detect ripe wheat write farming:wheat_8, for flowing water write default:water_flowing... If mode is inventory it will check for items in specified inventory of source node like a chest.@n@nAdvanced:@nIn inventory (must set a filter)/node detection mode, you can specify a second source and select AND/OR from the right top dropdown list to do logical operations.@nYou can also filter output signal in any modes:@n-2@=only OFF, -1@=NOT, 0/1@=normal, 2@=only ON, 3@=only if changed, 4@=if target is keypad set its text to detected object name.=
|
||||
Setup: Right click or punch and follow chat instructions (hold sneak and punch a block to abort setup). With a detector you can detect nodes, objects, players, items inside inventories, nodes information and light levels. If detector activates it will trigger machine (on or off) at target position.@n@nThere are 6 modes of operation - node/player/object/inventory/infotext/light detection. Inside detection filter write node/player/object name or infotext/light level. If you detect node/player/object you can specify a range of detection. If you want detector to activate target precisely when its not triggered set output signal to 1.@n@nFor example, to detect empty space write air, to detect tree write default:tree, to detect ripe wheat write farming:wheat_8, for flowing water write default:water_flowing... If mode is inventory it will check for items in specified inventory of source node like a chest.@n@nAdvanced:@nIn inventory (must set a filter)/node detection mode, you can specify a second source and select AND/OR from the right top dropdown list to do logical operations.@nYou can also filter output signal in any modes:@n-2@=only OFF, -1@=NOT, 0/1@=normal, 2@=only ON, 3@=only if changed, 4@=if target is keypad set its text to detected object name.=
|
||||
MOVER: Wrong filter - must be name of existing minetest block=
|
||||
Mesecon Adapter: place machine to be activated on top=
|
||||
Mesecon Adapter=
|
||||
|
@ -1,5 +1,5 @@
|
||||
-- (c) 2015-2016 rnd
|
||||
-- Copyright (C) 2022-2023 мтест
|
||||
-- Copyright (C) 2022-2024 мтест
|
||||
-- See README.md for license details
|
||||
|
||||
local F, S = basic_machines.F, basic_machines.S
|
||||
@ -52,6 +52,7 @@ local punchable_nodes = {
|
||||
local description_translated = {
|
||||
["DETECTOR"] = S("DETECTOR"),
|
||||
["DISTRIBUTOR"] = S("DISTRIBUTOR"),
|
||||
["KEYPAD"] = S("KEYPAD"),
|
||||
["MOVER"] = S("MOVER")
|
||||
}
|
||||
|
||||
@ -127,8 +128,9 @@ minetest.register_on_punchnode(function(pos, node, puncher)
|
||||
|
||||
local self_pos = punchset[name].pos
|
||||
|
||||
if minetest.get_node(self_pos).name ~= punch_node then
|
||||
punchset[name] = {state = 0, node = ""}; return
|
||||
if minetest.get_node(self_pos).name ~= punch_node or (puncher:get_player_control() or {}).sneak then
|
||||
minetest.chat_send_player(name, S("@1: Aborting interactive setup.", description_translated[punchset_desc]))
|
||||
machines.remove_markers(name, {"1", "11", "2"}); punchset[name] = {state = 0, node = ""}; return
|
||||
end
|
||||
|
||||
|
||||
@ -162,24 +164,24 @@ minetest.register_on_punchnode(function(pos, node, puncher)
|
||||
|
||||
punchset[name].pos1 = pos -- source1
|
||||
punchset[name].state = 2
|
||||
machines.mark_pos1(name, pos) -- mark pos1
|
||||
machines.mark_pos1(name, pos, true) -- mark pos1
|
||||
minetest.chat_send_player(name, S("MOVER: Source1 position for mover set. Punch again to set source2 position."))
|
||||
elseif punch_state == 2 then
|
||||
if not privs and
|
||||
(abs(pos.x - self_pos.x) > range or abs(pos.y - self_pos.y) > range or abs(pos.z - self_pos.z) > range)
|
||||
then
|
||||
minetest.chat_send_player(name, S("MOVER: Punch closer to mover. Resetting."))
|
||||
punchset[name] = {state = 0, node = ""}; return
|
||||
machines.remove_markers(name, {"1"}); punchset[name] = {state = 0, node = ""}; return
|
||||
end
|
||||
|
||||
if vector.equals(pos, self_pos) then
|
||||
minetest.chat_send_player(name, S("MOVER: Punch something else. Aborting."))
|
||||
punchset[name] = {state = 0, node = ""}; return
|
||||
machines.remove_markers(name, {"1"}); punchset[name] = {state = 0, node = ""}; return
|
||||
end
|
||||
|
||||
punchset[name].pos11 = pos -- source2
|
||||
punchset[name].state = 3
|
||||
machines.mark_pos11(name, pos) -- mark pos11
|
||||
machines.mark_pos11(name, pos, true) -- mark pos11
|
||||
minetest.chat_send_player(name, S("MOVER: Source2 position for mover set. Punch again to set target position."))
|
||||
elseif punch_state == 3 then
|
||||
local mode = meta:get_string("mode")
|
||||
@ -205,7 +207,7 @@ minetest.register_on_punchnode(function(pos, node, puncher)
|
||||
minetest.chat_send_player(name, S("MOVER: Elevator setup completed, upgrade level @1.", upgrade - 1))
|
||||
else
|
||||
minetest.chat_send_player(name, S("MOVER: Error while trying to make an elevator. Need at least @1 diamond block(s) in upgrade (1 for every 100 distance).", requirement))
|
||||
punchset[name] = {state = 0, node = ""}; return
|
||||
machines.remove_markers(name, {"1", "11"}); punchset[name] = {state = 0, node = ""}; return
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -213,10 +215,10 @@ minetest.register_on_punchnode(function(pos, node, puncher)
|
||||
(abs(pos.x - self_pos.x) > range or abs(pos.y - self_pos.y) > range or abs(pos.z - self_pos.z) > range)
|
||||
then
|
||||
minetest.chat_send_player(name, S("MOVER: Punch closer to mover. Aborting."))
|
||||
punchset[name] = {state = 0, node = ""}; return
|
||||
machines.remove_markers(name, {"1", "11"}); punchset[name] = {state = 0, node = ""}; return
|
||||
end
|
||||
|
||||
machines.mark_pos2(name, pos) -- mark pos2
|
||||
machines.mark_pos2(name, pos, true) -- mark pos2
|
||||
|
||||
local x0 = pos1.x - self_pos.x -- source1
|
||||
local y0 = pos1.y - self_pos.y
|
||||
@ -259,7 +261,7 @@ minetest.register_on_punchnode(function(pos, node, puncher)
|
||||
punchset[name] = {state = 0, node = ""}; return
|
||||
end
|
||||
|
||||
machines.mark_pos1(name, pos) -- mark pos1
|
||||
machines.mark_pos1(name, pos, true) -- mark pos1
|
||||
|
||||
local meta = minetest.get_meta(self_pos)
|
||||
meta:set_int("x" .. punch_state, x); meta:set_int("y" .. punch_state, y); meta:set_int("z" .. punch_state, z)
|
||||
@ -285,11 +287,15 @@ minetest.register_on_punchnode(function(pos, node, puncher)
|
||||
punchset[name] = {state = 0, node = ""}; return
|
||||
end
|
||||
|
||||
machines.mark_pos1(name, pos) -- mark pos1
|
||||
machines.mark_pos1(name, pos, true) -- mark pos1
|
||||
|
||||
local meta = minetest.get_meta(self_pos)
|
||||
meta:set_int("x0", x); meta:set_int("y0", y); meta:set_int("z0", z)
|
||||
meta:set_string("infotext", S("Punch keypad to use it."))
|
||||
if meta:get_string("pass") == "" then
|
||||
meta:set_string("infotext", S("Punch keypad to use it."))
|
||||
else
|
||||
meta:set_string("infotext", S("Punch keypad to use it. Password protected."))
|
||||
end
|
||||
punchset[name] = {state = 0, node = ""}
|
||||
minetest.chat_send_player(name, S("KEYPAD: Target set with coordinates @1, @2, @3.", x, y, z))
|
||||
|
||||
@ -307,12 +313,12 @@ minetest.register_on_punchnode(function(pos, node, puncher)
|
||||
if punch_state == 1 then
|
||||
punchset[name].pos1 = pos
|
||||
punchset[name].state = 2
|
||||
machines.mark_pos1(name, pos) -- mark pos1
|
||||
machines.mark_pos1(name, pos, true) -- mark pos1
|
||||
minetest.chat_send_player(name, S("DETECTOR: Now punch the target machine."))
|
||||
elseif punch_state == 2 then
|
||||
if vector.equals(pos, self_pos) then
|
||||
minetest.chat_send_player(name, S("DETECTOR: Punch something else. Aborting."))
|
||||
punchset[name] = {state = 0, node = ""}; return
|
||||
machines.remove_markers(name, {"1"}); punchset[name] = {state = 0, node = ""}; return
|
||||
end
|
||||
|
||||
machines.mark_pos2(name, pos) -- mark pos2
|
||||
@ -491,15 +497,15 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
|
||||
elseif fields.show then -- display mover area defined by sources
|
||||
local pos1 = {x = meta:get_int("x0"), y = meta:get_int("y0"), z = meta:get_int("z0")} -- source1
|
||||
local pos11 = {x = meta:get_int("x1"), y = meta:get_int("y1"), z = meta:get_int("z1")} -- source2
|
||||
local markerA = machines.mark_posA(name, vector.add(pos, vector.divide(vector.add(pos1, pos11), 2)))
|
||||
if markerA then
|
||||
markerA:set_properties({visual_size = {x = abs(pos11.x - pos1.x) + 1.11,
|
||||
local markerS = machines.mark_posS(name, vector.add(pos, vector.divide(vector.add(pos1, pos11), 2)))
|
||||
if markerS then
|
||||
markerS:set_properties({visual_size = {x = abs(pos11.x - pos1.x) + 1.11,
|
||||
y = abs(pos11.y - pos1.y) + 1.11, z = abs(pos11.z - pos1.z) + 1.11}})
|
||||
end
|
||||
|
||||
elseif fields.help then
|
||||
minetest.show_formspec(name, "basic_machines:help_mover", "formspec_version[4]size[8,9.3]textarea[0,0.35;8,8.95;help;" ..
|
||||
F(S("Mover help")) .. ";" .. F(S("version @1\nSetup: For interactive setup punch the mover and then punch source1, source2, target node (follow instructions)." ..
|
||||
F(S("Mover help")) .. ";" .. F(S("version @1\nSetup: For interactive setup punch the mover and follow chat instructions (hold sneak and punch a block to abort setup)." ..
|
||||
" Put the mover directly next to a battery. For advanced setup right click mover." ..
|
||||
" Positions are defined by (x, y, z) coordinates. Mover itself is at coordinates (0, 0, 0).", basic_machines.version)) ..
|
||||
F(S("\n\nModes of operation: normal (just teleport block), dig (digs and gives you resulted node - good for harvesting farms);" ..
|
||||
@ -644,7 +650,7 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
|
||||
F(S("Distributor help")) .. ";" .. F(S("Target: Coordinates (x, y, z) relative to the distributor." ..
|
||||
"\n\nMode: -2=only OFF, -1=NOT input, 0/1=input, 2=only ON, output signal of the target." ..
|
||||
"\n\nDelay: Adds delay to activations, in seconds. A negative delay activation is randomized with probability -delay/1000.")) ..
|
||||
F(S("\n\nSetup: To select a target for activation, click \"Set\" button then click the target.\n" ..
|
||||
F(S("\n\nSetup: To select a target for activation, click \"Set\" button then click the target (hold sneak and punch a block to abort setup).\n" ..
|
||||
"You can add more targets with \"Add\" button. To see where the target is click \"Show\" button next to it.\n" ..
|
||||
"4 numbers in each row represent (from left to right): first 3 numbers are target coordinates (x, y, z), last number (Mode) controls how signal is passed to target.\n" ..
|
||||
"For example, to only pass OFF signal use -2, to only pass ON signal use 2, -1 negates the signal, 1 passes original signal, 0 blocks signal.\n" ..
|
||||
@ -729,7 +735,11 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
|
||||
|
||||
local pass = fields.pass or ""
|
||||
|
||||
if pass ~= "" then
|
||||
if pass == "" then
|
||||
if meta:get_string("pass") ~= "" then
|
||||
meta:set_string("pass", "")
|
||||
end
|
||||
else
|
||||
local mpass = meta:get_string("pass")
|
||||
if pass ~= mpass then
|
||||
if pass:len() > 16 then -- don't replace password with hash which is longer - 27 chars
|
||||
@ -812,7 +822,7 @@ 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: Right click or punch (left click) the keypad, then follow instructions." ..
|
||||
F(S("\n\nSetup: Right click or punch (left click) the keypad, then follow chat instructions (hold sneak and punch a block to abort setup)." ..
|
||||
"\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" ..
|
||||
@ -921,7 +931,7 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
|
||||
|
||||
elseif fields.help then
|
||||
minetest.show_formspec(name, "basic_machines:help_detector", "formspec_version[4]size[7.4,7.4]textarea[0,0.35;7.4,7.05;help;" ..
|
||||
F(S("Detector help")) .. ";" .. F(S("Setup: Right click or punch and follow chat instructions." ..
|
||||
F(S("Detector help")) .. ";" .. F(S("Setup: Right click or punch and follow chat instructions (hold sneak and punch a block to abort setup)." ..
|
||||
" With a detector you can detect nodes, objects, players, items inside inventories, nodes information and light levels. " ..
|
||||
"If detector activates it will trigger machine (on or off) at target position." ..
|
||||
"\n\nThere are 6 modes of operation - node/player/object/inventory/infotext/light detection." ..
|
||||
|
47
mark.lua
47
mark.lua
@ -1,40 +1,61 @@
|
||||
-- rnd: code borrowed from machines, mark.lua
|
||||
-- Copyright (C) 2022-2023 мтест
|
||||
-- Copyright (C) 2022-2024 мтест
|
||||
-- See README.md for license details
|
||||
|
||||
-- Needed for marking
|
||||
machines = {}
|
||||
local machines_marks = {"1", "11", "2", "N", "S"}
|
||||
|
||||
for _, n in ipairs({"1", "11", "2", "N", "A"}) do
|
||||
machines = {
|
||||
remove_markers = function(name, marks)
|
||||
marks = marks or machines_marks
|
||||
for _, n in ipairs(marks) do
|
||||
local markern = "marker" .. n
|
||||
if machines[markern][name] then
|
||||
machines[markern][name]:remove() -- remove marker
|
||||
end
|
||||
end
|
||||
end
|
||||
}
|
||||
|
||||
for _, n in ipairs(machines_marks) do
|
||||
local markern = "marker" .. n
|
||||
local posn = "machines:pos" .. n
|
||||
local texturen, delay
|
||||
|
||||
if n == "N" then
|
||||
if n == "N" then -- mover "Now" button marker
|
||||
texturen = "machines_pos.png^[colorize:#ffd700"
|
||||
delay = 27
|
||||
elseif n == "A" then
|
||||
elseif n == "S" then -- mover "Show" button marker
|
||||
texturen = "machines_pos.png^[colorize:#008080"
|
||||
delay = 21
|
||||
else
|
||||
else -- source1, source2 and target markers
|
||||
texturen = "machines_pos" .. n .. ".png"
|
||||
delay = 9
|
||||
end
|
||||
|
||||
machines[markern] = {}
|
||||
|
||||
machines["mark_pos" .. n] = function(name, pos)
|
||||
machines["mark_pos" .. n] = function(name, pos, node_is_punchable)
|
||||
if machines[markern][name] then -- marker already exists
|
||||
machines[markern][name]:remove() -- remove marker
|
||||
end
|
||||
|
||||
-- add marker
|
||||
machines[markern][name] = minetest.add_entity(pos, posn)
|
||||
if machines[markern][name] then
|
||||
machines[markern][name]:get_luaentity()._name = name
|
||||
local obj = minetest.add_entity(pos, posn)
|
||||
if obj then
|
||||
obj:get_luaentity()._name = name
|
||||
if node_is_punchable then
|
||||
obj:set_properties({pointable = false})
|
||||
else
|
||||
local node_name = minetest.get_node(obj:get_pos()).name
|
||||
if (node_name):sub(1, 15) == "basic_machines:" then
|
||||
obj:set_properties({pointable = false})
|
||||
end
|
||||
end
|
||||
machines[markern][name] = obj
|
||||
end
|
||||
|
||||
return machines[markern][name]
|
||||
return obj
|
||||
end
|
||||
|
||||
minetest.register_entity(":" .. posn, {
|
||||
@ -59,7 +80,9 @@ for _, n in ipairs({"1", "11", "2", "N", "A"}) do
|
||||
end,
|
||||
on_punch = function(self)
|
||||
minetest.after(0.1, function()
|
||||
self.object:remove()
|
||||
if self and self.object then
|
||||
self.object:remove()
|
||||
end
|
||||
end)
|
||||
end,
|
||||
_name = "",
|
||||
|
@ -138,8 +138,8 @@ local mover = {
|
||||
["3d_armor_stand:armor_entity"] = true,
|
||||
["__builtin:item"] = true,
|
||||
["itemframes:item"] = true,
|
||||
["machines:posA"] = true,
|
||||
["machines:posN"] = true,
|
||||
["machines:posS"] = true,
|
||||
["painting:paintent"] = true,
|
||||
["painting:picent"] = true,
|
||||
["shield_frame:shield_entity"] = true,
|
||||
|
@ -1,5 +1,5 @@
|
||||
-- (c) 2015-2016 rnd
|
||||
-- Copyright (C) 2022-2023 мтест
|
||||
-- Copyright (C) 2022-2024 мтест
|
||||
-- See README.md for license details
|
||||
|
||||
local F, S = basic_machines.F, basic_machines.S
|
||||
@ -68,7 +68,7 @@ local function dig(pos, meta, owner, prefer, pos1, node1, node1_name, source_che
|
||||
prefer = prefer or meta:get_string("prefer")
|
||||
source_chest = source_chest or mover_chests[node1_name]
|
||||
local third_upgradetype = upgradetype == 3
|
||||
local seed_planting, node_def, node1_param2, last_pos2, new_fuel_cost
|
||||
local seed_planting, node_def, node1_param2, sound_def, last_pos2, new_fuel_cost
|
||||
|
||||
-- checks
|
||||
if prefer ~= "" then -- filter check
|
||||
@ -85,6 +85,7 @@ local function dig(pos, meta, owner, prefer, pos1, node1, node1_name, source_che
|
||||
else
|
||||
return
|
||||
end
|
||||
sound_def = ((plant_def or minetest.registered_nodes[prefer] or {}).sounds or {}).place -- preparing for sound_play
|
||||
else -- set preferred node
|
||||
node_def = minetest.registered_nodes[prefer]
|
||||
if node_def then
|
||||
@ -224,12 +225,15 @@ local function dig(pos, meta, owner, prefer, pos1, node1, node1_name, source_che
|
||||
new_fuel_cost = fuel_cost * (1 - node2_count / length_pos2)
|
||||
end
|
||||
end
|
||||
sound_def = (node_def.sounds or {}).place -- preparing for sound_play
|
||||
|
||||
minetest.bulk_set_node(pos2, node1)
|
||||
else -- try to place node as the owner would
|
||||
sound_def = (node_def.sounds or {}).place -- preparing for sound_play
|
||||
|
||||
local placer, is_placed = minetest.get_player_by_name(owner)
|
||||
if placer then -- only if owner online
|
||||
local on_place = (node_def or {}).on_place
|
||||
local on_place = node_def.on_place
|
||||
if on_place then
|
||||
local _, placed_pos = on_place(node_to_stack(node1, node_def.paramtype2),
|
||||
placer, {type = "node", under = pos2,
|
||||
@ -384,7 +388,7 @@ local function dig(pos, meta, owner, prefer, pos1, node1, node1_name, source_che
|
||||
source_neighbor = minetest.find_node_near(pos1, 1, liquiddef.source)
|
||||
end
|
||||
if not (source_neighbor and liquiddef.force_renew) then
|
||||
minetest.set_node(pos1, {name = "air"})
|
||||
minetest.remove_node(pos1)
|
||||
end
|
||||
--
|
||||
end
|
||||
@ -400,7 +404,7 @@ local function dig(pos, meta, owner, prefer, pos1, node1, node1_name, source_che
|
||||
end
|
||||
end
|
||||
else -- remove node and put drops in chest
|
||||
minetest.set_node(pos1, {name = "air"})
|
||||
minetest.remove_node(pos1)
|
||||
check_for_falling(pos1) -- pre 5.0.0 nodeupdate(pos1)
|
||||
|
||||
add_node_drops(node1_name, pos2, node1, prefer ~= "", node_def, node1_param2)
|
||||
@ -408,7 +412,7 @@ local function dig(pos, meta, owner, prefer, pos1, node1, node1_name, source_che
|
||||
end
|
||||
end
|
||||
elseif node2_name == "air" and not third_upgradetype then -- move node from pos1 to pos2
|
||||
minetest.set_node(pos1, {name = "air"})
|
||||
minetest.remove_node(pos1)
|
||||
check_for_falling(pos1) -- pre 5.0.0 nodeupdate(pos1)
|
||||
|
||||
minetest.set_node(pos2, node1)
|
||||
@ -417,11 +421,11 @@ local function dig(pos, meta, owner, prefer, pos1, node1, node1_name, source_che
|
||||
end
|
||||
end
|
||||
|
||||
-- play sound
|
||||
local activation_count = meta:get_int("activation_count")
|
||||
-- if activation_count < 16 then
|
||||
-- minetest.sound_play("basic_machines_transport", {pos = last_pos2 or pos2, gain = 1, max_hear_distance = 8}, true)
|
||||
-- end
|
||||
|
||||
if sound_def and activation_count < 16 then -- play sound
|
||||
minetest.sound_play(sound_def, {pitch = 0.9, pos = last_pos2 or pos2, max_hear_distance = 12}, true)
|
||||
end
|
||||
|
||||
return activation_count, new_fuel_cost
|
||||
end
|
||||
|
@ -1,5 +1,5 @@
|
||||
-- (c) 2015-2016 rnd
|
||||
-- Copyright (C) 2022-2023 мтест
|
||||
-- Copyright (C) 2022-2024 мтест
|
||||
-- See README.md for license details
|
||||
|
||||
local F, S = basic_machines.F, basic_machines.S
|
||||
@ -80,7 +80,7 @@ local function drop(_, meta, owner, prefer, pos1, node1, node1_name, source_ches
|
||||
inv:remove_item("main", stack)
|
||||
end
|
||||
elseif prefer == node1_name and inv:is_empty("main") then -- remove chest only if empty
|
||||
minetest.set_node(pos1, {name = "air"})
|
||||
minetest.remove_node(pos1)
|
||||
else
|
||||
return
|
||||
end
|
||||
@ -90,7 +90,7 @@ local function drop(_, meta, owner, prefer, pos1, node1, node1_name, source_ches
|
||||
return
|
||||
end
|
||||
elseif minetest.get_node(pos2).name == "air" then -- drop node
|
||||
minetest.set_node(pos1, {name = "air"})
|
||||
minetest.remove_node(pos1)
|
||||
|
||||
if prefer ~= "" then
|
||||
minetest.add_item(pos2, node_to_stack(node1, nil, node1_param2))
|
||||
|
@ -1,5 +1,5 @@
|
||||
-- (c) 2015-2016 rnd
|
||||
-- Copyright (C) 2022-2023 мтест
|
||||
-- Copyright (C) 2022-2024 мтест
|
||||
-- See README.md for license details
|
||||
|
||||
local F, S = basic_machines.F, basic_machines.S
|
||||
@ -18,7 +18,7 @@ local function normal(pos, meta, owner, prefer, pos1, node1, node1_name, source_
|
||||
prefer = prefer or meta:get_string("prefer")
|
||||
source_chest = source_chest or mover_chests[node1_name]
|
||||
local third_upgradetype = upgradetype == 3
|
||||
local node2_name, target_chest, node_def, node1_param2, new_fuel_cost, last_pos2
|
||||
local node2_name, target_chest, node_def, node1_param2, new_fuel_cost, last_pos2, sound_def
|
||||
|
||||
-- checks
|
||||
if prefer ~= "" then -- filter check
|
||||
@ -117,6 +117,8 @@ local function normal(pos, meta, owner, prefer, pos1, node1, node1_name, source_
|
||||
return
|
||||
end
|
||||
|
||||
sound_def = (node_def.sounds or {}).place -- preparing for sound_play
|
||||
|
||||
if third_upgradetype then
|
||||
if fuel_cost > 0 then
|
||||
local length_pos2 = #pos2
|
||||
@ -190,7 +192,7 @@ local function normal(pos, meta, owner, prefer, pos1, node1, node1_name, source_
|
||||
|
||||
minetest.bulk_set_node(pos1, {name = "air"})
|
||||
else
|
||||
minetest.set_node(pos1, {name = "air"})
|
||||
minetest.remove_node(pos1)
|
||||
|
||||
local inv = minetest.get_meta(pos2):get_inventory()
|
||||
if prefer ~= "" then
|
||||
@ -201,18 +203,19 @@ local function normal(pos, meta, owner, prefer, pos1, node1, node1_name, source_
|
||||
end
|
||||
end
|
||||
elseif node2_name == "air" and not third_upgradetype then -- move node from pos1 to pos2
|
||||
minetest.set_node(pos1, {name = "air"})
|
||||
sound_def = ((node_def or minetest.registered_nodes[node1_name] or {}).sounds or {}).place -- preparing for sound_play
|
||||
minetest.remove_node(pos1)
|
||||
minetest.set_node(pos2, node1)
|
||||
else -- nothing to do
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
-- play sound
|
||||
local activation_count = meta:get_int("activation_count")
|
||||
-- if activation_count < 16 then
|
||||
-- minetest.sound_play("basic_machines_transport", {pos = last_pos2 or pos2, gain = 1, max_hear_distance = 8}, true)
|
||||
-- end
|
||||
|
||||
if sound_def and activation_count < 16 then -- play sound
|
||||
minetest.sound_play(sound_def, {pitch = 0.9, pos = last_pos2 or pos2, max_hear_distance = 12}, true)
|
||||
end
|
||||
|
||||
return activation_count, new_fuel_cost
|
||||
end
|
||||
|
@ -1,5 +1,5 @@
|
||||
-- (c) 2015-2016 rnd
|
||||
-- Copyright (C) 2022-2023 мтест
|
||||
-- Copyright (C) 2022-2024 мтест
|
||||
-- See README.md for license details
|
||||
|
||||
local F, S = basic_machines.F, basic_machines.S
|
||||
@ -8,11 +8,12 @@ local check_palette_index = basic_machines.check_palette_index
|
||||
|
||||
local function transport(pos, meta, owner, prefer, pos1, node1, node1_name, source_chest, pos2)
|
||||
prefer = prefer or meta:get_string("prefer")
|
||||
local node_def, sound_def
|
||||
|
||||
-- checks
|
||||
if prefer ~= "" then -- filter check
|
||||
if prefer == node1_name then -- only take preferred node
|
||||
local node_def = minetest.registered_nodes[prefer]
|
||||
node_def = minetest.registered_nodes[prefer]
|
||||
if node_def then
|
||||
if not check_palette_index(meta, node1, node_def) then -- only take preferred node with palette_index
|
||||
return
|
||||
@ -30,8 +31,8 @@ local function transport(pos, meta, owner, prefer, pos1, node1, node1_name, sour
|
||||
local node2_name = minetest.get_node(pos2).name
|
||||
|
||||
-- transport items
|
||||
if source_chest and mover_chests[node2_name] then -- transport all chest items from source to target
|
||||
if prefer == node2_name then -- transport only with same chest type
|
||||
if source_chest and mover_chests[node2_name] then -- take all items from chest to chest (filter needed)
|
||||
if prefer == node2_name then -- only to same chest type
|
||||
local inv2 = minetest.get_meta(pos2):get_inventory()
|
||||
if inv2:is_empty("main") then
|
||||
local inv1 = minetest.get_meta(pos1):get_inventory()
|
||||
@ -45,19 +46,20 @@ local function transport(pos, meta, owner, prefer, pos1, node1, node1_name, sour
|
||||
return
|
||||
end
|
||||
elseif node2_name == "air" then -- transport nodes parallel as defined by source1 and target, clone with complete metadata
|
||||
sound_def = ((node_def or minetest.registered_nodes[node1_name] or {}).sounds or {}).place -- preparing for sound_play
|
||||
local meta1 = minetest.get_meta(pos1):to_table()
|
||||
minetest.set_node(pos2, node1)
|
||||
if meta1 then minetest.get_meta(pos2):from_table(meta1) end
|
||||
minetest.set_node(pos1, {name = "air"})
|
||||
minetest.remove_node(pos1)
|
||||
else -- nothing to do
|
||||
return
|
||||
end
|
||||
|
||||
-- play sound
|
||||
local activation_count = meta:get_int("activation_count")
|
||||
-- if activation_count < 16 then
|
||||
-- minetest.sound_play("basic_machines_transport", {pos = pos2, gain = 1, max_hear_distance = 8}, true)
|
||||
-- end
|
||||
|
||||
if sound_def and activation_count < 16 then -- play sound
|
||||
minetest.sound_play(sound_def, {pitch = 0.9, pos = pos2, max_hear_distance = 12}, true)
|
||||
end
|
||||
|
||||
return activation_count
|
||||
end
|
||||
|
15
space.lua
15
space.lua
@ -1,5 +1,5 @@
|
||||
-- (c) 2015-2016 rnd
|
||||
-- Copyright (C) 2022-2023 мтест
|
||||
-- Copyright (C) 2022-2024 мтест
|
||||
-- See README.md for license details
|
||||
|
||||
local S = basic_machines.S
|
||||
@ -10,10 +10,13 @@ local space_start_eff = basic_machines.settings.space_start_eff
|
||||
local use_player_monoids = minetest.global_exists("player_monoids")
|
||||
local use_basic_protect = minetest.global_exists("basic_protect")
|
||||
|
||||
minetest.register_on_punchplayer(function(player, hitter, _, tool_capabilities, dir)
|
||||
if player:get_pos().y > space_start and hitter:is_player() then
|
||||
if vector.length(player:get_velocity()) > 0 then
|
||||
player:add_velocity(vector.multiply(dir, 5)) -- push player a little
|
||||
minetest.register_on_punchplayer(function(player, hitter, time_from_last_punch, tool_capabilities)
|
||||
if player:get_pos().y > space_start and hitter and hitter:is_player() then
|
||||
if time_from_last_punch > 0.8 and vector.length(player:get_velocity()) > 0.2 then
|
||||
local dir = vector.subtract(player:get_pos(), hitter:get_pos())
|
||||
local unit_vector = vector.divide(dir, vector.length(dir))
|
||||
local punch_vector = {x = 5, y = 0.9, z = 5}
|
||||
player:add_velocity(vector.multiply(unit_vector, punch_vector)) -- push player a little
|
||||
end
|
||||
if tool_capabilities and ((tool_capabilities.damage_groups or {}).fleshy or 0) == 1 then
|
||||
return true
|
||||
@ -188,7 +191,7 @@ if basic_machines.use_default then
|
||||
interval = 10,
|
||||
chance = 1,
|
||||
action = function(pos)
|
||||
minetest.set_node(pos, {name = "air"})
|
||||
minetest.remove_node(pos)
|
||||
end
|
||||
})
|
||||
end
|
||||
|
@ -1,5 +1,5 @@
|
||||
-- (c) 2015-2016 rnd
|
||||
-- Copyright (C) 2022-2023 мтест
|
||||
-- Copyright (C) 2022-2024 мтест
|
||||
-- See README.md for license details
|
||||
|
||||
local F, S = basic_machines.F, basic_machines.S
|
||||
@ -444,7 +444,7 @@ minetest.register_abm({
|
||||
|
||||
local function generator_near_found(pos, name) -- check to prevent too many generators being placed at one place
|
||||
if minetest.find_node_near(pos, 15, {"basic_machines:generator"}) then
|
||||
minetest.set_node(pos, {name = "air"})
|
||||
minetest.remove_node(pos)
|
||||
minetest.add_item(pos, "basic_machines:generator")
|
||||
minetest.chat_send_player(name, S("Generator: Interference from nearby generator detected"))
|
||||
return true
|
||||
|
Loading…
x
Reference in New Issue
Block a user