Minor improvements

master
Joachim Stolberg 2022-06-23 20:36:36 +02:00
parent 998689aafd
commit b936024113
11 changed files with 240 additions and 119 deletions

View File

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

View File

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

View File

@ -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 "<circular reference>"
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

View File

@ -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"})
techage.register_simple_nodes({"techage:power_lineS"}, true)

View File

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

View File

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

View File

@ -30,6 +30,7 @@ local HELP = S("Syntax:\n") ..
S(" - 'send <node num> <cmnd>' (techage command)\n") ..
S(" - 'goto <num>' (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

View File

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

View File

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

View File

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

View File

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