built on 24/09/2022 11:01:30

This commit is contained in:
Joachim Stolberg 2022-09-24 11:01:30 +02:00
parent 641e79e084
commit f441d7daa5
103 changed files with 1752 additions and 949 deletions

View File

@ -47,6 +47,12 @@ ta4_jetpack requires the modpack 3d_armor. 3d_armor is itself a modpack and can'
### History ### History
#### 2022-08-17
Updated Mods:
- techage (fix "Invalid field use_texture_alpha" errors)
#### 2022-08-06 #### 2022-08-06
Updated Mods: Updated Mods:

View File

@ -80,7 +80,7 @@ All this testing nodes can be enabled via mod settings `networks_test_enabled =
### License ### License
Copyright (C) 2021 Joachim Stolberg Copyright (C) 2021-2022 Joachim Stolberg
Code: Licensed under the GNU AGPL version 3 or later. See LICENSE.txt Code: Licensed under the GNU AGPL version 3 or later. See LICENSE.txt
Textures: CC BY-SA 3.0 Textures: CC BY-SA 3.0
@ -128,3 +128,6 @@ Required: tubelib2
**2022-01-06 V0.11** **2022-01-06 V0.11**
- Support for junction rotation added - Support for junction rotation added
**2022-09-10 V0.12**
- New API function `networks.liquid.get_liquids` added

View File

@ -13,7 +13,7 @@
networks = {} networks = {}
-- Version for compatibility checks, see readme.md/history -- Version for compatibility checks, see readme.md/history
networks.version = 0.11 networks.version = 0.12
if not minetest.global_exists("tubelib2") or tubelib2.version < 2.2 then if not minetest.global_exists("tubelib2") or tubelib2.version < 2.2 then
minetest.log("error", "[networks] Networks requires tubelib2 version 2.2 or newer!") minetest.log("error", "[networks] Networks requires tubelib2 version 2.2 or newer!")

View File

@ -265,3 +265,31 @@ function networks.liquid.turn_valve_off(pos, tlib2, name_off, name_on)
return true return true
end end
end end
-------------------------------------------------------------------------------
-- Info/Tools
-------------------------------------------------------------------------------
-- Return list of liquids of connected tanks
-- Node at pos must be a pump
function networks.liquid.get_liquids(pos, tlib2)
local tbl = {}
for _, dir in ipairs(networks.get_node_connection_dirs(pos, tlib2.tube_type)) do
for _,item in ipairs(get_network_table(pos, tlib2, dir, "tank")) do
local liq = LQD(item.pos)
if liq and liq.peek then
local liq_name = liq.peek(item.pos, item.indir)
if liq_name then
local def = minetest.registered_items[liq_name] or minetest.registered_craftitems[liq_name]
if def then
tbl[def.description] = true
end
end
end
end
end
local out = {}
for k,v in pairs(tbl) do
out[#out + 1] = k
end
return out
end

View File

@ -57,7 +57,8 @@ The mod has an in-game help to all blocks and signs. Therefore, it is highly rec
The commands are also all described as help in the "Sign command" node. The commands are also all described as help in the "Sign command" node.
All blocks or signs that are set are taken from the bot inventory. All blocks or signs that are set are taken from the bot inventory.
Any blocks or signs removed will be added back to the Bot Inventory. Any blocks or signs removed will be added back to the Bot Inventory.
For all Inventory commands applies: If the inventory stack specified by <slot> is full, so that nothing more can be done, or just empty, so that nothing more can be removed, the next slot will automatically be used. `<slot>` is always the bot internal inventory stack (1..8).
For all Inventory commands applies: If the bot inventory stack specified by `<slot>` is full, so that nothing more can be done, or just empty, so that nothing more can be removed, the next slot will automatically be used.
move <steps> - to follow one or more steps forward without signs move <steps> - to follow one or more steps forward without signs
cond_move - walk to the next sign and work it off cond_move - walk to the next sign and work it off
@ -69,6 +70,7 @@ For all Inventory commands applies: If the inventory stack specified by <slot> i
pause <sec> - wait one or more seconds pause <sec> - wait one or more seconds
move_up - move up (maximum 2 times) move_up - move up (maximum 2 times)
move_down - move down move_down - move down
fall_down - fall into a hole/chasm (up to 10 blocks)
take_item <num> <slot> - take one or more items from a box take_item <num> <slot> - take one or more items from a box
add_item <num> <slot> - put one or more items in a box add_item <num> <slot> - put one or more items in a box
add_fuel <num> <slot> - for furnaces or similar add_fuel <num> <slot> - for furnaces or similar
@ -106,6 +108,20 @@ For all Inventory commands applies: If the inventory stack specified by <slot> i
flame_on - Make fire flame_on - Make fire
flame_off - Put out the fire flame_off - Put out the fire
#### Techage specific commands
ignite - Ignite the techage charcoal lighter
low_batt <percent> - Turn the bot off if the battery power is below the
given value in percent (1..99)
jump_low_batt <percent> <label> - Jump to <label> if the battery power is below the
given value in percent (1..99)
(see "Flow control commands")
send_cmnd <receiver> <command> - Send a techage command to a given node.
Receiver is addressed by the techage node number.
For commands with two or more words, use the '*' character
instead of spaces, e.g.: send_cmnd 3465 pull*default:dirt*2
#### Flow control commands #### Flow control commands
jump <label> -- jump command, <label> is a word from the characters a-z or A-Z jump <label> -- jump command, <label> is a word from the characters a-z or A-Z
@ -115,6 +131,16 @@ For all Inventory commands applies: If the inventory stack specified by <slot> i
end -- end of a loop block end -- end of a loop block
call <label> -- call of a function (with return via the command 'return') call <label> -- call of a function (with return via the command 'return')
#### Further jump commands
jump_check_item <num> <slot> <label> - Check if there are <num> items in the chest like node.
If not, jump to <label>.
<slot> is the bot inventory slot (1..8) to specify the item,
or 0 for any item.
jump_low_batt <percent> <label> - See "Techage specific commands"
Example with a function at the beginning: Example with a function at the beginning:
jump main -- jump to the label 'main' jump main -- jump to the label 'main'
@ -149,7 +175,7 @@ Or alternatively with the function at the end:
return -- end of 'foo'. Jump back return -- end of 'foo'. Jump back
### License ### License
Copyright (C) 2019-2021 Joachim Stolberg Copyright (C) 2019-2022 Joachim Stolberg
Copyright (C) 2021 Michal 'Micu' Cieslakiewicz (soup commands) Copyright (C) 2021 Michal 'Micu' Cieslakiewicz (soup commands)
Code: Licensed under the GNU GPL version 3 or later. See LICENSE.txt Code: Licensed under the GNU GPL version 3 or later. See LICENSE.txt
@ -185,5 +211,6 @@ optional: farming redo, node_io, doc, techage, minecart, xdecor, compost
- 2021-08-22 v1.09 * Add soup commands and signs, add aspen sign - 2021-08-22 v1.09 * Add soup commands and signs, add aspen sign
- 2021-09-18 v1.10 * Add techage command 'set <num>' to the Bot Control Unit - 2021-09-18 v1.10 * Add techage command 'set <num>' to the Bot Control Unit
- 2022-03-19 V1.11 * Extend farming (and add ethereal) support (Thanks to nixnoxus) - 2022-03-19 V1.11 * Extend farming (and add ethereal) support (Thanks to nixnoxus)
- 2022-09-11 V1.12 * Add commands `jump_low_batt` , `jump_check_item`, and `fall_down`

View File

@ -65,6 +65,23 @@ function signs_bot.robot_put(base_pos, robot_pos, param2, num, slot)
end end
end end
function signs_bot.robot_peek(base_pos, robot_pos, param2, want_count, slot)
local target_pos = lib.next_pos(robot_pos, param2)
local node = tubelib2.get_node_lvm(target_pos)
local def = RegisteredInventories[node.name]
local owner = M(base_pos):get_string("owner")
-- Is known type of inventory node?
if def and (not def.allow_take or def.allow_take(target_pos, nil, owner)) then
local src_inv = minetest.get_inventory({type="node", pos=target_pos})
-- take specified item_name from bot slot configuration OR any item from the chest
local item_name = signs_bot.bot_inv_item_name(base_pos, slot) or lib.peek_inv(src_inv, def.take_listname)
if item_name then
return src_inv:contains_item(def.take_listname, ItemStack(item_name.." "..want_count))
end
end
end
-- From robot to furnace -- From robot to furnace
function signs_bot.robot_put_fuel(base_pos, robot_pos, param2, num, slot) function signs_bot.robot_put_fuel(base_pos, robot_pos, param2, num, slot)
local target_pos = lib.next_pos(robot_pos, param2) local target_pos = lib.next_pos(robot_pos, param2)
@ -88,7 +105,7 @@ signs_bot.register_botcommand("take_item", {
params = "<num> <slot>", params = "<num> <slot>",
num_param = 2, num_param = 2,
description = S("Take <num> items from a chest like node\nand put it into the item inventory.\n".. description = S("Take <num> items from a chest like node\nand put it into the item inventory.\n"..
"<slot> is the inventory slot (1..8) or 0 for any one"), "<slot> is the bot inventory slot\n(1..8) or 0 for any one"),
check = function(num, slot) check = function(num, slot)
num = tonumber(num) or 1 num = tonumber(num) or 1
if num < 1 or num > 99 then if num < 1 or num > 99 then
@ -108,12 +125,41 @@ signs_bot.register_botcommand("take_item", {
end, end,
}) })
signs_bot.register_botcommand("jump_check_item", {
mod = "item",
params = "<num> <slot> <label>",
num_param = 3,
description = S("Check if there are <num>\n"..
"items in the chest like node.\n"..
"If not, jump to <label>\n"..
"<slot> is the bot inventory slot\n"..
"(1..8) to specify the item, or 0 for any item"),
check = function(num, slot, lbl)
num = tonumber(num) or 1
if num < 1 or num > 99 then
return false
end
slot = tonumber(slot) or 0
if slot < 0 or slot > 8 then
return false
end
return signs_bot.check_label(lbl)
end,
cmnd = function(base_pos, mem, num, slot, addr)
num = tonumber(num) or 1
if not signs_bot.robot_peek(base_pos, mem.robot_pos, mem.robot_param2, num, slot) then
mem.pc = (addr or 4) - 4
end
return signs_bot.DONE
end,
})
signs_bot.register_botcommand("add_item", { signs_bot.register_botcommand("add_item", {
mod = "item", mod = "item",
params = "<num> <slot>", params = "<num> <slot>",
num_param = 2, num_param = 2,
description = S("Add <num> items to a chest like node\ntaken from the item inventory.\n".. description = S("Add <num> items to a chest like node\ntaken from the item inventory.\n"..
"<slot> is the inventory slot (1..8) or 0 for any one"), "<slot> is the bot inventory slot (1..8) or 0 for any one"),
check = function(num, slot) check = function(num, slot)
num = tonumber(num) or 1 num = tonumber(num) or 1
if num < 1 or num > 99 then if num < 1 or num > 99 then
@ -138,7 +184,7 @@ signs_bot.register_botcommand("add_fuel", {
params = "<num> <slot>", params = "<num> <slot>",
num_param = 2, num_param = 2,
description = S("Add <num> fuel to a furnace like node\ntaken from the item inventory.\n".. description = S("Add <num> fuel to a furnace like node\ntaken from the item inventory.\n"..
"<slot> is the inventory slot (1..8) or 0 for any one"), "<slot> is the bot inventory slot (1..8) or 0 for any one"),
check = function(num, slot) check = function(num, slot)
num = tonumber(num) or 1 num = tonumber(num) or 1
if num < 1 or num > 99 then if num < 1 or num > 99 then
@ -190,7 +236,7 @@ signs_bot.register_botcommand("pickup_items", {
num_param = 1, num_param = 1,
description = S("Pick up all objects\n".. description = S("Pick up all objects\n"..
"in a 3x3 field.\n".. "in a 3x3 field.\n"..
"<slot> is the inventory slot (1..8) or 0 for any one"), "<slot> is the bot inventory slot (1..8) or 0 for any one"),
check = function(slot) check = function(slot)
slot = tonumber(slot) or 0 slot = tonumber(slot) or 0
return slot >= 0 and slot < 9 return slot >= 0 and slot < 9
@ -217,7 +263,7 @@ signs_bot.register_botcommand("drop_items", {
params = "<num> <slot>", params = "<num> <slot>",
num_param = 2, num_param = 2,
description = S("Drop items in front of the bot.\n".. description = S("Drop items in front of the bot.\n"..
"<slot> is the inventory slot (1..8) or 0 for any one"), "<slot> is the bot inventory slot (1..8) or 0 for any one"),
check = function(num, slot) check = function(num, slot)
num = tonumber(num) or 1 num = tonumber(num) or 1
if num < 1 or num > 99 then if num < 1 or num > 99 then

View File

@ -255,6 +255,36 @@ signs_bot.register_botcommand("move_down", {
end, end,
}) })
signs_bot.register_botcommand("fall_down", {
mod = "move",
params = "",
num_param = 0,
description = S("Fall into a hole/chasm (up to 10 blocks)"),
cmnd = function(base_pos, mem)
if not mem.bot_falling then
local pos1 = {x=mem.robot_pos.x, y=mem.robot_pos.y-1, z=mem.robot_pos.z}
local pos2 = {x=mem.robot_pos.x, y=mem.robot_pos.y-10, z=mem.robot_pos.z}
local sts, pos3 = minetest.line_of_sight(pos1, pos2)
if sts == false then
sts, _ = minetest.spawn_falling_node(mem.robot_pos)
if sts then
mem.bot_falling = 2
mem.robot_pos = {x=pos3.x, y=pos3.y+1, z=pos3.z}
return signs_bot.BUSY
end
end
return signs_bot.ERROR, "Too deep"
else
mem.bot_falling = mem.bot_falling - 1
if mem.bot_falling <= 0 then
mem.bot_falling = nil
return signs_bot.DONE
end
return signs_bot.BUSY
end
end,
})
signs_bot.register_botcommand("pause", { signs_bot.register_botcommand("pause", {
mod = "move", mod = "move",
params = "<sec>", params = "<sec>",

View File

@ -30,6 +30,9 @@ signs_bot.NEW = ci.NEW
signs_bot.ERROR = ci.ERROR signs_bot.ERROR = ci.ERROR
signs_bot.TURN_OFF = ci.TURN_OFF signs_bot.TURN_OFF = ci.TURN_OFF
-- API functions
signs_bot.check_label = ci.check_label
local tCommands = {} local tCommands = {}
local SortedKeys = {} local SortedKeys = {}
local SortedMods = {} local SortedMods = {}

0
signs_bot/i18n.py Normal file → Executable file
View File

View File

@ -15,7 +15,7 @@
signs_bot = {} signs_bot = {}
-- Version for compatibility checks, see readme.md/history -- Version for compatibility checks, see readme.md/history
signs_bot.version = 1.09 signs_bot.version = 1.12
-- Test for MT 5.4 new string mode -- Test for MT 5.4 new string mode
signs_bot.CLIP = minetest.features.use_texture_alpha_string_modes and "clip" or true signs_bot.CLIP = minetest.features.use_texture_alpha_string_modes and "clip" or true

View File

@ -234,6 +234,11 @@ function api.register_command(cmnd_name, num_param, cmnd_func, check_func)
register_command(cmnd_name, num_param, cmnd_func, check_func) register_command(cmnd_name, num_param, cmnd_func, check_func)
end end
function api.check_label(label)
return label and tSymbolTbl[label..":"] ~= nil
end
-- function returns: true/false, error_string, line-num -- function returns: true/false, error_string, line-num
function api.check_script(script) function api.check_script(script)
local tbl = {} local tbl = {}
@ -303,6 +308,7 @@ function api.reset_script(base_pos, mem)
CodeCache[hash] = nil CodeCache[hash] = nil
mem.pc = 1 mem.pc = 1
mem.Stack = {} mem.Stack = {}
mem.bot_falling = nil
end end
return api return api

View File

@ -25,6 +25,11 @@ The box inventory simulates the inventory of the bot.=Das Inventar der Box simul
You will not be able to access the inventory, if the bot is running.=Du hast keinen Zugriff auf das Inventar, sofern der Roboter unterwegs ist. You will not be able to access the inventory, if the bot is running.=Du hast keinen Zugriff auf das Inventar, sofern der Roboter unterwegs ist.
The bot can carry up to 8 stacks and 6 signs with it.=Der Roboter kann 8 Stapel von Blöcken und 6 Zeichen transportieren. The bot can carry up to 8 stacks and 6 signs with it.=Der Roboter kann 8 Stapel von Blöcken und 6 Zeichen transportieren.
### basis.lua ###
### techage.lua ###
charging=aufladen
### bot_flap.lua ### ### bot_flap.lua ###
Exit=Beenden Exit=Beenden
@ -41,11 +46,6 @@ Bot Sensor: Not connected=Bot Sensor: Nicht verbunden
The Bot Sensor detects any bot and sends a signal, if a bot is nearby.=Der Roboter Sensor entdeckt jeden Roboter und sendet ein Signal, sofern ein Roboter in der Nähe ist. The Bot Sensor detects any bot and sends a signal, if a bot is nearby.=Der Roboter Sensor entdeckt jeden Roboter und sendet ein Signal, sofern ein Roboter in der Nähe ist.
The sensor direction does not care.=Die Ausrichtung des Sensor spielt keine Rolle. The sensor direction does not care.=Die Ausrichtung des Sensor spielt keine Rolle.
### bot_sensor.lua ###
### cart_sensor.lua ###
the sensor range is one node/meter.=Der Sensorbereich ist einen Block/Meter groß.
### cart_sensor.lua ### ### cart_sensor.lua ###
Cart Sensor: Connected with=Wagen Sensor: Verbunden mit Cart Sensor: Connected with=Wagen Sensor: Verbunden mit
@ -54,6 +54,11 @@ Cart Sensor: Not connected=Wagen Sensor: Nicht verbunden
The Cart Sensor detects and sends a signal, if a cart (Minecart) is nearby.=Der Wagen Sensor sendet ein Signal, sofern ein Wagen in der Nähe ist. The Cart Sensor detects and sends a signal, if a cart (Minecart) is nearby.=Der Wagen Sensor sendet ein Signal, sofern ein Wagen in der Nähe ist.
The sensor has an active side (red) that must point to the rail/cart.=Der Sensor hat eine aktive Seite (rot), welche zu den Schienen zeigen muss. The sensor has an active side (red) that must point to the rail/cart.=Der Sensor hat eine aktive Seite (rot), welche zu den Schienen zeigen muss.
### cart_sensor.lua ###
### bot_sensor.lua ###
the sensor range is one node/meter.=Der Sensorbereich ist einen Block/Meter groß.
### changer.lua ### ### changer.lua ###
Signs:=Zeichen: Signs:=Zeichen:
@ -85,27 +90,28 @@ Sign 'farming'=Zeichen 'Farming'
Used to harvest and seed a 3x3 field.=Benötigt um ein 3x3 Feld zu ernten und wieder zu sähen. Used to harvest and seed a 3x3 field.=Benötigt um ein 3x3 Feld zu ernten und wieder zu sähen.
The seed to be placed has to be in the first inventory slot of the bot.=Das Saatgut, dass gesät werden soll, muss sich an der 1. Position im Inventar befinden. The seed to be placed has to be in the first inventory slot of the bot.=Das Saatgut, dass gesät werden soll, muss sich an der 1. Position im Inventar befinden.
### cmd_flowers.lua ###
Cutting flowers, leaves and tree blocks@nin front of the robot@non a 3x3 field.=Schneide Blumen, Blätter und Baumblöcke@nin einem 3x3 großem Feld@nvor dem Roboter.
Sign "flowers"=Zeichen "Blumen"
Sign 'flowers'=Zeichen 'Blumen'
Used to cut flowers on a 3x3 field.=Benötigt um ein 3x3 Blumenfeld zu ernten.
### cmd_flowers.lua ###
### cmd_farming.lua ### ### cmd_farming.lua ###
### cmd_flowers.lua ###
Place the sign in front of the field.=Platziere das Zeichen vor das Feld. Place the sign in front of the field.=Platziere das Zeichen vor das Feld.
When finished, the bot turns.=Der Roboter dreht um, wenn er fertig ist. When finished, the bot turns.=Der Roboter dreht um, wenn er fertig ist.
### cmd_flowers.lua ###
Cutting flowers, papyrus,@nleaves and tree blocks@nin front of the robot@non a 3x3 field.=Schneide Blumen, Papyrus,@nBlätter und Baumblöcke@nin einem 3x3 großem Feld@nvor dem Roboter.
Sign "flowers"=Zeichen "Blumen"
Sign 'flowers'=Zeichen 'Blumen'
Used to cut flowers on a 3x3 field.=Benötigt um ein 3x3 Blumenfeld zu ernten.
### cmd_item.lua ### ### cmd_item.lua ###
Take <num> items from a chest like node@nand put it into the item inventory.@n<slot> is the inventory slot (1..8) or 0 for any one=Nehme <num> Gegenstände aus der@nKiste oder dem Kisten-ähnlichen Block@nund tue diese in das eigene Inventar@nan der Position <slot>. Slot = (1..8)@noder 0 für irgend eine Position Take <num> items from a chest like node@nand put it into the item inventory.@n<slot> is the bot inventory slot@n(1..8) or 0 for any one=Nehme <num> Gegenstände aus der@nKiste oder dem Kisten-ähnlichen Block@nund tue diese in das eigene Inventar@nan der Position <slot>. Slot = (1..8)@noder 0 für irgend eine Position
Add <num> items to a chest like node@ntaken from the item inventory.@n<slot> is the inventory slot (1..8) or 0 for any one=Lege <num> Gegenstände aus dem@neigenen Inventar in die andere Kiste.@n<slot> ist die Position im@neigenen Inventar (1--8).@noder 0 für irgend eine Position Check if there are <num>@nitems in the chest like node.@nIf not, jump to <label>@n<slot> is the bot inventory slot@n(1..8) to specify the item, or 0 for any item=Prüfe, ob sich <num> Gegenstände@nin dem Kisten-ähnlichen Block befinden.@nWenn nicht, springe zu <label>@n<slot> ist der Bot-Inventar-Slot@n(1..8) um einen Gegenstand auszuwählen, oder 0 für irgendeinen Gegenstand
Add <num> fuel to a furnace like node@ntaken from the item inventory.@n<slot> is the inventory slot (1..8) or 0 for any one=Lege <num> Brennstoffe aus dem@neigenen Inventar in den anderen Block.@n<slot> ist die Position im@neigenen Inventar (1--8).@noder 0 für irgend eine Position Add <num> items to a chest like node@ntaken from the item inventory.@n<slot> is the bot inventory slot (1..8) or 0 for any one=Lege <num> Gegenstände aus dem@neigenen Inventar in die andere Kiste.@n<slot> ist die Position im@neigenen Inventar (1--8).@noder 0 für irgend eine Position
Add <num> fuel to a furnace like node@ntaken from the item inventory.@n<slot> is the bot inventory slot (1..8) or 0 for any one=Lege <num> Brennstoffe aus dem@neigenen Inventar in den anderen Block.@n<slot> ist die Position im@neigenen Inventar (1--8).@noder 0 für irgend eine Position
deprecated, use bot inventory configuration instead=veraltet, benutze stattdessen die Inventar Konfigurationsmöglichkeit deprecated, use bot inventory configuration instead=veraltet, benutze stattdessen die Inventar Konfigurationsmöglichkeit
Pick up all objects@nin a 3x3 field.@n<slot> is the inventory slot (1..8) or 0 for any one=Hebe alle Objekte in einem@n3x3 Blöcke großen Feld auf@nund lege diese in das eigene@nInventar an Position <slot> (1-8)@noder 0 für irgend eine Position Pick up all objects@nin a 3x3 field.@n<slot> is the bot inventory slot (1..8) or 0 for any one=Hebe alle Objekte in einem@n3x3 Blöcke großen Feld auf@nund lege diese in das eigene@nInventar an Position <slot> (1-8)@noder 0 für irgend eine Position
Drop items in front of the bot.@n<slot> is the inventory slot (1..8) or 0 for any one=Lasse ein Objekt aus dem eigenen@nInventar vor dem Roboter fallen.@n<slot> ist die Position im@neigenen Inventar (1--8).@noder 0 für irgend eine Position Drop items in front of the bot.@n<slot> is the bot inventory slot (1..8) or 0 for any one=Lasse ein Objekt aus dem eigenen@nInventar vor dem Roboter fallen.@n<slot> ist die Position im@neigenen Inventar (1--8).@noder 0 für irgend eine Position
Punch a rail cart to start it=Schlage den Wagen um ihn zu starten Punch a rail cart to start it=Schlage den Wagen um ihn zu starten
### cmd_move.lua ### ### cmd_move.lua ###
@ -116,6 +122,7 @@ Turn the robot to the right=Drehe den Roboter@nnach rechts
Turn the robot around=Drehe den Roboter@num (180 Grad) Turn the robot around=Drehe den Roboter@num (180 Grad)
Move the robot upwards=Bewege den Roboter@nnach oben Move the robot upwards=Bewege den Roboter@nnach oben
Move the robot down=Bewege den Roboter@nnach unten Move the robot down=Bewege den Roboter@nnach unten
Fall into a hole/chasm (up to 10 blocks)=Falle in ein Loch/Abgrund (bis zu 10 Blöcke)
Stop the robot for <sec> seconds@n(1..9999)=Stoppe den Roboter@nfür <sec> Sekunden (1.9999) Stop the robot for <sec> seconds@n(1..9999)=Stoppe den Roboter@nfür <sec> Sekunden (1.9999)
Stop the robot.=Stoppe den Roboter. Stop the robot.=Stoppe den Roboter.
Turn the robot off@nand put it back in the box.=Schalte den Roboter aus und@nsetze ihn damit zurück in@nseine Box. Turn the robot off@nand put it back in the box.=Schalte den Roboter aus und@nsetze ihn damit zurück in@nseine Box.
@ -151,6 +158,11 @@ Dig the block above the robot.@n<slot> is the inventory slot (1..8)=Entferne ein
Rotate the block in front of the robot@n<lvl> is one of: -1 0 +1@n<steps> is one of: 1 2 3=Rotiere den Block vor dem Roboter.@nFür <lvl> ist zulässig: -1 0 +1@nFür <steps> ist zulässig: 1 2 3 Rotate the block in front of the robot@n<lvl> is one of: -1 0 +1@n<steps> is one of: 1 2 3=Rotiere den Block vor dem Roboter.@nFür <lvl> ist zulässig: -1 0 +1@nFür <steps> ist zulässig: 1 2 3
Bot torch=Bot Fackel Bot torch=Bot Fackel
### cmd_place.lua ###
### cmd_soup.lua ###
Error: Position protected=Fehler: Position geschützt
### cmd_sign.lua ### ### cmd_sign.lua ###
Commands,Help=Kommandos,Hilfe Commands,Help=Kommandos,Hilfe
@ -218,11 +230,6 @@ to prevent wooden sign from catching fire.=um zu verhindern, dass das Holzschild
4 - empty bowl (from farming or xdecor mods)= 4 - Leere Schüssel (Von der Mod farming oder xdecor) 4 - empty bowl (from farming or xdecor mods)= 4 - Leere Schüssel (Von der Mod farming oder xdecor)
The result is one bowl with vegetable soup in selected inventory slot.=Das Ergebnis ist eine Schüssel mit Gemüsesuppe an der ausgewählten Inventarposition. The result is one bowl with vegetable soup in selected inventory slot.=Das Ergebnis ist eine Schüssel mit Gemüsesuppe an der ausgewählten Inventarposition.
### cmd_soup.lua ###
### cmd_place.lua ###
Error: Position protected=Fehler: Position geschützt
### cmd_trees.lua ### ### cmd_trees.lua ###
Used to harvest an aspen or pine tree trunk=Wird verwendet, um einen Espen- oder Kiefernstamm zu ernten Used to harvest an aspen or pine tree trunk=Wird verwendet, um einen Espen- oder Kiefernstamm zu ernten
@ -244,8 +251,8 @@ call a subroutine (with 'return' statement)=Aufruf einer Unterfunktion (mit 'ret
return from a subroutine=Rückkehr von einer Unterfunktion return from a subroutine=Rückkehr von einer Unterfunktion
jump to a label=Sprung zu einer Marke jump to a label=Sprung zu einer Marke
Move the robot 1..999 steps forward@nwithout paying attention to any signs.@nUp and down movements also become@ncounted as steps.=Bewege den Roboter 1..999 Schritte@nvorwärts ohne auf Zeichen zu achten.@nAuf- und Ab-Bewegungen werden auch@nals Schritte gezählt. Move the robot 1..999 steps forward@nwithout paying attention to any signs.@nUp and down movements also become@ncounted as steps.=Bewege den Roboter 1..999 Schritte@nvorwärts ohne auf Zeichen zu achten.@nAuf- und Ab-Bewegungen werden auch@nals Schritte gezählt.
Walk until a sign or obstacle is@nreached. Then continue with the next command.@nWhen a sign has been reached, @nthe current program is ended@nand the bot executes the@nnew program from the sign=Gehe bis ein Zeichen oder Hindernis@nerreicht wurde. Führe dann das nächste@nKommando aus. @nWurde ein Zeichen erreicht, so arbeite@ndie Kommandos des Zeichens als@nUnter-Prozess ab Walk until a sign or obstacle is@nreached. Then continue with the next command.@nWhen a sign has been reached,@nthe current program is ended@nand the bot executes the@nnew program from the sign=Gehe bis ein Zeichen oder Hindernis@nerreicht wurde. Führe dann das nächste@nKommando aus. @nWurde ein Zeichen erreicht, so arbeite@ndie Kommandos des Zeichens als@nUnter-Prozess ab
Print given text as chat message.@nFor two or more words, use the '*' character @ninstead of spaces, like "Hello*world"=Gebe den angegebenen Text als Chat-Nachricht aus.@nFür zwei oder mehr Wörter verwende das Zeichen '*' @nanstelle von Leerzeichen, z. B. "Hallo*Welt". Print given text as chat message.@nFor two or more words, use the '*' character@ninstead of spaces, like "Hello*world"=Gebe den angegebenen Text als Chat-Nachricht aus.@nFür zwei oder mehr Wörter verwende das Zeichen '*' @nanstelle von Leerzeichen, z. B. "Hallo*Welt".
### compost.lua ### ### compost.lua ###
@ -269,6 +276,11 @@ Signal Delayer=Signal Verzögerer
Signals are forwarded delayed. Subsequent signals are queued.=Signale werden verzögert weitergeleitet. Nachfolgende Signale werden in die Warteschlange gestellt. Signals are forwarded delayed. Subsequent signals are queued.=Signale werden verzögert weitergeleitet. Nachfolgende Signale werden in die Warteschlange gestellt.
The delay time can be configured.=Die Verzögerungszeit kann eingestellt werden. The delay time can be configured.=Die Verzögerungszeit kann eingestellt werden.
### delayer.lua ###
### timer.lua ###
Start=Start
### doc.lua ### ### doc.lua ###
After you have placed the Signs Bot Box, you can start the bot by means of the 'On' button in the box menu.=Nachdem du die Roboter-Kiste platziert hast, kannst du den Roboter über den "An" Button im Kistenmenü starten. After you have placed the Signs Bot Box, you can start the bot by means of the 'On' button in the box menu.=Nachdem du die Roboter-Kiste platziert hast, kannst du den Roboter über den "An" Button im Kistenmenü starten.
@ -400,11 +412,6 @@ inputs=Eingängen
Signal AND=Signal UND Signal AND=Signal UND
Signal is sent, if all input signals are received.=Signal wird gesendet, wenn all Eingangssignale empfangen wurden. Signal is sent, if all input signals are received.=Signal wird gesendet, wenn all Eingangssignale empfangen wurden.
### logic_and.lua ###
### timer.lua ###
Connected with=Verbunden mit
### node_sensor.lua ### ### node_sensor.lua ###
Node Sensor: Connected with =Block Sensor: Verbunden mit Node Sensor: Connected with =Block Sensor: Verbunden mit
@ -447,13 +454,9 @@ The Bot takes items out of a minecart in front of it, pushes the cart and then t
no power=kein Strom no power=kein Strom
Ignite the techage charcoal lighter=Zünde den Holzkohle-Anzünder an Ignite the techage charcoal lighter=Zünde den Holzkohle-Anzünder an
Turns the bot off if the@nbattery power is below the@ngiven value in percent (1..99)=Schalte den Bot aus,@nwenn die Batterieladung kleiner@nist als der angegebene Wert@nin Prozent (1.99) Turns the bot off if the@nbattery power is below the@ngiven value in percent (1..99)=Schalte den Bot aus,@nwenn die Batterieladung kleiner@nist als der angegebene Wert@nin Prozent (1.99)
Jump to <label> if the@nbattery power is below the@ngiven value in percent (1..99)=Springe zu <label> wenn die@nBatterieladung unter dem@ngegebenen Wert in Prozent (1..99) liegt
fully charged=voll geladen fully charged=voll geladen
Sends a techage command@nto a given node. @nReceiver is addressed by@nthe techage node number.@nFor commands with two or more @nwords, use the '*' character @ninstead of spaces, e.g.: @nsend_cmnd 3465 pull*default:dirt*2=Sende ein techage Kommando@nan einen Block mit der@nangegebenen Blocknummer.@nFür Kommandos mit zwei oder mehr @nWörtern verwende das Zeichen '*' @nanstelle des Leerzeichens, wie bspw.:@nsend_cmnd 3465 pull*default:dirt*2 Sends a techage command@nto a given node.@nReceiver is addressed by@nthe techage node number.@nFor commands with two or more@nwords, use the '*' character@ninstead of spaces, e.g.:@nsend_cmnd 3465 pull*default:dirt*2=Sende ein techage Kommando@nan einen Block mit der@nangegebenen Blocknummer.@nFür Kommandos mit zwei oder mehr @nWörtern verwende das Zeichen '*' @nanstelle des Leerzeichens, wie bspw.:@nsend_cmnd 3465 pull*default:dirt*2
### techage.lua ###
### basis.lua ###
charging=aufladen
### timer.lua ### ### timer.lua ###
@ -464,10 +467,11 @@ Special kind of sensor.=Spezielle Form eines Sensors.
Can be programmed with a time in seconds, e.g. to start the bot cyclically.=Kann mit einer Zeit in Sekunden programmiert werden, um bspw. den Roboter zyklisch zu starten. Can be programmed with a time in seconds, e.g. to start the bot cyclically.=Kann mit einer Zeit in Sekunden programmiert werden, um bspw. den Roboter zyklisch zu starten.
### timer.lua ### ### timer.lua ###
### delayer.lua ### ### logic_and.lua ###
Start=Start Connected with=Verbunden mit
### tool.lua ### ### tool.lua ###
Sensor Connection Tool=Sensor Verbindungswerkzeug Sensor Connection Tool=Sensor Verbindungswerkzeug

View File

@ -25,6 +25,11 @@ The box inventory simulates the inventory of the bot.=
You will not be able to access the inventory, if the bot is running.= You will not be able to access the inventory, if the bot is running.=
The bot can carry up to 8 stacks and 6 signs with it.= The bot can carry up to 8 stacks and 6 signs with it.=
### basis.lua ###
### techage.lua ###
charging=
### bot_flap.lua ### ### bot_flap.lua ###
Exit= Exit=
@ -41,11 +46,6 @@ Bot Sensor: Not connected=
The Bot Sensor detects any bot and sends a signal, if a bot is nearby.= The Bot Sensor detects any bot and sends a signal, if a bot is nearby.=
The sensor direction does not care.= The sensor direction does not care.=
### bot_sensor.lua ###
### cart_sensor.lua ###
the sensor range is one node/meter.=
### cart_sensor.lua ### ### cart_sensor.lua ###
Cart Sensor: Connected with= Cart Sensor: Connected with=
@ -54,6 +54,11 @@ Cart Sensor: Not connected=
The Cart Sensor detects and sends a signal, if a cart (Minecart) is nearby.= The Cart Sensor detects and sends a signal, if a cart (Minecart) is nearby.=
The sensor has an active side (red) that must point to the rail/cart.= The sensor has an active side (red) that must point to the rail/cart.=
### cart_sensor.lua ###
### bot_sensor.lua ###
the sensor range is one node/meter.=
### changer.lua ### ### changer.lua ###
Signs:= Signs:=
@ -85,27 +90,28 @@ Sign 'farming'=
Used to harvest and seed a 3x3 field.= Used to harvest and seed a 3x3 field.=
The seed to be placed has to be in the first inventory slot of the bot.= The seed to be placed has to be in the first inventory slot of the bot.=
### cmd_flowers.lua ###
Cutting flowers, leaves and tree blocks@nin front of the robot@non a 3x3 field.=
Sign "flowers"=
Sign 'flowers'=
Used to cut flowers on a 3x3 field.=
### cmd_flowers.lua ###
### cmd_farming.lua ### ### cmd_farming.lua ###
### cmd_flowers.lua ###
Place the sign in front of the field.= Place the sign in front of the field.=
When finished, the bot turns.= When finished, the bot turns.=
### cmd_flowers.lua ###
Cutting flowers, papyrus,@nleaves and tree blocks@nin front of the robot@non a 3x3 field.=
Sign "flowers"=
Sign 'flowers'=
Used to cut flowers on a 3x3 field.=
### cmd_item.lua ### ### cmd_item.lua ###
Take <num> items from a chest like node@nand put it into the item inventory.@n<slot> is the inventory slot (1..8) or 0 for any one= Take <num> items from a chest like node@nand put it into the item inventory.@n<slot> is the bot inventory slot@n(1..8) or 0 for any one=
Add <num> items to a chest like node@ntaken from the item inventory.@n<slot> is the inventory slot (1..8) or 0 for any one= Check if there are <num>@nitems in the chest like node.@nIf not, jump to <label>@n<slot> is the bot inventory slot@n(1..8) to specify the item, or 0 for any item=
Add <num> fuel to a furnace like node@ntaken from the item inventory.@n<slot> is the inventory slot (1..8) or 0 for any one= Add <num> items to a chest like node@ntaken from the item inventory.@n<slot> is the bot inventory slot (1..8) or 0 for any one=
Add <num> fuel to a furnace like node@ntaken from the item inventory.@n<slot> is the bot inventory slot (1..8) or 0 for any one=
deprecated, use bot inventory configuration instead= deprecated, use bot inventory configuration instead=
Pick up all objects@nin a 3x3 field.@n<slot> is the inventory slot (1..8) or 0 for any one= Pick up all objects@nin a 3x3 field.@n<slot> is the bot inventory slot (1..8) or 0 for any one=
Drop items in front of the bot.@n<slot> is the inventory slot (1..8) or 0 for any one= Drop items in front of the bot.@n<slot> is the bot inventory slot (1..8) or 0 for any one=
Punch a rail cart to start it= Punch a rail cart to start it=
### cmd_move.lua ### ### cmd_move.lua ###
@ -116,6 +122,7 @@ Turn the robot to the right=
Turn the robot around= Turn the robot around=
Move the robot upwards= Move the robot upwards=
Move the robot down= Move the robot down=
Fall into a hole/chasm (up to 10 blocks)=
Stop the robot for <sec> seconds@n(1..9999)= Stop the robot for <sec> seconds@n(1..9999)=
Stop the robot.= Stop the robot.=
Turn the robot off@nand put it back in the box.= Turn the robot off@nand put it back in the box.=
@ -151,6 +158,11 @@ Dig the block above the robot.@n<slot> is the inventory slot (1..8)=
Rotate the block in front of the robot@n<lvl> is one of: -1 0 +1@n<steps> is one of: 1 2 3= Rotate the block in front of the robot@n<lvl> is one of: -1 0 +1@n<steps> is one of: 1 2 3=
Bot torch= Bot torch=
### cmd_place.lua ###
### cmd_soup.lua ###
Error: Position protected=
### cmd_sign.lua ### ### cmd_sign.lua ###
Commands,Help= Commands,Help=
@ -218,11 +230,6 @@ to prevent wooden sign from catching fire.=
4 - empty bowl (from farming or xdecor mods)= 4 - empty bowl (from farming or xdecor mods)=
The result is one bowl with vegetable soup in selected inventory slot.= The result is one bowl with vegetable soup in selected inventory slot.=
### cmd_soup.lua ###
### cmd_place.lua ###
Error: Position protected=
### cmd_trees.lua ### ### cmd_trees.lua ###
Used to harvest an aspen or pine tree trunk= Used to harvest an aspen or pine tree trunk=
@ -244,8 +251,8 @@ call a subroutine (with 'return' statement)=
return from a subroutine= return from a subroutine=
jump to a label= jump to a label=
Move the robot 1..999 steps forward@nwithout paying attention to any signs.@nUp and down movements also become@ncounted as steps.= Move the robot 1..999 steps forward@nwithout paying attention to any signs.@nUp and down movements also become@ncounted as steps.=
Walk until a sign or obstacle is@nreached. Then continue with the next command.@nWhen a sign has been reached, @nthe current program is ended@nand the bot executes the@nnew program from the sign= Walk until a sign or obstacle is@nreached. Then continue with the next command.@nWhen a sign has been reached,@nthe current program is ended@nand the bot executes the@nnew program from the sign=
Print given text as chat message.@nFor two or more words, use the '*' character @ninstead of spaces, like "Hello*world"= Print given text as chat message.@nFor two or more words, use the '*' character@ninstead of spaces, like "Hello*world"=
### compost.lua ### ### compost.lua ###
@ -269,6 +276,11 @@ Signal Delayer=
Signals are forwarded delayed. Subsequent signals are queued.= Signals are forwarded delayed. Subsequent signals are queued.=
The delay time can be configured.= The delay time can be configured.=
### delayer.lua ###
### timer.lua ###
Start=
### doc.lua ### ### doc.lua ###
After you have placed the Signs Bot Box, you can start the bot by means of the 'On' button in the box menu.= After you have placed the Signs Bot Box, you can start the bot by means of the 'On' button in the box menu.=
@ -400,11 +412,6 @@ inputs=
Signal AND= Signal AND=
Signal is sent, if all input signals are received.= Signal is sent, if all input signals are received.=
### logic_and.lua ###
### timer.lua ###
Connected with=
### node_sensor.lua ### ### node_sensor.lua ###
Node Sensor: Connected with = Node Sensor: Connected with =
@ -447,13 +454,9 @@ The Bot takes items out of a minecart in front of it, pushes the cart and then t
no power= no power=
Ignite the techage charcoal lighter= Ignite the techage charcoal lighter=
Turns the bot off if the@nbattery power is below the@ngiven value in percent (1..99)= Turns the bot off if the@nbattery power is below the@ngiven value in percent (1..99)=
Jump to <label> if the@nbattery power is below the@ngiven value in percent (1..99)=
fully charged= fully charged=
Sends a techage command@nto a given node. @nReceiver is addressed by@nthe techage node number.@nFor commands with two or more @nwords, use the '*' character @ninstead of spaces, e.g.: @nsend_cmnd 3465 pull*default:dirt*2= Sends a techage command@nto a given node.@nReceiver is addressed by@nthe techage node number.@nFor commands with two or more@nwords, use the '*' character@ninstead of spaces, e.g.:@nsend_cmnd 3465 pull*default:dirt*2=
### techage.lua ###
### basis.lua ###
charging=
### timer.lua ### ### timer.lua ###
@ -464,9 +467,9 @@ Special kind of sensor.=
Can be programmed with a time in seconds, e.g. to start the bot cyclically.= Can be programmed with a time in seconds, e.g. to start the bot cyclically.=
### timer.lua ### ### timer.lua ###
### delayer.lua ### ### logic_and.lua ###
Start= Connected with=
### tool.lua ### ### tool.lua ###

View File

@ -37,7 +37,8 @@ if minetest.get_modpath("techage") then
local power = networks.power local power = networks.power
signs_bot.register_inventory({"techage:chest_ta2", "techage:chest_ta3", "techage:chest_ta4", signs_bot.register_inventory({"techage:chest_ta2", "techage:chest_ta3", "techage:chest_ta4",
"techage:ta3_silo", "techage:ta4_silo", "techage:ta4_sensor_chest"}, { "techage:ta3_silo", "techage:ta4_silo", "techage:ta4_sensor_chest",
"techage:ta4_reactor"}, {
allow_inventory_put = function(pos, stack, player_name) allow_inventory_put = function(pos, stack, player_name)
return not minetest.is_protected(pos, player_name) return not minetest.is_protected(pos, player_name)
end, end,
@ -147,6 +148,26 @@ if minetest.get_modpath("techage") then
end, end,
}) })
signs_bot.register_botcommand("jump_low_batt", {
mod = "techage",
params = "<percent> <label>",
num_param = 2,
description = S("Jump to <label> if the\nbattery power is below the\ngiven value in percent (1..99)"),
check = function(val, lbl)
val = tonumber(val) or 5
return val and val > 0 and val < 100 and signs_bot.check_label(lbl)
end,
cmnd = function(base_pos, mem, val, addr)
val = tonumber(val) or 5
local pwr = percent_value(signs_bot.MAX_CAPA, mem.capa)
if pwr < val then
mem.pc = addr - 3
return signs_bot.DONE
end
return signs_bot.DONE
end,
})
signs_bot.register_botcommand("send_cmnd", { signs_bot.register_botcommand("send_cmnd", {
mod = "techage", mod = "techage",
params = "<receiver> <command>", params = "<receiver> <command>",

View File

@ -95,55 +95,57 @@ minetest.register_entity(
if self.attached ~= nil then if self.attached ~= nil then
local player = minetest.get_player_by_name(self.attached) local player = minetest.get_player_by_name(self.attached)
local controls = player:get_player_control() if player then
local hspeed = 5.0 local controls = player:get_player_control()
local vspeed = -1 local hspeed = 5.0
self.idle = (self.idle or 1) - 1 local vspeed = -1
self.idle = (self.idle or 1) - 1
if controls.up then if controls.up then
vspeed = -3 vspeed = -3
hspeed = 8 hspeed = 8
player:set_look_vertical(math.tan(-vspeed / hspeed)) player:set_look_vertical(math.tan(-vspeed / hspeed))
set_player_yaw(self, player, yaw) set_player_yaw(self, player, yaw)
self.idle = 1 self.idle = 1
elseif controls.down then elseif controls.down then
vspeed = -0.25 vspeed = -0.25
hspeed = 2 hspeed = 2
player:set_look_vertical(math.tan(-vspeed / hspeed)) player:set_look_vertical(math.tan(-vspeed / hspeed))
set_player_yaw(self, player, yaw) set_player_yaw(self, player, yaw)
self.idle = 1 self.idle = 1
end end
if controls.right then if controls.right then
yaw = yaw - math.pi / 60 yaw = yaw - math.pi / 60
vspeed = -2 vspeed = -2
hspeed = 4 hspeed = 4
player:set_look_vertical(math.tan(-vspeed / hspeed)) player:set_look_vertical(math.tan(-vspeed / hspeed))
set_player_yaw(self, player, yaw) set_player_yaw(self, player, yaw)
self.idle = 1 self.idle = 1
elseif controls.left then elseif controls.left then
yaw = yaw + math.pi / 60 yaw = yaw + math.pi / 60
vspeed = -2 vspeed = -2
hspeed = 4 hspeed = 4
player:set_look_vertical(math.tan(-vspeed / hspeed)) player:set_look_vertical(math.tan(-vspeed / hspeed))
set_player_yaw(self, player, yaw) set_player_yaw(self, player, yaw)
self.idle = 1 self.idle = 1
end end
if self.idle == 0 then if self.idle == 0 then
player:set_look_vertical(math.tan(-vspeed / hspeed)) player:set_look_vertical(math.tan(-vspeed / hspeed))
set_player_yaw(self, player, yaw) set_player_yaw(self, player, yaw)
end end
self.object:set_yaw(yaw) self.object:set_yaw(yaw)
local vel = vector.multiply(minetest.yaw_to_dir(yaw), hspeed) local vel = vector.multiply(minetest.yaw_to_dir(yaw), hspeed)
vel.y = vspeed vel.y = vspeed
self.object:set_velocity(vel) self.object:set_velocity(vel)
if node_under.name ~= "air" then if node_under.name ~= "air" then
default.player_attached[self.attached] = false default.player_attached[self.attached] = false
local player = minetest.get_player_by_name(self.attached) local player = minetest.get_player_by_name(self.attached)
player:get_meta():set_int("player_physics_locked", 0) player:get_meta():set_int("player_physics_locked", 0)
end
end end
else else
self.object:remove() self.object:remove()
@ -155,7 +157,9 @@ minetest.register_entity(
default.player_attached[self.attached] = false default.player_attached[self.attached] = false
self.object:set_detach() self.object:set_detach()
local player = minetest.get_player_by_name(self.attached) local player = minetest.get_player_by_name(self.attached)
player:get_meta():set_int("player_physics_locked", 0) if player then
player:get_meta():set_int("player_physics_locked", 0)
end
end end
self.object:remove() self.object:remove()
end end

View File

@ -63,16 +63,24 @@ It is highly recommended that you install the following mods, too:
* [autobahn](https://github.com/joe7575/autobahn): Street blocks and slopes with stripes for faster traveling * [autobahn](https://github.com/joe7575/autobahn): Street blocks and slopes with stripes for faster traveling
* [[ta4_jetpack](https://github.com/joe7575/ta4_jetpack): A Jetpack with hydrogen as fuel and TA4 recipe * [[ta4_jetpack](https://github.com/joe7575/ta4_jetpack): A Jetpack with hydrogen as fuel and TA4 recipe
For large servers with many player `lsqlite3` is recommended. For large servers with many players, the following packages are recommended:
The package has to be installed via [luarocks](https://luarocks.org/):
luarocks install lsqlite3 * lua-mashal for faster serialization/deserialization of data
* lsqlite3 for storing node and network data
To enable this `unsafe` package, add 'techage' to the list of trusted mods in minetest.conf: The packages have to be installed via [luarocks](https://luarocks.org/):
secure.trusted_mods = techage luarocks --lua-version 5.1 install lsqlite3
luarocks --lua-version 5.1 install lua-marshal
For the installation of 'luarocks' (if not already available), see [luarocks](https://luarocks.org/) To enable these `unsafe` packages, add 'techage' and 'lua-marshal'
to the list of trusted mods in `minetest.conf`:
secure.trusted_mods = techage,lua-marshal
and add the following line to your `world.mt` or `minetest.conf`:
techage_use_sqlite = true
Available worlds will be converted to 'lsqlite3', but there is no way back, so: Available worlds will be converted to 'lsqlite3', but there is no way back, so:
@ -81,6 +89,10 @@ Available worlds will be converted to 'lsqlite3', but there is no way back, so:
### History ### History
**2022-09-03 V1.09**
- Change the way items are pushed
- Add "Flow Limiter" mode to TA4 pump and TA4 pusher
**2022-06-06 V1.08** **2022-06-06 V1.08**
- Native support for the mod Beduino added - Native support for the mod Beduino added

View File

@ -230,6 +230,8 @@ function techage.register_consumer(base_name, inv_name, tiles, tNode, validState
on_metadata_inventory_put = tNode.on_metadata_inventory_put, on_metadata_inventory_put = tNode.on_metadata_inventory_put,
on_metadata_inventory_take = tNode.on_metadata_inventory_take, on_metadata_inventory_take = tNode.on_metadata_inventory_take,
ta_rotate_node = tNode.ta_rotate_node, ta_rotate_node = tNode.ta_rotate_node,
ta3_formspec = stage == 3 and tNode.ta3_formspec,
ta4_formspec = stage == 4 and tNode.ta4_formspec,
paramtype = tNode.paramtype, paramtype = tNode.paramtype,
paramtype2 = "facedir", paramtype2 = "facedir",
@ -271,6 +273,8 @@ function techage.register_consumer(base_name, inv_name, tiles, tNode, validState
on_metadata_inventory_put = tNode.on_metadata_inventory_put, on_metadata_inventory_put = tNode.on_metadata_inventory_put,
on_metadata_inventory_take = tNode.on_metadata_inventory_take, on_metadata_inventory_take = tNode.on_metadata_inventory_take,
ta_rotate_node = tNode.ta_rotate_node, ta_rotate_node = tNode.ta_rotate_node,
ta3_formspec = stage == 3 and tNode.ta3_formspec,
ta4_formspec = stage == 4 and tNode.ta4_formspec,
paramtype = tNode.paramtype, paramtype = tNode.paramtype,
paramtype2 = "facedir", paramtype2 = "facedir",

View File

@ -277,10 +277,17 @@ local function push_item(pos, base_filter, itemstack, num_items, nvm)
num_of_trials = num_of_trials + 1 num_of_trials = num_of_trials + 1
local push_dir = filter[idx] local push_dir = filter[idx]
local num_to_push = math.min(amount, num_items - num_pushed) local num_to_push = math.min(amount, num_items - num_pushed)
if techage.push_items(pos, push_dir, itemstack:peek_item(num_to_push)) then local leftover = techage.push_items(pos, push_dir, itemstack:peek_item(num_to_push))
num_pushed = num_pushed + num_to_push local pushed
nvm.port_counter[push_dir] = (nvm.port_counter[push_dir] or 0) + num_to_push if not leftover then
pushed = 0
elseif leftover ~= true then
pushed = num_to_push - leftover:get_count()
else -- leftover == true
pushed = num_to_push
end end
num_pushed = num_pushed + pushed
nvm.port_counter[push_dir] = (nvm.port_counter[push_dir] or 0) + pushed
-- filter start offset -- filter start offset
idx = idx + 1 idx = idx + 1
if idx > num_ports then if idx > num_ports then

View File

@ -73,11 +73,17 @@ minetest.register_node("techage:itemsource", {
local stack = inv:get_stack('main', 1) local stack = inv:get_stack('main', 1)
if stack:get_count() > 0 then if stack:get_count() > 0 then
local push_dir = meta:get_int("push_dir") local push_dir = meta:get_int("push_dir")
if techage.push_items(pos, push_dir, stack) then local leftover = techage.push_items(pos, push_dir, stack)
local cnt = meta:get_int("counter") + stack:get_count() local pushed
meta:set_int("counter", cnt) if not leftover then
meta:set_string("infotext", "Techage Item Source: "..cnt) pushed = 0
elseif leftover ~= true then
pushed = stack:get_count() - leftover:get_count()
else -- leftover == true
pushed = stack:get_count()
end end
meta:set_int("counter", pushed)
meta:set_string("infotext", "Techage Item Source: "..pushed)
end end
return true return true
end, end,

View File

@ -34,6 +34,16 @@ local STANDBY_TICKS = 2
local COUNTDOWN_TICKS = 4 local COUNTDOWN_TICKS = 4
local CYCLE_TIME = 2 local CYCLE_TIME = 2
local WRENCH_MENU = {
{
type = "number",
name = "limit",
label = S("Number of items"),
tooltip = S("Number of items that are allowed to be pushed"),
default = "0",
},
}
local function ta4_formspec(self, pos, nvm) local function ta4_formspec(self, pos, nvm)
if CRD(pos).stage == 4 then -- TA4 node? if CRD(pos).stage == 4 then -- TA4 node?
return "size[8,7.2]".. return "size[8,7.2]"..
@ -42,7 +52,8 @@ local function ta4_formspec(self, pos, nvm)
default.gui_slots.. default.gui_slots..
"box[0,-0.1;7.8,0.5;#c6e8ff]".. "box[0,-0.1;7.8,0.5;#c6e8ff]"..
"label[3,-0.1;"..minetest.colorize("#000000", S("Pusher")).."]".. "label[3,-0.1;"..minetest.colorize("#000000", S("Pusher")).."]"..
techage.question_mark_help(8, S("Optionally configure\nthe pusher with one item")).. techage.question_mark_help(7.5, S("Optionally configure\nthe pusher with one item"))..
techage.wrench_image(7.4, -0.05) ..
"list[context;main;3.5,0.8;1,1;]".. "list[context;main;3.5,0.8;1,1;]"..
"image_button[3.5,2;1,1;".. self:get_state_button_image(nvm) ..";state_button;]".. "image_button[3.5,2;1,1;".. self:get_state_button_image(nvm) ..";state_button;]"..
"tooltip[3.5,2;1,1;"..self:get_state_tooltip(nvm).."]".. "tooltip[3.5,2;1,1;"..self:get_state_tooltip(nvm).."]"..
@ -87,30 +98,71 @@ local function allow_metadata_inventory_take(pos, listname, index, stack, player
return 0 return 0
end end
local function pushing(pos, crd, meta, nvm) local function set_limit(pos, nvm, val)
local pull_dir = meta:get_int("pull_dir") val = tonumber(val) or 0
local push_dir = meta:get_int("push_dir") if val > 0 then
local num = nvm.item_count or nvm.num_items or crd.num_items nvm.limit = val
nvm.num_items = 0
M(pos):set_int("limit", val)
else
nvm.limit = nil
nvm.num_items = nil
M(pos):set_string("limit", "")
end
end
-- Function returns the number of pushed items
local function push(pos, crd, meta, nvm, pull_dir, push_dir, num)
local items = techage.pull_items(pos, pull_dir, num, nvm.item_name) local items = techage.pull_items(pos, pull_dir, num, nvm.item_name)
if items ~= nil then if items ~= nil then
if techage.push_items(pos, push_dir, items) ~= true then local taken = items:get_count()
local leftover = techage.push_items(pos, push_dir, items)
if not leftover then
-- place item back -- place item back
techage.unpull_items(pos, pull_dir, items) techage.unpull_items(pos, pull_dir, items)
crd.State:blocked(pos, nvm) crd.State:blocked(pos, nvm)
return return 0
elseif leftover ~= true then
-- place item back
techage.unpull_items(pos, pull_dir, leftover)
crd.State:blocked(pos, nvm)
return taken - leftover:get_count()
end end
if nvm.item_count then -- remote job? return taken
nvm.item_count = nil
nvm.item_name = nil
crd.State:stop(pos, nvm)
local number = M(pos):get_string("node_number")
techage.send_single(number, nvm.rmt_num, "off")
else
crd.State:keep_running(pos, nvm, COUNTDOWN_TICKS)
end
return
end end
crd.State:idle(pos, nvm) crd.State:idle(pos, nvm)
return 0
end
local function pushing(pos, crd, meta, nvm)
local pull_dir = meta:get_int("pull_dir")
local push_dir = meta:get_int("push_dir")
if not nvm.limit then
local num = nvm.item_count or nvm.num_items or crd.num_items
num = push(pos, crd, meta, nvm, pull_dir, push_dir, num)
if num > 0 then
if nvm.item_count then
nvm.item_count = nvm.item_count - num
if nvm.item_count <= 0 then
crd.State:stop(pos, nvm)
nvm.item_count = nil
end
end
crd.State:keep_running(pos, nvm, COUNTDOWN_TICKS)
end
elseif nvm.num_items < nvm.limit then
local num = math.min(crd.num_items, nvm.limit - nvm.num_items)
num = push(pos, crd, meta, nvm, pull_dir, push_dir, num)
if num > 0 then
nvm.num_items = nvm.num_items + num
if nvm.num_items >= nvm.limit then
crd.State:stop(pos, nvm)
else
crd.State:keep_running(pos, nvm, COUNTDOWN_TICKS)
end
end
end
end end
local function keep_running(pos, elapsed) local function keep_running(pos, elapsed)
@ -180,6 +232,18 @@ local function can_start(pos, nvm, state)
return true return true
end end
local function ta_after_formspec(pos, fields, playername)
local nvm = techage.get_nvm(pos)
set_limit(pos, nvm, fields.limit)
end
local function on_state_change(pos, old_state, new_state)
if old_state == techage.STOPPED and new_state == techage.RUNNING then
local nvm = techage.get_nvm(pos)
set_limit(pos, nvm, M(pos):get_int("limit"))
end
end
local function config_item(pos, payload) local function config_item(pos, payload)
if type(payload) == "string" then if type(payload) == "string" then
if payload == "" then if payload == "" then
@ -247,43 +311,56 @@ local tubing = {
is_pusher = true, -- is a pulling/pushing node is_pusher = true, -- is a pulling/pushing node
on_recv_message = function(pos, src, topic, payload) on_recv_message = function(pos, src, topic, payload)
if topic == "pull" then if topic == "pull" then -- Deprecated command, use config/limit/start instead
local nvm = techage.get_nvm(pos) local nvm = techage.get_nvm(pos)
CRD(pos).State:stop(pos, nvm) CRD(pos).State:stop(pos, nvm)
nvm.item_count = math.min(config_item(pos, payload), 12) nvm.item_count = math.min(config_item(pos, payload), 12)
nvm.rmt_num = src nvm.rmt_num = src
CRD(pos).State:start(pos, nvm) CRD(pos).State:start(pos, nvm)
return true return true
elseif topic == "config" then elseif topic == "config" then -- Set item type
local nvm = techage.get_nvm(pos) local nvm = techage.get_nvm(pos)
CRD(pos).State:stop(pos, nvm) CRD(pos).State:stop(pos, nvm)
config_item(pos, payload) config_item(pos, payload)
CRD(pos).State:start(pos, nvm)
return true return true
elseif topic == "limit" then -- Set push limit
local nvm = techage.get_nvm(pos)
CRD(pos).State:stop(pos, nvm)
set_limit(pos, nvm, payload)
return true
elseif topic == "count" then -- Get number of push items
local nvm = techage.get_nvm(pos)
return nvm.num_items or 0
else else
return CRD(pos).State:on_receive_message(pos, topic, payload) return CRD(pos).State:on_receive_message(pos, topic, payload)
end end
end, end,
on_beduino_receive_cmnd = function(pos, src, topic, payload) on_beduino_receive_cmnd = function(pos, src, topic, payload)
if topic == 64 then -- Start pusher if topic == 65 then -- Set item type
local nvm = techage.get_nvm(pos)
CRD(pos).State:stop(pos, nvm)
nvm.item_count = math.min(config_item(pos, payload), 12)
nvm.rmt_num = src
CRD(pos).State:start(pos, nvm)
return 0
elseif topic == 65 then -- Config Pusher
local nvm = techage.get_nvm(pos) local nvm = techage.get_nvm(pos)
CRD(pos).State:stop(pos, nvm) CRD(pos).State:stop(pos, nvm)
config_item(pos, payload) config_item(pos, payload)
CRD(pos).State:start(pos, nvm) return 0
elseif topic == 68 then -- Set push limit
local nvm = techage.get_nvm(pos)
CRD(pos).State:stop(pos, nvm)
set_limit(pos, nvm, payload[1])
return 0 return 0
else else
local nvm = techage.get_nvm(pos)
if nvm.limit then
nvm.num_items = 0
end
return CRD(pos).State:on_beduino_receive_cmnd(pos, topic, payload) return CRD(pos).State:on_beduino_receive_cmnd(pos, topic, payload)
end end
end, end,
on_beduino_request_data = function(pos, src, topic, payload) on_beduino_request_data = function(pos, src, topic, payload)
return CRD(pos).State:on_beduino_request_data(pos, topic, payload) if topic == 150 then -- Get number of pushed items
local nvm = techage.get_nvm(pos)
return 0, {nvm.num_items or 0}
else
return CRD(pos).State:on_beduino_request_data(pos, topic, payload)
end
end, end,
} }
@ -294,6 +371,7 @@ local node_name_ta2, node_name_ta3, node_name_ta4 =
formspec = ta4_formspec, formspec = ta4_formspec,
tubing = tubing, tubing = tubing,
can_start = can_start, can_start = can_start,
on_state_change = on_state_change,
after_place_node = function(pos, placer) after_place_node = function(pos, placer)
local meta = M(pos) local meta = M(pos)
local node = minetest.get_node(pos) local node = minetest.get_node(pos)
@ -321,6 +399,8 @@ local node_name_ta2, node_name_ta3, node_name_ta4 =
node_timer = keep_running, node_timer = keep_running,
on_rotate = screwdriver.disallow, on_rotate = screwdriver.disallow,
tubelib2_on_update2 = tubelib2_on_update2, tubelib2_on_update2 = tubelib2_on_update2,
ta4_formspec = WRENCH_MENU,
ta_after_formspec = ta_after_formspec,
groups = {choppy=2, cracky=2, crumbly=2}, groups = {choppy=2, cracky=2, crumbly=2},
is_ground_content = false, is_ground_content = false,

View File

@ -133,7 +133,7 @@ local function doesItemStackMatchNvmStack(itemstack, nvmstack)
-- The following seems to be the most reliable approach to compare meta. -- The following seems to be the most reliable approach to compare meta.
local nvm_meta = ItemStack():get_meta() local nvm_meta = ItemStack():get_meta()
nvm_meta:from_table(minetest.deserialize(nvmstack.meta)) nvm_meta:from_table(minetest.deserialize(nvmstack.meta or ""))
if not nvm_meta:equals(itemstack:get_meta()) then if not nvm_meta:equals(itemstack:get_meta()) then
return false, "Mismatching meta" return false, "Mismatching meta"
end end
@ -197,7 +197,7 @@ local function take_from_chest(pos, idx, output_stack, max_total_count, keep_ass
count = count, count = count,
wear = nvm_stack.wear, wear = nvm_stack.wear,
})) }))
output_stack:get_meta():from_table(minetest.deserialize(nvm_stack.meta)) output_stack:get_meta():from_table(minetest.deserialize(nvm_stack.meta or ""))
nvm_stack.count = nvm_stack.count - count nvm_stack.count = nvm_stack.count - count
if nvm_stack.count == 0 then if nvm_stack.count == 0 then
gen_stack(nvm.inventory or {}, idx) gen_stack(nvm.inventory or {}, idx)
@ -210,21 +210,14 @@ local function tube_add_to_chest(pos, input_stack)
local nvm = techage.get_nvm(pos) local nvm = techage.get_nvm(pos)
nvm.inventory = nvm.inventory or {} nvm.inventory = nvm.inventory or {}
-- Backup some values needed for restoring the old
-- state if items can't fully be added to chest.
local orig_count = input_stack:get_count()
local backup = table.copy(nvm.inventory)
for idx = 1,8 do for idx = 1,8 do
input_stack:take_item(add_to_chest(pos, input_stack, idx)) input_stack:take_item(add_to_chest(pos, input_stack, idx))
end end
if input_stack:get_count() > 0 then if input_stack:get_count() > 0 then
nvm.inventory = backup -- Restore old nvm inventory return input_stack -- Not all items were added to chest
input_stack:set_count(orig_count) -- Restore input_stack
return false -- No items were added to chest
else else
return true -- Items were added successfully return true -- All items were added
end end
end end

View File

@ -460,7 +460,7 @@ function techage.push_items(pos, out_dir, stack, idx)
minetest.add_item(npos, stack) minetest.add_item(npos, stack)
return true return true
end end
return false return stack
end end
-- Check for recursion and too long distances -- Check for recursion and too long distances
@ -485,7 +485,7 @@ function techage.safe_push_items(pos, out_dir, stack, idx)
end end
end end
end end
return false return stack
end end
function techage.unpull_items(pos, out_dir, stack) function techage.unpull_items(pos, out_dir, stack)
@ -496,37 +496,6 @@ function techage.unpull_items(pos, out_dir, stack)
return false return false
end end
-------------------------------------------------------------------
-- Client side Push/Pull item functions for hopper like nodes
-- (nodes with no tube support)
-------------------------------------------------------------------
function techage.neighbour_pull_items(pos, out_dir, num)
local res, npos, in_dir, name = get_next_node(pos, out_dir)
if res and NodeDef[name] and NodeDef[name].on_pull_item then
return NodeDef[name].on_pull_item(npos, in_dir, num)
end
end
function techage.neighbour_push_items(pos, out_dir, stack)
local res, npos, in_dir, name = get_next_node(pos, out_dir)
if res and NodeDef[name] and NodeDef[name].on_push_item then
return NodeDef[name].on_push_item(npos, in_dir, stack)
elseif name == "air" then
minetest.add_item(npos, stack)
return true
end
return false
end
function techage.neighbour_unpull_items(pos, out_dir, stack)
local res, npos, in_dir, name = get_next_node(pos, out_dir)
if res and NodeDef[name] and NodeDef[name].on_unpull_item then
return NodeDef[name].on_unpull_item(npos, in_dir, stack)
end
return false
end
------------------------------------------------------------------- -------------------------------------------------------------------
-- Server side helper functions -- Server side helper functions
------------------------------------------------------------------- -------------------------------------------------------------------
@ -554,23 +523,33 @@ function techage.get_items(pos, inv, listname, num)
return nil return nil
end end
-- Put the given stack into the given ItemList. -- Put the given stack into the given ItemList/inventory.
-- Function returns false if ItemList is full. -- Function returns:
-- - true, if all items are moved
-- - false, if no item is moved
-- - leftover, if less than all items are moved
-- (true/false is the legacy mode and can't be removed)
function techage.put_items(inv, listname, item, idx) function techage.put_items(inv, listname, item, idx)
local leftover
if idx and inv and idx <= inv:get_size(listname) then if idx and inv and idx <= inv:get_size(listname) then
local stack = inv:get_stack(listname, idx) local stack = inv:get_stack(listname, idx)
if stack:item_fits(item) then leftover = stack:add_item(item)
stack:add_item(item) inv:set_stack(listname, idx, stack)
inv:set_stack(listname, idx, stack) elseif inv then
return true leftover = inv:add_item(listname, item)
end
else else
if inv and inv:room_for_item(listname, item) then return false
inv:add_item(listname, item)
return true
end
end end
return false
local cnt = leftover:get_count()
if cnt == item:get_count() then
return false
elseif cnt == 0 then
return true
else
return leftover
end
end end
-- Return "full", "loaded", or "empty" depending -- Return "full", "loaded", or "empty" depending

View File

@ -76,16 +76,22 @@ function inv_lib.allow_conf_inv_move(pos, from_list, from_index, to_list, to_ind
end end
function inv_lib.put_items(pos, inv, listname, item, stacks, idx) function inv_lib.put_items(pos, inv, listname, item, stacks, idx)
local name = item:get_name()
local count = item:get_count()
for _, i in ipairs(stacks or {}) do for _, i in ipairs(stacks or {}) do
if not idx or idx == i then if not idx or idx == i then
local stack = inv:get_stack(listname, i) local stack = inv:get_stack(listname, i)
if stack:item_fits(item) then local leftover = stack:add_item({name = name, count = count})
stack:add_item(item) count = leftover:get_count()
inv:set_stack(listname, i, stack) inv:set_stack(listname, i, stack)
if count == 0 then
return true return true
end end
end end
end end
if count > 0 then
return ItemStack({name = name, count = count})
end
return false return false
end end

View File

@ -75,14 +75,15 @@ function flylib.distance(v)
return math.abs(v.x) + math.abs(v.y) + math.abs(v.z) return math.abs(v.x) + math.abs(v.y) + math.abs(v.z)
end end
function flylib.to_vector(s) function flylib.to_vector(s, max_dist)
local x,y,z = unpack(string.split(s, ",")) local x,y,z = unpack(string.split(s, ","))
x = tonumber(x) or 0
y = tonumber(y) or 0
z = tonumber(z) or 0
if x and y and z then if x and y and z then
return { if not max_dist or (math.abs(x) + math.abs(y) + math.abs(z)) <= max_dist then
x=tonumber(x) or 0, return {x = x, y = y, z = z}
y=tonumber(y) or 0, end
z=tonumber(z) or 0,
}
end end
end end
@ -101,7 +102,7 @@ function flylib.to_path(s, max_dist)
tPath = tPath or {} tPath = tPath or {}
tPath[#tPath + 1] = v tPath[#tPath + 1] = v
else else
return tPath, S("Error: Max. length of the flight route exceeded !!") return tPath, S("Error: Max. length of the flight route exceeded by @1 blocks !!", dist - max_dist)
end end
else else
return tPath, S("Error: Invalid path !!") return tPath, S("Error: Invalid path !!")

View File

@ -65,6 +65,7 @@ function api.store_mapblock_data(key, mapblock_data)
if pos then if pos then
item._POS_ = nil item._POS_ = nil
local data = serialize(item) local data = serialize(item)
item._POS_ = pos
local meta = M(pos) local meta = M(pos)
meta:set_string("ta_data", data) meta:set_string("ta_data", data)
meta:mark_as_private("ta_data") meta:mark_as_private("ta_data")

View File

@ -169,6 +169,14 @@ function techage.recipes.get_recipe(name)
return NormalizedRecipes[name] return NormalizedRecipes[name]
end end
function techage.recipes.set_recipe(pos, rtype, idx)
local nvm = techage.get_nvm(pos)
if not nvm.running then
local recipes = Recipes[rtype] or {}
idx = tonumber(idx) or 1
nvm.recipe_idx = range(idx, 1, #recipes)
end
end
function techage.recipes.get_default_group_item_name(item_name) function techage.recipes.get_default_group_item_name(item_name)
if item_name and item_name:sub(1, 6) == "group:" then if item_name and item_name:sub(1, 6) == "group:" then

View File

@ -16,8 +16,8 @@ local S = techage.S
techage.menu = {} techage.menu = {}
local function index(list, x) local function index(list, x)
for idx, v in ipairs(list) do for idx, v in ipairs(list or {}) do
if v == x then return idx end if tostring(v) == x then return idx end
end end
return nil return nil
end end
@ -99,7 +99,6 @@ local function generate_formspec_substring(pos, meta, form_def, player_name)
end end
tbl[#tbl+1] = "label[4.75," .. offs .. ";" .. val .. "]" tbl[#tbl+1] = "label[4.75," .. offs .. ";" .. val .. "]"
elseif elem.type == "dropdown" then elseif elem.type == "dropdown" then
local l = elem.choices:split(",")
if nvm.running or techage.is_running(nvm) then if nvm.running or techage.is_running(nvm) then
local val = elem.default or "" local val = elem.default or ""
if meta:contains(elem.name) then if meta:contains(elem.name) then
@ -120,7 +119,13 @@ local function generate_formspec_substring(pos, meta, form_def, player_name)
if meta:contains(elem.name) then if meta:contains(elem.name) then
val = meta:get_string(elem.name) or "" val = meta:get_string(elem.name) or ""
end end
local idx = index(l, val) or 1 local idx
if elem.values then
idx = index(elem.values, val) or 1
else
local l = elem.choices:split(",")
idx = index(l, val) or 1
end
tbl[#tbl+1] = "dropdown[4.72," .. (offs) .. ";5.5,1.4;" .. elem.name .. ";" .. elem.choices .. ";" .. idx .. "]" tbl[#tbl+1] = "dropdown[4.72," .. (offs) .. ";5.5,1.4;" .. elem.name .. ";" .. elem.choices .. ";" .. idx .. "]"
end end
elseif elem.type == "items" then -- inventory elseif elem.type == "items" then -- inventory
@ -137,9 +142,9 @@ local function generate_formspec_substring(pos, meta, form_def, player_name)
return player_inv_needed, table.concat(tbl, "") return player_inv_needed, table.concat(tbl, "")
end end
local function value_check(elem, value) local function value_check(elem, value, player_name)
if elem.check then if elem.check then
return elem.check(value) return elem.check(value, player_name)
end end
return value ~= nil return value ~= nil
end end
@ -159,7 +164,7 @@ local function evaluate_data(pos, meta, form_def, fields, player_name)
meta:set_string(elem.name, "") meta:set_string(elem.name, "")
elseif fields[elem.name]:find("^[%d ]+$") then elseif fields[elem.name]:find("^[%d ]+$") then
local val = tonumber(fields[elem.name]) local val = tonumber(fields[elem.name])
if value_check(elem, val) then if value_check(elem, val, player_name) then
meta:set_int(elem.name, val) meta:set_int(elem.name, val)
--print("set_int", elem.name, val) --print("set_int", elem.name, val)
else else
@ -173,7 +178,8 @@ local function evaluate_data(pos, meta, form_def, fields, player_name)
if fields[elem.name] then if fields[elem.name] then
if fields[elem.name] == "" then if fields[elem.name] == "" then
meta:set_string(elem.name, "") meta:set_string(elem.name, "")
elseif fields[elem.name]:find("^[%d ]+$") and value_check(elem, fields[elem.name]) then elseif fields[elem.name]:find("^[%d ]+$") and
value_check(elem, fields[elem.name], player_name) then
meta:set_string(elem.name, fields[elem.name]) meta:set_string(elem.name, fields[elem.name])
else else
res = false res = false
@ -184,7 +190,7 @@ local function evaluate_data(pos, meta, form_def, fields, player_name)
meta:set_string(elem.name, "") meta:set_string(elem.name, "")
elseif fields[elem.name] then elseif fields[elem.name] then
local val = tonumber(fields[elem.name]) local val = tonumber(fields[elem.name])
if val and value_check(elem, val) then if val and value_check(elem, val, player_name) then
meta:set_string(elem.name, val) meta:set_string(elem.name, val)
else else
res = false res = false
@ -194,7 +200,7 @@ local function evaluate_data(pos, meta, form_def, fields, player_name)
if fields[elem.name] == ""then if fields[elem.name] == ""then
meta:set_string(elem.name, "") meta:set_string(elem.name, "")
elseif fields[elem.name] then elseif fields[elem.name] then
if value_check(elem, fields[elem.name]) then if value_check(elem, fields[elem.name], player_name) then
meta:set_string(elem.name, fields[elem.name]) meta:set_string(elem.name, fields[elem.name])
else else
res = false res = false
@ -202,7 +208,14 @@ local function evaluate_data(pos, meta, form_def, fields, player_name)
end end
elseif elem.type == "dropdown" then elseif elem.type == "dropdown" then
if fields[elem.name] ~= nil then if fields[elem.name] ~= nil then
meta:set_string(elem.name, fields[elem.name]) if elem.values then
local l = elem.choices:split(",")
local idx = index(l, fields[elem.name]) or 1
local text = elem.values[idx]
meta:set_string(elem.name, text)
else
meta:set_string(elem.name, fields[elem.name])
end
end end
elseif elem.type == "items" and player_name then elseif elem.type == "items" and player_name then
local inv_name = minetest.formspec_escape(player_name) .. "_techage_wrench_menu" local inv_name = minetest.formspec_escape(player_name) .. "_techage_wrench_menu"

View File

@ -358,7 +358,12 @@ liquid.register_nodes({"techage:ta4_doser", "techage:ta4_doser_on"}, Pipe, "pump
techage.register_node({"techage:ta4_doser", "techage:ta4_doser_on"}, { techage.register_node({"techage:ta4_doser", "techage:ta4_doser_on"}, {
on_recv_message = function(pos, src, topic, payload) on_recv_message = function(pos, src, topic, payload)
return State:on_receive_message(pos, topic, payload) if topic == "recipe" then
techage.recipes.set_recipe(pos, "ta4_doser", payload)
return true
else
return State:on_receive_message(pos, topic, payload)
end
end, end,
on_beduino_receive_cmnd = function(pos, src, topic, payload) on_beduino_receive_cmnd = function(pos, src, topic, payload)
return State:on_beduino_receive_cmnd(pos, topic, payload) return State:on_beduino_receive_cmnd(pos, topic, payload)

View File

@ -168,6 +168,28 @@ minetest.register_node("techage:ta4_reactor", {
sounds = default.node_sound_metal_defaults(), sounds = default.node_sound_metal_defaults(),
}) })
techage.register_node({"techage:ta4_reactor"}, {
on_inv_request = function(pos, in_dir, access_type)
local meta = minetest.get_meta(pos)
return meta:get_inventory(), "main"
end,
on_pull_item = function(pos, in_dir, num, item_name)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
return techage.get_items(pos, inv, "main", num)
end,
on_push_item = function(pos, in_dir, stack)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
return techage.put_items(inv, "main", stack)
end,
on_unpull_item = function(pos, in_dir, stack)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
return techage.put_items(inv, "main", stack)
end,
})
minetest.register_craft({ minetest.register_craft({
output = 'techage:ta4_reactor', output = 'techage:ta4_reactor',
recipe = { recipe = {

View File

@ -86,7 +86,7 @@ minetest.register_node("techage:coalfirebox", {
after_place_node = function(pos, placer) after_place_node = function(pos, placer)
if firebox.is_free_position(pos, placer:get_player_name()) then if firebox.is_free_position(pos, placer:get_player_name()) then
techage.add_node(pos, "techage:coalfirebox") techage.add_node(pos, "techage:coalfirebox", true)
local nvm = techage.get_nvm(pos) local nvm = techage.get_nvm(pos)
nvm.running = false nvm.running = false
nvm.burn_cycles = 0 nvm.burn_cycles = 0

View File

@ -88,7 +88,7 @@ minetest.register_node("techage:oilfirebox", {
after_place_node = function(pos, placer) after_place_node = function(pos, placer)
if firebox.is_free_position(pos, placer:get_player_name()) then if firebox.is_free_position(pos, placer:get_player_name()) then
techage.add_node(pos, "techage:oilfirebox") techage.add_node(pos, "techage:oilfirebox", true)
local nvm = techage.get_nvm(pos) local nvm = techage.get_nvm(pos)
nvm.running = false nvm.running = false
nvm.burn_cycles = 0 nvm.burn_cycles = 0

View File

@ -229,6 +229,7 @@ techage.manual_DE.aTitel = {
"3,TA4 Elektronikfabrik / Electronic Fab", "3,TA4 Elektronikfabrik / Electronic Fab",
"3,TA4 Injektor / Injector", "3,TA4 Injektor / Injector",
"3,TA4 Recycler", "3,TA4 Recycler",
"3,TA4 Item Durchlaufbegrenzer / Item Flow Limiter",
"1,TA5: Zukunft", "1,TA5: Zukunft",
"2,Energiequellen", "2,Energiequellen",
"3,TA5 Fusionsreaktor", "3,TA5 Fusionsreaktor",
@ -1042,7 +1043,7 @@ techage.manual_DE.aText = {
"\n".. "\n"..
"\n", "\n",
"Der Taster/Schalter sendet 'on'/'off' Kommandos zu den Blöcken\\, die über die Nummern konfiguriert wurden.\n".. "Der Taster/Schalter sendet 'on'/'off' Kommandos zu den Blöcken\\, die über die Nummern konfiguriert wurden.\n"..
"Der Taster/Schalter kann als Taster (button) oder Schalter (switch) konfiguriert werden. Wird er als Taster konfiguriert\\, so kann die Zeit zwischen den 'on' und 'off' Kommandos eingestellt werden.\n".. "Der Taster/Schalter kann als Taster (button) oder Schalter (switch) konfiguriert werden. Wird er als Taster konfiguriert\\, so kann die Zeit zwischen den 'on' und 'off' Kommandos eingestellt werden. Mit der Betriebsart \"on button\" wird nur ein 'on' und kein 'off' Kommandos gesendet.\n"..
"\n".. "\n"..
"Über die Checkbox \"public\" kann eingestellt werden\\, ob den Taster von jedem (gesetzt)\\, oder nur vom Besitzer selbst (nicht gesetzt) genutzt werden darf.\n".. "Über die Checkbox \"public\" kann eingestellt werden\\, ob den Taster von jedem (gesetzt)\\, oder nur vom Besitzer selbst (nicht gesetzt) genutzt werden darf.\n"..
"\n".. "\n"..
@ -1125,7 +1126,9 @@ techage.manual_DE.aText = {
"\n".. "\n"..
"\n", "\n",
"Die Signallampe kann mit 'on'/'off' Kommando ein- bzw. ausgeschaltet werden. Diese Lampe braucht keinen Strom und\n".. "Die Signallampe kann mit 'on'/'off' Kommando ein- bzw. ausgeschaltet werden. Diese Lampe braucht keinen Strom und\n"..
"kann mit der Spritzpistole aus der Mod \"Unified Dyes\" farbig gemacht werden.\n".. "kann mit der Spritzpistole aus der Mod \"Unified Dyes\" und über Lua/Beduino Kommandos eingefärbt werden.\n"..
"\n"..
"Mit dem Chat-Kommando '/ta_color' wird die Farbpalette mit den Werten für die Lua/Beduino Kommandos angezeigt und mit '/ta_send color <num>' kann die Farbe geändert werden.\n"..
"\n".. "\n"..
"\n".. "\n"..
"\n", "\n",
@ -1630,7 +1633,7 @@ techage.manual_DE.aText = {
"\n".. "\n"..
"\n", "\n",
"", "",
"Beim TA4 Taster/Schalter hat sich nur das Aussehen geändert. Die Funktionalität ist gleich wie beim TA3 Taster/Schalter.\n".. "Beim TA4 Taster/Schalter hat sich nur das Aussehen geändert. Die Funktionalität ist gleich wie beim TA3 Taster/Schalter. Mit dem Schraubenschlüssel-Menü können die Daten aber nachträglich geändert werden.\n"..
"\n".. "\n"..
"\n".. "\n"..
"\n", "\n",
@ -1696,6 +1699,8 @@ techage.manual_DE.aText = {
"\n".. "\n"..
"Das 'goto' Kommando wird nur angenommen\\, wenn der Sequenzer gestoppt ist.\n".. "Das 'goto' Kommando wird nur angenommen\\, wenn der Sequenzer gestoppt ist.\n"..
"\n".. "\n"..
"Über das Gabelschlüssel-Menü kann beim Sequenzer die Zykluszeit (normal: 100 ms) geändert werden. \n"..
"\n"..
"\n".. "\n"..
"\n", "\n",
"", "",
@ -1705,7 +1710,7 @@ techage.manual_DE.aText = {
"Anleitung:\n".. "Anleitung:\n"..
"\n".. "\n"..
" - Controller setzen und die Blöcke\\, die bewegt werden sollen\\, über das Menü an-trainieren (Es können bis zu 16 Blöcke an-trainiert werden)\n".. " - Controller setzen und die Blöcke\\, die bewegt werden sollen\\, über das Menü an-trainieren (Es können bis zu 16 Blöcke an-trainiert werden)\n"..
" - die \"Flugstrecke\" muss über eine x\\,y\\,z Angabe (relativ) eingegeben werden (die maximale Distanz beträgt 100 m)\n".. " - die \"Flugstrecke\" muss über eine x\\,y\\,z Angabe (relativ) eingegeben werden (die maximale Distanz (x+y+z) beträgt 200 m)\n"..
" - mit den Menü-Tasten \"Bewege A-B\" sowie \"Bewege B-A\" kann die Bewegung getestet werden\n".. " - mit den Menü-Tasten \"Bewege A-B\" sowie \"Bewege B-A\" kann die Bewegung getestet werden\n"..
" - man kann auch durch Wände oder andere Blöcke fliegen\n".. " - man kann auch durch Wände oder andere Blöcke fliegen\n"..
" - auch die Zielposition für die Blöcke kann belegt sein. Die Blöcke werden in diesem Falle \"unsichtbar\" gespeichert. Dies ist für Schiebetüren und ähnliches gedacht\n".. " - auch die Zielposition für die Blöcke kann belegt sein. Die Blöcke werden in diesem Falle \"unsichtbar\" gespeichert. Dies ist für Schiebetüren und ähnliches gedacht\n"..
@ -1892,7 +1897,13 @@ techage.manual_DE.aText = {
"\n", "\n",
"Siehe TA3 Pumpe.\n".. "Siehe TA3 Pumpe.\n"..
"\n".. "\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".. "Die TA4 Pumpe pumpt 8 Einheiten Flüssigkeit alle zwei Sekunden. \n"..
"\n"..
"In der Betriebsart \"Durchflussbegrenzer\" kann die Anzahl der Einheiten\\, die von der Pumpe gepumpt werden\\, begrenzt werden. Die Betriebsart Durchflussbegrenzer kann über das Gabelschlüssel-Menü aktiviert werden\\, indem im Menü die Anzahl an Einheiten konfiguriert wird. Sobald die konfigurierte Anzahl an Einheiten gepumpt wurden\\, schaltet sich die Pumpe ab. Wird die Pumpe wieder eingeschaltet\\, pumpt sie wieder die konfigurierte Anzahl an Einheiten und schaltet sich dann ab.\n"..
"\n"..
"Der Durchflussbegrenzer kann auch per Lua- oder Beduino Controller konfiguriert und gestartet werden.\n"..
"\n"..
"Zusätzlich unterstützt die Pumpe das Kommando 'flowrate'. Damit kann die Gesamtdurchflussmenge durch die Pumpe abgefragt werden.\n"..
"\n".. "\n"..
"\n".. "\n"..
"\n", "\n",
@ -1918,10 +1929,14 @@ techage.manual_DE.aText = {
"Die Funktion entspricht grundsätzlich der von TA2/TA3. Zusätzlich kann aber über ein Menü konfiguriert werden\\, welche Gegenstände aus einer TA4 Kiste geholt und weiter transportiert werden sollen.\n".. "Die Funktion entspricht grundsätzlich der von TA2/TA3. Zusätzlich kann aber über ein Menü konfiguriert werden\\, welche Gegenstände aus einer TA4 Kiste geholt und weiter transportiert werden sollen.\n"..
"Die Verarbeitungsleistung beträgt 12 Items alle 2 s\\, sofern auf beiden Seiten TA4 Röhren verwendet werden. Anderenfalls sind es nur 6 Items alle 2 s.\n".. "Die Verarbeitungsleistung beträgt 12 Items alle 2 s\\, sofern auf beiden Seiten TA4 Röhren verwendet werden. Anderenfalls sind es nur 6 Items alle 2 s.\n"..
"\n".. "\n"..
"Der TA4 Schieber besitzt zwei zusätzliche Kommandos für den Lua Controller:\n".. "In der Betriebsart \"Durchlaufbegrenzer\" kann die Anzahl der Items\\, die von dem Schieber bewegt werden\\, begrenzt werden. Die Betriebsart Durchlaufbegrenzer kann über das Gabelschlüssel-Menü aktiviert werden\\, indem im Menü die Anzahl an Items konfiguriert wird. Sobald die konfigurierte Anzahl an Items bewegt wurden\\, schaltet sich der Schieber ab. Wird der Schieber wieder eingeschaltet\\, bewegt er wieder die konfigurierte Anzahl an Items und schaltet sich dann ab.\n"..
"\n"..
"Der TA4 Schieber kann auch per Lua- oder Beduino Controller konfiguriert und gestartet werden.\n"..
"\n"..
"Hier die zusätzlichen Kommandos für den Lua Controller:\n"..
"\n".. "\n"..
" - 'config' dient zur Konfiguration des Schiebers\\, analog zum manuellen Konfiguration über das Menü.\nBeispiel: '$send_cmnd(1234\\, \"config\"\\, \"default:dirt\")'\nMit '$send_cmnd(1234\\, \"config\"\\, \"\")' wird die Konfiguration gelöscht\n".. " - 'config' dient zur Konfiguration des Schiebers\\, analog zum manuellen Konfiguration über das Menü.\nBeispiel: '$send_cmnd(1234\\, \"config\"\\, \"default:dirt\")'\nMit '$send_cmnd(1234\\, \"config\"\\, \"\")' wird die Konfiguration gelöscht\n"..
" - 'pull' dient zum Absetzen eines Auftrags an den Schieber:\nBeispiel: '$send_cmnd(1234\\, \"pull\"\\, \"default:dirt 8\")'\nAls Nummer sind Werte von 1 bis 12 zulässig. Danach geht der Schieber wieder in den 'stopped' Mode und sendet ein \"off\" Kommando zurück an den Sender des \"pull\" Kommandos.\n".. " - 'limit' dient zum Setzen der Anzahl der Items für die Durchlaufbegrenzer Betriebsart:\nBeispiel: '$send_cmnd(1234\\, \"init\"\\, 7)'\n"..
"\n".. "\n"..
"\n".. "\n"..
"\n", "\n",
@ -2007,6 +2022,10 @@ techage.manual_DE.aText = {
"\n".. "\n"..
"\n".. "\n"..
"\n", "\n",
"Die Funktion entspricht der von TA3. \n"..
"\n"..
"\n"..
"\n",
"Maschinen zur Überwindung von Raum und Zeit\\, neue Energiequellen und andere Errungenschaften prägen dein Leben. \n".. "Maschinen zur Überwindung von Raum und Zeit\\, neue Energiequellen und andere Errungenschaften prägen dein Leben. \n"..
"\n".. "\n"..
"Für die Herstellung und Nutzung von TA5 Maschinen und Blöcken sind Erfahrungspunkte (experience points) notwendig. Diese können nur über den Teilchenbeschleuniger aus TA4 erarbeitet werden.\n".. "Für die Herstellung und Nutzung von TA5 Maschinen und Blöcken sind Erfahrungspunkte (experience points) notwendig. Diese können nur über den Teilchenbeschleuniger aus TA4 erarbeitet werden.\n"..
@ -2358,6 +2377,7 @@ techage.manual_DE.aItemName = {
"ta4_electronicfab", "ta4_electronicfab",
"ta4_injector", "ta4_injector",
"ta4_recycler", "ta4_recycler",
"ta4_item_flow_limiter_pas",
"techage_ta5", "techage_ta5",
"", "",
"", "",
@ -2615,6 +2635,7 @@ techage.manual_DE.aPlanTable = {
"", "",
"", "",
"", "",
"",
"ta5_fusion_reactor", "ta5_fusion_reactor",
"", "",
"", "",

View File

@ -135,6 +135,7 @@ techage.manual_EN.aTitel = {
"3,TA3 Gravel Rinser", "3,TA3 Gravel Rinser",
"3,TA3 Grinder", "3,TA3 Grinder",
"3,TA3 Injector", "3,TA3 Injector",
"3,TA3 Item Flow Limiter",
"2,Tools", "2,Tools",
"3,Techage Info Tool", "3,Techage Info Tool",
"3,TechAge Programmer", "3,TechAge Programmer",
@ -229,6 +230,7 @@ techage.manual_EN.aTitel = {
"3,TA4 Electronic Fab", "3,TA4 Electronic Fab",
"3,TA4 Injector", "3,TA4 Injector",
"3,TA4 Recycler", "3,TA4 Recycler",
"3,TA4 Item Flow Limiter",
"1,TA5: Future", "1,TA5: Future",
"2,Energy Sources", "2,Energy Sources",
"3,TA5 Fusion Reactor", "3,TA5 Fusion Reactor",
@ -1044,7 +1046,7 @@ techage.manual_EN.aText = {
"\n".. "\n"..
"\n", "\n",
"The button/switch sends 'on' / 'off' commands to the blocks that have been configured via the numbers.\n".. "The button/switch sends 'on' / 'off' commands to the blocks that have been configured via the numbers.\n"..
"The button/switch can be configured as a button or a switch. If it is configured as a button\\, the time between the 'on' and 'off' commands can be set.\n".. "The button/switch can be configured as a button or a switch. If it is configured as a button\\, the time between the 'on' and 'off' commands can be set. With the operating mode \"on button\" only an 'on' and no 'off' command is sent.\n"..
"\n".. "\n"..
"The checkbox \"public\" can be used to set whether the button can be used by everyone (set) or only by the owner himself (not set).\n".. "The checkbox \"public\" can be used to set whether the button can be used by everyone (set) or only by the owner himself (not set).\n"..
"\n".. "\n"..
@ -1126,8 +1128,9 @@ techage.manual_EN.aText = {
"\n".. "\n"..
"\n".. "\n"..
"\n", "\n",
"The signal lamp can be switched on or off with the 'on' / 'off' command. This lamp does not need electricity and\n".. "The signal lamp can be switched on or off with the 'on' / 'off' command. This lamp does not need electricity and can be colored with the airbrush tool from the mod Unified Dyes\" and via Lua/Beduino commands.\n"..
"can be colored with the airbrush tool of the mod Unified Dyes.\n".. "\n"..
"With the chat command '/ta_color' the color palette with the values for the Lua/Beduino commands is displayed and with '/ta_send color <num>' the color can be changed.\n"..
"\n".. "\n"..
"\n".. "\n"..
"\n", "\n",
@ -1264,6 +1267,16 @@ techage.manual_EN.aText = {
"\n".. "\n"..
"\n".. "\n"..
"\n", "\n",
"The Flow Limiter limits the number of items that can be pushed through by using a slider. This allows the number of items that are put into an oven\\, for example\\, to be precisely adapted to the recipe.\n"..
"\n"..
"The Flow Limiter must be configured via the menu and then started. If the configured number of items has been passed\\, the block switches off. The next time the Flow Limiter is switched on\\, it again transmits the configured number of items.\n"..
"\n"..
"*Note: The Flow Limiter must be placed behind the pusher.*\n"..
"\n"..
"The Flow Limiter can also be configured and started using a Lua or Beduino controller.\n"..
"\n"..
"\n"..
"\n",
"", "",
"The Techage Info Tool (open-ended wrench) has several functions. It shows the time\\, position\\, temperature and biome when an unknown block is clicked on.\n".. "The Techage Info Tool (open-ended wrench) has several functions. It shows the time\\, position\\, temperature and biome when an unknown block is clicked on.\n"..
"If you click on a TechAge block with command interface\\, all available data will be shown (see also \"Logic / switching blocks\").\n".. "If you click on a TechAge block with command interface\\, all available data will be shown (see also \"Logic / switching blocks\").\n"..
@ -1626,7 +1639,7 @@ techage.manual_EN.aText = {
"\n".. "\n"..
"\n", "\n",
"", "",
"Only the appearance of the TA4 button/switch has changed. The functionality is the same as with the TA3 button/switch.\n".. "Only the appearance of the TA4 button/switch has changed. The functionality is the same as with the TA3 button/switch. With the wrench menu\\, however\\, the data can be changed later.\n"..
"\n".. "\n"..
"\n".. "\n"..
"\n", "\n",
@ -1692,6 +1705,8 @@ techage.manual_EN.aText = {
"\n".. "\n"..
"The 'goto' command is only accepted when the sequencer is stopped.\n".. "The 'goto' command is only accepted when the sequencer is stopped.\n"..
"\n".. "\n"..
"The cycle time (default: 100 ms) can be changed for the sequencer via the open-end wrench menu.\n"..
"\n"..
"\n".. "\n"..
"\n", "\n",
"", "",
@ -1701,7 +1716,7 @@ techage.manual_EN.aText = {
"Instructions:\n".. "Instructions:\n"..
"\n".. "\n"..
" - Set the controller and train the blocks to be moved via the menu (up to 16 blocks can be trained)\n".. " - Set the controller and train the blocks to be moved via the menu (up to 16 blocks can be trained)\n"..
" - the \"flight route\" must be entered via an x\\, y\\, z specification (relative) (the maximum distance is 100 m)\n".. " - the \"flight route\" must be entered via an x\\, y\\, z specification (relative) (the maximum distance (x+y+z) is 200 m)\n"..
" - The movement can be tested with the menu buttons \"Move A-B\" and \"Move B-A\"\n".. " - The movement can be tested with the menu buttons \"Move A-B\" and \"Move B-A\"\n"..
" - you can also fly through walls or other blocks\n".. " - you can also fly through walls or other blocks\n"..
" - The target position for the blocks can also be occupied. In this case\\, the blocks are saved \"invisibly\". This is intended for sliding doors and the like\n".. " - The target position for the blocks can also be occupied. In this case\\, the blocks are saved \"invisibly\". This is intended for sliding doors and the like\n"..
@ -1888,7 +1903,13 @@ techage.manual_EN.aText = {
"\n", "\n",
"See TA3 pump.\n".. "See TA3 pump.\n"..
"\n".. "\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".. "The TA4 pump pumps 8 units of liquid every two seconds. \n"..
"\n"..
"In the \"Flow limiter\" mode\\, the number of units pumped by the pump can be limited. The flow limiter mode can be activated via the open-end wrench menu by configuring the number of units in the menu. Once the configured number of units have been pumped\\, the pump will turn off. When the pump is turned on again\\, it will pump the configured number of units again and then turn off.\n"..
"\n"..
"The flow limiter can also be configured and started using a Lua or Beduino controller.\n"..
"\n"..
"The pump also supports the 'flowrate' command. This allows the total flow rate through the pump to be queried.\n"..
"\n".. "\n"..
"\n".. "\n"..
"\n", "\n",
@ -1914,10 +1935,14 @@ techage.manual_EN.aText = {
"The function basically corresponds to that of TA2 / TA3. In addition\\, a menu can be used to configure which objects should be taken from a TA4 chest and transported further.\n".. "The function basically corresponds to that of TA2 / TA3. In addition\\, a menu can be used to configure which objects should be taken from a TA4 chest and transported further.\n"..
"The processing power is 12 items every 2 s\\, if TA4 tubes are used on both sides. Otherwise there are only 6 items every 2 s.\n".. "The processing power is 12 items every 2 s\\, if TA4 tubes are used on both sides. Otherwise there are only 6 items every 2 s.\n"..
"\n".. "\n"..
"The TA4 pusher has two additional commands for the Lua controller:\n".. "In the \"flow limiter\" mode\\, the number of items that are moved by the pusher can be limited. The flow limiter mode can be activated via the open-end wrench menu by configuring the number of items in the menu. As soon as the configured number of items have been moved\\, the pusher switches off. If the pusher is switched on again\\, it moves the configured number of items again and then switches off.\n"..
"\n".. "\n"..
" - 'config' is used to configure the pusher\\, analogous to manual configuration via the menu.\nExample: '$send_cmnd(1234\\, \"config\"\\, \"default: dirt\")'\nWith '$send_cmnd(1234\\, \"config\"\\, \"\")' the configuration is deleted\n".. "The TA4 pusher can also be configured and started using a Lua or Beduino controller.\n"..
" - 'pull' is used to send an order to the pusher:\nExample: '$send_cmnd(1234\\, \"pull\"\\, \"default: dirt 8\")'\nValues from 1 to 12 are permitted as numbers. Then the pusher goes back to 'stopped' mode and sends an\" off \"command back to the transmitter of the\" pull \"command.\n".. "\n"..
"Here are the additional commands for the Lua controller:\n"..
"\n"..
" - 'config' is used to configure the pusher\\, analogous to manual configuration via the menu.\n Example: '$send_cmnd(1234\\, \"config\"\\, \"default:dirt\")'\n With '$send_cmnd(1234\\, \"config\"\\, \"\")' the configuration is deleted\n"..
" - 'limit' is used to set the number of items for the flow limiter mode:\n Example: '$send_cmnd(1234\\, \"init\"\\, 7)'\n"..
"\n".. "\n"..
"\n".. "\n"..
"\n", "\n",
@ -2004,6 +2029,10 @@ techage.manual_EN.aText = {
"\n".. "\n"..
" \n".. " \n"..
"\n", "\n",
"The function corresponds to that of TA3.\n"..
"\n"..
"\n"..
"\n",
"Machines to overcome space and time\\, new sources of energy and other achievements shape your life.\n".. "Machines to overcome space and time\\, new sources of energy and other achievements shape your life.\n"..
"\n".. "\n"..
"Experience points are required for the manufacture and use of TA5 machines and blocks. These can only be worked out using the collider from TA4.\n".. "Experience points are required for the manufacture and use of TA5 machines and blocks. These can only be worked out using the collider from TA4.\n"..
@ -2259,6 +2288,7 @@ techage.manual_EN.aItemName = {
"ta3_gravelrinser", "ta3_gravelrinser",
"ta3_grinder", "ta3_grinder",
"ta3_injector", "ta3_injector",
"ta3_item_flow_limiter_pas",
"", "",
"ta3_end_wrench", "ta3_end_wrench",
"ta3_programmer", "ta3_programmer",
@ -2353,6 +2383,7 @@ techage.manual_EN.aItemName = {
"ta4_electronicfab", "ta4_electronicfab",
"ta4_injector", "ta4_injector",
"ta4_recycler", "ta4_recycler",
"ta4_item_flow_limiter_pas",
"techage_ta5", "techage_ta5",
"", "",
"", "",
@ -2520,6 +2551,7 @@ techage.manual_EN.aPlanTable = {
"", "",
"", "",
"", "",
"",
"ta4_windturbine", "ta4_windturbine",
"", "",
"", "",
@ -2609,6 +2641,7 @@ techage.manual_EN.aPlanTable = {
"", "",
"", "",
"", "",
"",
"ta5_fusion_reactor", "ta5_fusion_reactor",
"", "",
"", "",

View File

@ -105,7 +105,7 @@ minetest.register_node("techage:furnace_firebox", {
on_construct = function(pos) on_construct = function(pos)
local nvm = techage.get_nvm(pos) local nvm = techage.get_nvm(pos)
techage.add_node(pos, "techage:furnace_firebox") techage.add_node(pos, "techage:furnace_firebox", true)
nvm.running = false nvm.running = false
nvm.burn_cycles = 0 nvm.burn_cycles = 0
nvm.liquid = {} nvm.liquid = {}

View File

@ -36,8 +36,8 @@ elseif minetest.global_exists("lcdlib") and lcdlib.version < 1.01 then
elseif minetest.global_exists("safer_lua") and safer_lua.version < 1.01 then 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!") minetest.log("error", "[techage] Techage requires safer_lua version 1.01 or newer!")
return return
elseif minetest.global_exists("networks") and networks.version < 0.10 then elseif minetest.global_exists("networks") and networks.version < 0.12 then
minetest.log("error", "[techage] Techage requires networks version 0.10 or newer!") minetest.log("error", "[techage] Techage requires networks version 0.12 or newer!")
return return
elseif minetest.global_exists("hyperloop") and hyperloop.version < 2.07 then elseif minetest.global_exists("hyperloop") and hyperloop.version < 2.07 then
minetest.log("error", "[techage] Techage requires hyperloop version 2.07 or newer!") minetest.log("error", "[techage] Techage requires hyperloop version 2.07 or newer!")

View File

@ -86,7 +86,7 @@ local function on_punch(pos, node, puncher, pointed_thing)
if inv:room_for_item("src", stack) then if inv:room_for_item("src", stack) then
inv:add_item("src", stack) inv:add_item("src", stack)
minetest.swap_node(pos, {name = "techage:sieve0"}) minetest.swap_node(pos, {name = "techage:sieve0"})
minetest.get_node_timer(pos):start(1) minetest.get_node_timer(pos):start(1.5)
local w = puncher:get_wielded_item() local w = puncher:get_wielded_item()
if not(minetest.setting_getbool("creative_mode")) then if not(minetest.setting_getbool("creative_mode")) then
w:take_item(1) w:take_item(1)
@ -163,7 +163,7 @@ techage.register_node({"techage:sieve0", "techage:sieve1", "techage:sieve2", "te
local inv = meta:get_inventory() local inv = meta:get_inventory()
if inv:room_for_item("src", stack) then if inv:room_for_item("src", stack) then
inv:add_item("src", stack) inv:add_item("src", stack)
minetest.get_node_timer(pos):start(1) minetest.get_node_timer(pos):start(1.5)
return true return true
end end
return false return false

View File

@ -22,7 +22,7 @@ minetest.register_alias("techage:hopper_ta1", "minecart:hopper")
minecart.register_inventory( minecart.register_inventory(
{ {
"techage:chest_ta2", "techage:chest_ta3", "techage:chest_ta4", "techage:chest_ta2", "techage:chest_ta3", "techage:chest_ta4",
"techage:meltingpot", "techage:meltingpot_active", "techage:meltingpot", "techage:meltingpot_active", "techage:ta4_reactor",
}, },
{ {
put = { put = {
@ -68,7 +68,7 @@ minecart.register_inventory(
local meta = minetest.get_meta(pos) local meta = minetest.get_meta(pos)
local inv = meta:get_inventory() local inv = meta:get_inventory()
if inv:is_empty("src") then if inv:is_empty("src") then
minetest.get_node_timer(pos):start(1) minetest.get_node_timer(pos):start(2)
return true return true
end end
end, end,

View File

@ -25,12 +25,21 @@ local COUNTDOWN_TICKS = 4
local CYCLE_TIME = 2 local CYCLE_TIME = 2
local CAPA = 4 local CAPA = 4
local WRENCH_MENU = {{ local WRENCH_MENU = {
type = "output", {
name = "flowrate", type = "output",
label = S("Total flow rate"), name = "flowrate",
tooltip = S("Total flow rate in liquid units"), label = S("Total flow rate"),
}} tooltip = S("Total flow rate in liquid units"),
},
{
type = "number",
name = "limit",
label = S("Number of units"),
tooltip = S("Number of liquid units that are allowed to be pumped"),
default = "0",
},
}
local State3 = techage.NodeStates:new({ local State3 = techage.NodeStates:new({
node_name_passive = "techage:t3_pump", node_name_passive = "techage:t3_pump",
@ -48,11 +57,9 @@ local State4 = techage.NodeStates:new({
standby_ticks = STANDBY_TICKS, standby_ticks = STANDBY_TICKS,
}) })
local function pumping(pos, nvm, state, capa) -- Function returns the number of pumped units
local mem = techage.get_mem(pos) local function pump(pos, mem, nvm, state, outdir, units)
mem.dbg_cycles = (mem.dbg_cycles or 0) - 1 local taken, name = liquid.take(pos, Pipe, Flip[outdir], nil, units, mem.dbg_cycles > 0)
local outdir = M(pos):get_int("outdir")
local taken, name = liquid.take(pos, Pipe, Flip[outdir], nil, capa, mem.dbg_cycles > 0)
if taken > 0 then if taken > 0 then
local leftover = liquid.put(pos, Pipe, outdir, name, taken, mem.dbg_cycles > 0) local leftover = liquid.put(pos, Pipe, outdir, name, taken, mem.dbg_cycles > 0)
if leftover and leftover > 0 then if leftover and leftover > 0 then
@ -66,13 +73,39 @@ local function pumping(pos, nvm, state, capa)
state:blocked(pos, nvm) state:blocked(pos, nvm)
return 0 return 0
end end
state:keep_running(pos, nvm, COUNTDOWN_TICKS)
return taken - leftover return taken - leftover
end end
state:keep_running(pos, nvm, COUNTDOWN_TICKS)
return taken return taken
else
state:idle(pos, nvm)
return 0
end
end
local function pumping(pos, nvm, state, capa)
local mem = techage.get_mem(pos)
mem.dbg_cycles = (mem.dbg_cycles or 0) - 1
local outdir = M(pos):get_int("outdir")
if not nvm.limit then
local num = pump(pos, mem, nvm, state, outdir, capa)
if num > 0 then
state:keep_running(pos, nvm, COUNTDOWN_TICKS)
end
return num
elseif nvm.num_items < nvm.limit then
local num = math.min(capa, nvm.limit - nvm.num_items)
num = pump(pos, mem, nvm, state, outdir, num)
if num > 0 then
nvm.num_items = nvm.num_items + num
if nvm.num_items >= nvm.limit then
state:stop(pos, nvm)
else
state:keep_running(pos, nvm, COUNTDOWN_TICKS)
end
end
return num
end end
state:idle(pos, nvm)
return 0 return 0
end end
@ -119,6 +152,14 @@ local function on_rightclick(pos, node, clicker)
elseif node.name == "techage:t4_pump" then elseif node.name == "techage:t4_pump" then
local mem = techage.get_mem(pos) local mem = techage.get_mem(pos)
mem.dbg_cycles = 5 mem.dbg_cycles = 5
local val = M(pos):get_int("limit")
if val and val > 0 then
nvm.limit = val
nvm.num_items = 0
else
nvm.limit = nil
nvm.num_items = nil
end
State4:start(pos, nvm) State4:start(pos, nvm)
elseif node.name == "techage:t4_pump_on" then elseif node.name == "techage:t4_pump_on" then
State4:stop(pos, nvm) State4:stop(pos, nvm)
@ -277,7 +318,24 @@ techage.register_node({"techage:t3_pump", "techage:t3_pump_on"}, {
techage.register_node({"techage:t4_pump", "techage:t4_pump_on"}, { techage.register_node({"techage:t4_pump", "techage:t4_pump_on"}, {
on_recv_message = function(pos, src, topic, payload) on_recv_message = function(pos, src, topic, payload)
if topic == "flowrate" then if topic == "limit" then -- Set pump limit
local nvm = techage.get_nvm(pos)
State4:stop(pos, nvm)
local val = tonumber(payload) or 0
if val and val > 0 then
nvm.limit = val
nvm.num_items = 0
M(pos):set_int("limit", val)
else
nvm.limit = nil
nvm.num_items = nil
M(pos):set_string("limit", "")
end
return true
elseif topic == "count" then -- Get number of pumped units
local nvm = techage.get_nvm(pos)
return nvm.num_items or 0
elseif topic == "flowrate" then -- Get total number of pumped units
local nvm = techage.get_nvm(pos) local nvm = techage.get_nvm(pos)
return nvm.flowrate or 0 return nvm.flowrate or 0
else else
@ -285,12 +343,34 @@ techage.register_node({"techage:t4_pump", "techage:t4_pump_on"}, {
end end
end, end,
on_beduino_receive_cmnd = function(pos, src, topic, payload) on_beduino_receive_cmnd = function(pos, src, topic, payload)
return State4:on_beduino_receive_cmnd(pos, topic, payload) if topic == 69 and payload then -- Set pump limit
local nvm = techage.get_nvm(pos)
State4:stop(pos, nvm)
if payload[1] > 0 then
nvm.limit = payload[1]
nvm.num_items = 0
M(pos):set_int("limit", payload[1])
else
nvm.limit = nil
nvm.num_items = nil
M(pos):set_string("limit", "")
end
return 0
else
local nvm = techage.get_nvm(pos)
if nvm.limit then
nvm.num_items = 0
end
return State4:on_beduino_receive_cmnd(pos, topic, payload)
end
end, end,
on_beduino_request_data = function(pos, src, topic, payload) on_beduino_request_data = function(pos, src, topic, payload)
if topic == 137 then -- Total Flow Rate if topic == 137 then -- Get total number of pumped units
local nvm = techage.get_nvm(pos) local nvm = techage.get_nvm(pos)
return 0, {nvm.flowrate or 0} return 0, {nvm.flowrate or 0}
elseif topic == 151 then -- Get number of pumped units
local nvm = techage.get_nvm(pos)
return 0, {nvm.num_items or 0}
else else
return State4:on_beduino_request_data(pos, topic, payload) return State4:on_beduino_request_data(pos, topic, payload)
end end

View File

@ -114,7 +114,11 @@ TA3 Booster=TA3 Gebläse
### button.lua ### ### button.lua ###
Access:=Zugriff: Access:=Zugriff:
Button or switch=Taster oder Schalter
Change the block name (infotext)=Ändere den Blocknamen
Command to be sent=Zu sendender Befehl Command to be sent=Zu sendender Befehl
Destination block number(s)=Zielblocknummer
Infotext=Infotext
TA3 Button/Switch=TA3 Taster/Schalter TA3 Button/Switch=TA3 Taster/Schalter
TA4 Button/Switch=TA4 Schalter/Taster TA4 Button/Switch=TA4 Schalter/Taster
@ -122,7 +126,11 @@ TA4 Button/Switch=TA4 Schalter/Taster
### button_2x.lua ### ### button_2x.lua ###
### button_4x.lua ### ### button_4x.lua ###
Access=Zugriff
Button protection=Tastenschutz
Command=Kommando Command=Kommando
Number=Nummer
Type=Typ
### button.lua ### ### button.lua ###
### cart_detector.lua ### ### cart_detector.lua ###
@ -154,14 +162,10 @@ TA4 2x Button=TA4 2x Taster
### button_2x.lua ### ### button_2x.lua ###
### button_4x.lua ### ### button_4x.lua ###
Access=Zugriff
Button protection=Tastenschutz
Command to be sent (ignored for switches)=Zu sendender Befehl (wird für Schalter ignoriert) Command to be sent (ignored for switches)=Zu sendender Befehl (wird für Schalter ignoriert)
Destination block number=Zielblocknummer Destination block number=Zielblocknummer
Label for the button=Beschriftung für die Taste Label for the button=Beschriftung für die Taste
Momentary button or on/off switch=Taster oder Ein-/Ausschalter Momentary button or on/off switch=Taster oder Ein-/Ausschalter
Number=Nummer
Type=Typ
### button_2x.lua ### ### button_2x.lua ###
### button_4x.lua ### ### button_4x.lua ###
@ -446,7 +450,7 @@ Firebox=Feuerkasten
### fly_lib.lua ### ### fly_lib.lua ###
Destination position is protected=Zielposition ist geschützt Destination position is protected=Zielposition ist geschützt
Error: Max. length of the flight route exceeded !!=Fehler: Max. Flugstreckenlänge überschritten !! Error: Max. length of the flight route exceeded by @1 blocks !!=Fehler: max. Länge der Flugstrecke um @1 Blöcke überschritten !!
No valid destination position=Keine gültige Zielposition No valid destination position=Keine gültige Zielposition
No valid node at the start position=Kein gültiger Block an der Startposition No valid node at the start position=Kein gültiger Block an der Startposition
Start position is protected=Startposition ist geschützt Start position is protected=Startposition ist geschützt
@ -460,7 +464,6 @@ Error: Invalid path !!=Fehler: Ungültiger Pfad !!
Error: Recording is missing !!=Fehler: Aufzeichnung fehlt !! Error: Recording is missing !!=Fehler: Aufzeichnung fehlt !!
Flight route (A to B)=Flug Route (A nach B) Flight route (A to B)=Flug Route (A nach B)
Move=Bewege
See chat output=Siehe chat Ausgabe See chat output=Siehe chat Ausgabe
TA5 Fly Controller=TA5 Flug Controller TA5 Fly Controller=TA5 Flug Controller
Test=Test Test=Test
@ -480,6 +483,7 @@ Store=Speichern
Click on all blocks that shall be moved=Klicke auf alle Blöcke, die verschoben werden sollen Click on all blocks that shall be moved=Klicke auf alle Blöcke, die verschoben werden sollen
Maximum Speed=Maximalgeschwindigkeit Maximum Speed=Maximalgeschwindigkeit
Maximum speed for moving blocks=Maximale Geschwindigkeit für bewegliche Blöcke Maximum speed for moving blocks=Maximale Geschwindigkeit für bewegliche Blöcke
Move=Bewege
Move A-B=Bewege A-B Move A-B=Bewege A-B
Move B-A=Bewege B-A Move B-A=Bewege B-A
Move block height=Move Block Höhe Move block height=Move Block Höhe
@ -495,7 +499,6 @@ TA2 Flywheel=TA2 Schwungrad
Area already loaded or max. number of Forceload Blocks reached!=Bereich bereits geladen oder maximale Anzahl von Forceload Blöcken erreicht! Area already loaded or max. number of Forceload Blocks reached!=Bereich bereits geladen oder maximale Anzahl von Forceload Blöcken erreicht!
List of your Forceload Blocks:=Liste der Forceload Blöcke List of your Forceload Blocks:=Liste der Forceload Blöcke
Priv missing=Rechte fehlen
Punch the block to make the area visible.=Schlage auf den Bock um den Bereich anzuzeigen. Punch the block to make the area visible.=Schlage auf den Bock um den Bereich anzuzeigen.
Show all forceload blocks in a 64x64x64 range=Zeige alle Forceload Blöcke im Umkreis von 64x64x64 Blöcken Show all forceload blocks in a 64x64x64 range=Zeige alle Forceload Blöcke im Umkreis von 64x64x64 Blöcken
Techage Forceload Block=Techage Forceload Block Techage Forceload Block=Techage Forceload Block
@ -870,15 +873,27 @@ TA1 Pine Wood Board=TA1 Kiefernholzbrett
TA4 Streetlamp Solar Cell=TA4 Straßenlampen-Solarzelle TA4 Streetlamp Solar Cell=TA4 Straßenlampen-Solarzelle
### minichest.lua ###
Test Chest=
### minitank.lua ###
Test Mini Tank=
### movecontroller.lua ### ### movecontroller.lua ###
Error: Invalid distance !!=Fehler: Ungültige Entfernung !! Error: Invalid distance !!=Fehler: Ungültige Entfernung !!
Handover to A=Übergabe an A Handover to A=Übergabe an A
Handover to B=Übergabe an B Handover to B=Übergabe an B
Move distance=Entfernung
Move distance (A to B)=Entfernung (A nach B) Move distance (A to B)=Entfernung (A nach B)
Number of the next movecontroller=Nummer des nächsten Move Controllers Number of the next movecontroller=Nummer des nächsten Move Controllers
Number of the previous movecontroller=Nummer des vorhergehenden Move Controllers Number of the previous movecontroller=Nummer des vorhergehenden Move Controllers
Object offset=Objekt Offset Object offset=Objekt Offset
Operational mode=Betriebsmodus
Reset=Rücksetzen
Switch to the remote controlled 'move xyz' mode=Wechseln in den ferngesteuerten 'move xyz'-Modus
TA4 Move Controller=TA4 Move Controller TA4 Move Controller=TA4 Move Controller
Y-offset for non-player objects like vehicles (-0.5 to 0.5)=Y-Offset für Nicht-Spieler Objekte wie Fahrzeuge (-0.5 bis 0.5) Y-offset for non-player objects like vehicles (-0.5 to 0.5)=Y-Offset für Nicht-Spieler Objekte wie Fahrzeuge (-0.5 bis 0.5)
@ -1010,6 +1025,8 @@ Allow to dig/place Techage power lines nearby power poles=Erlaubt TODO
### pump.lua ### ### pump.lua ###
Number of liquid units that are allowed to be pumped=Anzahl der Flüssigkeitseinheiten, die gepumpt werden dürfen
Number of units=Anzahl der Einheiten
TA3 Pump=TA3 Pumpe TA3 Pump=TA3 Pumpe
TA4 Pump=TA4 Pumpe TA4 Pump=TA4 Pumpe
@ -1029,7 +1046,9 @@ no oil=Kein Öl
### pusher.lua ### ### pusher.lua ###
Optionally configure@nthe pusher with one item=Der Schieber kann optional@nmit einem Gegenstand@nkonfiguriert werden Number of items=Anzahl der Elemente
Number of items that are allowed to be pushed=Anzahl der Elemente, die verschoben werden dürfen
Optionally configure@nthe pusher with one item=Der Schieber kann optional@nmit einem Elemente@nkonfiguriert werden
Pusher=Schieber Pusher=Schieber
### quarry.lua ### ### quarry.lua ###
@ -1083,6 +1102,8 @@ Biome=Biom
Node owner=Blockbesitzer Node owner=Blockbesitzer
Position=Position Position=Position
Position temperature=Positionstemperatur Position temperature=Positionstemperatur
Pump connected to no/empty tank(s).=Pumpe an keine/leere Tank(s) angeschlossen.
Pump connected to tank(s) with: @1=Pumpe an Tank(s) angeschlossen mit: @1
TechAge Info Tool (use @= read status info)=TechAge Info Werkzeug TechAge Info Tool (use @= read status info)=TechAge Info Werkzeug
TechAge Repair Kit=TechAge Reparaturset TechAge Repair Kit=TechAge Reparaturset
@ -1120,6 +1141,7 @@ stopped=gestoppt
### sequencer2.lua ### ### sequencer2.lua ###
- 'goto <num>' (jump to another line)@n= - 'goto <num>' (springe zu einer anderen Zeile)@n - 'goto <num>' (jump to another line)@n= - 'goto <num>' (springe zu einer anderen Zeile)@n
- 'nop' (do nothing)@n= - 'nop' (mache nichts)@n
- 'send <node num> <cmnd>' (techage command)@n= - 'send <node num> <cmnd>' (techage Kommando)@n - 'send <node num> <cmnd>' (techage command)@n= - 'send <node num> <cmnd>' (techage Kommando)@n
- 'stop' (stop the execution)@n= - 'stop' (stoppe die Ausführung)@n - 'stop' (stop the execution)@n= - 'stop' (stoppe die Ausführung)@n
- 1 corresponds to 100 ms@n= - 1 entspricht 100 ms@n - 1 corresponds to 100 ms@n= - 1 entspricht 100 ms@n
@ -1152,7 +1174,7 @@ TA5 Fusion Reactor Shell=TA5 Fusionsreaktor Hülle
TA4 Wind Turbine Signal Lamp=TA4 Windkraftanlagenlampe TA4 Wind Turbine Signal Lamp=TA4 Windkraftanlagenlampe
TechAge Signal Lamp=TechAge Signallampe TechAge Signal Lamp=TechAge Signallampe
TechAge Signal Lamp (can be colored)=TechAge Signallampe (kann gefärbt werden) TechAge Signal Lamp 2 =TechAge Signallampe 2
### signallamp_2x.lua ### ### signallamp_2x.lua ###
@ -1466,3 +1488,8 @@ Remove detector=Entferne Detektor
TA4 Collider Detector Worker=TA4 Collider Detektor Worker TA4 Collider Detector Worker=TA4 Collider Detektor Worker
[TA4] Detector is being built!=[TA4] Detektor wird gebaut! [TA4] Detector is being built!=[TA4] Detektor wird gebaut!
[TA4] Detector is being removed!=[TA4] Detektor wird entfernt! [TA4] Detector is being removed!=[TA4] Detektor wird entfernt!
##### not used anymore #####
Error: Max. length of the flight route exceeded !!=Fehler: Max. Flugstreckenlänge überschritten !!

View File

@ -114,7 +114,11 @@ TA3 Booster=
### button.lua ### ### button.lua ###
Access:= Access:=
Button or switch=
Change the node name (infotext)=
Command to be sent= Command to be sent=
Destination block number(s)=
Infotext=
TA3 Button/Switch= TA3 Button/Switch=
TA4 Button/Switch= TA4 Button/Switch=
@ -122,7 +126,11 @@ TA4 Button/Switch=
### button_2x.lua ### ### button_2x.lua ###
### button_4x.lua ### ### button_4x.lua ###
Access=
Button protection=
Command= Command=
Number=
Type=
### button.lua ### ### button.lua ###
### cart_detector.lua ### ### cart_detector.lua ###
@ -154,14 +162,10 @@ TA4 2x Button=
### button_2x.lua ### ### button_2x.lua ###
### button_4x.lua ### ### button_4x.lua ###
Access=
Button protection=
Command to be sent (ignored for switches)= Command to be sent (ignored for switches)=
Destination block number= Destination block number=
Label for the button= Label for the button=
Momentary button or on/off switch= Momentary button or on/off switch=
Number=
Type=
### button_2x.lua ### ### button_2x.lua ###
### button_4x.lua ### ### button_4x.lua ###
@ -446,7 +450,7 @@ Firebox=
### fly_lib.lua ### ### fly_lib.lua ###
Destination position is protected= Destination position is protected=
Error: Max. length of the flight route exceeded !!= Error: Max. length of the flight route exceeded by @1 blocks !!=
No valid destination position= No valid destination position=
No valid node at the start position= No valid node at the start position=
Start position is protected= Start position is protected=
@ -460,7 +464,6 @@ Error: Invalid path !!=
Error: Recording is missing !!= Error: Recording is missing !!=
Flight route (A to B)= Flight route (A to B)=
Move=
See chat output= See chat output=
TA5 Fly Controller= TA5 Fly Controller=
Test= Test=
@ -480,6 +483,7 @@ Store=
Click on all blocks that shall be moved= Click on all blocks that shall be moved=
Maximum Speed= Maximum Speed=
Maximum speed for moving blocks= Maximum speed for moving blocks=
Move=
Move A-B= Move A-B=
Move B-A= Move B-A=
Move block height= Move block height=
@ -495,7 +499,6 @@ TA2 Flywheel=
Area already loaded or max. number of Forceload Blocks reached!= Area already loaded or max. number of Forceload Blocks reached!=
List of your Forceload Blocks:= List of your Forceload Blocks:=
Priv missing=
Punch the block to make the area visible.= Punch the block to make the area visible.=
Show all forceload blocks in a 64x64x64 range= Show all forceload blocks in a 64x64x64 range=
Techage Forceload Block= Techage Forceload Block=
@ -870,15 +873,27 @@ TA1 Pine Wood Board=
TA4 Streetlamp Solar Cell= TA4 Streetlamp Solar Cell=
### minichest.lua ###
Test Chest=
### minitank.lua ###
Test Mini Tank=
### movecontroller.lua ### ### movecontroller.lua ###
Error: Invalid distance !!= Error: Invalid distance !!=
Handover to A= Handover to A=
Handover to B= Handover to B=
Move distance=
Move distance (A to B)= Move distance (A to B)=
Number of the next movecontroller= Number of the next movecontroller=
Number of the previous movecontroller= Number of the previous movecontroller=
Object offset= Object offset=
Operational mode=
Reset=
Switch to the remote controlled 'move xyz' mode=
TA4 Move Controller= TA4 Move Controller=
Y-offset for non-player objects like vehicles (-0.5 to 0.5)= Y-offset for non-player objects like vehicles (-0.5 to 0.5)=
@ -1010,6 +1025,8 @@ Allow to dig/place Techage power lines nearby power poles=
### pump.lua ### ### pump.lua ###
Number of liquid units that are allowed to be pumped=
Number of units=
TA3 Pump= TA3 Pump=
TA4 Pump= TA4 Pump=
@ -1029,6 +1046,8 @@ no oil=
### pusher.lua ### ### pusher.lua ###
Number of items=
Number of items that are allowed to be pushed=
Optionally configure@nthe pusher with one item= Optionally configure@nthe pusher with one item=
Pusher= Pusher=
@ -1083,6 +1102,8 @@ Biome=
Node owner= Node owner=
Position= Position=
Position temperature= Position temperature=
Pump connected to no/empty tank(s).=
Pump connected to tank(s) with: @1=
TechAge Info Tool (use @= read status info)= TechAge Info Tool (use @= read status info)=
TechAge Repair Kit= TechAge Repair Kit=
@ -1120,6 +1141,7 @@ stopped=
### sequencer2.lua ### ### sequencer2.lua ###
- 'goto <num>' (jump to another line)@n= - 'goto <num>' (jump to another line)@n=
- 'nop' (do nothing)@n=
- 'send <node num> <cmnd>' (techage command)@n= - 'send <node num> <cmnd>' (techage command)@n=
- 'stop' (stop the execution)@n= - 'stop' (stop the execution)@n=
- 1 corresponds to 100 ms@n= - 1 corresponds to 100 ms@n=
@ -1152,7 +1174,7 @@ TA5 Fusion Reactor Shell=
TA4 Wind Turbine Signal Lamp= TA4 Wind Turbine Signal Lamp=
TechAge Signal Lamp= TechAge Signal Lamp=
TechAge Signal Lamp (can be colored)= TechAge Signal Lamp 2 =
### signallamp_2x.lua ### ### signallamp_2x.lua ###

View File

@ -20,6 +20,22 @@ local NDEF = function(pos) return (minetest.registered_nodes[techage.get_node_lv
local logic = techage.logic local logic = techage.logic
local WRENCH_MENU = { local WRENCH_MENU = {
{
type = "dropdown",
choices = "switch,on button,button 1s,button 2s,button 4s,button 8s,button 16s,button 32s",
name = "type",
label = S("Type"),
tooltip = S("Button or switch"),
default = "1",
},
{
type = "numbers",
name = "numbers",
label = S("Number"),
tooltip = S("Destination block number(s)"),
default = "",
check = techage.check_numbers,
},
{ {
type = "ascii", type = "ascii",
name = "command", name = "command",
@ -27,6 +43,21 @@ local WRENCH_MENU = {
tooltip = S("Command to be sent"), tooltip = S("Command to be sent"),
default = "on", default = "on",
}, },
{
type = "dropdown",
choices = "private,protected,public",
name = "access",
label = S("Access"),
tooltip = S("Button protection"),
default = "1",
},
{
type = "ascii",
name = "decription",
label = S("Infotext"),
tooltip = S("Change the block name (infotext)"),
default = "",
},
} }
local function switch_on(pos) local function switch_on(pos)
@ -56,7 +87,8 @@ local function switch_off(pos, is_button)
logic.swap_node(pos, "techage:ta4_button_off") logic.swap_node(pos, "techage:ta4_button_off")
end end
local meta = M(pos) local meta = M(pos)
if not meta:contains("command") or meta:get_string("command") == "on" then if meta:get_string("off_command") ~= "true" and
(not meta:contains("command") or meta:get_string("command") == "on") then
logic.send_off(pos, M(pos)) logic.send_off(pos, M(pos))
end end
if not is_button then if not is_button then
@ -74,22 +106,18 @@ local function formspec(meta)
if idx == 0 then idx = 1 end if idx == 0 then idx = 1 end
local access_idx = meta:get_string("public") == "true" and 3 or meta:get_string("protected") == "true" and 2 or 1 local access_idx = meta:get_string("public") == "true" and 3 or meta:get_string("protected") == "true" and 2 or 1
return "size[7.5,6]".. return "size[7.5,6]"..
"dropdown[0.2,0;3;type;switch,button 1s,button 2s,button 4s,button 8s,button 16s,button 32s;"..idx.."]".. "dropdown[0.2,0;3;type;switch,on button,button 1s,button 2s,button 4s,button 8s,button 16s,button 32s;"..idx.."]"..
"field[0.5,2;7,1;numbers;"..S("Insert destination node number(s)")..";"..numbers.."]" .. "field[0.5,2;7,1;numbers;"..S("Insert destination node number(s)")..";"..numbers.."]" ..
"label[0.2,3;"..S("Access:").."]".. "label[0.2,3;"..S("Access:").."]"..
"dropdown[3,3;4;access;private,protected,public;"..access_idx.."]".. "dropdown[3,3;4;access;private,protected,public;"..access_idx.."]"..
"button_exit[2,4;3,1;exit;"..S("Save").."]" "button_exit[2,4;3,1;exit;"..S("Save").."]"
end end
local function on_receive_fields(pos, formname, fields, player) local function store_fields_data(pos, fields)
if minetest.is_protected(pos, player:get_player_name()) then
return
end
local meta = M(pos) local meta = M(pos)
if not techage.check_numbers(fields.numbers, player:get_player_name()) then
return
end
meta:set_string("numbers", fields.numbers) meta:set_string("numbers", fields.numbers)
meta:set_string("off_command", "")
if fields.access == "protected" then if fields.access == "protected" then
meta:set_string("protected", "true") meta:set_string("protected", "true")
meta:set_string("public", "") meta:set_string("public", "")
@ -106,28 +134,46 @@ local function on_receive_fields(pos, formname, fields, player)
if fields.type == "switch" then if fields.type == "switch" then
meta:set_int("cycle_idx", 1) meta:set_int("cycle_idx", 1)
cycle_time = 0 cycle_time = 0
elseif fields.type == "button 1s" then elseif fields.type == "on button" then
meta:set_int("cycle_idx", 2) meta:set_int("cycle_idx", 2)
meta:set_string("off_command", "true")
cycle_time = 1
elseif fields.type == "button 1s" then
meta:set_int("cycle_idx", 3)
cycle_time = 1 cycle_time = 1
elseif fields.type == "button 2s" then elseif fields.type == "button 2s" then
meta:set_int("cycle_idx", 3) meta:set_int("cycle_idx", 4)
cycle_time = 2 cycle_time = 2
elseif fields.type == "button 4s" then elseif fields.type == "button 4s" then
meta:set_int("cycle_idx", 4) meta:set_int("cycle_idx", 5)
cycle_time = 4 cycle_time = 4
elseif fields.type == "button 8s" then elseif fields.type == "button 8s" then
meta:set_int("cycle_idx", 5) meta:set_int("cycle_idx", 6)
cycle_time = 8 cycle_time = 8
elseif fields.type == "button 16s" then elseif fields.type == "button 16s" then
meta:set_int("cycle_idx", 6) meta:set_int("cycle_idx", 7)
cycle_time = 16 cycle_time = 16
elseif fields.type == "button 32s" then elseif fields.type == "button 32s" then
meta:set_int("cycle_idx", 7) meta:set_int("cycle_idx", 8)
cycle_time = 32 cycle_time = 32
end end
if cycle_time ~= nil then if cycle_time ~= nil then
meta:set_int("cycle_time", cycle_time) meta:set_int("cycle_time", cycle_time)
end end
meta:set_string("access", fields.access)
meta:set_string("type", fields.type)
end
local function on_receive_fields(pos, formname, fields, player)
if minetest.is_protected(pos, player:get_player_name()) then
return
end
if not techage.check_numbers(fields.numbers, player:get_player_name()) then
return
end
store_fields_data(pos, fields)
local meta = M(pos)
logic.infotext(meta, NDEF(pos).description) logic.infotext(meta, NDEF(pos).description)
if fields.exit then if fields.exit then
meta:set_string("formspec", nil) meta:set_string("formspec", nil)
@ -137,6 +183,16 @@ local function on_receive_fields(pos, formname, fields, player)
end end
end end
local function ta_after_formspec(pos, fields, playername)
store_fields_data(pos, fields)
local meta = M(pos)
if fields.decription ~= "" then
logic.infotext(meta, fields.decription)
else
logic.infotext(meta, NDEF(pos).description)
end
end
local function can_access(pos, player) local function can_access(pos, player)
local meta = M(pos) local meta = M(pos)
local public = meta:get_string("public") == "true" local public = meta:get_string("public") == "true"
@ -269,6 +325,7 @@ minetest.register_node("techage:ta4_button_off", {
end, end,
ta4_formspec = WRENCH_MENU, ta4_formspec = WRENCH_MENU,
ta_after_formspec = ta_after_formspec,
on_receive_fields = on_receive_fields, on_receive_fields = on_receive_fields,
on_rightclick = on_rightclick_on, on_rightclick = on_rightclick_on,
techage_set_numbers = techage_set_numbers, techage_set_numbers = techage_set_numbers,
@ -305,6 +362,8 @@ minetest.register_node("techage:ta4_button_on", {
}, },
}, },
ta4_formspec = WRENCH_MENU,
ta_after_formspec = ta_after_formspec,
on_rightclick = on_rightclick_off, on_rightclick = on_rightclick_off,
on_timer = switch_off, on_timer = switch_off,
on_rotate = screwdriver.disallow, on_rotate = screwdriver.disallow,

View File

@ -55,6 +55,7 @@ local WRENCH_MENU = {
label = S("Number") .. " 1", label = S("Number") .. " 1",
tooltip = S("Destination block number"), tooltip = S("Destination block number"),
default = "", default = "",
check = techage.check_numbers,
}, },
{ {
type = "ascii", type = "ascii",
@ -76,6 +77,7 @@ local WRENCH_MENU = {
label = S("Number") .. " 2", label = S("Number") .. " 2",
tooltip = S("Destination block number"), tooltip = S("Destination block number"),
default = "", default = "",
check = techage.check_numbers,
}, },
{ {
type = "ascii", type = "ascii",

View File

@ -59,6 +59,7 @@ local WRENCH_MENU = {
label = S("Number") .. " 1", label = S("Number") .. " 1",
tooltip = S("Destination block number"), tooltip = S("Destination block number"),
default = "", default = "",
check = techage.check_numbers,
}, },
{ {
type = "ascii", type = "ascii",
@ -80,6 +81,7 @@ local WRENCH_MENU = {
label = S("Number") .. " 2", label = S("Number") .. " 2",
tooltip = S("Destination block number"), tooltip = S("Destination block number"),
default = "", default = "",
check = techage.check_numbers,
}, },
{ {
type = "ascii", type = "ascii",
@ -101,6 +103,7 @@ local WRENCH_MENU = {
label = S("Number") .. " 3", label = S("Number") .. " 3",
tooltip = S("Destination block number"), tooltip = S("Destination block number"),
default = "", default = "",
check = techage.check_numbers,
}, },
{ {
type = "ascii", type = "ascii",
@ -122,6 +125,7 @@ local WRENCH_MENU = {
label = S("Number") .. " 4", label = S("Number") .. " 4",
tooltip = S("Destination block number"), tooltip = S("Destination block number"),
default = "", default = "",
check = techage.check_numbers,
}, },
{ {
type = "ascii", type = "ascii",

View File

@ -249,12 +249,13 @@ minetest.register_craft({
techage.register_node({"techage:ta3_detector_off", "techage:ta3_detector_on"}, { techage.register_node({"techage:ta3_detector_off", "techage:ta3_detector_on"}, {
on_push_item = function(pos, in_dir, stack) on_push_item = function(pos, in_dir, stack)
if techage.safe_push_items(pos, in_dir, stack) then local leftover = techage.safe_push_items(pos, in_dir, stack)
if leftover then
local inv = minetest.get_inventory({type = "node", pos = pos}) local inv = minetest.get_inventory({type = "node", pos = pos})
if not inv or inv:is_empty("cfg") or inv:contains_item("cfg", ItemStack(stack:get_name())) then if not inv or inv:is_empty("cfg") or inv:contains_item("cfg", ItemStack(stack:get_name())) then
switch_on(pos) switch_on(pos)
end end
return true return leftover
end end
return false return false
end, end,
@ -263,11 +264,19 @@ techage.register_node({"techage:ta3_detector_off", "techage:ta3_detector_on"}, {
techage.register_node({"techage:ta4_detector_off", "techage:ta4_detector_on"}, { techage.register_node({"techage:ta4_detector_off", "techage:ta4_detector_on"}, {
on_push_item = function(pos, in_dir, stack) on_push_item = function(pos, in_dir, stack)
if techage.safe_push_items(pos, in_dir, stack) then local leftover = techage.safe_push_items(pos, in_dir, stack)
switch_on(pos) if leftover then
local nvm = techage.get_nvm(pos) local inv = minetest.get_inventory({type = "node", pos = pos})
nvm.counter = (nvm.counter or 0) + stack:get_count() if not inv or inv:is_empty("cfg") or inv:contains_item("cfg", ItemStack(stack:get_name())) then
return true switch_on(pos)
local nvm = techage.get_nvm(pos)
if leftover == true then
nvm.counter = (nvm.counter or 0) + stack:get_count()
else
nvm.counter = (nvm.counter or 0) + stack:get_count() - leftover:get_count()
end
end
return leftover
end end
return false return false
end, end,

View File

@ -38,6 +38,27 @@ local HELP = S("Syntax:\n") ..
" [30] send 1234 b2a\n" .. " [30] send 1234 b2a\n" ..
" [60] goto 1 -- keep going" " [60] goto 1 -- keep going"
local WRENCH_MENU = {
{
type = "dropdown",
choices = "100ms,200ms,500ms,1s,2s",
name = "cycletime",
label = S("Cycle time"),
tooltip = S("Timer cycle time (default: 100 ms)"),
default = "1",
values = {0.1, 0.2, 0.5, 1.0, 2.0}
},
}
local function cycle_time(pos)
local mem = techage.get_mem(pos)
if not mem.cycletime then
mem.cycletime = tonumber(M(pos):get_string("cycletime")) or 0.1
end
return mem.cycletime
end
local function strsplit(text) local function strsplit(text)
text = text:gsub("\r\n", "\n") text = text:gsub("\r\n", "\n")
text = text:gsub("\r", "\n") text = text:gsub("\r", "\n")
@ -169,12 +190,12 @@ local function formspec_help(meta)
"background[0.1,0.3;9.8,8.0;techage_form_mask.png]" "background[0.1,0.3;9.8,8.0;techage_form_mask.png]"
end end
local function restart_timer(pos, time) local function restart_timer(pos, ticks)
local timer = minetest.get_node_timer(pos) local timer = minetest.get_node_timer(pos)
if timer:is_started() then if timer:is_started() then
timer:stop() timer:stop()
end end
timer:start(time / 10) timer:start(ticks * cycle_time(pos))
end end
local function node_timer(pos, elapsed) local function node_timer(pos, elapsed)
@ -240,7 +261,8 @@ local function on_receive_fields(pos, formname, fields, player)
meta:set_string("text", fields.text or "") meta:set_string("text", fields.text or "")
mem.code = nil mem.code = nil
mem.idx = nil mem.idx = nil
minetest.get_node_timer(pos):start(0.5) mem.cycletime = nil
restart_timer(pos, 1)
logic.infotext(meta, S("TA4 Sequencer"), S("running")) logic.infotext(meta, S("TA4 Sequencer"), S("running"))
end end
end end
@ -274,6 +296,7 @@ minetest.register_node("techage:ta4_sequencer", {
end, end,
on_timer = node_timer, on_timer = node_timer,
ta4_formspec = WRENCH_MENU,
paramtype2 = "facedir", paramtype2 = "facedir",
groups = {choppy=2, cracky=2, crumbly=2}, groups = {choppy=2, cracky=2, crumbly=2},
@ -300,7 +323,7 @@ techage.register_node({"techage:ta4_sequencer"}, {
local mem = techage.get_mem(pos) local mem = techage.get_mem(pos)
nvm.running = true nvm.running = true
mem.idx = tonumber(payload or 1) or 1 mem.idx = tonumber(payload or 1) or 1
restart_timer(pos, 0.1) restart_timer(pos, 1)
logic.infotext(M(pos), S("TA4 Sequencer"), S("running")) logic.infotext(M(pos), S("TA4 Sequencer"), S("running"))
elseif topic == "stop" or topic == "off" then elseif topic == "stop" or topic == "off" then
nvm.running = false nvm.running = false
@ -319,7 +342,7 @@ techage.register_node({"techage:ta4_sequencer"}, {
local mem = techage.get_mem(pos) local mem = techage.get_mem(pos)
nvm.running = true nvm.running = true
mem.idx = tonumber(payload or 1) or 1 mem.idx = tonumber(payload or 1) or 1
restart_timer(pos, 0.1) restart_timer(pos, 1)
logic.infotext(M(pos), S("TA4 Sequencer"), S("running")) logic.infotext(M(pos), S("TA4 Sequencer"), S("running"))
return 0 return 0
elseif payload[1] == 0 then elseif payload[1] == 0 then

View File

@ -8,7 +8,7 @@
AGPL v3 AGPL v3
See LICENSE.txt for more information See LICENSE.txt for more information
Colored Signal Lamp (requires unifieddyes) Colored Signal Lamps (with unifieddyes support)
]]-- ]]--
@ -20,127 +20,215 @@ local logic = techage.logic
local COLORED = minetest.get_modpath("unifieddyes") and minetest.global_exists("unifieddyes") local COLORED = minetest.get_modpath("unifieddyes") and minetest.global_exists("unifieddyes")
local LampsOff = {}
local LampsOn = {}
local function switch_on(pos, node) local function switch_on(pos, node, player, color)
node.name = "techage:signal_lamp_on" if player and minetest.is_protected(pos, player:get_player_name()) then
minetest.swap_node(pos, node) return
end
color = tonumber(color) or node.param2
if LampsOff[node.name] then
node.name = LampsOff[node.name]
node.param2 = color
minetest.swap_node(pos, node)
elseif LampsOn[node.name] and color ~= node.param2 then
node.param2 = color
minetest.swap_node(pos, node)
end
end end
local function switch_off(pos, node) local function switch_off(pos, node, player)
node.name = "techage:signal_lamp_off" if player and minetest.is_protected(pos, player:get_player_name()) then
minetest.swap_node(pos, node) return
end
if LampsOn[node.name] then
node.name = LampsOn[node.name]
minetest.swap_node(pos, node)
end
end end
minetest.register_node("techage:signal_lamp_off", { local function register_signallamp(name, description, tiles_off, tiles_on, node_box)
description = S("TechAge Signal Lamp (can be colored)"), LampsOff[name .. "_off"] = name .. "_on"
tiles = {"techage_signal_lamp.png^[colorize:#000000:100"}, LampsOn[name .. "_on"] = name .. "_off"
drawtype = "nodebox",
node_box = { minetest.register_node(name .. "_off", {
description = description,
tiles = tiles_off,
drawtype = node_box and "nodebox",
node_box = node_box,
after_place_node = function(pos, placer, itemstack, pointed_thing)
logic.after_place_node(pos, placer, name .. "_off", description)
logic.infotext(M(pos), description)
if COLORED then
unifieddyes.recolor_on_place(pos, placer, itemstack, pointed_thing)
else
local node = minetest.get_node(pos)
node.param2 = 35
minetest.swap_node(pos, node)
end
end,
on_rightclick = switch_on,
after_dig_node = function(pos, oldnode, oldmetadata, digger)
techage.remove_node(pos, oldnode, oldmetadata)
if COLORED then
unifieddyes.after_dig_node(pos, oldnode, oldmetadata, digger)
end
end,
on_construct = COLORED and unifieddyes.on_construct or nil,
on_dig = COLORED and unifieddyes.on_dig or nil,
paramtype = "light",
paramtype2 = "color",
--palette = "techage_palette256.png",
palette = COLORED and "unifieddyes_palette_extended.png" or "techage_palette256.png",
place_param2 = 240,
sunlight_propagates = true,
sounds = default.node_sound_glass_defaults(),
groups = {choppy=2, cracky=1, ud_param2_colorable = 1},
is_ground_content = false,
drop = name .. "_off"
})
minetest.register_node(name .. "_on", {
description = description,
tiles = tiles_on,
drawtype = node_box and "nodebox",
node_box = node_box,
on_rightclick = switch_off,
paramtype = "light",
paramtype2 = "color",
--palette = "techage_palette256.png",
palette = COLORED and "unifieddyes_palette_extended.png" or "techage_palette256.png",
groups = {choppy=2, cracky=1, not_in_creative_inventory=1, ud_param2_colorable = 1},
after_dig_node = function(pos, oldnode, oldmetadata, digger)
techage.remove_node(pos, oldnode, oldmetadata)
if COLORED then
unifieddyes.after_dig_node(pos, oldnode, oldmetadata, digger)
end
end,
on_dig = COLORED and unifieddyes.on_dig or nil,
light_source = 10,
is_ground_content = false,
drop = name .. "_off"
})
techage.register_node({name .. "_off", name .. "_on"}, {
on_recv_message = function(pos, src, topic, payload)
if topic == "on" then
local node = techage.get_node_lvm(pos)
switch_on(pos, node)
return true
elseif topic == "off" then
local node = techage.get_node_lvm(pos)
switch_off(pos, node)
return true
elseif topic == "color" then
local node = techage.get_node_lvm(pos)
switch_on(pos, node, nil, payload)
return true
else
return "unsupported"
end
end,
on_beduino_receive_cmnd = function(pos, src, topic, payload)
if topic == 1 and payload[1] == 1 then
local node = techage.get_node_lvm(pos)
switch_on(pos, node)
return 0
elseif topic == 1 and payload[1] == 0 then
local node = techage.get_node_lvm(pos)
switch_off(pos, node)
return 0
elseif topic == 70 then
local node = techage.get_node_lvm(pos)
switch_on(pos, node, nil, payload[1])
return 0
else
return 2
end
end,
})
end
minetest.register_chatcommand("ta_color", {
description = minetest.formspec_escape(
"Output the color palette and the numbers for Lua/Beduino color commands"),
func = function(name, param)
local tbl = {}
if COLORED then
tbl[1] = "size[14,7]"
tbl[2] = "background[0,0;14,7;unifieddyes_palette_extended.png]"
for i = 0, 10 do
local y = i * 0.64
tbl[#tbl + 1] = "label[0," .. y .. ";" .. (i * 24 + 0) .. "]"
tbl[#tbl + 1] = "label[7," .. y .. ";" .. (i * 24 + 12) .. "]"
end
else
tbl[1] = "size[10,7.5]"
tbl[2] = "background[0,0;10,7.5;techage_palette256.png]"
for i = 0, 13 do
local y = i * 0.5
tbl[#tbl + 1] = "label[0," .. y .. ";" .. (i * 18 + 0) .. "]"
tbl[#tbl + 1] = "label[5," .. y .. ";" .. (i * 18 + 9) .. "]"
end
end
minetest.show_formspec(name, ";techage:color_form", table.concat(tbl, ""))
return true
end
})
-- Register callback
minetest.register_on_player_receive_fields(function(player, formname, fields)
if formname ~= "techage:color_form" then
return false
end
return true
end)
register_signallamp("techage:signal_lamp",
S("TechAge Signal Lamp"),
{"techage_signal_lamp.png^[colorize:#000000:80"},
{"techage_signal_lamp.png"},
{
type = "fixed", type = "fixed",
fixed = { fixed = {
{-6/16, -6/16, -6/16, 6/16, 6/16, 6/16}, {-6/16, -6/16, -6/16, 6/16, 6/16, 6/16},
{-4/16, -10/16, -4/16, 4/16, -6/16, 4/16}, {-4/16, -10/16, -4/16, 4/16, -6/16, 4/16},
}, }
}, }
)
after_place_node = function(pos, placer, itemstack, pointed_thing) register_signallamp("techage:signal_lamp2",
logic.after_place_node(pos, placer, "techage:signal_lamp_off", S("TechAge Signal Lamp")) S("TechAge Signal Lamp 2 "),
logic.infotext(M(pos), S("TechAge Signal Lamp")) {"techage_signallamp2.png^[colorize:#000000:80"},
if COLORED then {"techage_signallamp2.png"}
unifieddyes.recolor_on_place(pos, placer, itemstack, pointed_thing) )
end
end,
on_rightclick = switch_on,
after_dig_node = function(pos, oldnode, oldmetadata, digger)
techage.remove_node(pos, oldnode, oldmetadata)
if COLORED then
unifieddyes.after_dig_node(pos, oldnode, oldmetadata, digger)
end
end,
on_construct = COLORED and unifieddyes.on_construct or nil,
on_dig = COLORED and unifieddyes.on_dig or nil,
paramtype = "light",
paramtype2 = "color",
palette = COLORED and "unifieddyes_palette_extended.png" or 'techage_color16.png',
place_param2 = 241,
sunlight_propagates = true,
sounds = default.node_sound_stone_defaults(),
groups = {choppy=2, cracky=1, ud_param2_colorable = 1},
is_ground_content = false,
drop = "techage:signal_lamp_off"
})
minetest.register_node("techage:signal_lamp_on", {
description = S("TechAge Signal Lamp"),
tiles = {"techage_signal_lamp.png"},
drawtype = "nodebox",
node_box = {
type = "fixed",
fixed = {
{-6/16, -6/16, -6/16, 6/16, 6/16, 6/16},
{-4/16, -10/16, -4/16, 4/16, -6/16, 4/16},
},
},
on_rightclick = switch_off,
paramtype = "light",
paramtype2 = "color",
palette = COLORED and "unifieddyes_palette_extended.png" or 'techage_color16.png',
groups = {choppy=2, cracky=1, not_in_creative_inventory=1, ud_param2_colorable = 1},
on_construct = COLORED and unifieddyes.on_construct or nil,
after_place_node = COLORED and unifieddyes.recolor_on_place or nil,
after_dig_node = function(pos, oldnode, oldmetadata, digger)
techage.remove_node(pos, oldnode, oldmetadata)
if COLORED then
unifieddyes.after_dig_node(pos, oldnode, oldmetadata, digger)
end
end,
on_dig = COLORED and unifieddyes.on_dig or nil,
light_source = 10,
is_ground_content = false,
drop = "techage:signal_lamp_off"
})
techage.register_node({"techage:signal_lamp_off", "techage:signal_lamp_on"}, {
on_recv_message = function(pos, src, topic, payload)
if topic == "on" then
local node = techage.get_node_lvm(pos)
switch_on(pos, node)
elseif topic == "off" then
local node = techage.get_node_lvm(pos)
switch_off(pos, node)
else
return "unsupported"
end
end,
on_beduino_receive_cmnd = function(pos, src, topic, payload)
if topic == 1 and payload[1] == 1 then
local node = techage.get_node_lvm(pos)
switch_on(pos, node)
return 0
elseif topic == 1 and payload[1] == 0 then
local node = techage.get_node_lvm(pos)
switch_off(pos, node)
return 0
else
return 2
end
end,
})
minetest.register_craft({ minetest.register_craft({
output = "techage:signal_lamp_off", output = "techage:signal_lamp_off",
recipe = { recipe = {
{"", "wool:white", ""}, {"", "wool:white", ""},
{"", "default:torch", ""}, {"", "default:torch", ""},
{"", "techage:vacuum_tube", ""}, {"", "techage:vacuum_tube", ""},
}, },
}) })
minetest.register_craft({
output = "techage:signal_lamp2_off",
recipe = {
{"", "default:glass", ""},
{"", "default:torch", ""},
{"", "techage:vacuum_tube", ""},
},
})

View File

@ -527,7 +527,7 @@ Dieser Status und weitere Informationen werden auch ausgegeben, wenn mit dem Sch
### TA3 Taster/Schalter / Button/Switch ### TA3 Taster/Schalter / Button/Switch
Der Taster/Schalter sendet `on`/`off` Kommandos zu den Blöcken, die über die Nummern konfiguriert wurden. Der Taster/Schalter sendet `on`/`off` Kommandos zu den Blöcken, die über die Nummern konfiguriert wurden.
Der Taster/Schalter kann als Taster (button) oder Schalter (switch) konfiguriert werden. Wird er als Taster konfiguriert, so kann die Zeit zwischen den `on` und `off` Kommandos eingestellt werden. Der Taster/Schalter kann als Taster (button) oder Schalter (switch) konfiguriert werden. Wird er als Taster konfiguriert, so kann die Zeit zwischen den `on` und `off` Kommandos eingestellt werden. Mit der Betriebsart "on button" wird nur ein `on` und kein `off` Kommandos gesendet.
Über die Checkbox "public" kann eingestellt werden, ob den Taster von jedem (gesetzt), oder nur vom Besitzer selbst (nicht gesetzt) genutzt werden darf. Über die Checkbox "public" kann eingestellt werden, ob den Taster von jedem (gesetzt), oder nur vom Besitzer selbst (nicht gesetzt) genutzt werden darf.
@ -631,7 +631,9 @@ Im privaten Modus (private) kann das Terminal nur von Spielern verwendet werden,
### TechAge Signallampe / Signal Lamp ### TechAge Signallampe / Signal Lamp
Die Signallampe kann mit `on`/`off` Kommando ein- bzw. ausgeschaltet werden. Diese Lampe braucht keinen Strom und Die Signallampe kann mit `on`/`off` Kommando ein- bzw. ausgeschaltet werden. Diese Lampe braucht keinen Strom und
kann mit der Spritzpistole aus der Mod "Unified Dyes" farbig gemacht werden. kann mit der Spritzpistole aus der Mod "Unified Dyes" und über Lua/Beduino Kommandos eingefärbt werden.
Mit dem Chat-Kommando `/ta_color` wird die Farbpalette mit den Werten für die Lua/Beduino Kommandos angezeigt und mit `/ta_send color <num>` kann die Farbe geändert werden.
[ta3_signallamp|image] [ta3_signallamp|image]

View File

@ -526,7 +526,7 @@ This status and other information is also output when the wrench is clicked on t
### TA3 Button / Switch ### TA3 Button / Switch
The button/switch sends `on` / `off` commands to the blocks that have been configured via the numbers. The button/switch sends `on` / `off` commands to the blocks that have been configured via the numbers.
The button/switch can be configured as a button or a switch. If it is configured as a button, the time between the `on` and `off` commands can be set. The button/switch can be configured as a button or a switch. If it is configured as a button, the time between the `on` and `off` commands can be set. With the operating mode "on button" only an `on` and no `off` command is sent.
The checkbox "public" can be used to set whether the button can be used by everyone (set) or only by the owner himself (not set). The checkbox "public" can be used to set whether the button can be used by everyone (set) or only by the owner himself (not set).
@ -629,8 +629,9 @@ In public mode, all players can use the preconfigured keys.
### TechAge Signal Lamp ### TechAge Signal Lamp
The signal lamp can be switched on or off with the `on` / `off` command. This lamp does not need electricity and The signal lamp can be switched on or off with the `on` / `off` command. This lamp does not need electricity and can be colored with the airbrush tool from the mod Unified Dyes" and via Lua/Beduino commands.
can be colored with the airbrush tool of the mod Unified Dyes.
With the chat command `/ta_color` the color palette with the values for the Lua/Beduino commands is displayed and with `/ta_send color <num>` the color can be changed.
[ta3_signallamp|image] [ta3_signallamp|image]
@ -826,6 +827,18 @@ The processing power is up to 8 times one item every 4 seconds.
[ta3_injector|image] [ta3_injector|image]
### TA3 Item Flow Limiter
The Flow Limiter limits the number of items that can be pushed through by using a slider. This allows the number of items that are put into an oven, for example, to be precisely adapted to the recipe.
The Flow Limiter must be configured via the menu and then started. If the configured number of items has been passed, the block switches off. The next time the Flow Limiter is switched on, it again transmits the configured number of items.
**Note: The Flow Limiter must be placed behind the pusher.**
The Flow Limiter can also be configured and started using a Lua or Beduino controller.
[ta3_item_flow_limiter_pas|image]
## Tools ## Tools

View File

@ -467,7 +467,7 @@ Das Terminal dient zur Ein-/Ausgabe für den Lua Controller.
### TA4 Taster/Schalter / Button/Switch ### TA4 Taster/Schalter / Button/Switch
Beim TA4 Taster/Schalter hat sich nur das Aussehen geändert. Die Funktionalität ist gleich wie beim TA3 Taster/Schalter. Beim TA4 Taster/Schalter hat sich nur das Aussehen geändert. Die Funktionalität ist gleich wie beim TA3 Taster/Schalter. Mit dem Schraubenschlüssel-Menü können die Daten aber nachträglich geändert werden.
[ta4_button|image] [ta4_button|image]
@ -554,6 +554,8 @@ Der TA4 Sequenzer unterstützt folgende techage Kommandos:
Das `goto` Kommando wird nur angenommen, wenn der Sequenzer gestoppt ist. Das `goto` Kommando wird nur angenommen, wenn der Sequenzer gestoppt ist.
Über das Gabelschlüssel-Menü kann beim Sequenzer die Zykluszeit (normal: 100 ms) geändert werden.
[ta4_sequencer|image] [ta4_sequencer|image]
@ -569,7 +571,7 @@ Da die bewegten Blöcke Spieler und Mobs mitnehmen können, die auf dem Block st
Anleitung: Anleitung:
- Controller setzen und die Blöcke, die bewegt werden sollen, über das Menü an-trainieren (Es können bis zu 16 Blöcke an-trainiert werden) - Controller setzen und die Blöcke, die bewegt werden sollen, über das Menü an-trainieren (Es können bis zu 16 Blöcke an-trainiert werden)
- die "Flugstrecke" muss über eine x,y,z Angabe (relativ) eingegeben werden (die maximale Distanz beträgt 100 m) - die "Flugstrecke" muss über eine x,y,z Angabe (relativ) eingegeben werden (die maximale Distanz (x+y+z) beträgt 200 m)
- mit den Menü-Tasten "Bewege A-B" sowie "Bewege B-A" kann die Bewegung getestet werden - mit den Menü-Tasten "Bewege A-B" sowie "Bewege B-A" kann die Bewegung getestet werden
- man kann auch durch Wände oder andere Blöcke fliegen - man kann auch durch Wände oder andere Blöcke fliegen
- auch die Zielposition für die Blöcke kann belegt sein. Die Blöcke werden in diesem Falle "unsichtbar" gespeichert. Dies ist für Schiebetüren und ähnliches gedacht - auch die Zielposition für die Blöcke kann belegt sein. Die Blöcke werden in diesem Falle "unsichtbar" gespeichert. Dies ist für Schiebetüren und ähnliches gedacht
@ -804,7 +806,13 @@ In einen TA4 Tank passen 2000 Einheiten oder 200 Fässer einer Flüssigkeit.
Siehe TA3 Pumpe. Siehe TA3 Pumpe.
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. Die TA4 Pumpe pumpt 8 Einheiten Flüssigkeit alle zwei Sekunden.
In der Betriebsart "Durchflussbegrenzer" kann die Anzahl der Einheiten, die von der Pumpe gepumpt werden, begrenzt werden. Die Betriebsart Durchflussbegrenzer kann über das Gabelschlüssel-Menü aktiviert werden, indem im Menü die Anzahl an Einheiten konfiguriert wird. Sobald die konfigurierte Anzahl an Einheiten gepumpt wurden, schaltet sich die Pumpe ab. Wird die Pumpe wieder eingeschaltet, pumpt sie wieder die konfigurierte Anzahl an Einheiten und schaltet sich dann ab.
Der Durchflussbegrenzer kann auch per Lua- oder Beduino Controller konfiguriert und gestartet werden.
Zusätzlich unterstützt die Pumpe das Kommando `flowrate`. Damit kann die Gesamtdurchflussmenge durch die Pumpe abgefragt werden.
[ta4_pump|image] [ta4_pump|image]
@ -840,14 +848,18 @@ Aber: TA4 Schieber und TA4 Verteiler erreichen ihre volle Leistungsfähigkeit nu
Die Funktion entspricht grundsätzlich der von TA2/TA3. Zusätzlich kann aber über ein Menü konfiguriert werden, welche Gegenstände aus einer TA4 Kiste geholt und weiter transportiert werden sollen. Die Funktion entspricht grundsätzlich der von TA2/TA3. Zusätzlich kann aber über ein Menü konfiguriert werden, welche Gegenstände aus einer TA4 Kiste geholt und weiter transportiert werden sollen.
Die Verarbeitungsleistung beträgt 12 Items alle 2 s, sofern auf beiden Seiten TA4 Röhren verwendet werden. Anderenfalls sind es nur 6 Items alle 2 s. Die Verarbeitungsleistung beträgt 12 Items alle 2 s, sofern auf beiden Seiten TA4 Röhren verwendet werden. Anderenfalls sind es nur 6 Items alle 2 s.
Der TA4 Schieber besitzt zwei zusätzliche Kommandos für den Lua Controller: In der Betriebsart "Durchlaufbegrenzer" kann die Anzahl der Items, die von dem Schieber bewegt werden, begrenzt werden. Die Betriebsart Durchlaufbegrenzer kann über das Gabelschlüssel-Menü aktiviert werden, indem im Menü die Anzahl an Items konfiguriert wird. Sobald die konfigurierte Anzahl an Items bewegt wurden, schaltet sich der Schieber ab. Wird der Schieber wieder eingeschaltet, bewegt er wieder die konfigurierte Anzahl an Items und schaltet sich dann ab.
Der TA4 Schieber kann auch per Lua- oder Beduino Controller konfiguriert und gestartet werden.
Hier die zusätzlichen Kommandos für den Lua Controller:
- `config` dient zur Konfiguration des Schiebers, analog zum manuellen Konfiguration über das Menü. - `config` dient zur Konfiguration des Schiebers, analog zum manuellen Konfiguration über das Menü.
Beispiel: `$send_cmnd(1234, "config", "default:dirt")` Beispiel: `$send_cmnd(1234, "config", "default:dirt")`
Mit `$send_cmnd(1234, "config", "")` wird die Konfiguration gelöscht Mit `$send_cmnd(1234, "config", "")` wird die Konfiguration gelöscht
- `pull` dient zum Absetzen eines Auftrags an den Schieber: - `limit` dient zum Setzen der Anzahl der Items für die Durchlaufbegrenzer Betriebsart:
Beispiel: `$send_cmnd(1234, "pull", "default:dirt 8")` Beispiel: `$send_cmnd(1234, "init", 7)`
Als Nummer sind Werte von 1 bis 12 zulässig. Danach geht der Schieber wieder in den `stopped` Mode und sendet ein "off" Kommando zurück an den Sender des "pull" Kommandos.
[ta4_pusher|image] [ta4_pusher|image]
@ -957,3 +969,8 @@ Die Verarbeitungsleistung beträgt ein Item alle 8 s. Der Block benötigt hierf
[ta4_recycler|image] [ta4_recycler|image]
### TA4 Item Durchlaufbegrenzer / Item Flow Limiter
Die Funktion entspricht der von TA3.
[ta4_item_flow_limiter_pas|image]

View File

@ -459,7 +459,7 @@ The terminal is used for input / output for the Lua controller.
### TA4 Button/Switch ### TA4 Button/Switch
Only the appearance of the TA4 button/switch has changed. The functionality is the same as with the TA3 button/switch. Only the appearance of the TA4 button/switch has changed. The functionality is the same as with the TA3 button/switch. With the wrench menu, however, the data can be changed later.
[ta4_button|image] [ta4_button|image]
@ -546,6 +546,8 @@ The TA4 sequencer supports the following techage commands:
The `goto` command is only accepted when the sequencer is stopped. The `goto` command is only accepted when the sequencer is stopped.
The cycle time (default: 100 ms) can be changed for the sequencer via the open-end wrench menu.
[ta4_sequencer|image] [ta4_sequencer|image]
@ -560,7 +562,7 @@ Since the moving blocks can take players and mobs standing on the block with the
Instructions: Instructions:
- Set the controller and train the blocks to be moved via the menu (up to 16 blocks can be trained) - Set the controller and train the blocks to be moved via the menu (up to 16 blocks can be trained)
- the "flight route" must be entered via an x, y, z specification (relative) (the maximum distance is 100 m) - the "flight route" must be entered via an x, y, z specification (relative) (the maximum distance (x+y+z) is 200 m)
- The movement can be tested with the menu buttons "Move A-B" and "Move B-A" - The movement can be tested with the menu buttons "Move A-B" and "Move B-A"
- you can also fly through walls or other blocks - you can also fly through walls or other blocks
- The target position for the blocks can also be occupied. In this case, the blocks are saved "invisibly". This is intended for sliding doors and the like - The target position for the blocks can also be occupied. In this case, the blocks are saved "invisibly". This is intended for sliding doors and the like
@ -796,7 +798,13 @@ A TA4 tank can hold 2000 units or 200 barrels of liquid.
See TA3 pump. See TA3 pump.
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. The TA4 pump pumps 8 units of liquid every two seconds.
In the "Flow limiter" mode, the number of units pumped by the pump can be limited. The flow limiter mode can be activated via the open-end wrench menu by configuring the number of units in the menu. Once the configured number of units have been pumped, the pump will turn off. When the pump is turned on again, it will pump the configured number of units again and then turn off.
The flow limiter can also be configured and started using a Lua or Beduino controller.
The pump also supports the `flowrate` command. This allows the total flow rate through the pump to be queried.
[ta4_pump|image] [ta4_pump|image]
@ -832,14 +840,17 @@ But: TA4 pushers and TA4 distributors only achieve their full performance when u
The function basically corresponds to that of TA2 / TA3. In addition, a menu can be used to configure which objects should be taken from a TA4 chest and transported further. The function basically corresponds to that of TA2 / TA3. In addition, a menu can be used to configure which objects should be taken from a TA4 chest and transported further.
The processing power is 12 items every 2 s, if TA4 tubes are used on both sides. Otherwise there are only 6 items every 2 s. The processing power is 12 items every 2 s, if TA4 tubes are used on both sides. Otherwise there are only 6 items every 2 s.
The TA4 pusher has two additional commands for the Lua controller: In the "flow limiter" mode, the number of items that are moved by the pusher can be limited. The flow limiter mode can be activated via the open-end wrench menu by configuring the number of items in the menu. As soon as the configured number of items have been moved, the pusher switches off. If the pusher is switched on again, it moves the configured number of items again and then switches off.
The TA4 pusher can also be configured and started using a Lua or Beduino controller.
Here are the additional commands for the Lua controller:
- `config` is used to configure the pusher, analogous to manual configuration via the menu. - `config` is used to configure the pusher, analogous to manual configuration via the menu.
Example: `$send_cmnd(1234, "config", "default: dirt")` Example: `$send_cmnd(1234, "config", "default:dirt")`
With `$send_cmnd(1234, "config", "")` the configuration is deleted With `$send_cmnd(1234, "config", "")` the configuration is deleted
- `pull` is used to send an order to the pusher: - `limit` is used to set the number of items for the flow limiter mode:
Example: `$send_cmnd(1234, "pull", "default: dirt 8")` Example: `$send_cmnd(1234, "init", 7)`
Values from 1 to 12 are permitted as numbers. Then the pusher goes back to `stopped` mode and sends an" off "command back to the transmitter of the" pull "command.
[ta4_pusher|image] [ta4_pusher|image]
@ -949,3 +960,10 @@ The machine can disassemble pretty much any Techage and Hyperloop blocks. But no
The processing power is one item every 8 s. The block requires 16 ku of electricity for this. The processing power is one item every 8 s. The block requires 16 ku of electricity for this.
[ta4_recycler|image] [ta4_recycler|image]
### TA4 Item Flow Limiter
The function corresponds to that of TA3.
[ta4_item_flow_limiter_pas|image]

View File

@ -5,7 +5,7 @@
import re import re
import sys import sys
import pprint import pprint
import mistune import mistune # must be v0.8.4
def formspec_escape(text): def formspec_escape(text):
text = text.replace("\\", "") text = text.replace("\\", "")

View File

@ -372,6 +372,8 @@ Please note, that this is not a technical distinction, only a logical.
| "stacks" | Array with up to 4 Stores with the inventory content (see example) | 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 | 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). | | "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). |
| "count" | number of items | Read the number of pushed items for a TA4 Pusher in "flow limiter" mode |
| "count" | number of units | Read the number of pumped liquid units for a TA4 Pump in "flow limiter" mode |
| "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) | | "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" | | "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. | | "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. |
@ -395,7 +397,8 @@ Please note, that this is not a technical distinction, only a logical.
| "config" | "\<slot> \<item list>" | Configure a Distributor filter slot, like: "red default:dirt dye:blue" | | "config" | "\<slot> \<item list>" | Configure a Distributor filter slot, like: "red default:dirt dye:blue" |
| "text" | text string | Text to be used for the Sensor Chest menu | | "text" | text string | Text to be used for the Sensor Chest menu |
| "reset" | nil | Reset the item counter of the TA4 Item Detector block | | "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` | | "limit" | number | Configure a TA4 Pusher with the number of items that are allowed to be pushed ("flow limiter" mode)<br />limit = 0 turns off the "flow limiter" mode |
| "limit" | number | Configure a TA4 Pump with the number of liquid units that are allowed to be pumped ("flow limiter" mode)<br />limit = 0 turns off the "flow limiter" mode |
| "config" | item string | Configure the TA4 pusher.<br />Example: `wool:blue` | | "config" | item string | Configure the TA4 pusher.<br />Example: `wool:blue` |
| "exchange" | inventory slot number | TA3 Door Controller II (techage:ta3_doorcontroller2)<br />Exchange a block<br />*idx* is the inventory slot number (1..n) of/for the block to be exchanged | | "exchange" | inventory slot number | TA3 Door Controller II (techage:ta3_doorcontroller2)<br />Exchange a block<br />*idx* is the inventory slot number (1..n) of/for the block to be exchanged |
| "set" | inventory slot number | TA3 Door Controller II (techage:ta3_doorcontroller2)<br />Set/add a block<br />*idx* is the inventory slot number (1..n) with the block to be set | | "set" | inventory slot number | TA3 Door Controller II (techage:ta3_doorcontroller2)<br />Set/add a block<br />*idx* is the inventory slot number (1..n) with the block to be set |
@ -414,6 +417,7 @@ Please note, that this is not a technical distinction, only a logical.
| "stop" | nil | Stop command for the TA4 Sequencer. | | "stop" | nil | Stop command for the TA4 Sequencer. |
| "gain" | volume | Set volume of the sound block (`volume` is a value between 0 and 1.0) | | "gain" | volume | Set volume of the sound block (`volume` is a value between 0 and 1.0) |
| "sound" | index | Select sound sample of the sound block | | "sound" | index | Select sound sample of the sound block |
| "color" | \<color> | Set the color of the TechAge Signal Lamp and TechAge Signal Lamp 2 (color = 0..255) |
### Server and Terminal Functions ### Server and Terminal Functions

View File

@ -228,6 +228,7 @@
- [TA4 Elektronikfabrik / Electronic Fab](./manual_ta4_DE.md#ta4-elektronikfabrik--electronic-fab) - [TA4 Elektronikfabrik / Electronic Fab](./manual_ta4_DE.md#ta4-elektronikfabrik--electronic-fab)
- [TA4 Injektor / Injector](./manual_ta4_DE.md#ta4-injektor--injector) - [TA4 Injektor / Injector](./manual_ta4_DE.md#ta4-injektor--injector)
- [TA4 Recycler](./manual_ta4_DE.md#ta4-recycler) - [TA4 Recycler](./manual_ta4_DE.md#ta4-recycler)
- [TA4 Item Durchlaufbegrenzer / Item Flow Limiter](./manual_ta4_DE.md#ta4-item-durchlaufbegrenzer--item-flow-limiter)
- [TA5: Zukunft](./manual_ta5_DE.md#ta5:-zukunft) - [TA5: Zukunft](./manual_ta5_DE.md#ta5:-zukunft)
- [Energiequellen](./manual_ta5_DE.md#energiequellen) - [Energiequellen](./manual_ta5_DE.md#energiequellen)
- [TA5 Fusionsreaktor](./manual_ta5_DE.md#ta5-fusionsreaktor) - [TA5 Fusionsreaktor](./manual_ta5_DE.md#ta5-fusionsreaktor)

View File

@ -134,6 +134,7 @@
- [TA3 Gravel Rinser](./manual_ta3_EN.md#ta3-gravel-rinser) - [TA3 Gravel Rinser](./manual_ta3_EN.md#ta3-gravel-rinser)
- [TA3 Grinder](./manual_ta3_EN.md#ta3-grinder) - [TA3 Grinder](./manual_ta3_EN.md#ta3-grinder)
- [TA3 Injector](./manual_ta3_EN.md#ta3-injector) - [TA3 Injector](./manual_ta3_EN.md#ta3-injector)
- [TA3 Item Flow Limiter](./manual_ta3_EN.md#ta3-item-flow-limiter)
- [Tools](./manual_ta3_EN.md#tools) - [Tools](./manual_ta3_EN.md#tools)
- [Techage Info Tool](./manual_ta3_EN.md#techage-info-tool) - [Techage Info Tool](./manual_ta3_EN.md#techage-info-tool)
- [TechAge Programmer](./manual_ta3_EN.md#techage-programmer) - [TechAge Programmer](./manual_ta3_EN.md#techage-programmer)
@ -228,6 +229,7 @@
- [TA4 Electronic Fab](./manual_ta4_EN.md#ta4-electronic-fab) - [TA4 Electronic Fab](./manual_ta4_EN.md#ta4-electronic-fab)
- [TA4 Injector](./manual_ta4_EN.md#ta4-injector) - [TA4 Injector](./manual_ta4_EN.md#ta4-injector)
- [TA4 Recycler](./manual_ta4_EN.md#ta4-recycler) - [TA4 Recycler](./manual_ta4_EN.md#ta4-recycler)
- [TA4 Item Flow Limiter](./manual_ta4_EN.md#ta4-item-flow-limiter)
- [TA5: Future](./manual_ta5_EN.md#ta5:-future) - [TA5: Future](./manual_ta5_EN.md#ta5:-future)
- [Energy Sources](./manual_ta5_EN.md#energy-sources) - [Energy Sources](./manual_ta5_EN.md#energy-sources)
- [TA5 Fusion Reactor](./manual_ta5_EN.md#ta5-fusion-reactor) - [TA5 Fusion Reactor](./manual_ta5_EN.md#ta5-fusion-reactor)

View File

@ -1,4 +1,4 @@
name = techage name = techage
depends = default,doors,flowers,tubelib2,networks,basic_materials,bucket,stairs,screwdriver,minecart,lcdlib,safer_lua depends = default,doors,flowers,tubelib2,networks,basic_materials,bucket,stairs,screwdriver,minecart,lcdlib,safer_lua
optional_depends = unified_inventory,wielded_light,unifieddyes,moreores,ethereal,mesecon,digtron,bakedclay,moreblocks,i3,creative,craftguide optional_depends = unified_inventory,wielded_light,unifieddyes,moreores,ethereal,mesecons,digtron,bakedclay,moreblocks,i3,creative,craftguide
description = Techage, go through 5 tech ages in search of wealth and power! description = Techage, go through 5 tech ages in search of wealth and power!

View File

@ -46,7 +46,8 @@ local WRENCH_MENU = {
local function formspec(nvm, meta) local function formspec(nvm, meta)
local status = meta:get_string("status") local status = meta:get_string("status")
local path = meta:contains("path") and meta:get_string("path") or "0,3,0" local path = meta:contains("fs_path") and meta:get_string("fs_path") or
meta:contains("path") and meta:get_string("path") or "0,3,0"
return "size[8,6.7]" .. return "size[8,6.7]" ..
"style_type[textarea;font=mono;textcolor=#FFFFFF;border=true]" .. "style_type[textarea;font=mono;textcolor=#FFFFFF;border=true]" ..
"box[0,-0.1;7.2,0.5;#c6e8ff]" .. "box[0,-0.1;7.2,0.5;#c6e8ff]" ..
@ -107,6 +108,7 @@ minetest.register_node("techage:ta5_flycontroller", {
local pos_list = mark.get_poslist(name) local pos_list = mark.get_poslist(name)
local _, err = fly.to_path(fields.path, MAX_DIST) local _, err = fly.to_path(fields.path, MAX_DIST)
if not err then if not err then
meta:set_string("fs_path", fields.path)
meta:set_string("path", fields.path) meta:set_string("path", fields.path)
end end
nvm.running = nil nvm.running = nil
@ -120,8 +122,11 @@ minetest.register_node("techage:ta5_flycontroller", {
local _, err = fly.to_path(fields.path, MAX_DIST) local _, err = fly.to_path(fields.path, MAX_DIST)
if not err then if not err then
meta:set_string("path", fields.path) meta:set_string("path", fields.path)
meta:set_string("fs_path", fields.path)
meta:set_string("status", S("Stored")) meta:set_string("status", S("Stored"))
else else
meta:set_string("path", "0,0,0")
meta:set_string("fs_path", fields.path)
meta:set_string("status", err) meta:set_string("status", err)
end end
meta:set_string("formspec", formspec(nvm, meta)) meta:set_string("formspec", formspec(nvm, meta))

View File

@ -22,7 +22,7 @@ local MP = minetest.get_modpath("techage")
local fly = dofile(MP .. "/basis/fly_lib.lua") local fly = dofile(MP .. "/basis/fly_lib.lua")
local mark = dofile(MP .. "/basis/mark_lib.lua") local mark = dofile(MP .. "/basis/mark_lib.lua")
local MAX_DIST = 100 local MAX_DIST = 200
local MAX_BLOCKS = 16 local MAX_BLOCKS = 16
local WRENCH_MENU = { local WRENCH_MENU = {
@ -40,6 +40,7 @@ local WRENCH_MENU = {
label = S("Handover to B"), label = S("Handover to B"),
tooltip = S("Number of the next movecontroller"), tooltip = S("Number of the next movecontroller"),
default = "", default = "",
check = techage.check_numbers,
}, },
{ {
type = "number", type = "number",
@ -47,6 +48,7 @@ local WRENCH_MENU = {
label = S("Handover to A"), label = S("Handover to A"),
tooltip = S("Number of the previous movecontroller"), tooltip = S("Number of the previous movecontroller"),
default = "", default = "",
check = techage.check_numbers,
}, },
{ {
type = "float", type = "float",
@ -183,7 +185,7 @@ minetest.register_node("techage:ta4_movecontroller", {
if fly.to_vector(fields.path or "", MAX_DIST) then if fly.to_vector(fields.path or "", MAX_DIST) then
meta:set_string("path", fields.path) meta:set_string("path", fields.path)
end end
local line = fly.to_vector(meta:get_string("path")) local line = fly.to_vector(meta:get_string("path"), MAX_DIST)
if line then if line then
nvm.running = true nvm.running = true
fly.move_to(pos, line) fly.move_to(pos, line)
@ -235,12 +237,12 @@ techage.register_node({"techage:ta4_movecontroller"}, {
nvm.moveBA = false nvm.moveBA = false
nvm.running = true nvm.running = true
return fly.move_to_other_pos(pos, true) return fly.move_to_other_pos(pos, true)
elseif move_xyz and topic == "move" then elseif not move_xyz and topic == "move" then
nvm.moveBA = nvm.moveBA == false nvm.moveBA = nvm.moveBA == false
nvm.running = true nvm.running = true
return fly.move_to_other_pos(pos, nvm.moveBA == false) return fly.move_to_other_pos(pos, nvm.moveBA == false)
elseif move_xyz and topic == "move2" then elseif move_xyz and topic == "move2" then
local line = fly.to_vector(payload) local line = fly.to_vector(payload, MAX_DIST)
if line then if line then
nvm.running = true nvm.running = true
nvm.controller_mode = true nvm.controller_mode = true

View File

@ -158,11 +158,14 @@ techage.register_node({"techage:ta5_tele_tube"}, {
local rmt_nvm = techage.get_nvm(rmt_pos) local rmt_nvm = techage.get_nvm(rmt_pos)
if techage.is_operational(rmt_nvm) then if techage.is_operational(rmt_nvm) then
local tube_dir = M(rmt_pos):get_int("tube_dir") local tube_dir = M(rmt_pos):get_int("tube_dir")
if techage.push_items(rmt_pos, tube_dir, stack) then local leftover = techage.push_items(rmt_pos, tube_dir, stack)
-- Moved any items
if leftover then
State:keep_running(pos, nvm, COUNTDOWN_TICKS) State:keep_running(pos, nvm, COUNTDOWN_TICKS)
State:keep_running(rmt_pos, rmt_nvm, COUNTDOWN_TICKS) State:keep_running(rmt_pos, rmt_nvm, COUNTDOWN_TICKS)
return true return true
end end
return leftover
else else
State:blocked(pos, nvm, S("Remote block error")) State:blocked(pos, nvm, S("Remote block error"))
end end

40
techage/textures/generate.py Executable file
View File

@ -0,0 +1,40 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Script to generate the palette PNG file.
#
# Copyright (C) 2022 Joachim Stolberg
# LGPLv2.1+
from PIL import Image
MainColors = [
0x000080, 0x008000, 0x800000, 0x008080, 0x808000, 0x800080,
0x0000FF, 0x00FF00, 0xFF0000, 0x00FFFF, 0xFFFF00, 0xFF00FF,
0x0080FF, 0x8000FF, 0x80FF00, 0x00FF80, 0xFF8000, 0xFF0080,
]
def generate():
img = Image.new("RGB", (18, 15), color='#000000')
# Main colors
for x in range(0,18):
img.putpixel((x, 0), MainColors[x])
# Grey scale
for x in range(0,18):
img.putpixel((x, 1), (x * 15, x * 15, x * 15))
# 216 colors palette
idx = 36
for r in range(0,6):
for g in range(0,6):
for b in range(0,6):
x = idx % 18
y = int(idx / 18)
img.putpixel((x, y), (r * 0x33, g * 0x33, b * 0x33))
idx += 1
img.save("techage_palette256.png", "PNG")
generate()

Binary file not shown.

After

Width:  |  Height:  |  Size: 133 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 B

View File

@ -115,6 +115,16 @@ local function read_state(itemstack, user, pointed_thing)
if owner ~= "" then if owner ~= "" then
minetest.chat_send_player(user:get_player_name(), S("Node owner")..": "..owner.." ") minetest.chat_send_player(user:get_player_name(), S("Node owner")..": "..owner.." ")
end end
if ndef and ndef.networks and ndef.networks.pipe2 and ndef.networks.pipe2.ntype == "pump" then
local tbl = networks.liquid.get_liquids(pos, Pipe2)
if #tbl > 0 then
local names = table.concat(tbl, ", ")
minetest.chat_send_player(user:get_player_name(), S("Pump connected to tank(s) with: @1", names))
else
minetest.chat_send_player(user:get_player_name(), S("Pump connected to no/empty tank(s)."))
end
end
minetest.chat_send_player(user:get_player_name(), S("Position")..": "..minetest.pos_to_string(pos).." ") minetest.chat_send_player(user:get_player_name(), S("Position")..": "..minetest.pos_to_string(pos).." ")
itemstack:add_wear(65636/200) itemstack:add_wear(65636/200)
return itemstack return itemstack

View File

@ -114,6 +114,8 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
end end
end) end)
-- Player slots are preserved when unified_inventory is disabled. Do not allow modification.
-- Fix: use a detached inventory and store the data separately.
local function save_bags_metadata(player, bags_inv) local function save_bags_metadata(player, bags_inv)
local is_empty = true local is_empty = true
local bags = {} local bags = {}
@ -163,7 +165,7 @@ local function load_bags_metadata(player, bags_inv)
save_bags_metadata(player, bags_inv) save_bags_metadata(player, bags_inv)
end end
-- Clean up deprecated garbage after saving -- Legacy: Clean up old player lists
for i = 1, 4 do for i = 1, 4 do
local bag = "bag" .. i local bag = "bag" .. i
player_inv:set_size(bag, 0) player_inv:set_size(bag, 0)
@ -172,46 +174,29 @@ end
minetest.register_on_joinplayer(function(player) minetest.register_on_joinplayer(function(player)
local player_name = player:get_player_name() local player_name = player:get_player_name()
local bags_inv = minetest.create_detached_inventory(player_name .. "_bags",{ local bags_inv = minetest.create_detached_inventory(player_name .. "_bags", {
allow_put = function(inv, listname, index, stack, player)
local new_slots = stack:get_definition().groups.bagslots
if not new_slots then
return 0 -- ItemStack is not a bag.
end
-- The execution order of `allow_put`/`allow_take` is not defined.
-- We do not know the replacement ItemStack if the items are swapped.
-- Hence, bag slot upgrades and downgrades are not possible with the
-- current API.
if not player:get_inventory():is_empty(listname .. "contents") then
-- Legacy: in case `allow_take` is not executed on old Minetest versions.
return 0
end
return 1
end,
on_put = function(inv, listname, index, stack, player) on_put = function(inv, listname, index, stack, player)
player:get_inventory():set_size(listname .. "contents", player:get_inventory():set_size(listname .. "contents",
stack:get_definition().groups.bagslots) stack:get_definition().groups.bagslots)
save_bags_metadata(player, inv) save_bags_metadata(player, inv)
end, end,
allow_put = function(inv, listname, index, stack, player)
local new_slots = stack:get_definition().groups.bagslots
if not new_slots then
return 0
end
local player_inv = player:get_inventory()
local old_slots = player_inv:get_size(listname .. "contents")
if new_slots >= old_slots then
return 1
end
-- using a smaller bag, make sure it fits
local old_list = player_inv:get_list(listname .. "contents")
local new_list = {}
local slots_used = 0
local use_new_list = false
for i, v in ipairs(old_list) do
if v and not v:is_empty() then
slots_used = slots_used + 1
use_new_list = i > new_slots
new_list[slots_used] = v
end
end
if new_slots >= slots_used then
if use_new_list then
player_inv:set_list(listname .. "contents", new_list)
end
return 1
end
-- New bag is smaller: Disallow inserting
return 0
end,
allow_take = function(inv, listname, index, stack, player) allow_take = function(inv, listname, index, stack, player)
if player:get_inventory():is_empty(listname .. "contents") then if player:get_inventory():is_empty(listname .. "contents") then
return stack:get_count() return stack:get_count()
@ -230,6 +215,20 @@ minetest.register_on_joinplayer(function(player)
load_bags_metadata(player, bags_inv) load_bags_metadata(player, bags_inv)
end) end)
minetest.register_allow_player_inventory_action(function(player, action, inventory, info)
-- From detached inventory -> player inventory: put & take callbacks
if action ~= "put" or not info.listname:find("bag%dcontents") then
return
end
if info.stack:get_definition().groups.bagslots then
-- Problem 1: empty bags could be moved into their own slots
-- Problem 2: cannot reliably keep track of ItemStack ownership due to
--> Disallow all external bag movements into this list
return 0
end
end)
-- register bag tools -- register bag tools
minetest.register_tool("unified_inventory:bag_small", { minetest.register_tool("unified_inventory:bag_small", {
description = S("Small Bag"), description = S("Small Bag"),

View File

@ -7,17 +7,17 @@ Bag @1=Tasche @1
Small Bag=Kleine Tasche Small Bag=Kleine Tasche
Medium Bag=Mittelgroße Tasche Medium Bag=Mittelgroße Tasche
Large Bag=Große Tasche Large Bag=Große Tasche
All Items= All Items=Alle Gegenstände
Misc. Items= Misc. Items=Sonstige Gegenstände
Plant Life= Plant Life=Pfanzenwelt
Building Materials= Building Materials=Baumaterialien
Tools= Tools=Werkzeuge
Minerals and Metals= Minerals and Metals=Minerale und Metalle
Environment and Worldgen= Environment and Worldgen=Umwelt und Welterstellung
Lighting= Lighting=Beleuchtung
and = und and = und
Scroll categories left= Scroll categories left=Kategorien nach links blättern
Scroll categories right= Scroll categories right=Kategorien nach rechts blättern
Search=Suchen Search=Suchen
Reset search and display everything=Suche zurücksetzen und alles anzeigen Reset search and display everything=Suche zurücksetzen und alles anzeigen
First page=Erste Seite First page=Erste Seite
@ -76,10 +76,10 @@ Waypoints=Wegpunkte
Select Waypoint #@1=Wegpunkt Nr. @1 auswählen Select Waypoint #@1=Wegpunkt Nr. @1 auswählen
Waypoint @1=Wegpunkt Nr. @1 Waypoint @1=Wegpunkt Nr. @1
Set waypoint to current location=Setze Wegpunkt zur derzeitigen Position Set waypoint to current location=Setze Wegpunkt zur derzeitigen Position
Hide waypoint= Hide waypoint=Wegpunkt verstecken
Show waypoint= Show waypoint=Wegpunkt zeigen
Hide coordinates= Hide coordinates=Koordinaten verstecken
Show coordinates= Show coordinates=Koordinaten zeigen
Change color of waypoint display=Farbe der Darstellung der Wegpunkte ändern Change color of waypoint display=Farbe der Darstellung der Wegpunkte ändern
Edit waypoint name=Name des Wegpunkts ändern Edit waypoint name=Name des Wegpunkts ändern
Waypoint active=Wegpunkt aktiv Waypoint active=Wegpunkt aktiv

View File

@ -207,11 +207,9 @@ ui.register_page("craft", {
local function stack_image_button(x, y, w, h, buttonname_prefix, item) local function stack_image_button(x, y, w, h, buttonname_prefix, item)
local name = item:get_name() local name = item:get_name()
local count = item:get_count()
local wear = item:get_wear()
local description = item:get_meta():get_string("description") local description = item:get_meta():get_string("description")
local show_is_group = false local show_is_group = false
local displayitem = name.." "..count.." "..wear local displayitem = item:to_string()
local selectitem = name local selectitem = name
if name:sub(1, 6) == "group:" then if name:sub(1, 6) == "group:" then
local group_name = name:sub(7) local group_name = name:sub(7)
@ -245,6 +243,9 @@ local function stack_image_button(x, y, w, h, buttonname_prefix, item)
return button return button
end end
-- The recipe text contains parameters, hence they can yet not be translated.
-- Instead, use a dummy translation call so that it can be picked up by the
-- static parsing of the translation string update script
local recipe_text = { local recipe_text = {
recipe = NS("Recipe @1 of @2"), recipe = NS("Recipe @1 of @2"),
usage = NS("Usage @1 of @2"), usage = NS("Usage @1 of @2"),