Add recipeblock and mba_detector, improve ta4 pump and ta4 autocrafter

This commit is contained in:
Joachim Stolberg 2021-11-28 14:42:18 +01:00
parent a2d39706cf
commit fea1a6981c
20 changed files with 603 additions and 62 deletions

View File

@ -189,6 +189,17 @@ local function normalize(item_list)
return item_list
end
local function get_input_from_recipeblock(pos, number, idx)
local own_num = M(pos):get_string("node_number")
local owner = M(pos):get_string("owner")
if techage.check_numbers(number, owner) then
local input = techage.send_single(own_num, number, "input", idx)
if input and type(input) == "string" then
return input
end
end
end
local function on_output_change(pos, inventory, stack)
if not stack then
inventory:set_list("output", {})
@ -212,6 +223,47 @@ local function on_output_change(pos, inventory, stack)
after_recipe_change(pos, inventory)
end
local function determine_recipe_items(pos, input)
if input and type(input) == "string" then
-- Test if "<node-number>.<recipe-number>" input
local num, idx = unpack(string.split(input, ".", false, 1))
if num and idx then
input = get_input_from_recipeblock(pos, num, idx)
end
if input then
-- "<item>,<item>,..." input
local items = string.split(input, ",", true, 8)
if items and type(items) == "table" and next(items) then
return items
end
end
end
end
local function on_new_recipe(pos, input)
local items = determine_recipe_items(pos, input)
if items then
input = {
method = "normal",
width = 3,
items = items,
}
local output, _ = minetest.get_craft_result(input)
if output.item:get_name() ~= "" then
local inv = M(pos):get_inventory()
for i = 1, 9 do
inv:set_stack("recipe", i, input.items[i])
end
after_recipe_change(pos, inv)
end
else
local inv = M(pos):get_inventory()
inv:set_list("recipe", {})
after_recipe_change(pos, inv)
end
end
local function allow_metadata_inventory_put(pos, listname, index, stack, player)
if minetest.is_protected(pos, player:get_player_name()) then
@ -346,6 +398,8 @@ tiles.act = {
},
}
local INFO = [[Commands: 'state', 'recipe']]
local tubing = {
on_inv_request = function(pos, in_dir, access_type)
if access_type == "push" then
@ -378,7 +432,20 @@ local tubing = {
end
end,
on_recv_message = function(pos, src, topic, payload)
return CRD(pos).State:on_receive_message(pos, topic, payload)
if topic == "recipe" and CRD(pos).stage == 4 then
if payload and payload ~= "" then
local inv = M(pos):get_inventory()
on_new_recipe(pos, payload)
return true
else
local inv = M(pos):get_inventory()
return inv:get_stack("output", 1):get_name()
end
elseif topic == "info" and CRD(pos).stage == 4 then
return INFO
else
return CRD(pos).State:on_receive_message(pos, topic, payload)
end
end,
on_node_load = function(pos)
CRD(pos).State:on_node_load(pos)
@ -410,7 +477,7 @@ local node_name_ta2, node_name_ta3, node_name_ta4 =
num_items = {0,1,2,4},
power_consumption = {0,4,6,9},
},
{false, true, true, false}) -- TA2/TA3
{false, true, true, true}) -- TA2/TA3/TA4
minetest.register_craft({
output = node_name_ta2,
@ -430,9 +497,18 @@ minetest.register_craft({
},
})
minetest.register_craft({
output = node_name_ta4,
recipe = {
{"", "default:diamond", ""},
{"", node_name_ta3, ""},
{"", "techage:ta4_wlanchip", ""},
},
})
local Cable = techage.ElectricCable
local power = networks.power
techage.register_node_for_v1_transition({"techage:ta3_autocrafter_pas"}, function(pos, node)
techage.register_node_for_v1_transition({"techage:ta3_autocrafter_pas", "techage:ta4_autocrafter_pas"}, function(pos, node)
power.update_network(pos, nil, Cable)
end)
end)

View File

@ -0,0 +1,244 @@
--[[
TechAge
=======
Copyright (C) 2019-2021 Joachim Stolberg
AGPL v3
See LICENSE.txt for more information
TA4 Recipe Block for the TA4 Autocrafter
]]--
-- for lazy programmers
local P2S = function(pos) if pos then return minetest.pos_to_string(pos) end end
local S2P = minetest.string_to_pos
local M = minetest.get_meta
local S = techage.S
local MAX_RECIPE = 10
local function recipes_formspec(x, y, idx)
return "container[" .. x .. "," .. y .. "]" ..
"background[0,0;8,3.2;techage_form_grey.png]" ..
"list[context;input;0.1,0.1;3,3;]" ..
"image[3,1.1;1,1;techage_form_arrow.png]" ..
"list[context;output;3.9,1.1;1,1;]" ..
"button[5.5,1.1;1,1;priv;<<]" ..
"button[6.5,1.1;1,1;next;>>]" ..
"label[5.5,0.5;"..S("Recipe") .. ": " .. idx .. "/" .. MAX_RECIPE .. "]" ..
"container_end[]"
end
local function formspec(pos, nvm)
return "size[8,7.4]"..
recipes_formspec(0, 0, nvm.recipe_idx or 1) ..
"list[current_player;main;0,3.6;8,4;]" ..
"listring[current_player;main]"..
"listring[context;src]" ..
"listring[current_player;main]"..
"listring[context;dst]" ..
"listring[current_player;main]"
end
local function determine_new_input(pos, inv)
local output = inv:get_stack("output", 1):get_name()
if output and output ~= "" then
local recipe = minetest.get_craft_recipe(output)
if recipe.items and recipe.type == "normal" then
for i = 1, 9 do
local name = recipe.items[i]
if name then
if minetest.registered_items[name] then
inv:set_stack("input", i, name)
end
end
end
inv:set_stack("output", 1, recipe.output)
end
else
for i = 1, 9 do
inv:set_stack("input", i, nil)
end
end
end
local function determine_new_output(pos, inv)
local items = {}
for i = 1, 9 do
items[i] = inv:get_stack("input", i):get_name()
end
local input = {
method = "normal",
width = 3,
items = items,
}
local output, _ = minetest.get_craft_result(input)
inv:set_stack("output", 1, output.item)
end
local function get_recipe(inv)
local items = {}
local last_idx = 0
for i = 1, 9 do
local name = inv:get_stack("input", i):get_name()
if name ~= "" then
last_idx = i
end
items[i] = name
end
local input = table.concat(items, ",", 1, last_idx)
local stack = inv:get_stack("output", 1)
return {
input = input,
output = stack:get_name() .. " " .. stack:get_count()
}
end
local function after_recipe_change(pos, inv, listname)
if listname == "input" then
determine_new_output(pos, inv)
else
determine_new_input(pos, inv)
end
local nvm = techage.get_nvm(pos)
nvm.recipes = nvm.recipes or {}
nvm.recipes[nvm.recipe_idx or 1] = get_recipe(inv)
end
local function update_inventor(pos, inv, idx)
local nvm = techage.get_nvm(pos)
nvm.recipes = nvm.recipes or {}
local recipe = nvm.recipes[idx]
if recipe then
local items = string.split(recipe.input, ",", true)
for i = 1, 9 do
inv:set_stack("input", i, items[i] or "")
end
inv:set_stack("output", 1, recipe.output)
else
for i = 1, 9 do
inv:set_stack("input", i, nil)
end
inv:set_stack("output", 1, nil)
end
end
local function allow_metadata_inventory_put(pos, listname, index, stack, player)
if minetest.is_protected(pos, player:get_player_name()) then
return 0
end
local inv = M(pos):get_inventory()
local list = inv:get_list(listname)
stack:set_count(1)
inv:set_stack(listname, index, stack)
after_recipe_change(pos, inv, listname)
return 0
end
local function allow_metadata_inventory_take(pos, listname, index, stack, player)
if minetest.is_protected(pos, player:get_player_name()) then
return 0
end
local inv = M(pos):get_inventory()
inv:set_stack(listname, index, nil)
after_recipe_change(pos, inv, listname)
return 0
end
local function allow_metadata_inventory_move(pos, from_list, from_index, to_list, to_index, count, player)
if minetest.is_protected(pos, player:get_player_name()) then
return 0
end
local inv = M(pos):get_inventory()
if from_list == to_list then
minetest.after(0.1, after_recipe_change, pos, inv, from_list)
return 1
end
return 0
end
minetest.register_node("techage:ta4_recipeblock", {
description = S("TA4 Recipe Block"),
tiles = {
-- up, down, right, left, back, front
"techage_filling_ta4.png^techage_frame_ta4_top.png",
"techage_filling_ta4.png^techage_frame_ta4_top.png",
"techage_filling_ta4.png^techage_frame_ta4.png^techage_appl_recipeblock.png",
},
on_construct = function(pos)
local inv = M(pos):get_inventory()
inv:set_size('input', 9)
inv:set_size('output', 1)
end,
after_place_node = function(pos, placer, itemstack)
local nvm = techage.get_nvm(pos)
local number = techage.add_node(pos, "techage:ta4_chest")
M(pos):set_string("owner", placer:get_player_name())
M(pos):set_string("node_number", number)
M(pos):set_string("formspec", formspec(pos, nvm))
M(pos):set_string("infotext", S("TA4 Recipe Block") .. " " .. number)
end,
on_receive_fields = function(pos, formname, fields, player)
if minetest.is_protected(pos, player:get_player_name()) then
return
end
local nvm = techage.get_nvm(pos)
nvm.recipe_idx = nvm.recipe_idx or 1
if fields.next == ">>" then
nvm.recipe_idx = techage.in_range(nvm.recipe_idx + 1, 1, MAX_RECIPE)
elseif fields.priv == "<<" then
nvm.recipe_idx = techage.in_range(nvm.recipe_idx - 1, 1, MAX_RECIPE)
end
local inv = M(pos):get_inventory()
update_inventor(pos, inv, nvm.recipe_idx or 1)
M(pos):set_string("formspec", formspec(pos, nvm))
end,
after_dig_node = function(pos, oldnode, oldmetadata, digger)
techage.remove_node(pos, oldnode, oldmetadata)
techage.del_mem(pos)
end,
allow_metadata_inventory_put = allow_metadata_inventory_put,
allow_metadata_inventory_take = allow_metadata_inventory_take,
allow_metadata_inventory_move = allow_metadata_inventory_move,
paramtype2 = "facedir",
groups = {choppy=2, cracky=2, crumbly=2},
is_ground_content = false,
sounds = default.node_sound_wood_defaults(),
})
techage.register_node({"techage:ta4_recipeblock"}, {
on_recv_message = function(pos, src, topic, payload)
local nvm = techage.get_nvm(pos)
if topic == "input" and payload and payload ~= "" then
nvm.recipes = nvm.recipes or {}
local recipe = nvm.recipes[tonumber(payload) or 1]
if recipe then
return recipe.input
end
else
return "unsupported"
end
end,
})
minetest.register_craft({
output = "techage:ta4_recipeblock",
recipe = {
{"techage:ta4_carbon_fiber", "dye:blue", "techage:aluminum"},
{"", "basic_materials:ic", ""},
{"default:steel_ingot", "techage:ta4_wlanchip", "default:steel_ingot"},
},
})

View File

@ -547,7 +547,7 @@ end
minetest.register_chatcommand("ta_send", {
description = minetest.formspec_escape(
"Send a techage command to the block with the number given: /ta_send <number> <topic> [<data>]"),
"Send a techage command to the block with the number given: /ta_send <number> <command> [<data>]"),
func = function(name, param)
local num, cmnd, payload = param:match('^([0-9]+)%s+(%w+)%s*(.*)$')
@ -563,6 +563,43 @@ minetest.register_chatcommand("ta_send", {
return false, "Destination block is protected"
end
end
return false, "Syntax: /ta_send <number> <topic> [<data>]"
return false, "Syntax: /ta_send <number> <command> [<data>]"
end
})
minetest.register_chatcommand("expoints", {
privs = {
server = true
},
func = function(name, param)
local player_name, points = param:match("^(%S+)%s*(%d*)$")
if player_name then
local player = minetest.get_player_by_name(player_name)
if player then
if points and points ~= "" then
if techage.set_expoints(player, tonumber(points)) then
return true, "The player "..player_name.." now has "..points.." experience points."
end
else
points = techage.get_expoints(player)
return true, "The player "..player_name.." has "..points.." experience points."
end
else
return false, "Unknown player "..player_name
end
end
return false, "Syntax error! Syntax: /expoints <name> [<points>]"
end
})
minetest.register_chatcommand("my_expoints", {
func = function(name, param)
local player = minetest.get_player_by_name(name)
if player then
local points = techage.get_expoints(player)
if points then
return true, "You have "..points.." experience points."
end
end
end
})

View File

@ -20,6 +20,36 @@ local S = techage.S
local flylib = {}
local function lvect_add_vec(lvect1, offs)
if not lvect1 or not offs then return end
local lvect2 = {}
for _, v in ipairs(lvect1) do
lvect2[#lvect2 + 1] = vector.add(v, offs)
end
return lvect2
end
local function lvect_add(lvect1, lvect2)
if not lvect1 or not lvect2 then return end
local lvect3 = {}
for i, v in ipairs(lvect1) do
lvect3[#lvect3 + 1] = vector.add(v, lvect2[i])
end
return lvect3
end
local function lvect_subtract(lvect1, lvect2)
if not lvect1 or not lvect2 then return end
local lvect3 = {}
for i, v in ipairs(lvect1) do
lvect3[#lvect3 + 1] = vector.subtract(v, lvect2[i])
end
return lvect3
end
-------------------------------------------------------------------------------
-- to_path function for the fly/move path
-------------------------------------------------------------------------------
@ -294,7 +324,10 @@ end
local function determine_dir(pos1, pos2)
local vdist = vector.subtract(pos2, pos1)
local ndist = vector.length(vdist)
return vector.divide(vdist, ndist)
if ndist > 0 then
return vector.divide(vdist, ndist)
end
return {x=0, y=0, z=0}
end
local function move_entity(obj, dest_pos, dir, is_corner)
@ -413,12 +446,14 @@ minetest.register_entity("techage:move_item", {
on_step = function(self, dtime, moveresult)
local stop_obj = function(obj, self)
local dest_pos = self.dest_pos
obj:move_to(self.dest_pos, true)
obj:set_acceleration({x=0, y=0, z=0})
obj:set_velocity({x=0, y=0, z=0})
self.dest_pos = nil
self.old_dist = nil
self.ttl = 2
return dest_pos
end
if self.dest_pos then
@ -431,24 +466,21 @@ minetest.register_entity("techage:move_item", {
-- Landing
if self.lpath and self.lpath[self.path_idx] then
if dist < 1 or dist > self.old_dist then
local dest_pos = self.dest_pos
stop_obj(obj, self)
local dest_pos = stop_obj(obj, self)
if not moveon_entity(obj, self, dest_pos) then
minetest.after(0.5, entity_to_node, dest_pos, obj)
end
return
end
elseif self.handover and dist < 0.2 or dist > self.old_dist then
local dest_pos = self.dest_pos
stop_obj(obj, self)
local dest_pos = stop_obj(obj, self)
if not handover_to(obj, self, dest_pos) then
minetest.after(0.5, entity_to_node, dest_pos, obj)
end
return
else
if dist < 0.05 or dist > self.old_dist then
local dest_pos = self.dest_pos
stop_obj(obj, self)
local dest_pos = stop_obj(obj, self)
minetest.after(0.5, entity_to_node, dest_pos, obj)
return
end
@ -513,17 +545,7 @@ local function is_simple_node(pos)
return true
end
local function table_add(tbl, offs)
if not tbl or not offs then return end
local tbl2 = {}
for _, v in ipairs(tbl) do
tbl2[#tbl2 + 1] = vector.add(v, offs)
end
return tbl2
end
local function move_node(pos, pos1_idx, start_pos, lpath, max_speed, height, move2to1, handover)
local function move_node(pos, pos1_idx, start_pos, lpath, max_speed, height, move2to1, handover, cpos)
local pos2 = next_path_pos(start_pos, lpath, 1)
--print("move_node", P2S(pos), P2S(start_pos), lpath, max_speed, height, move2to1, P2S(pos2))
if pos2 then
@ -547,7 +569,7 @@ local function move_node(pos, pos1_idx, start_pos, lpath, max_speed, height, mov
self.base_pos = pos
self.move2to1 = move2to1
self.handover = handover
print("move_node", P2S(start_pos), P2S(pos2), P2S(dir), P2S(pos))
--print("move_node", P2S(start_pos), P2S(pos2), P2S(dir), P2S(pos))
move_entity(obj, pos2, dir)
end
end
@ -598,13 +620,14 @@ function flylib.move_to_other_pos(pos, move2to1)
local handover
height = techage.in_range(height, 0, 1)
max_speed = techage.in_range(max_speed, MIN_SPEED, MAX_SPEED)
nvm.lpos1 = nvm.lpos1 or {}
local offs = dest_offset(lpath)
if move2to1 then
lpath = reverse_path(lpath)
end
nvm.lpos1 = nvm.lpos1 or {}
nvm.lpos2 = table_add(nvm.lpos1, offs)
-- calc destination positions
nvm.lpos2 = lvect_add_vec(nvm.lpos1, offs)
if move2to1 then
handover = meta:contains("handoverA") and meta:get_string("handoverA")

View File

@ -84,31 +84,33 @@ end
-------------------------------------------------------------------------------
-- Rotate nodes around the center
-------------------------------------------------------------------------------
local function center(nodes)
function techage.positions_center(lpos)
local c = {x=0, y=0, z=0}
for _,v in ipairs(nodes) do
for _,v in ipairs(lpos) do
c = vector.add(c, v)
end
c = vector.divide(c, #nodes)
c = vector.divide(c, #lpos)
c = vector.round(c)
c.y = 0
return c
end
local function rotate_around_axis(v, c, rot)
function techage.rotate_around_axis(v, c, turn)
local dx, dz = v.x - c.x, v.z - c.z
if rot == "l" then
if turn == "l" then
return {
x = c.x - dz,
y = v.y,
z = c.z + dx,
}
elseif rot == "r" then
elseif turn == "r" then
return {
x = c.x + dz,
y = v.y,
z = c.z - dx,
}
elseif turn == "" then
return v
else -- turn 180 degree
return {
x = c.x - dx,
@ -119,13 +121,13 @@ local function rotate_around_axis(v, c, rot)
end
-- Function returns a list ẃith the new node positions
-- rot is one of "l", "r", "2l", "2r"
-- turn is one of "l", "r", "2l", "2r"
-- cpos is the center pos (optional)
function techage.rotate_around_center(nodes1, rot, cpos)
cpos = cpos or center(nodes1)
function techage.rotate_around_center(nodes1, turn, cpos)
cpos = cpos or techage.positions_center(nodes1)
local nodes2 = {}
for _,pos in ipairs(nodes1) do
nodes2[#nodes2 + 1] = rotate_around_axis(pos, cpos, rot)
nodes2[#nodes2 + 1] = techage.rotate_around_axis(pos, cpos, turn)
end
return nodes2
end
@ -471,6 +473,7 @@ function techage.add_expoint(player)
local meta = player:get_meta()
if meta then
meta:set_int("techage_ex_points", meta:get_int("techage_ex_points") + 1)
return true
end
end
end
@ -480,6 +483,7 @@ function techage.set_expoints(player, ex_points)
local meta = player:get_meta()
if meta then
meta:set_int("techage_ex_points", ex_points)
return true
end
end
end

View File

@ -22,6 +22,19 @@ local range = techage.in_range
techage.recipes = {}
local GROUP_ITEMS = {
stone = "default:cobble",
wood = "default:wood",
book = "default:book",
sand = "default:sand",
leaves = "default:leaves",
stick = "default:stick",
tree = "default:tree",
vessel = "vessels:glass_bottle",
wool = "wool:white",
}
local RECIPE = {
output = {name = "", num = 0},
waste = {name = "", num = 0},
@ -137,3 +150,17 @@ function techage.recipes.get_recipe(name)
return NormalizedRecipes[name]
end
function techage.recipes.get_default_group_item_name(item_name)
if item_name and item_name:sub(1, 6) == "group:" then
local default_name = GROUP_ITEMS[item_name:sub(7)]
if default_name then
return default_name
end
end
return item_name
end
function techage.recipes.add_group_item(group, default_item_name)
GROUP_ITEMS[group] = default_item_name
end

View File

@ -1729,7 +1729,7 @@ techage.manual_DE.aText = {
"\n",
"Siehe TA3 Pumpe.\n"..
"\n"..
"Die TA4 Pumpe pumpt 8 Einheiten Flüssigkeit alle zwei Sekunden.\n"..
"Die TA4 Pumpe pumpt 8 Einheiten Flüssigkeit alle zwei Sekunden. Zusätzlich unterstützt die Pumpe das Kommando 'flowrate'. Damit kann die Gesamtdurchflussmenge durch die Pumpe abgefragt werden.\n"..
"\n"..
"\n"..
"\n",

View File

@ -1725,7 +1725,7 @@ techage.manual_EN.aText = {
"\n",
"See TA3 pump.\n"..
"\n"..
"The TA4 pump pumps 8 units of liquid every two seconds.\n"..
"The TA4 pump pumps 8 units of liquid every two seconds. The pump also supports the 'flowrate' command. This means that the total flow rate through the pump can be queried. \n"..
"\n"..
"\n"..
"\n",

View File

@ -33,8 +33,8 @@ elseif minetest.global_exists("minecart") and minecart.version < 1.08 then
elseif minetest.global_exists("lcdlib") and lcdlib.version < 1.01 then
minetest.log("error", "[techage] Techage requires lcdlib version 1.01 or newer!")
return
elseif minetest.global_exists("safer_lua") and safer_lua.version < 1.0 then
minetest.log("error", "[techage] Techage requires safer_lua version 1.0 or newer!")
elseif minetest.global_exists("safer_lua") and safer_lua.version < 1.01 then
minetest.log("error", "[techage] Techage requires safer_lua version 1.01 or newer!")
return
elseif minetest.global_exists("networks") and networks.version < 0.10 then
minetest.log("error", "[techage] Techage requires networks version 0.10 or newer!")
@ -187,6 +187,7 @@ dofile(MP.."/basic_machines/ta4_injector.lua")
dofile(MP.."/basic_machines/itemsource.lua")
dofile(MP.."/basic_machines/recycler.lua")
dofile(MP.."/basic_machines/concentrator.lua")
dofile(MP.."/basic_machines/recipeblock.lua")
-- Liquids II
dofile(MP.."/liquids/tank.lua")
@ -274,6 +275,7 @@ dofile(MP.."/logic/lua_logic.lua") -- old
dofile(MP.."/logic/logic_block.lua") -- new
dofile(MP.."/logic/node_detector.lua")
dofile(MP.."/logic/player_detector.lua")
dofile(MP.."/logic/mba_detector.lua")
dofile(MP.."/logic/cart_detector.lua")
dofile(MP.."/logic/collector.lua")
dofile(MP.."/logic/button_2x.lua")

View File

@ -25,6 +25,13 @@ local COUNTDOWN_TICKS = 4
local CYCLE_TIME = 2
local CAPA = 4
local WRENCH_MENU = {{
type = "output",
name = "flowrate",
label = S("Total flow rate"),
tooltip = S("Total flow rate in liquid units"),
}}
local State3 = techage.NodeStates:new({
node_name_passive = "techage:t3_pump",
node_name_active = "techage:t3_pump_on",
@ -52,13 +59,15 @@ local function pumping(pos, nvm, state, capa)
liquid.untake(pos, Pipe, Flip[outdir], name, leftover)
if leftover == taken then
state:blocked(pos, nvm)
return
return 0
end
return taken - leftover
end
state:keep_running(pos, nvm, COUNTDOWN_TICKS)
return
return taken
end
state:idle(pos, nvm)
return 0
end
local function after_place_node3(pos, placer)
@ -85,7 +94,7 @@ end
local function node_timer4(pos, elapsed)
local nvm = techage.get_nvm(pos)
pumping(pos, nvm, State4, CAPA * 2)
nvm.flowrate = (nvm.flowrate or 0) + pumping(pos, nvm, State4, CAPA * 2)
return State4:is_active(nvm)
end
@ -235,6 +244,7 @@ minetest.register_node("techage:t4_pump", {
groups = {cracky=2},
is_ground_content = false,
sounds = default.node_sound_metal_defaults(),
ta4_formspec = WRENCH_MENU,
})
minetest.register_node("techage:t4_pump_on", {
@ -261,7 +271,12 @@ techage.register_node({"techage:t3_pump", "techage:t3_pump_on"}, {
techage.register_node({"techage:t4_pump", "techage:t4_pump_on"}, {
on_recv_message = function(pos, src, topic, payload)
return State4:on_receive_message(pos, topic, payload)
if topic == "flowrate" then
local nvm = techage.get_nvm(pos)
return nvm.flowrate or 0
else
return State4:on_receive_message(pos, topic, payload)
end
end,
})

100
logic/mba_detector.lua Normal file
View File

@ -0,0 +1,100 @@
--[[
TechAge
=======
Copyright (C) 2017-2020 Joachim Stolberg
AGPL v3
See LICENSE.txt for more information
TA4 Mapblock Active Detector
]]--
-- for lazy programmers
local M = minetest.get_meta
local S = techage.S
local logic = techage.logic
minetest.register_node("techage:ta4_mbadetector", {
description = "TA4 Mapblock Active Detector",
inventory_image = 'techage_smartline_mba_detector_inv.png',
tiles = {
-- up, down, right, left, back, front
"techage_smartline.png",
"techage_smartline.png",
"techage_smartline.png",
"techage_smartline.png",
"techage_smartline.png",
"techage_smartline.png^techage_smartline_mba_detector.png",
},
drawtype = "nodebox",
node_box = {
type = "fixed",
fixed = {
{ -6/32, -6/32, 14/32, 6/32, 6/32, 16/32},
},
},
after_place_node = function(pos, placer)
local meta = M(pos)
logic.after_place_node(pos, placer, "techage:ta4_mbadetector", S("TA4 Mapblock Active Detector"))
logic.infotext(meta, S("TA4 Mapblock Active Detector"))
minetest.get_node_timer(pos):start(1)
end,
on_timer = function(pos, elapsed)
local mem = techage.get_mem(pos)
mem.gametime = minetest.get_gametime()
return true
end,
after_dig_node = function(pos, oldnode, oldmetadata, digger)
techage.remove_node(pos, oldnode, oldmetadata)
techage.del_mem(pos)
end,
paramtype = "light",
sunlight_propagates = true,
paramtype2 = "facedir",
groups = {choppy=2, cracky=2, crumbly=2},
is_ground_content = false,
sounds = default.node_sound_metal_defaults(),
})
minetest.register_craft({
output = "techage:ta4_mbadetector",
recipe = {
{"", "group:wood", "default:mese_crystal"},
{"", "techage:vacuum_tube", "default:copper_ingot"},
{"", "group:wood", ""},
},
})
techage.register_node({"techage:ta4_mbadetector"}, {
on_recv_message = function(pos, src, topic, payload)
if topic == "state" then
if minetest.compare_block_status then
if minetest.compare_block_status(pos, "active") then
return "on"
else
return "off"
end
else
local mem = techage.get_mem(pos)
local res = mem.gametime and mem.gametime > (minetest.get_gametime() - 2)
return res and "on" or "off"
end
else
return "unsupported"
end
end,
on_node_load = function(pos)
minetest.get_node_timer(pos):start(1)
end,
}
)

View File

@ -689,7 +689,7 @@ In einen TA4 Tank passen 2000 Einheiten oder 200 Fässer einer Flüssigkeit.
Siehe TA3 Pumpe.
Die TA4 Pumpe pumpt 8 Einheiten Flüssigkeit alle zwei Sekunden.
Die TA4 Pumpe pumpt 8 Einheiten Flüssigkeit alle zwei Sekunden. Zusätzlich unterstützt die Pumpe das Kommando `flowrate`. Damit kann die Gesamtdurchflussmenge durch die Pumpe abgefragt werden.
[ta4_pump|image]

View File

@ -681,7 +681,7 @@ A TA4 tank can hold 2000 units or 200 barrels of liquid.
See TA3 pump.
The TA4 pump pumps 8 units of liquid every two seconds.
The TA4 pump pumps 8 units of liquid every two seconds. The pump also supports the `flowrate` command. This means that the total flow rate through the pump can be queried.
[ta4_pump|image]

View File

@ -134,7 +134,8 @@ SaferLua directly supports the following standard functions:
- string.rep
- string.sub
- string.upper
- string.split
- string.split (result is an Array)
- string.split2 (result are multiple returns like the Lua function unpack)
- string.trim
For own function definitions, the menu tab 'func' can be used. Here you write your functions like:
@ -366,12 +367,14 @@ Please note, that this is not a technical distinction, only a logical.
| "depth" | number | Read the current depth value of a quarry block (1..80) |
| "load" | number | Read the load value in percent (0..100) of a tank, silo, accu, or battery block, or from the Signs Bot Box. Silo and tank return two values: The percentage value and the absolute value in units.<br /> Example: percent, absolute = $send_cmnd("223", "load") |
| "delivered" | number | Read the current delivered power value of a generator block. A power consuming block (accu) provides a negative value |
| "flowrate" | Total flow rate in liquid units | Only for TA4 Pumps |
| "action" | player-name, action-string | Only for Sensor Chests |
| "stacks" | Array with up to 4 Stores with the inventory content (see example) | Only for Sensor Chests |
| "count" | number | Read the item counter of the TA4 Item Detector block |
| "count" | number of items | Read the total amount of TA4 chest items. An optional number as `add_data` is used to address only one inventory slot (1..8, from left to right). |
| "itemstring" | item string of the given slot | Specific command for the TA4 8x2000 Chest to read the item type (technical name) of one chest slot, specified via `add_data` (1..8).<br />Example: s = $send_cmnd("223", "itemstring", 1) |
| "output" | recipe output string, <br />e.g.: "default:glass" | Only for the Industrial Furnace. If no recipe is active, the command returns "unknown" |
| "input" | `<index>` | Read a recipe from the TA4 Recipe Block. `<index>` is the number of the recipe. The block return a list of recipe items. |
@ -385,18 +388,23 @@ Please note, that this is not a technical distinction, only a logical.
| -------------------------------- | ------------ | ------------------------------------------------------------ |
| "on", "off" | nil | turn a node on/off (machine, lamp,...) |
| "red, "amber", "green", "off" | nil | set Signal Tower color |
| "red, "amber", "green", "off" | lamp number (1..4) | Set the signal lamp color. Valid for "TA4 2x Signal Lamp" and "TA4 4x Signal Lamp" |
| "port" | `<color>=on/off` | Enable/disable a Distributor filter slot..<br />Example: `yellow=on`<br />colors: "red", "green", "blue", "yellow" |
| "text" | text string | Text to be used for the Sensor Chest menu |
| "reset" | nil | Reset the item counter of the TA4 Item Detector block |
| "pull" | item string | Start the TA4 pusher to pull/push items.<br /> Example: `default:dirt 8` |
| "config" | item string | Configure the TA4 pusher.<br />Example: `wool:blue` |
| "exchange" | inventory slot number | place/remove/exchange an block by means of the TA3 Door Controller II (techage:ta3_doorcontroller2) |
* `$display(num, row, text)` Send a text string to the display with number _num_. _row_ is the display row, a value from 1 to 5, or 0 to add the text string at the bottom (scroll screen mode). _text_ is the string to be displayed. If the first char of the string is a blank, the text will be horizontally centered.
* `$clear_screen(num)` Clear the screen of the display with number _num_.
* `$position(num)` Returns the position as string "'(x,y,z)" of the device with the given _num_.
| "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 |
| "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 |
| "recipe" | `<item_name>,<item_name>,...` | Set the TA4 Autocrafter recipe. <br />Example for the torch recipe: `default:coal_lump,,,default:stick` <br />Hint: Empty fields may only be left out at the end of the item list! |
| "recipe" | `<number>.<index>` | Set the TA4 Autocrafter recipe with a recipe from a TA4 Recipe Block.<br />`<number>` is the TA4 Recipe Block number<br />`<index>` is the number of the recipe in the TA4 Recipe Block |
| "goto" | `<slot>` | Start command for the TA4 Sequencer. `<slot>` is the time slot like `[1]` where the execution starts. |
| "stop" | nil | Stop command for the TA4 Sequencer. |
### Server and Terminal Functions
@ -414,25 +422,27 @@ In contrast the Controller can send text strings to the terminal.
- `$get_term()` - Read a text command received from the Terminal
- `$put_term(num, text)` - Send a text string to the Terminal. _num_ is the number of the Terminal.
### Further Functions
### Communication between Lua Controllers
Messages are used to transport data between Controllers. Messages can contain arbitrary data. Incoming messages are stored in order (up to 10) and can be read one after the other.
* `$get_msg([raw])` - Read a received message. The function returns the sender number and the message. (see example "Emails"). If the _raw_ parameter is not set or false, the message is guaranteed to be a string.
* `$send_msg(num, msg)` - Send a message to another Controller. _num_ is the destination number. (see example "Emails")
* `$chat(text)` - Send yourself a chat message. _text_ is a text string.
### Further Functions
* `$chat(text)` - Send yourself a chat message. _text_ is a text string.
* `$door(pos, text)` - Open/Close a door at position "pos".
Example: `$door("123,7,-1200", "close")`.
Hint: Use the Techage Info Tool to determine the door position.
* `$item_description("default:apple")`
Get the description (item name) for a specified itemstring, e. g. determined via the TA4 8x2000 Chest command `itemstring`:
`str = $send_cmnd("223", "itemstring", 1)`
`descr = $item_description(str)`
* `$display(num, row, text)` Send a text string to the display with number _num_. _row_ is the display row, a value from 1 to 5, or 0 to add the text string at the bottom (scroll screen mode). _text_ is the string to be displayed. If the first char of the string is a blank, the text will be horizontally centered.
* `$clear_screen(num)` Clear the screen of the display with number _num_.
* `$position(num)` Returns the position as string "'(x,y,z)" of the device with the given _num_.
## Example Scripts
@ -662,7 +672,7 @@ loop() code:
-- read from Terminal and send the message
s = $get_term()
if s then
name,text = unpack(string.split(s, ":", false, 1))
name,text = string.split2(s, ":", false, 1)
num = $server_read(SERVER, name)
if num then
$send_msg(num, text)

Binary file not shown.

View File

@ -97,7 +97,6 @@ minetest.register_node("techage:ta4_turncontroller", {
nvm.lpos = new_posses
local name = player:get_player_name()
mark.stop(name)
print("new_posses", #new_posses)
end
meta:set_string("formspec", formspec(nvm, meta))
elseif fields.right then
@ -107,7 +106,6 @@ minetest.register_node("techage:ta4_turncontroller", {
nvm.lpos = new_posses
local name = player:get_player_name()
mark.stop(name)
print("new_posses", #new_posses)
end
meta:set_string("formspec", formspec(nvm, meta))
end

Binary file not shown.

After

Width:  |  Height:  |  Size: 144 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 408 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 669 B

View File

@ -109,6 +109,11 @@ local function read_state(itemstack, user, pointed_thing)
consumption = dump(consumption)
minetest.chat_send_player(user:get_player_name(), ndef.description.." "..number..": consumption = "..consumption.." kud ")
end
local flowrate = techage.send_single("0", number, "flowrate", nil)
if flowrate and flowrate ~= "" and flowrate ~= "unsupported" then
flowrate = dump(flowrate)
minetest.chat_send_player(user:get_player_name(), ndef.description.." "..number..": flowrate = "..flowrate.." ")
end
local owner = M(pos):get_string("owner") or ""
if owner ~= "" then
minetest.chat_send_player(user:get_player_name(), S("Node owner")..": "..owner.." ")