From b936024113dd8d6417a821a96f5c8aaf670f36a8 Mon Sep 17 00:00:00 2001 From: Joachim Stolberg Date: Thu, 23 Jun 2022 20:36:36 +0200 Subject: [PATCH] Minor improvements --- basic_machines/recycler.lua | 2 +- basis/fly_lib.lua | 114 +++++++++++++++++++++++----- basis/lib.lua | 110 +++++++++++++-------------- items/registered_nodes.lua | 2 +- logic/button.lua | 5 +- logic/light_detector.lua | 2 +- logic/sequencer2.lua | 3 +- manuals/ta4_lua_controller_EN.md | 2 + move_controller/doorcontroller2.lua | 36 ++------- move_controller/movecontroller.lua | 81 ++++++++++++++++++-- oil/drillbox.lua | 2 +- 11 files changed, 240 insertions(+), 119 deletions(-) diff --git a/basic_machines/recycler.lua b/basic_machines/recycler.lua index b2d51d4..5e82e49 100644 --- a/basic_machines/recycler.lua +++ b/basic_machines/recycler.lua @@ -45,7 +45,7 @@ local SpecialItems = { ["dye:black"] = "", ["techage:basalt_glass_thin"] = "", ["group:stone"] = "techage:sieved_gravel", - ["basic_materials:plastic_sheet"] = "", + --["basic_materials:plastic_sheet"] = "", ["group:wood"] = "default:stick 5", ["techage:basalt_glass"] = "", ["default:junglewood"] = "default:stick 5", diff --git a/basis/fly_lib.lua b/basis/fly_lib.lua index 49c9076..742407b 100644 --- a/basis/fly_lib.lua +++ b/basis/fly_lib.lua @@ -134,13 +134,39 @@ local function dest_offset(lpath) return offs end +------------------------------------------------------------------------------- +-- Protect the doors from being opened by hand +------------------------------------------------------------------------------- +local function new_on_rightclick(old_on_rightclick) + return function(pos, node, clicker, itemstack, pointed_thing) + if M(pos):contains("ta_door_locked") then + return itemstack + end + if old_on_rightclick then + return old_on_rightclick(pos, node, clicker, itemstack, pointed_thing) + else + return itemstack + end + end +end + +function flylib.protect_door_from_being_opened(name) + -- Change on_rightclick function. + local ndef = minetest.registered_nodes[name] + if ndef then + local old_on_rightclick = ndef.on_rightclick + minetest.override_item(ndef.name, { + on_rightclick = new_on_rightclick(old_on_rightclick) + }) + end +end + ------------------------------------------------------------------------------- -- Entity / Move / Attach / Detach ------------------------------------------------------------------------------- local MIN_SPEED = 0.4 local MAX_SPEED = 8 local CORNER_SPEED = 4 -local SimpleNodes = techage.logic.SimpleNodes local function calc_speed(v) return math.sqrt(v.x * v.x + v.y * v.y + v.z * v.z) @@ -303,6 +329,7 @@ local function entity_to_node(pos, obj) minetest.set_node(pos, {name=name, param2=param2}) meta:from_table(metadata) meta:set_string("ta_move_block", "") + meta:set_int("ta_door_locked", 1) return end local meta = M(pos) @@ -326,11 +353,14 @@ local function node_to_entity(start_pos) node = minetest.deserialize(meta:get_string("ta_move_block")) metadata = {} meta:set_string("ta_move_block", "") - else + meta:set_string("ta_block_locked", "true") + elseif not meta:contains("ta_block_locked") then -- Block with other metadata node = minetest.get_node(start_pos) metadata = meta:to_table() minetest.after(0.2, minetest.remove_node, start_pos) + else + return end local obj = minetest.add_entity(start_pos, "techage:move_item") if obj then @@ -554,8 +584,7 @@ minetest.register_entity("techage:move_item", { local function is_valid_dest(pos) local node = minetest.get_node(pos) - local ndef = minetest.registered_nodes[node.name] - if ndef and ndef.buildable_to then + if techage.is_air_like(node.name) then return true end if not M(pos):contains("ta_move_block") then @@ -565,20 +594,9 @@ local function is_valid_dest(pos) end local function is_simple_node(pos) - -- special handling - local name = minetest.get_node(pos).name - if SimpleNodes[name] ~= nil then - return SimpleNodes[name] - end - - local ndef = minetest.registered_nodes[name] - if not ndef or name == "air" or name == "ignore" then return false end - -- don't remove nodes with some intelligence or undiggable nodes - if ndef.drop == "" then return false end - if ndef.diggable == false then return false end - if ndef.after_dig_node then return false end - - return true + local node = minetest.get_node(pos) + local ndef = minetest.registered_nodes[node.name] + return not techage.is_air_like(node.name) and techage.can_dig_node(node.name, ndef) end local function move_node(pos, pos1_idx, start_pos, lpath, max_speed, height, move2to1, handover, cpos) @@ -651,6 +669,43 @@ local function move_nodes(pos, meta, nvm, lpath, max_speed, height, move2to1, ha return true end +-- Move nodes from lpos1 by the given x/y/z 'line' +local function move_nodes2(pos, meta, lpos1, line, max_speed, height) + --print("move_nodes2", dump(lpos1), dump(line), max_speed, height) + local owner = meta:get_string("owner") + techage.counting_add(owner, #lpos1) + + local lpos2 = {} + for idx = 1, #lpos1 do + + local pos1 = lpos1[idx] + local pos2 = vector.add(lpos1[idx], line) + lpos2[idx] = pos2 + + if not minetest.is_protected(pos1, owner) and not minetest.is_protected(pos2, owner) then + if is_simple_node(pos1) and is_valid_dest(pos2) then + move_node(pos, idx, pos1, {line}, max_speed, height, false, false) + else + if not is_simple_node(pos1) then + meta:set_string("status", S("No valid node at the start position")) + else + meta:set_string("status", S("No valid destination position")) + end + end + else + if minetest.is_protected(pos1, owner) then + meta:set_string("status", S("Start position is protected")) + else + meta:set_string("status", S("Destination position is protected")) + end + return false, lpos1 + end + end + + meta:set_string("status", "") + return true, lpos2 +end + function flylib.move_to_other_pos(pos, move2to1) local meta = M(pos) local nvm = techage.get_nvm(pos) @@ -680,6 +735,29 @@ function flylib.move_to_other_pos(pos, move2to1) return move_nodes(pos, meta, nvm, lpath, max_speed, height, move2to1, handover) end +function flylib.move_to(pos, line) + local meta = M(pos) + local nvm = techage.get_nvm(pos) + local height = techage.in_range(meta:contains("height") and meta:get_float("height") or 1, 0, 1) + local max_speed = meta:contains("max_speed") and meta:get_int("max_speed") or MAX_SPEED + local resp + + resp, nvm.lastpos = move_nodes2(pos, meta, nvm.lastpos or nvm.lpos1, line, max_speed, height) + return resp +end + +function flylib.reset_move(pos) + local meta = M(pos) + local nvm = techage.get_nvm(pos) + local height = techage.in_range(meta:contains("height") and meta:get_float("height") or 1, 0, 1) + local max_speed = meta:contains("max_speed") and meta:get_int("max_speed") or MAX_SPEED + local move = vector.subtract(nvm.lpos1[1], (nvm.lastpos or nvm.lpos1)[1]) + local resp + + resp, nvm.lastpos = move_nodes2(pos, meta, nvm.lastpos or nvm.lpos1, move, max_speed, height) + return resp +end + -- rot is one of "l", "r", "2l", "2r" -- cpos is the center pos (optional) function flylib.rotate_nodes(pos, posses1, rot) diff --git a/basis/lib.lua b/basis/lib.lua index 33d2120..6311bc5 100644 --- a/basis/lib.lua +++ b/basis/lib.lua @@ -129,7 +129,6 @@ function techage.param2_turn_up(facedir, param2) end - ------------------------------------------------------------------------------- -- Rotate nodes around the center ------------------------------------------------------------------------------- @@ -181,12 +180,12 @@ function techage.rotate_around_center(nodes1, turn, cpos) return nodes2 end --- allowed for digging -local RegisteredNodesToBeDug = {} -function techage.register_node_to_be_dug(name) - RegisteredNodesToBeDug[name] = true -end +------------------------------------------------------------------------------- +-- Helper functions +------------------------------------------------------------------------------- +-- allowed for digging +local SimpleNodes = {} -- translation from param2 to dir (out of the node upwards) local Param2Dir = {} @@ -284,21 +283,54 @@ function techage.is_air_like(name) end -- returns true, if node can be dug, otherwise false -function techage.can_node_dig(node, ndef) - if RegisteredNodesToBeDug[node.name] then +function techage.can_dig_node(name, ndef) + if not ndef then return false end + if SimpleNodes[name] ~= nil then + return SimpleNodes[name] + end + + if ndef.groups and ndef.groups.techage_door == 1 then + SimpleNodes[name] = true return true end - if not ndef then return false end - if node.name == "ignore" then return false end - if node.name == "air" then return true end - if ndef.buildable_to == true then return true end - if ndef.diggable == false then return false end - if ndef.after_dig_node then return false end + if name == "ignore" then + SimpleNodes[name] = false + return false + end + if name == "air" then + SimpleNodes[name] = true + return true + end + if ndef.buildable_to == true then + SimpleNodes[name] = true + return true + end + -- don't remove nodes with some intelligence or undiggable nodes + if ndef.drop == "" then + SimpleNodes[name] = false + return false + end + if ndef.diggable == false then + SimpleNodes[name] = false + return false + end + if ndef.after_dig_node then + SimpleNodes[name] = false + return false + end -- add it to the white list - RegisteredNodesToBeDug[node.name] = true + SimpleNodes[name] = true return true end +-- Simple nodes +function techage.register_simple_nodes(node_names, is_valid) + if is_valid == nil then is_valid = true end + for _,name in ipairs(node_names or {}) do + SimpleNodes[name] = is_valid + end +end + techage.dig_states = { NOT_DIGGABLE = 1, INV_FULL = 2, @@ -432,50 +464,6 @@ function techage.item_image_small(x, y, itemname, tooltip_prefix) tooltip end -function techage.mydump(o, indent, nested, level) - local t = type(o) - if not level and t == "userdata" then - -- when userdata (e.g. player) is passed directly, print its metatable: - return "userdata metatable: " .. techage.mydump(getmetatable(o)) - end - if t ~= "table" then - return basic_dump(o) - end - -- Contains table -> true/nil of currently nested tables - nested = nested or {} - if nested[o] then - return "" - end - nested[o] = true - indent = " " - level = level or 1 - local t = {} - local dumped_indexes = {} - for i, v in ipairs(o) do - t[#t + 1] = techage.mydump(v, indent, nested, level + 1) - dumped_indexes[i] = true - end - for k, v in pairs(o) do - if not dumped_indexes[k] then - if type(k) ~= "string" or not is_valid_identifier(k) then - k = "["..techage.mydump(k, indent, nested, level + 1).."]" - end - v = techage.mydump(v, indent, nested, level + 1) - t[#t + 1] = k.." = "..v - end - end - nested[o] = nil - if indent ~= "" then - local indent_str = string.rep(indent, level) - local end_indent_str = string.rep(indent, level - 1) - return string.format("{%s%s%s}", - indent_str, - table.concat(t, ","..indent_str), - end_indent_str) - end - return "{"..table.concat(t, ", ").."}" -end - function techage.vector_dump(posses) local t = {} for _,pos in ipairs(posses) do @@ -504,6 +492,10 @@ function techage.register_mobs_mods(mod) techage.RegisteredMobsMods[mod] = true end +function techage.beduino_signed_var(val) + val = val or 0 + return val >= 32768 and val - 0x10000 or val +end ------------------------------------------------------------------------------- -- Terminal history buffer diff --git a/items/registered_nodes.lua b/items/registered_nodes.lua index 8ff4fd8..bf29591 100644 --- a/items/registered_nodes.lua +++ b/items/registered_nodes.lua @@ -67,4 +67,4 @@ techage.register_mobs_mods("mobf_trader") techage.register_mobs_mods("ts_vehicles_cars") -- Used as e.g. crane cable -techage.logic.register_doorcontroller_nodes({"techage:power_lineS"}) \ No newline at end of file +techage.register_simple_nodes({"techage:power_lineS"}, true) \ No newline at end of file diff --git a/logic/button.lua b/logic/button.lua index 9778e6d..651fc37 100644 --- a/logic/button.lua +++ b/logic/button.lua @@ -55,7 +55,10 @@ local function switch_off(pos, is_button) elseif name == "techage:ta4_button_on" then logic.swap_node(pos, "techage:ta4_button_off") end - logic.send_off(pos, M(pos)) + local meta = M(pos) + if not meta:contains("command") or meta:get_string("command") == "on" then + logic.send_off(pos, M(pos)) + end if not is_button then minetest.sound_play("techage_button", { pos = pos, diff --git a/logic/light_detector.lua b/logic/light_detector.lua index 3719311..4072f88 100755 --- a/logic/light_detector.lua +++ b/logic/light_detector.lua @@ -39,7 +39,7 @@ local function node_timer(pos) local nvm = techage.get_nvm(pos) - trigger = nvm.mode or 7 + local trigger = nvm.mode or 7 local pos_above = {x = pos.x, y = pos.y + 1, z = pos.z} if minetest.get_node_light(pos_above, nil) == nil then diff --git a/logic/sequencer2.lua b/logic/sequencer2.lua index a4db881..0151863 100644 --- a/logic/sequencer2.lua +++ b/logic/sequencer2.lua @@ -30,6 +30,7 @@ local HELP = S("Syntax:\n") .. S(" - 'send ' (techage command)\n") .. S(" - 'goto ' (jump to another line)\n") .. S(" - 'stop' (stop the execution)\n") .. + S(" - 'nop' (do nothing)\n") .. S("\n") .. S("Example:\n") .. " -- move controller commands\n" .. @@ -108,7 +109,7 @@ local function compile(s, tRes) tCode[idx] = {next_idx = tonumber(cmnd2) or 1} elseif cmnd1 == "stop" then tCode[idx] = false - elseif cmnd1 == nil then + elseif cmnd1 == nil or cmnd1 == "nop" then tCode[idx] = {} end old_idx = idx diff --git a/manuals/ta4_lua_controller_EN.md b/manuals/ta4_lua_controller_EN.md index 4c27f8e..07c1b61 100644 --- a/manuals/ta4_lua_controller_EN.md +++ b/manuals/ta4_lua_controller_EN.md @@ -401,6 +401,8 @@ Please note, that this is not a technical distinction, only a logical. | "a2b" | nil | TA4 Move Controller command to move the block(s) from position A to B | | "b2a" | nil | TA4 Move Controller command to move the block(s) from position B to A | | "move" | nil | TA4 Move Controller command to move the block(s) to the opposite position | +| "move2" | x,y,z | TA4 Move Controller command to move the block(s) by the given
x/y/z-distance. Valid ranges for x, y, and z are -100 to 100. | +| "reset" | nil | Reset TA4 Move Controller (move block(s) to start position) | | "left" | nil | TA4 Turn Controller command to turn the block(s) to the left | | "right" | nil | TA4 Turn Controller command to turn the block(s) to the right | | "uturn" | nil | TA4 Turn Controller command to turn the block(s) 180 degrees | diff --git a/move_controller/doorcontroller2.lua b/move_controller/doorcontroller2.lua index 664ec30..8004be2 100644 --- a/move_controller/doorcontroller2.lua +++ b/move_controller/doorcontroller2.lua @@ -23,24 +23,10 @@ local logic = techage.logic local MarkedNodes = {} -- t[player] = {{entity, pos},...} local CurrentPos -- to mark punched entities -local RegisteredNodes = {} -- to be checked before removed/placed local function is_simple_node(name) - -- special handling - if RegisteredNodes[name] ~= nil then - return RegisteredNodes[name] - end - local ndef = minetest.registered_nodes[name] - if not ndef or name == "air" then return true end - if ndef.groups and ndef.groups.techage_door == 1 then return true end - - -- don't remove nodes with some intelligence or undiggable nodes - if ndef.drop == "" then return false end - if ndef.diggable == false then return false end - if ndef.after_dig_node then return false end - - return true + return techage.can_dig_node(name, ndef) end local function unmark_position(name, pos) @@ -160,7 +146,7 @@ local function exchange_node(pos, item, param2) else flylib.remove_node(pos) end - if node.name ~= "air" then + if not techage.is_air_like(node.name) then return ItemStack(node.name), node.param2 else return ItemStack(), nil @@ -214,7 +200,7 @@ local function show_nodes(pos) gain = 1, max_hear_distance = 15}) end - return exchange_nodes(pos, nvm) + return exchange_nodes(pos, nvm, nil, "set") end end @@ -228,7 +214,7 @@ local function hide_nodes(pos) gain = 1, max_hear_distance = 15}) end - return exchange_nodes(pos, nvm) + return exchange_nodes(pos, nvm, nil, "dig") end end @@ -435,12 +421,6 @@ minetest.register_on_punchnode(function(pos, node, puncher, pointed_thing) end end) -function logic.register_doorcontroller_nodes(node_names) - for _,name in ipairs(node_names or {}) do - RegisteredNodes[name] = true - end -end - local Doors = { "doors:door_steel", "doors:prison_door", @@ -459,7 +439,8 @@ local Doors = { for _, name in ipairs(Doors) do for _, postfix in ipairs({"a", "b", "c", "d"}) do - logic.register_doorcontroller_nodes({name .. "_" .. postfix}) + techage.register_simple_nodes({name .. "_" .. postfix}, true) + flylib.protect_door_from_being_opened(name .. "_" .. postfix) end end @@ -472,8 +453,7 @@ local ProtectorDoors = { for _, name in ipairs(ProtectorDoors) do for _, postfix in ipairs({"b_1", "b_2", "t_1", "t_2"}) do - logic.register_doorcontroller_nodes({name .. "_" .. postfix}) + techage.register_simple_nodes({name .. "_" .. postfix}, true) + flylib.protect_door_from_being_opened(name .. "_" .. postfix) end end - -logic.SimpleNodes = RegisteredNodes diff --git a/move_controller/movecontroller.lua b/move_controller/movecontroller.lua index 8afaeee..c6b3ecc 100644 --- a/move_controller/movecontroller.lua +++ b/move_controller/movecontroller.lua @@ -62,11 +62,30 @@ local WRENCH_MENU = { tooltip = S("Y-offset for non-player objects like vehicles (-0.5 to 0.5)"), default = "0.0", }, + { + type = "dropdown", + choices = "A-B / B-A,move xyz", + name = "opmode", + label = S("Operational mode"), + tooltip = S("Switch to the remote controlled 'move xyz' mode"), + default = "A-B / B-A", + }, } local function formspec(nvm, meta) local status = meta:get_string("status") local path = meta:contains("path") and meta:get_string("path") or "0,3,0" + local buttons + if meta:get_string("opmode") == "move xyz" then + buttons = "field[0.4,2.5;3.8,1;path;" .. S("Move distance") .. ";" .. path .. "]" .. + "button_exit[4.1,2.2;3.8,1;move2;" .. S("Move") .. "]" .. + "button_exit[0.1,3.3;3.8,1;reset;" .. S("Reset") .. "]" + else + buttons = "field[0.4,2.5;3.8,1;path;" .. S("Move distance (A to B)") .. ";" .. path .. "]" .. + "button_exit[0.1,3.3;3.8,1;moveAB;" .. S("Move A-B") .. "]" .. + "button_exit[4.1,3.3;3.8,1;moveBA;" .. S("Move B-A") .. "]" .. + "button[4.1,2.2;3.8,1;store;" .. S("Store") .. "]" + end return "size[8,5]" .. default.gui_bg .. default.gui_bg_img .. @@ -76,10 +95,7 @@ local function formspec(nvm, meta) techage.wrench_image(7.4, -0.05) .. "button[0.1,0.8;3.8,1;record;" .. S("Record") .. "]" .. "button[4.1,0.8;3.8,1;done;" .. S("Done") .. "]" .. - "field[0.4,2.5;3.8,1;path;" .. S("Move distance (A to B)") .. ";" .. path .. "]" .. - "button[4.1,2.2;3.8,1;store;" .. S("Store") .. "]" .. - "button_exit[0.1,3.3;3.8,1;moveAB;" .. S("Move A-B") .. "]" .. - "button_exit[4.1,3.3;3.8,1;moveBA;" .. S("Move B-A") .. "]" .. + buttons .. "label[0.3,4.3;" .. status .. "]" end @@ -163,9 +179,30 @@ minetest.register_node("techage:ta4_movecontroller", { mark.stop(name) end meta:set_string("formspec", formspec(nvm, meta)) + elseif fields.move2 then + if fly.to_vector(fields.path or "", MAX_DIST) then + meta:set_string("path", fields.path) + end + local line = fly.to_vector(meta:get_string("path")) + if line then + nvm.running = true + fly.move_to(pos, line) + end + elseif fields.reset then + nvm.running = true + fly.reset_move(pos) end end, + on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) + if not clicker or minetest.is_protected(pos, clicker:get_player_name()) then + return + end + local meta = M(pos) + local nvm = techage.get_nvm(pos) + meta:set_string("formspec", formspec(nvm, meta)) + end, + after_dig_node = function(pos, oldnode, oldmetadata, digger) local name = digger:get_player_name() mark.unmark_all(name) @@ -185,28 +222,43 @@ local INFO = [[Commands: 'state', 'a2b', 'b2a', 'move']] techage.register_node({"techage:ta4_movecontroller"}, { on_recv_message = function(pos, src, topic, payload) local nvm = techage.get_nvm(pos) + local move_xyz = M(pos):get_string("opmode") == "move xyz" if topic == "info" then return INFO elseif topic == "state" then return nvm.running and "running" or "stopped" - elseif topic == "a2b" then + elseif not move_xyz and topic == "a2b" then nvm.moveBA = true nvm.running = true return fly.move_to_other_pos(pos, false) - elseif topic == "b2a" then + elseif not move_xyz and topic == "b2a" then nvm.moveBA = false nvm.running = true return fly.move_to_other_pos(pos, true) - elseif topic == "move" then + elseif move_xyz and topic == "move" then nvm.moveBA = nvm.moveBA == false nvm.running = true return fly.move_to_other_pos(pos, nvm.moveBA == false) + elseif move_xyz and topic == "move2" then + local line = fly.to_vector(payload) + if line then + nvm.running = true + nvm.controller_mode = true + return fly.move_to(pos, line) + end + return false + elseif topic == "reset" then + nvm.running = true + nvm.controller_mode = true + return fly.reset_move(pos) end return false end, on_beduino_receive_cmnd = function(pos, src, topic, payload) local nvm = techage.get_nvm(pos) - if topic == 11 then + local move_xyz = M(pos):get_string("opmode") == "move xyz" + --print("on_beduino_receive_cmnd", P2S(pos), move_xyz, topic, payload[1]) + if not move_xyz and topic == 11 then if payload[1] == 1 then nvm.moveBA = true nvm.running = true @@ -220,6 +272,19 @@ techage.register_node({"techage:ta4_movecontroller"}, { nvm.running = true return fly.move_to_other_pos(pos, nvm.moveBA == false) and 0 or 3 end + elseif move_xyz and topic == 18 then -- move xyz + local line = { + x = techage.in_range(techage.beduino_signed_var(payload[1]), -10, 10), + y = techage.in_range(techage.beduino_signed_var(payload[2]), -10, 10), + z = techage.in_range(techage.beduino_signed_var(payload[3]), -10, 10), + } + nvm.running = true + nvm.controller_mode = true + return fly.move_to(pos, line) and 0 or 3 + elseif move_xyz and topic == 19 then -- reset + nvm.running = true + nvm.controller_mode = true + return fly.reset_move(pos) and 0 or 3 else return 2 end diff --git a/oil/drillbox.lua b/oil/drillbox.lua index 0061596..63b9c92 100644 --- a/oil/drillbox.lua +++ b/oil/drillbox.lua @@ -149,7 +149,7 @@ local function drilling(pos, crd, nvm, inv) inv:remove_item("src", ItemStack("techage:oil_drillbit")) nvm.drill_pos.y = nvm.drill_pos.y-1 crd.State:keep_running(pos, nvm, COUNTDOWN_TICKS) - elseif techage.can_node_dig(node, ndef) then + elseif techage.can_dig_node(node.name, ndef) then local drop_name = techage.dropped_node(node, ndef) if drop_name then local item = ItemStack(drop_name)