built on 11/07/2022 20:24:44

This commit is contained in:
Joachim Stolberg 2022-07-11 20:24:44 +02:00
parent a9cc1d4579
commit 10dabd04ff
156 changed files with 3229 additions and 748 deletions

View File

@ -3,7 +3,7 @@
This modpack covers all necessary and useful mods to be able to use techage.
All mods have the own README.txt. For further information please consult these files.
This modpack includes:
This modpack contains:
- techage: The main mod
- ta4_jetpack: A Jetpack for techage with hydrogen as fuel and TA4 recipe
- ta4_paraglider: A Paraglider for techage with TA4 recipe
@ -47,6 +47,12 @@ ta4_jetpack requires the modpack 3d_armor. 3d_armor is itself a modpack and can'
### History
#### 2022-07-11
Updated Mods:
- techage (fusion reactor added)
#### 2022-01-28
Updated Mods:

View File

@ -109,7 +109,7 @@ minetest.register_node("hyperloop:tube_crowbar", {
description = S("Hyperloop Tube Crowbar"),
inventory_image = "hyperloop_tubecrowbar.png",
wield_image = "hyperloop_tubecrowbar.png",
use_texture_alpha = true,
use_texture_alpha = hyperloop.CLIP,
groups = {cracky=1, book=1},
on_use = remove_tube,
on_place = repair_tubes,

View File

@ -2,7 +2,7 @@
This LCD Lib is based on Display Lib and Font Lib from Pierre-Yves Rollo
**Dependancies**: default
**Dependancies**: none
**License**: LGPL

View File

1
lcdlib/mod.conf Normal file
View File

@ -0,0 +1 @@
name = lcdlib

View File

@ -144,7 +144,7 @@ minetest.register_entity("minecart:marker", {
initial_properties = {
visual = "upright_sprite",
textures = {"minecart_marker_cube.png"},
use_texture_alpha = true,
use_texture_alpha = minecart.CLIP,
physical = false,
glow = 12,
static_save = false,
@ -196,6 +196,7 @@ function minecart.is_owner(player, owner)
end
function minecart.get_buffer_pos(pos, player_name)
if pos then
local pos1 = minecart.find_node_near_lvm(pos, 1, {"minecart:buffer"})
if pos1 then
local meta = minetest.get_meta(pos1)
@ -203,9 +204,11 @@ function minecart.get_buffer_pos(pos, player_name)
return pos1
end
end
end
end
function minecart.get_buffer_name(pos)
if pos then
local pos1 = minecart.find_node_near_lvm(pos, 1, {"minecart:buffer"})
if pos1 then
local name = M(pos1):get_string("name")
@ -214,6 +217,7 @@ function minecart.get_buffer_name(pos)
end
return P2S(pos1)
end
end
end
function minecart.manage_attachment(player, entity, get_on)

View File

@ -102,7 +102,7 @@ minetest.register_node("minecart:tool", {
inventory_image = "minecart_tool.png",
wield_image = "minecart_tool.png",
liquids_pointable = true,
use_texture_alpha = true,
use_texture_alpha = minecart.CLIP,
groups = {cracky=1, book=1},
on_use = click_left,
on_place = click_right,

View File

@ -181,16 +181,16 @@ end
function networks.liquid.srv_peek(nvm)
nvm.liquid = nvm.liquid or {}
return nvm.liquid.name
nvm.liquid.amount = math.floor((nvm.liquid.amount or 0) + 0.5)
return nvm.liquid.amount > 0 and nvm.liquid.name
end
function networks.liquid.srv_put(nvm, name, amount, capa)
assert(name)
assert(amount and amount >= 0)
assert(capa and capa > 0)
amount = math.floor((amount or 0) + 0.5)
nvm.liquid = nvm.liquid or {}
amount = amount or 0
if not nvm.liquid.name then
nvm.liquid.name = name
nvm.liquid.amount = amount
@ -210,10 +210,9 @@ function networks.liquid.srv_put(nvm, name, amount, capa)
end
function networks.liquid.srv_take(nvm, name, amount)
assert(amount and amount >= 0)
amount = math.floor((amount or 0) + 0.5)
nvm.liquid = nvm.liquid or {}
amount = amount or 0
if not name or nvm.liquid.name == name then
name = nvm.liquid.name
nvm.liquid.amount = nvm.liquid.amount or 0

View File

@ -184,4 +184,6 @@ optional: farming redo, node_io, doc, techage, minecart, xdecor, compost
- 2021-05-04 v1.08 * Add print command, improve error msg
- 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
- 2022-03-19 V1.11 * Extend farming (and add ethereal) support (Thanks to nixnoxus)

View File

@ -417,6 +417,10 @@ minetest.register_node("signs_bot:box", {
end,
after_place_node = function(pos, placer, itemstack)
if not placer or not placer:is_player() then
minetest.remove_node(pos)
minetest.add_item(pos, itemstack)
end
local mem = tubelib2.init_mem(pos)
mem.running = false
mem.error = false

View File

@ -19,9 +19,9 @@ local lib = signs_bot.lib
local bot_inv_put_item = signs_bot.bot_inv_put_item
local bot_inv_take_item = signs_bot.bot_inv_take_item
local function soil_availabe(pos)
local function soil_availabe(pos, trellis)
local node = minetest.get_node_or_nil(pos)
if node.name == "air" then
if node.name == (trellis or "air") then
node = minetest.get_node_or_nil({x=pos.x, y=pos.y-1, z=pos.z})
if node and minetest.get_item_group(node.name, "soil") >= 1 then
return true
@ -33,13 +33,13 @@ end
local function planting(base_pos, mem, slot)
local pos = mem.pos_tbl and mem.pos_tbl[mem.steps]
mem.steps = (mem.steps or 1) + 1
if pos and lib.not_protected(base_pos, pos) and soil_availabe(pos) then
if pos and lib.not_protected(base_pos, pos) then
local stack = bot_inv_take_item(base_pos, slot, 1)
if stack and stack ~= "" then
local plant = stack:get_name()
if plant then
local item = signs_bot.FarmingSeed[plant]
if item then
if item and soil_availabe(pos, signs_bot.FarmingNeedTrellis[item]) then
if minetest.registered_nodes[item] then
local p2 = minetest.registered_nodes[item].place_param2 or 1
minetest.set_node(pos, {name = item, param2 = p2})
@ -87,10 +87,16 @@ local function harvesting(base_pos, mem)
if pos and lib.not_protected(base_pos, pos) then
local node = minetest.get_node_or_nil(pos)
if signs_bot.FarmingCrop[node.name] then
local trellis = signs_bot.FarmingKeepTrellis[node.name]
if trellis then
minetest.set_node(pos, {name = trellis})
elseif not trellis then
minetest.remove_node(pos)
end
-- Do not cache the result of get_node_drops; it is a probabilistic function!
local drops = minetest.get_node_drops(node.name)
for _,itemstring in ipairs(drops) do
if not trellis or trellis ~= itemstring then
local leftover = bot_inv_put_item(base_pos, 0, ItemStack(itemstring))
if leftover and leftover:get_count() > 0 then
signs_bot.lib.drop_items(mem.robot_pos, leftover)
@ -98,6 +104,7 @@ local function harvesting(base_pos, mem)
end
end
end
end
end
signs_bot.register_botcommand("harvest", {

View File

@ -1,4 +1,4 @@
name=signs_bot
depends = default,farming,basic_materials,tubelib2
optional_depends = node_io,techage,doc,minecart,bucket,fire,xdecor
optional_depends = node_io,techage,doc,minecart,bucket,fire,xdecor,ethereal
description = A robot controlled by signs

View File

@ -14,14 +14,20 @@
signs_bot.FarmingSeed = {}
signs_bot.FarmingCrop = {}
signs_bot.FarmingNeedTrellis = {}
signs_bot.FarmingKeepTrellis = {}
signs_bot.TreeSaplings = {}
-- inv_seed is the seed inventory name
-- plantlet is what has to be placed on the ground (stage 1)
-- crop is the farming crop in the final stage
function signs_bot.register_farming_plant(inv_seed, plantlet, crop)
function signs_bot.register_farming_plant(inv_seed, plantlet, crop, trellis)
signs_bot.FarmingCrop[crop] = true
signs_bot.FarmingSeed[inv_seed] = plantlet
if trellis then
signs_bot.FarmingNeedTrellis[plantlet] = trellis
signs_bot.FarmingKeepTrellis[crop] = trellis
end
end
-- inv_sapling is the sapling inventory name
@ -44,42 +50,27 @@ end
-- Farming Redo
-------------------------------------------------------------------------------
if farming.mod == "redo" then
fp("farming:seed_wheat", "farming:wheat_1", "farming:wheat_8")
fp("farming:seed_cotton", "farming:cotton_1", "farming:cotton_8")
fp("farming:carrot", "farming:carrot_1", "farming:carrot_8")
fp("farming:potato", "farming:potato_1", "farming:potato_4")
fp("farming:tomato", "farming:tomato_1", "farming:tomato_8")
fp("farming:cucumber", "farming:cucumber_1", "farming:cucumber_4")
fp("farming:corn", "farming:corn_1", "farming:corn_8")
fp("farming:coffee_beans", "farming:coffee_1", "farming:coffee_5")
fp("farming:melon_slice", "farming:melon_1", "farming:melon_8")
fp("farming:pumpkin_slice", "farming:pumpkin_1", "farming:pumpkin_8")
fp("farming:raspberries", "farming:raspberry_1", "farming:raspberry_4")
fp("farming:blueberries", "farming:blueberry_1", "farming:blueberry_4")
fp("farming:rhubarb", "farming:rhubarb_1", "farming:rhubarb_3")
fp("farming:beans", "farming:beanpole_1", "farming:beanpole_5")
fp("farming:grapes", "farming:grapes_1", "farming:grapes_8")
fp("farming:seed_barley", "farming:barley_1", "farming:barley_7")
fp("farming:chili_pepper", "farming:chili_1", "farming:chili_8")
fp("farming:seed_hemp", "farming:hemp_1", "farming:hemp_8")
fp("farming:seed_oat", "farming:oat_1", "farming:oat_8")
fp("farming:seed_rye", "farming:rye_1", "farming:rye_8")
fp("farming:seed_rice", "farming:rice_1", "farming:rice_8")
fp("farming:beetroot", "farming:beetroot_1", "farming:beetroot_5")
fp("farming:cocoa_beans", "farming:cocoa_1", "farming:cocoa_4")
fp("farming:garlic_clove", "farming:garlic_1", "farming:garlic_5")
fp("farming:onion", "farming:onion_1", "farming:onion_5")
fp("farming:pea_pod", "farming:pea_1", "farming:pea_5")
fp("farming:peppercorn", "farming:pepper_1", "farming:pepper_5")
fp("farming:pineapple_top", "farming:pineapple_1", "farming:pineapple_8")
local fp_grows = function(def, step)
local crop = def.crop .. "_" .. step
local node = minetest.registered_nodes[crop]
if node then
fp(def.seed, def.crop .. "_1", crop, def.trellis)
return node.groups and node.groups.growing
end
end
for name, def in pairs(farming.registered_plants) do
-- everything except cocoa (these can only be placed on jungletree)
if name ~= "farming:cocoa_beans" then
local step = def.steps
while fp_grows(def, step) do step = step + 1 end
end
end
end
-------------------------------------------------------------------------------
-- Ethereal Farming
-------------------------------------------------------------------------------
--fn("ethereal:strawberry_8", "ethereal:strawberry 2", "ethereal:strawberry 1")
--fn("ethereal:onion_5", "ethereal:wild_onion_plant 2", "ethereal:onion_1")
--fn("ethereal:willow_trunk", "ethereal:willow_trunk", "ethereal:willow_sapling")
--fn("ethereal:redwood_trunk", "ethereal:redwood_trunk", "ethereal:redwood_sapling")

View File

@ -121,3 +121,22 @@ minetest.register_node("signs_bot:robot_foot", {
},
sounds = default.node_sound_metal_defaults(),
})
minetest.register_lbm({
label = "[signs_bot] Remove lost robots",
name = "signs_bot:lost_robot_remove",
nodenames = {"signs_bot:robot"},
run_at_every_load = true,
action = function(pos, node)
local found = false
tubelib2.walk_over_all(function(npos, node, mem)
if node.name == "signs_bot:box" and mem.robot_pos and
vector.equals(pos, mem.robot_pos) then
found = true
end
end, "robot_pos")
if not found then
signs_bot.remove_robot({robot_pos = pos})
end
end
})

View File

@ -14,6 +14,7 @@
local S = minetest.get_translator("ta4_jetpack")
local liquid = networks.liquid
local LQD = function(pos) return (minetest.registered_nodes[tubelib2.get_node_lvm(pos).name] or {}).liquid end
local ta4_jetpack = {}
@ -334,11 +335,11 @@ local function load_fuel(itemstack, user, pointed_thing)
local newvalue
if user:get_player_control().sneak then -- back to tank?
local amount = math.min(value, FUEL_UNIT)
local rest = liquid.srv_put(nvm, "techage:hydrogen", amount, MAX_FUEL)
newvalue = value - amount + rest
local amount = math.max(math.min(value, FUEL_UNIT), 0)
local rest = liquid.srv_put(nvm, "techage:hydrogen", amount, LQD(pos).capa)
newvalue = value - (amount - rest)
else
local amount = math.min(FUEL_UNIT, MAX_FUEL - value)
local amount = math.max(math.min(FUEL_UNIT, MAX_FUEL - value), 0)
local taken = liquid.srv_take(nvm, "techage:hydrogen", amount)
newvalue = value + taken
end

View File

@ -2,12 +2,9 @@
Tech Age, a mod to go through 5 tech ages in search of wealth and power.
**Tech Age (techage) is the successor to TechPack V2, at first glance similar and yet completely different!**
![screenshot](https://github.com/joe7575/techage/blob/master/screenshot.png)
Important facts:
- techage is not backwards compatible and cannot be installed on a server together with TechPack
- techage is significantly more extensive, since additional mods are integrated
@ -22,6 +19,10 @@ Important facts:
In contrast to TechPack, the resources are more limited and it is much more difficult to pass all levels.
(no endless ore generation by means of cobble generators)
**Techage blocks store information outside of the block. This is for performance reasons.
If you move, place, or remove blocks with any tool, at best, only the information is lost.
In the worst case, the server crashes.**
[Manuals](https://github.com/joe7575/techage/wiki)
@ -75,11 +76,14 @@ For the installation of 'luarocks' (if not already available), see [luarocks](ht
Available worlds will be converted to 'lsqlite3', but there is no way back, so:
** Never disable 'lsqlite3' for a world that has already been used!**
**Never disable 'lsqlite3' for a world that has already been used!**
### History
**2022-06-06 V1.08**
- Native support for the mod Beduino added
**2022-01-22 V1.07**
- TA5 fusion reactor added

View File

@ -3,7 +3,7 @@
TechAge
=======
Copyright (C) 2019 Joachim Stolberg
Copyright (C) 2019-2022 Joachim Stolberg
AGPL v3
See LICENSE.txt for more information
@ -180,6 +180,15 @@ techage.register_node({"techage:chest_ta2", "techage:chest_ta3"}, {
return "unsupported"
end
end,
on_beduino_request_data = function(pos, src, topic, payload)
if topic == 131 then
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
return 0, {techage.get_inv_state_num(inv, "main")}
else
return 2, ""
end
end,
})
@ -412,6 +421,15 @@ techage.register_node({"techage:chest_ta4"}, {
return "unsupported"
end
end,
on_beduino_request_data = function(pos, src, topic, payload)
if topic == 131 then
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
return 0, {techage.get_inv_state_num(inv, "main")}
else
return 2, ""
end
end,
})
minetest.register_craft({

View File

@ -65,6 +65,10 @@ local names = networks.register_junction("techage:concentrator", 2/8, Boxes, Tub
end,
}, 27)
for _, name in ipairs(names) do
Tube:set_valid_sides(name, {"B", "R", "F", "L", "D", "U"})
end
techage.register_node(names, {
on_push_item = function(pos, in_dir, stack)
local push_dir = M(pos):get_int("push_dir")
@ -110,6 +114,10 @@ names = networks.register_junction("techage:ta4_concentrator", 2/8, Boxes, Tube,
end,
}, 27)
for _, name in ipairs(names) do
Tube:set_valid_sides(name, {"B", "R", "F", "L", "D", "U"})
end
techage.register_node(names, {
on_push_item = function(pos, in_dir, stack)
local push_dir = M(pos):get_int("push_dir")

View File

@ -3,7 +3,7 @@
TechAge
=======
Copyright (C) 2019 Joachim Stolberg
Copyright (C) 2019-2022 Joachim Stolberg
AGPL v3
See LICENSE.txt for more information
@ -34,6 +34,7 @@ local INFO = [[Turn port on/off or read its state: command = 'port', payload = r
--local Side2Color = {B="red", L="green", F="blue", R="yellow"}
local SlotColors = {"red", "green", "blue", "yellow"}
local SlotNumbers = {red = 1, green = 2, blue = 3, yellow = 4}
local Num2Ascii = {"B", "L", "F", "R"}
local FilterCache = {} -- local cache for filter settings
@ -383,16 +384,16 @@ end
-- techage command to turn on/off filter channels
local function change_filter_settings(pos, slot, val)
local slots = {["red"] = 1, ["green"] = 2, ["blue"] = 3, ["yellow"] = 4}
local meta = M(pos)
local filter = minetest.deserialize(meta:get_string("filter")) or {false,false,false,false}
local num = slots[slot] or 1
local num = SlotNumbers[slot] or 1
if num >= 1 and num <= 4 then
filter[num] = val == "on"
end
meta:set_string("filter", minetest.serialize(filter))
filter_settings(pos)
local hash = minetest.hash_node_position(pos)
FilterCache[hash] = nil
local nvm = techage.get_nvm(pos)
meta:set_string("formspec", formspec(CRD(pos).State, pos, nvm))
@ -401,9 +402,45 @@ end
-- techage command to read filter channel status (on/off)
local function read_filter_settings(pos, slot)
local slots = {["red"] = 1, ["green"] = 2, ["blue"] = 3, ["yellow"] = 4}
local filter = minetest.deserialize(M(pos):get_string("filter")) or {false,false,false,false}
return filter[slots[slot]] and "on" or "off"
return filter[SlotNumbers[slot]] and "on" or "off"
end
local function get_payload_values(payload)
local color
local idx = 0
local items = {ItemStack(""), ItemStack(""), ItemStack(""), ItemStack(""), ItemStack(""), ItemStack("")}
for s in payload:gmatch("[^%s]+") do --- white spaces
if not color then
if SlotNumbers[s] then
color = s
else
return "red", {}
end
else
idx = idx + 1
if idx <= 6 then
items[idx] = ItemStack(s)
end
end
end
return color, items
end
local function str_of_inv_items(pos, color)
color = SlotColors[color] or color
if SlotNumbers[color] then
local inv = M(pos):get_inventory()
local t = {}
for idx = 1, 6 do
local item = inv:get_stack(color, idx)
if item:get_count() > 0 then
t[#t + 1] = item:get_name()
end
end
return table.concat(t, " ")
end
return ""
end
local function can_dig(pos, player)
@ -474,10 +511,47 @@ local tubing = {
else
return change_filter_settings(pos, slot, val)
end
elseif topic == "config" then
local color, items = get_payload_values(payload)
local inv = M(pos):get_inventory()
for idx,item in ipairs(items) do
inv:set_stack(color, idx, item)
end
local hash = minetest.hash_node_position(pos)
FilterCache[hash] = nil
return true
elseif topic == "get" then
return str_of_inv_items(pos, payload)
else
return CRD(pos).State:on_receive_message(pos, topic, payload)
end
end,
on_beduino_receive_cmnd = function(pos, src, topic, payload)
if topic == 4 then
local slot = SlotColors[payload[1]]
local state = payload[2] == 1 and "on" or "off"
change_filter_settings(pos, slot, state)
return 0
elseif topic == 67 then
local color, items = get_payload_values(payload)
local inv = M(pos):get_inventory()
for idx,item in ipairs(items) do
inv:set_stack(color, idx, item)
end
local hash = minetest.hash_node_position(pos)
FilterCache[hash] = nil
return 0
else
return CRD(pos).State:on_beduino_receive_cmnd(pos, topic, payload)
end
end,
on_beduino_request_data = function(pos, src, topic, payload)
if topic == 148 then
return 0, str_of_inv_items(pos, payload[1])
else
return CRD(pos).State:on_beduino_request_data(pos, topic, payload)
end
end,
on_node_load = function(pos)
CRD(pos).State:on_node_load(pos)
end,

View File

@ -3,7 +3,7 @@
TechAge
=======
Copyright (C) 2019-2020 Joachim Stolberg
Copyright (C) 2019-2022 Joachim Stolberg
AGPL v3
See LICENSE.txt for more information
@ -74,8 +74,9 @@ local function allow_metadata_inventory_take(pos, listname, index, stack, player
end
local function making(pos, crd, nvm, inv)
local owner = M(pos):get_string("owner")
local rtype = RecipeType[crd.stage]
local recipe = recipes.get(nvm, rtype)
local recipe = recipes.get(nvm, rtype, owner)
local output = ItemStack(recipe.output.name.." "..recipe.output.num)
if inv:room_for_item("dst", output) then
for _,item in ipairs(recipe.input) do
@ -202,6 +203,12 @@ local tubing = {
on_recv_message = function(pos, src, topic, payload)
return CRD(pos).State:on_receive_message(pos, topic, payload)
end,
on_beduino_receive_cmnd = function(pos, src, topic, payload)
return CRD(pos).State:on_beduino_receive_cmnd(pos, topic, payload)
end,
on_beduino_request_data = function(pos, src, topic, payload)
return CRD(pos).State:on_beduino_request_data(pos, topic, payload)
end,
on_node_load = function(pos)
CRD(pos).State:on_node_load(pos)
end,

View File

@ -91,13 +91,13 @@ local function set_pos_list(player, lPos)
meta:set_string("techage_forceload_blocks", minetest.serialize(lPos))
end
local function shoe_flbs(pos, name, range)
local function show_flbs(pos, name, range)
local pos1 = {x=pos.x-range, y=pos.y-range, z=pos.z-range}
local pos2 = {x=pos.x+range, y=pos.y+range, z=pos.z+range}
for _,npos in ipairs(minetest.find_nodes_in_area(pos1, pos2, {"techage:forceload", "techage:forceloadtile"})) do
local _pos1, _pos2 = calc_area(npos)
local owner = M(npos):get_string("owner")
techage.mark_region(name, _pos1, _pos2, owner)
techage.mark_region(name, _pos1, _pos2, owner .. " " .. P2S(npos))
end
end
@ -204,6 +204,7 @@ minetest.register_node("techage:forceload", {
paramtype = "light",
sunlight_propagates = true,
use_texture_alpha = techage.CLIP,
groups = {choppy=2, cracky=2, crumbly=2,
digtron_protected = 1,
not_in_creative_inventory = techage.max_num_forceload_blocks == 0 and 1 or 0},
@ -292,15 +293,11 @@ minetest.register_chatcommand("forceload", {
params = "",
description = S("Show all forceload blocks in a 64x64x64 range"),
func = function(name, param)
if minetest.check_player_privs(name, "superminer") then
local player = minetest.get_player_by_name(name)
if player then
local pos = player:get_pos()
pos = vector.round(pos)
shoe_flbs(pos, name, 64)
end
else
return false, S("Priv missing")
show_flbs(pos, name, 64)
end
end,
})

View File

@ -3,7 +3,7 @@
TechAge
=======
Copyright (C) 2019 Joachim Stolberg
Copyright (C) 2019-2022 Joachim Stolberg
AGPL v3
See LICENSE.txt for more information
@ -249,6 +249,12 @@ local tubing = {
on_recv_message = function(pos, src, topic, payload)
return CRD(pos).State:on_receive_message(pos, topic, payload)
end,
on_beduino_receive_cmnd = function(pos, src, topic, payload)
return CRD(pos).State:on_beduino_receive_cmnd(pos, topic, payload)
end,
on_beduino_request_data = function(pos, src, topic, payload)
return CRD(pos).State:on_beduino_request_data(pos, topic, payload)
end,
on_node_load = function(pos)
remove_objects({x=pos.x, y=pos.y+1, z=pos.z})
CRD(pos).State:on_node_load(pos)

View File

@ -3,7 +3,7 @@
TechAge
=======
Copyright (C) 2019-2021 Joachim Stolberg
Copyright (C) 2019-2022 Joachim Stolberg
AGPL v3
See LICENSE.txt for more information
@ -174,6 +174,12 @@ local tubing = {
on_recv_message = function(pos, src, topic, payload)
return CRD(pos).State:on_receive_message(pos, topic, payload)
end,
on_beduino_receive_cmnd = function(pos, src, topic, payload)
return CRD(pos).State:on_beduino_receive_cmnd(pos, topic, payload)
end,
on_beduino_request_data = function(pos, src, topic, payload)
return CRD(pos).State:on_beduino_request_data(pos, topic, payload)
end,
on_node_load = function(pos)
CRD(pos).State:on_node_load(pos)
end,

View File

@ -3,7 +3,7 @@
TechAge
=======
Copyright (C) 2019-2021 Joachim Stolberg
Copyright (C) 2019-2022 Joachim Stolberg
AGPL v3
See LICENSE.txt for more information
@ -56,7 +56,10 @@ local function allow_metadata_inventory_put(pos, listname, index, stack, player)
return 0
end
if listname == "src" then
CRD(pos).State:start_if_standby(pos)
local state = CRD(pos).State
if state then
state:start_if_standby(pos)
end
end
return stack:get_count()
end
@ -206,6 +209,12 @@ local tubing = {
on_recv_message = function(pos, src, topic, payload)
return CRD(pos).State:on_receive_message(pos, topic, payload)
end,
on_beduino_receive_cmnd = function(pos, src, topic, payload)
return CRD(pos).State:on_beduino_receive_cmnd(pos, topic, payload)
end,
on_beduino_request_data = function(pos, src, topic, payload)
return CRD(pos).State:on_beduino_request_data(pos, topic, payload)
end,
on_node_load = function(pos)
CRD(pos).State:on_node_load(pos)
end,

View File

@ -3,7 +3,7 @@
TechAge
=======
Copyright (C) 2019-2020 Joachim Stolberg
Copyright (C) 2019-2022 Joachim Stolberg
AGPL v3
See LICENSE.txt for more information
@ -173,6 +173,12 @@ local tubing = {
on_recv_message = function(pos, src, topic, payload)
return CRD(pos).State:on_receive_message(pos, topic, payload)
end,
on_beduino_receive_cmnd = function(pos, src, topic, payload)
return CRD(pos).State:on_beduino_receive_cmnd(pos, topic, payload)
end,
on_beduino_request_data = function(pos, src, topic, payload)
return CRD(pos).State:on_beduino_request_data(pos, topic, payload)
end,
}
local node_name_ta2, node_name_ta3, _ =

View File

@ -3,7 +3,7 @@
TechAge
=======
Copyright (C) 2019 Joachim Stolberg
Copyright (C) 2019-2022 Joachim Stolberg
AGPL v3
See LICENSE.txt for more information
@ -181,6 +181,12 @@ local function can_start(pos, nvm, state)
end
local function config_item(pos, payload)
if type(payload) == "string" then
if payload == "" then
local inv = M(pos):get_inventory()
inv:set_stack("main", 1, nil)
return 0
else
local name, count = unpack(payload:split(" "))
if name and (minetest.registered_nodes[name] or minetest.registered_items[name]
or minetest.registered_craftitems[name]) then
@ -189,6 +195,8 @@ local function config_item(pos, payload)
inv:set_stack("main", 1, {name = name, count = 1})
return count
end
end
end
return 0
end
@ -256,6 +264,24 @@ local tubing = {
return CRD(pos).State:on_receive_message(pos, topic, payload)
end
end,
on_beduino_receive_cmnd = function(pos, src, topic, payload)
if topic == 64 then -- Start pusher
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)
CRD(pos).State:stop(pos, nvm)
config_item(pos, payload)
CRD(pos).State:start(pos, nvm)
return 0
else
return CRD(pos).State:on_beduino_receive_cmnd(pos, topic, payload)
end
end,
}
local node_name_ta2, node_name_ta3, node_name_ta4 =

View File

@ -3,7 +3,7 @@
TechAge
=======
Copyright (C) 2019-2020 Joachim Stolberg
Copyright (C) 2019-2022 Joachim Stolberg
AGPL v3
See LICENSE.txt for more information
@ -368,6 +368,17 @@ local tubing = {
return CRD(pos).State:on_receive_message(pos, topic, payload)
end
end,
on_beduino_receive_cmnd = function(pos, src, topic, payload)
return CRD(pos).State:on_beduino_receive_cmnd(pos, topic, payload)
end,
on_beduino_request_data = function(pos, src, topic, payload)
if topic == 133 then -- Quarry Depth
local nvm = techage.get_nvm(pos)
return 0, {nvm.level or 0}
else
return CRD(pos).State:on_beduino_request_data(pos, topic, payload)
end
end,
on_node_load = function(pos)
CRD(pos).State:on_node_load(pos)
end,

View File

@ -3,7 +3,7 @@
TechAge
=======
Copyright (C) 2019-2021 Joachim Stolberg
Copyright (C) 2019-2022 Joachim Stolberg
AGPL v3
See LICENSE.txt for more information
@ -45,7 +45,7 @@ local SpecialItems = {
["dye:black"] = "",
["techage:basalt_glass_thin"] = "",
["group:stone"] = "techage:sieved_gravel",
["basic_materials:plastic_sheet"] = "",
--["basic_materials:plastic_sheet"] = "",
["group:wood"] = "default:stick 5",
["techage:basalt_glass"] = "",
["default:junglewood"] = "default:stick 5",
@ -235,6 +235,12 @@ local tubing = {
on_recv_message = function(pos, src, topic, payload)
return CRD(pos).State:on_receive_message(pos, topic, payload)
end,
on_beduino_receive_cmnd = function(pos, src, topic, payload)
return CRD(pos).State:on_beduino_receive_cmnd(pos, topic, payload)
end,
on_beduino_request_data = function(pos, src, topic, payload)
return CRD(pos).State:on_beduino_request_data(pos, topic, payload)
end,
on_node_load = function(pos)
CRD(pos).State:on_node_load(pos)
end,

View File

@ -3,7 +3,7 @@
TechAge
=======
Copyright (C) 2020 Joachim Stolberg
Copyright (C) 2019-2022 Joachim Stolberg
AGPL v3
See LICENSE.txt for more information
@ -92,6 +92,18 @@ local function inv_state(nvm)
return "loaded"
end
local function inv_state_num(nvm)
local num = 0
for _,item in ipairs(nvm.inventory or {}) do
if item.count and item.count > 0 then
num = num + 1
end
end
if num == 0 then return 0 end
if num == 8 then return 2 end
return 1
end
local function max_stacksize(item_name)
-- It is sufficient to use minetest.registered_items as all registration
-- functions (node, craftitems, tools) add the definitions there.
@ -324,12 +336,17 @@ local function count_number_of_chests(pos)
local node = techage.get_node_lvm(pos)
local dir = techage.side_to_outdir("B", node.param2)
local pos1 = tubelib2.get_pos(pos, dir)
local param2 = node.param2
local cnt = 1
while cnt < 50 do
node = techage.get_node_lvm(pos1)
if node.name ~= "techage:ta4_chest_dummy" then
break
end
local meta = M(pos1)
if meta:contains("param2") and meta:get_int("param2") ~= param2 then
break
end
pos1 = tubelib2.get_pos(pos1, dir)
cnt = cnt + 1
end
@ -339,12 +356,17 @@ end
local function search_chest_in_front(pos, node)
local dir = techage.side_to_outdir("F", node.param2)
local pos1 = tubelib2.get_pos(pos, dir)
local param2 = node.param2
local cnt = 1
while cnt < 50 do
node = techage.get_node_lvm(pos1)
if node.name ~= "techage:ta4_chest_dummy" then
break
end
local meta = M(pos1)
if meta:contains("param2") and meta:get_int("param2") ~= param2 then
break
end
pos1 = tubelib2.get_pos(pos1, dir)
cnt = cnt + 1
end
@ -517,6 +539,7 @@ minetest.register_node("techage:ta4_chest", {
if search_chest_in_front(pos, node) then
node.name = "techage:ta4_chest_dummy"
minetest.swap_node(pos, node)
M(pos):set_int("param2", node.param2)
else
local nvm = techage.get_nvm(pos)
gen_inv(nvm)
@ -597,10 +620,10 @@ techage.register_node({"techage:ta4_chest"}, {
on_recv_message = function(pos, src, topic, payload)
if topic == "count" then
local nvm = techage.get_nvm(pos)
return get_count(nvm, tonumber(payload) or 0)
return get_count(nvm, tonumber(payload or 1) or 1)
elseif topic == "itemstring" then
local nvm = techage.get_nvm(pos)
return get_itemstring(nvm, tonumber(payload) or 0)
return get_itemstring(nvm, tonumber(payload or 1) or 1)
elseif topic == "state" then
local nvm = techage.get_nvm(pos)
return inv_state(nvm)
@ -608,6 +631,20 @@ techage.register_node({"techage:ta4_chest"}, {
return "unsupported"
end
end,
on_beduino_request_data = function(pos, src, topic, payload)
if topic == 140 and payload[1] == 1 then -- Inventory Item Count
local nvm = techage.get_nvm(pos)
return 0, {get_count(nvm, tonumber(payload[2] or 1) or 1)}
elseif topic == 140 and payload[1] == 2 then -- Inventory Item Name
local nvm = techage.get_nvm(pos)
return 0, get_itemstring(nvm, tonumber(payload[2] or 1) or 1)
elseif topic == 131 then -- Chest State
local nvm = techage.get_nvm(pos)
return 0, {inv_state_num(nvm)}
else
return 2, ""
end
end,
})
techage.register_node({"techage:ta4_chest_dummy"}, {

View File

@ -3,7 +3,7 @@
TechAge
=======
Copyright (C) 2020 Joachim Stolberg
Copyright (C) 2019-2022 Joachim Stolberg
AGPL v3
See LICENSE.txt for more information
@ -242,6 +242,12 @@ local tubing = {
on_recv_message = function(pos, src, topic, payload)
return CRD(pos).State:on_receive_message(pos, topic, payload)
end,
on_beduino_receive_cmnd = function(pos, src, topic, payload)
return CRD(pos).State:on_beduino_receive_cmnd(pos, topic, payload)
end,
on_beduino_request_data = function(pos, src, topic, payload)
return CRD(pos).State:on_beduino_request_data(pos, topic, payload)
end,
on_node_load = function(pos)
CRD(pos).State:on_node_load(pos)
end,

View File

@ -175,6 +175,15 @@ techage.register_node({"techage:ta5_hl_chest"}, {
return "unsupported"
end
end,
on_beduino_request_data = function(pos, src, topic, payload)
if topic == 131 then -- Chest State
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
return 0, {techage.get_inv_state_num(inv, "main")}
else
return 2, ""
end
end,
})

View File

@ -173,13 +173,14 @@ local function remove_inv(pos, inv, param2, AssemblyPlan, player_name, idx)
if inv:room_for_item("src", stack) then
local node = minetest.get_node(pos1)
if node.name == node_name then
local meta = M(pos1):to_table()
minetest.remove_node(pos1)
inv:add_item("src", stack)
play_sound(pos, "default_dig_cracky")
local ndef = minetest.registered_nodes[node_name]
if ndef and ndef.after_dig_node then
local digger = minetest.get_player_by_name(player_name)
ndef.after_dig_node(pos1, pos, ItemStack(node_name), {}, digger)
ndef.after_dig_node(pos1, node, meta, digger)
end
end
end

View File

@ -406,6 +406,33 @@ function techage.transfer(pos, outdir, topic, payload, network, nodenames)
return false
end
-------------------------------------------------------------------
-- Beduino functions (see "bep-005_ta_cmnd.md")
-------------------------------------------------------------------
function techage.beduino_send_cmnd(src, number, topic, payload)
--print("beduino_send_cmnd", src, number, topic)
local ninfo = NodeInfoCache[number] or update_nodeinfo(number)
if ninfo and ninfo.name and ninfo.pos then
local ndef = NodeDef[ninfo.name]
if ndef and ndef.on_beduino_receive_cmnd then
return ndef.on_beduino_receive_cmnd(ninfo.pos, src, topic, payload or {})
end
end
return 1, ""
end
function techage.beduino_request_data(src, number, topic, payload)
--print("beduino_request_data", src, number, topic)
local ninfo = NodeInfoCache[number] or update_nodeinfo(number)
if ninfo and ninfo.name and ninfo.pos then
local ndef = NodeDef[ninfo.name]
if ndef and ndef.on_beduino_request_data then
return ndef.on_beduino_request_data(ninfo.pos, src, topic, payload or {})
end
end
return 1, ""
end
-------------------------------------------------------------------
-- Client side Push/Pull item functions
-------------------------------------------------------------------
@ -564,6 +591,23 @@ function techage.get_inv_state(inv, listname)
return state
end
-- Beduino variant
function techage.get_inv_state_num(inv, listname)
local state
if inv:is_empty(listname) then
state = 0
else
local list = inv:get_list(listname)
state = 2
for _, item in ipairs(list) do
if item:is_empty() then
return 1
end
end
end
return state
end
minetest.register_chatcommand("ta_send", {
description = minetest.formspec_escape(
"Send a techage command to the block with the number given: /ta_send <number> <command> [<data>]"),

View File

@ -134,13 +134,39 @@ local function dest_offset(lpath)
return offs
end
-------------------------------------------------------------------------------
-- Protect the doors from being opened by hand
-------------------------------------------------------------------------------
local function new_on_rightclick(old_on_rightclick)
return function(pos, node, clicker, itemstack, pointed_thing)
if M(pos):contains("ta_door_locked") then
return itemstack
end
if old_on_rightclick then
return old_on_rightclick(pos, node, clicker, itemstack, pointed_thing)
else
return itemstack
end
end
end
function flylib.protect_door_from_being_opened(name)
-- Change on_rightclick function.
local ndef = minetest.registered_nodes[name]
if ndef then
local old_on_rightclick = ndef.on_rightclick
minetest.override_item(ndef.name, {
on_rightclick = new_on_rightclick(old_on_rightclick)
})
end
end
-------------------------------------------------------------------------------
-- Entity / Move / Attach / Detach
-------------------------------------------------------------------------------
local MIN_SPEED = 0.4
local MAX_SPEED = 8
local CORNER_SPEED = 4
local SimpleNodes = techage.logic.SimpleNodes
local function calc_speed(v)
return math.sqrt(v.x * v.x + v.y * v.y + v.z * v.z)
@ -292,8 +318,7 @@ local function entity_to_node(pos, obj)
local nvm = techage.get_nvm(self.base_pos)
nvm.running = nil
end
obj:remove()
minetest.after(0.1, obj.remove, obj)
local node = minetest.get_node(pos)
local ndef1 = minetest.registered_nodes[name]
local ndef2 = minetest.registered_nodes[node.name]
@ -303,6 +328,7 @@ local function entity_to_node(pos, obj)
minetest.set_node(pos, {name=name, param2=param2})
meta:from_table(metadata)
meta:set_string("ta_move_block", "")
meta:set_int("ta_door_locked", 1)
return
end
local meta = M(pos)
@ -326,11 +352,14 @@ local function node_to_entity(start_pos)
node = minetest.deserialize(meta:get_string("ta_move_block"))
metadata = {}
meta:set_string("ta_move_block", "")
else
meta:set_string("ta_block_locked", "true")
elseif not meta:contains("ta_block_locked") then
-- Block with other metadata
node = minetest.get_node(start_pos)
metadata = meta:to_table()
minetest.remove_node(start_pos)
minetest.after(0.1, minetest.remove_node, start_pos)
else
return
end
local obj = minetest.add_entity(start_pos, "techage:move_item")
if obj then
@ -388,13 +417,14 @@ end
-- Handover the entity to the next movecontroller
local function handover_to(obj, self, pos1)
if self.handover then
local info = techage.get_node_info(self.handover)
if info and info.name == "techage:ta4_movecontroller" then
local meta = M(info.pos)
if self.move2to1 then
self.handover = meta:contains("handoverA") and meta:get_string("handoverA")
self.handover = meta:contains("handoverA") and meta:get_string("handoverA") or nil
else
self.handover = meta:contains("handoverB") and meta:get_string("handoverB")
self.handover = meta:contains("handoverB") and meta:get_string("handoverB") or nil
end
self.lpath = flylib.to_path(meta:get_string("path"))
@ -420,6 +450,7 @@ local function handover_to(obj, self, pos1)
return true
end
end
end
end
minetest.register_entity("techage:move_item", {
@ -473,7 +504,7 @@ minetest.register_entity("techage:move_item", {
self.object:set_properties({wield_item = self.item})
--print("tbl.respawn", tbl.respawn)
if tbl.respawn then
entity_to_node(self.start_pos, self.object)
entity_to_node(self.dest_pos, self.object)
end
end
end,
@ -552,8 +583,7 @@ minetest.register_entity("techage:move_item", {
local function is_valid_dest(pos)
local node = minetest.get_node(pos)
local ndef = minetest.registered_nodes[node.name]
if ndef and ndef.buildable_to then
if techage.is_air_like(node.name) then
return true
end
if not M(pos):contains("ta_move_block") then
@ -563,20 +593,9 @@ local function is_valid_dest(pos)
end
local function is_simple_node(pos)
-- special handling
local name = minetest.get_node(pos).name
if SimpleNodes[name] ~= nil then
return SimpleNodes[name]
end
local ndef = minetest.registered_nodes[name]
if not ndef or name == "air" or name == "ignore" then return false end
-- don't remove nodes with some intelligence or undiggable nodes
if ndef.drop == "" then return false end
if ndef.diggable == false then return false end
if ndef.after_dig_node then return false end
return true
local node = minetest.get_node(pos)
local ndef = minetest.registered_nodes[node.name]
return not techage.is_air_like(node.name) and techage.can_dig_node(node.name, ndef)
end
local function move_node(pos, pos1_idx, start_pos, lpath, max_speed, height, move2to1, handover, cpos)
@ -649,6 +668,43 @@ local function move_nodes(pos, meta, nvm, lpath, max_speed, height, move2to1, ha
return true
end
-- Move nodes from lpos1 by the given x/y/z 'line'
local function move_nodes2(pos, meta, lpos1, line, max_speed, height)
--print("move_nodes2", dump(lpos1), dump(line), max_speed, height)
local owner = meta:get_string("owner")
techage.counting_add(owner, #lpos1)
local lpos2 = {}
for idx = 1, #lpos1 do
local pos1 = lpos1[idx]
local pos2 = vector.add(lpos1[idx], line)
lpos2[idx] = pos2
if not minetest.is_protected(pos1, owner) and not minetest.is_protected(pos2, owner) then
if is_simple_node(pos1) and is_valid_dest(pos2) then
move_node(pos, idx, pos1, {line}, max_speed, height, false, false)
else
if not is_simple_node(pos1) then
meta:set_string("status", S("No valid node at the start position"))
else
meta:set_string("status", S("No valid destination position"))
end
end
else
if minetest.is_protected(pos1, owner) then
meta:set_string("status", S("Start position is protected"))
else
meta:set_string("status", S("Destination position is protected"))
end
return false, lpos1
end
end
meta:set_string("status", "")
return true, lpos2
end
function flylib.move_to_other_pos(pos, move2to1)
local meta = M(pos)
local nvm = techage.get_nvm(pos)
@ -671,13 +727,36 @@ function flylib.move_to_other_pos(pos, move2to1)
nvm.lpos2 = lvect_add_vec(nvm.lpos1, offs)
if move2to1 then
handover = meta:contains("handoverA") and meta:get_string("handoverA")
handover = meta:contains("handoverA") and meta:get_string("handoverA") or nil
else
handover = meta:contains("handoverB") and meta:get_string("handoverB")
handover = meta:contains("handoverB") and meta:get_string("handoverB") or nil
end
return move_nodes(pos, meta, nvm, lpath, max_speed, height, move2to1, handover)
end
function flylib.move_to(pos, line)
local meta = M(pos)
local nvm = techage.get_nvm(pos)
local height = techage.in_range(meta:contains("height") and meta:get_float("height") or 1, 0, 1)
local max_speed = meta:contains("max_speed") and meta:get_int("max_speed") or MAX_SPEED
local resp
resp, nvm.lastpos = move_nodes2(pos, meta, nvm.lastpos or nvm.lpos1, line, max_speed, height)
return resp
end
function flylib.reset_move(pos)
local meta = M(pos)
local nvm = techage.get_nvm(pos)
local height = techage.in_range(meta:contains("height") and meta:get_float("height") or 1, 0, 1)
local max_speed = meta:contains("max_speed") and meta:get_int("max_speed") or MAX_SPEED
local move = vector.subtract(nvm.lpos1[1], (nvm.lastpos or nvm.lpos1)[1])
local resp
resp, nvm.lastpos = move_nodes2(pos, meta, nvm.lastpos or nvm.lpos1, move, max_speed, height)
return resp
end
-- rot is one of "l", "r", "2l", "2r"
-- cpos is the center pos (optional)
function flylib.rotate_nodes(pos, posses1, rot)
@ -712,6 +791,39 @@ function flylib.rotate_nodes(pos, posses1, rot)
return posses2
end
function flylib.exchange_node(pos, name, param2)
local meta = M(pos)
local move_block
-- consider stored "objects"
if meta:contains("ta_move_block") then
move_block = meta:get_string("ta_move_block")
end
minetest.swap_node(pos, {name = name, param2 = param2})
if move_block then
meta:set_string("ta_move_block", move_block)
end
end
function flylib.remove_node(pos)
local meta = M(pos)
local move_block
-- consider stored "objects"
if meta:contains("ta_move_block") then
move_block = meta:get_string("ta_move_block")
end
minetest.remove_node(pos)
if move_block then
local node = minetest.deserialize(move_block)
minetest.add_node(pos, node)
meta:set_string("ta_move_block", "")
end
end
minetest.register_on_joinplayer(function(player)
unlock_player(player)

View File

@ -57,8 +57,9 @@ local function get_remote_pos(pos, rmt_name)
end
local function get_free_server_list(pos, owner)
if Stations and Stations.get_node_table then
local tbl = {M(pos):get_string("remote_name")}
for key,item in pairs(Stations:get_node_table(pos)) do
for key,item in pairs(Stations:get_node_table(pos) or {}) do
if item.single and item.owner == owner then
if M(pos):get_string("node_type") == M(S2P(key)):get_string("node_type") then
tbl[#tbl+1] = item.conn_name
@ -67,6 +68,8 @@ local function get_free_server_list(pos, owner)
end
tbl[#tbl+1] = ""
return tbl
end
return {}
end
local function on_lose_connection(pos, node_type)
@ -78,8 +81,11 @@ local function on_lose_connection(pos, node_type)
end
local function on_dropdown(pos)
if pos then
local owner = M(pos):get_string("owner")
return table.concat(get_free_server_list(pos, owner), ",")
return table.concat(get_free_server_list(pos, owner), ",") or ""
end
return ""
end
local function update_node_data(pos, state, conn_name, remote_name, rmt_pos)

View File

@ -76,7 +76,7 @@ for _,row in ipairs(ROTATION) do
end
function techage.facedir_to_rotation(facedir)
return FACEDIR_TO_ROT[facedir]
return FACEDIR_TO_ROT[facedir] or FACEDIR_TO_ROT[0]
end
function techage.param2_turn_left(param2)
@ -129,7 +129,6 @@ function techage.param2_turn_up(facedir, param2)
end
-------------------------------------------------------------------------------
-- Rotate nodes around the center
-------------------------------------------------------------------------------
@ -181,12 +180,12 @@ function techage.rotate_around_center(nodes1, turn, cpos)
return nodes2
end
-- allowed for digging
local RegisteredNodesToBeDug = {}
function techage.register_node_to_be_dug(name)
RegisteredNodesToBeDug[name] = true
end
-------------------------------------------------------------------------------
-- Helper functions
-------------------------------------------------------------------------------
-- allowed for digging
local SimpleNodes = {}
-- translation from param2 to dir (out of the node upwards)
local Param2Dir = {}
@ -244,6 +243,17 @@ function techage.add_to_set(set, x)
end
end
-- techage.tbl_filter({"a", "b", "c", "d"}, function(v, k, t) return v >= "c" end) --> {"c","d"}
techage.tbl_filter = function(t, filterIter)
local out = {}
for k, v in pairs(t) do
if filterIter(v, k, t) then out[k] = v end
end
return out
end
function techage.get_node_lvm(pos)
local node = minetest.get_node_or_nil(pos)
if node then
@ -273,19 +283,52 @@ function techage.is_air_like(name)
end
-- returns true, if node can be dug, otherwise false
function techage.can_node_dig(node, ndef)
if RegisteredNodesToBeDug[node.name] then
function techage.can_dig_node(name, ndef)
if not ndef then return false end
if SimpleNodes[name] ~= nil then
return SimpleNodes[name]
end
if ndef.groups and ndef.groups.techage_door == 1 then
SimpleNodes[name] = true
return true
end
if not ndef then return false end
if node.name == "ignore" then return false end
if node.name == "air" then return true end
if ndef.buildable_to == true then return true end
if ndef.diggable == false then return false end
if ndef.after_dig_node then return false end
-- add it to the white list
RegisteredNodesToBeDug[node.name] = true
if name == "ignore" then
SimpleNodes[name] = false
return false
end
if name == "air" then
SimpleNodes[name] = true
return true
end
if ndef.buildable_to == true then
SimpleNodes[name] = true
return true
end
-- don't remove nodes with some intelligence or undiggable nodes
if ndef.drop == "" then
SimpleNodes[name] = false
return false
end
if ndef.diggable == false then
SimpleNodes[name] = false
return false
end
if ndef.after_dig_node then
SimpleNodes[name] = false
return false
end
-- add it to the white list
SimpleNodes[name] = true
return true
end
-- Simple nodes
function techage.register_simple_nodes(node_names, is_valid)
if is_valid == nil then is_valid = true end
for _,name in ipairs(node_names or {}) do
SimpleNodes[name] = is_valid
end
end
techage.dig_states = {
@ -421,50 +464,6 @@ function techage.item_image_small(x, y, itemname, tooltip_prefix)
tooltip
end
function techage.mydump(o, indent, nested, level)
local t = type(o)
if not level and t == "userdata" then
-- when userdata (e.g. player) is passed directly, print its metatable:
return "userdata metatable: " .. techage.mydump(getmetatable(o))
end
if t ~= "table" then
return basic_dump(o)
end
-- Contains table -> true/nil of currently nested tables
nested = nested or {}
if nested[o] then
return "<circular reference>"
end
nested[o] = true
indent = " "
level = level or 1
local t = {}
local dumped_indexes = {}
for i, v in ipairs(o) do
t[#t + 1] = techage.mydump(v, indent, nested, level + 1)
dumped_indexes[i] = true
end
for k, v in pairs(o) do
if not dumped_indexes[k] then
if type(k) ~= "string" or not is_valid_identifier(k) then
k = "["..techage.mydump(k, indent, nested, level + 1).."]"
end
v = techage.mydump(v, indent, nested, level + 1)
t[#t + 1] = k.." = "..v
end
end
nested[o] = nil
if indent ~= "" then
local indent_str = string.rep(indent, level)
local end_indent_str = string.rep(indent, level - 1)
return string.format("{%s%s%s}",
indent_str,
table.concat(t, ","..indent_str),
end_indent_str)
end
return "{"..table.concat(t, ", ").."}"
end
function techage.vector_dump(posses)
local t = {}
for _,pos in ipairs(posses) do
@ -493,6 +492,10 @@ function techage.register_mobs_mods(mod)
techage.RegisteredMobsMods[mod] = true
end
function techage.beduino_signed_var(val)
val = val or 0
return val >= 32768 and val - 0x10000 or val
end
-------------------------------------------------------------------------------
-- Terminal history buffer
@ -561,6 +564,8 @@ function techage.add_expoint(player, number)
end
end
-- Delete number with: `//lua minetest.get_player_by_name("<name>"):get_meta():set_string("techage_collider_number", "")`
function techage.on_remove_collider(player)
if player and player.get_meta then
local meta = player:get_meta()

View File

@ -82,7 +82,7 @@ minetest.register_entity(":techage:region_cube", {
initial_properties = {
visual = "upright_sprite",
textures = {"techage_cube_mark.png"},
use_texture_alpha = true,
use_texture_alpha = techage.BLEND,
physical = false,
glow = 12,
},

View File

@ -70,7 +70,7 @@ minetest.register_entity(":techage:position_cube", {
"techage_cube_mark.png",
"techage_cube_mark.png",
},
use_texture_alpha = true,
use_texture_alpha = techage.BLEND,
physical = false,
visual_size = {x = 1.1, y = 1.1},
collisionbox = {-0.55,-0.55,-0.55, 0.55,0.55,0.55},

View File

@ -97,7 +97,6 @@ minetest.register_entity(":techage:block_marker", {
"techage_cube_mark.png",
"techage_cube_mark.png",
},
--use_texture_alpha = true,
physical = false,
visual_size = {x=1.1, y=1.1},
collisionbox = {-0.55,-0.55,-0.55, 0.55,0.55,0.55},

View File

@ -3,7 +3,7 @@
TechAge
=======
Copyright (C) 2019 Joachim Stolberg
Copyright (C) 2019-2022 Joachim Stolberg
AGPL v3
See LICENSE.txt for more information
@ -72,6 +72,8 @@ techage.STANDBY = 3 -- nothing to do (e.g. no input items), or node (world) not
techage.NOPOWER = 4 -- only for power consuming nodes, no operation
techage.FAULT = 5 -- any fault state (e.g. wrong source items), which can be fixed by the player
techage.STOPPED = 6 -- not operational/turned off
techage.UNLOADED = 7 -- Map block unloaded
techage.INACTIVE = 8 -- Map block loaded but node is not actively working
techage.StatesImg = {
"techage_inv_button_on.png",
@ -133,13 +135,15 @@ local function has_power(pos, nvm)
return true
end
local function swap_node(pos, name)
local function swap_node(pos, new_name, old_name)
local node = techage.get_node_lvm(pos)
if node.name == name then
if node.name == new_name then
return
end
node.name = name
if node.name == old_name then
node.name = new_name
minetest.swap_node(pos, node)
end
end
-- true if node_timer should be executed
@ -220,7 +224,7 @@ function NodeStates:stop(pos, nvm)
self.stop_node(pos, nvm, state)
end
if self.node_name_passive then
swap_node(pos, self.node_name_passive)
swap_node(pos, self.node_name_passive, self.node_name_active)
end
if self.infotext_name then
local number = M(pos):get_string("node_number")
@ -257,7 +261,7 @@ function NodeStates:start(pos, nvm)
end
nvm.techage_countdown = self.countdown_ticks
if self.node_name_active then
swap_node(pos, self.node_name_active)
swap_node(pos, self.node_name_active, self.node_name_passive)
end
if self.infotext_name then
local number = M(pos):get_string("node_number")
@ -288,7 +292,7 @@ function NodeStates:standby(pos, nvm, err_string)
if state == RUNNING or state == BLOCKED then
nvm.techage_state = STANDBY
if self.node_name_passive then
swap_node(pos, self.node_name_passive)
swap_node(pos, self.node_name_passive, self.node_name_active)
end
if self.infotext_name then
local number = M(pos):get_string("node_number")
@ -313,7 +317,7 @@ function NodeStates:blocked(pos, nvm, err_string)
if state == RUNNING then
nvm.techage_state = BLOCKED
if self.node_name_passive then
swap_node(pos, self.node_name_passive)
swap_node(pos, self.node_name_passive, self.node_name_active)
end
if self.infotext_name then
local number = M(pos):get_string("node_number")
@ -337,7 +341,7 @@ function NodeStates:nopower(pos, nvm, err_string)
if state ~= NOPOWER then
nvm.techage_state = NOPOWER
if self.node_name_passive then
swap_node(pos, self.node_name_passive)
swap_node(pos, self.node_name_passive, self.node_name_active)
end
if self.infotext_name then
local number = M(pos):get_string("node_number")
@ -362,7 +366,7 @@ function NodeStates:fault(pos, nvm, err_string)
if state == RUNNING or state == STOPPED then
nvm.techage_state = FAULT
if self.node_name_passive then
swap_node(pos, self.node_name_passive)
swap_node(pos, self.node_name_passive, self.node_name_active)
end
if self.infotext_name then
local number = M(pos):get_string("node_number")
@ -479,6 +483,40 @@ function NodeStates:on_receive_message(pos, topic, payload)
end
end
function NodeStates:on_beduino_receive_cmnd(pos, topic, payload)
if topic == 1 then
if payload[1] == 0 then
self:stop(pos, techage.get_nvm(pos))
return 0
else
self:start(pos, techage.get_nvm(pos))
return 0
end
else
return 2 -- unknown or invalid topic
end
end
function NodeStates:on_beduino_request_data(pos, topic, payload)
local nvm = techage.get_nvm(pos)
if topic == 128 then
return 0, techage.get_node_lvm(pos).name
elseif topic == 129 then
local node = minetest.get_node(pos)
if node.name == "ignore" then -- unloaded node?
return 0, {techage.UNLOADED}
elseif nvm.techage_state == RUNNING then
local ttl = (nvm.last_active or 0) + 2 * (self.cycle_time or 0)
if ttl < minetest.get_gametime() then
return 0, {techage.INACTIVE}
end
end
return 0, {nvm.techage_state or STOPPED}
else
return 2, "" -- topic is unknown or invalid
end
end
-- restart timer
function NodeStates:on_node_load(pos)
local nvm = techage.get_nvm(pos)

View File

@ -71,7 +71,7 @@ end
-------------------------------------------------------------------
-- Storage scheduler
-------------------------------------------------------------------
local CYCLE_TIME = 900 -- store data every 15 min
local CYCLE_TIME = 600 -- store data every 10 min
local JobQueue = {}
local first = 0
local last = -1

View File

@ -74,9 +74,12 @@ local function input_string(recipe)
return table.concat(tbl, "")
end
function techage.recipes.get(nvm, rtype)
function techage.recipes.get(nvm, rtype, owner)
local recipes = Recipes[rtype] or {}
return recipes[nvm.recipe_idx or 1]
if owner then
recipes = filter_recipes_based_on_points(recipes, owner)
end
return recipes[nvm.recipe_idx or 1] or recipes[1]
end
-- Add 4 input/output/waste recipe

View File

@ -101,7 +101,7 @@ local function generate_formspec_substring(pos, meta, form_def, player_name)
elseif elem.type == "dropdown" then
local l = elem.choices:split(",")
if nvm.running or techage.is_running(nvm) then
local val = elem.default
local val = elem.default or ""
if meta:contains(elem.name) then
val = meta:get_string(elem.name) or ""
end

View File

@ -0,0 +1,60 @@
--[[
TechAge
=======
Copyright (C) 2019-2022 Joachim Stolberg
AGPL v3
See LICENSE.txt for more information
K/V Store for the Beduino controller
]]--
local COSTS = 400
local function ta_kv_init(cpu_pos, address, regA, regB, regC)
local nvm = techage.get_nvm(cpu_pos)
nvm.kv_store = {}
return 1, COSTS
end
local function ta_kv_add(cpu_pos, address, regA, regB, regC)
local nvm = techage.get_nvm(cpu_pos)
local text = vm16.read_ascii(cpu_pos, regA, 32)
nvm.kv_store[text] = regB
return 1, COSTS
end
local function ta_kv_get(cpu_pos, address, regA, regB, regC)
local nvm = techage.get_nvm(cpu_pos)
local text = vm16.read_ascii(cpu_pos, regA, 32)
return nvm.kv_store[text] or 0, COSTS
end
local kvstore_c = [[
// Initialize the key/value store
func ta_kv_init() {
return system(0x140, 0);
}
// Add a key/value pair to the store
func ta_kv_add(key_str, value) {
return system(0x141, key_str, value);
}
// Returns the value for the given key string
func ta_kv_get(key_str) {
return system(0x142, key_str);
}
]]
minetest.register_on_mods_loaded(function()
if minetest.global_exists("beduino") and minetest.global_exists("vm16") then
beduino.lib.register_SystemHandler(0x140, ta_kv_init)
beduino.lib.register_SystemHandler(0x141, ta_kv_add)
beduino.lib.register_SystemHandler(0x142, ta_kv_get)
vm16.register_ro_file("beduino", "ta_kvstore.c", kvstore_c)
end
end)

View File

@ -3,7 +3,7 @@
TechAge
=======
Copyright (C) 2019-2020 Joachim Stolberg
Copyright (C) 2019-2022 Joachim Stolberg
AGPL v3
See LICENSE.txt for more information
@ -159,6 +159,15 @@ techage.register_node({"techage:chest_cart"}, {
return "unsupported"
end
end,
on_beduino_request_data = function(pos, src, topic, payload)
if topic == 131 then -- Chest State
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
return 0, {techage.get_inv_state_num(inv, "main")}
else
return 2, ""
end
end,
})
Tube:set_valid_sides("techage:chest_cart", {"L", "R", "F", "B"})

View File

@ -3,7 +3,7 @@
TechAge
=======
Copyright (C) 2019-2021 Joachim Stolberg
Copyright (C) 2019-2022 Joachim Stolberg
AGPL v3
See LICENSE.txt for more information
@ -360,6 +360,12 @@ techage.register_node({"techage:ta4_doser", "techage:ta4_doser_on"}, {
on_recv_message = function(pos, src, topic, payload)
return State:on_receive_message(pos, topic, payload)
end,
on_beduino_receive_cmnd = function(pos, src, topic, payload)
return State:on_beduino_receive_cmnd(pos, topic, payload)
end,
on_beduino_request_data = function(pos, src, topic, payload)
return State:on_beduino_request_data(pos, topic, payload)
end,
})
techage.recipes.register_craft_type("ta4_doser", {

View File

@ -3,7 +3,7 @@
TechAge
=======
Copyright (C) 2019-2020 Joachim Stolberg
Copyright (C) 2019-2022 Joachim Stolberg
AGPL v3
See LICENSE.txt for more information
@ -207,6 +207,18 @@ techage.register_node({"techage:coalfirebox"}, {
return "unsupported"
end
end,
on_beduino_request_data = function(pos, src, topic, payload)
local nvm = techage.get_nvm(pos)
if topic == 128 then
return 0, techage.get_node_lvm(pos).name
elseif topic == 129 then
return 0, {nvm.running and techage.RUNNING or techage.STOPPED}
elseif topic == 132 then
return 0, {techage.fuel.get_fuel_amount(nvm)}
else
return 2, ""
end
end,
})
minetest.register_craft({

View File

@ -3,7 +3,7 @@
TechAge
=======
Copyright (C) 2019-2021 Joachim Stolberg
Copyright (C) 2019-2022 Joachim Stolberg
AGPL v3
See LICENSE.txt for more information
@ -231,6 +231,17 @@ techage.register_node({"techage:generator", "techage:generator_on"}, {
return State:on_receive_message(pos, topic, payload)
end
end,
on_beduino_receive_cmnd = function(pos, src, topic, payload)
return State:on_beduino_receive_cmnd(pos, topic, payload)
end,
on_beduino_request_data = function(pos, src, topic, payload)
local nvm = techage.get_nvm(pos)
if topic == 135 then -- Delivered Power
return 0, {math.floor((nvm.provided or 0) + 0.5)}
else
return State:on_beduino_request_data(pos, topic, payload)
end
end,
})
-- used by power terminal

View File

@ -3,7 +3,7 @@
TechAge
=======
Copyright (C) 2019-2021 Joachim Stolberg
Copyright (C) 2019-2022 Joachim Stolberg
AGPL v3
See LICENSE.txt for more information
@ -132,6 +132,18 @@ techage.register_node({"techage:oilfirebox"}, {
return "unsupported"
end
end,
on_beduino_request_data = function(pos, src, topic, payload)
local nvm = techage.get_nvm(pos)
if topic == 128 then
return 0, techage.get_node_lvm(pos).name
elseif topic == 129 then
return 0, {nvm.running and techage.RUNNING or techage.STOPPED}
elseif topic == 132 then
return 0, {fuel.get_fuel_amount(nvm)}
else
return 2, ""
end
end,
})
minetest.register_craft({

View File

@ -21,7 +21,9 @@ local getpos = techage.assemble.get_pos
local CYCLE_TIME = 2
local TNO_MAGNETS = 22
local PROBABILITY = 180 -- check every 20 s => 20 * 180 * 50% = 30 min
local IMPROBABILITY = 60 -- every 60 min
-- one point per 60 min: check every 20 s => factor = 60 * 3 = 180
IMPROBABILITY = (minetest.settings:get("techage_expoint_rate_in_min") or 60) * 3
local TIME_SLOTS = 10
local Schedule = {[0] =
@ -59,7 +61,7 @@ local function terminal_message(pos, msg)
end
local function experience_points(pos)
if math.random(PROBABILITY) == 1 then
if math.random(IMPROBABILITY) == 1 then
local owner = M(pos):get_string("owner")
local own_num = M(pos):get_string("node_number")
local player = minetest.get_player_by_name(owner)

View File

@ -110,6 +110,7 @@ techage.Items = {
ta3_logic = "techage:ta3_logic",
ta3_nodedetector = "techage:ta3_nodedetector_off",
ta3_playerdetector = "techage:ta3_playerdetector_off",
ta3_lightdetector = "techage:ta3_lightdetector_off",
ta3_repeater = "techage:ta3_repeater",
ta3_sequencer = "techage:ta3_sequencer",
ta3_timer = "techage:ta3_timer",

View File

@ -124,6 +124,7 @@ techage.manual_DE.aTitel = {
"3,TA3 Wagen Detektor / Cart Detector",
"3,TA3 Block Detektor / Node Detector",
"3,TA3 Spieler Detektor / Player Detector",
"3,TA3 Lichtdetektor",
"2,TA3 Maschinen",
"3,TA3 Schieber / Pusher",
"3,TA3 Verteiler / Distributor",
@ -1145,9 +1146,15 @@ techage.manual_DE.aText = {
"\n"..
"Wird ein 'on' / 'off' Kommando an den Tür Controller II gesendet\\, entfernt bzw. setzt er die Blöcke ebenfalls.\n"..
"\n"..
"Über ein 'exchange' Kommando können einzelne Böcke gesetzt\\, entfernt\\, bzw. durch andere Blöcke ersetzt werden. Die Slot-Nummer des Inventars (1 .. 16) muss als payload übergeben werden\\, also:\n"..
"Mit '$send_cmnd(node_number\\, \"exchange\"\\, 2)' können einzelne Böcke gesetzt\\, entfernt\\, bzw. durch andere Blöcke aus dem Inventar ersetzt werden. \n"..
"\n"..
" $send_cmnd(node_number\\, \"exchange\"\\, 2)\n"..
"Mit '$send_cmnd(node_number\\, \"set\"\\, 2)' kann ein Block aus dem Inventory explizit gesetzt werden\\, sofern der Inventory Slot nicht leer ist.\n"..
"\n"..
"Mit '$send_cmnd(node_number\\, \"dig\"\\, 2)' kann ein Block wieder entfernt werden\\, sofern der Inventory Slot leer ist. \n"..
"\n"..
"Mit '$send_cmnd(node_number\\, \"get\"\\, 2)' wird der Name des gesetzten Blocks zurückgeliefert. \n"..
"\n"..
"Die Slot-Nummer des Inventars (1 .. 16) muss in allen drei Fällen als payload übergeben werden.\n"..
"\n"..
"Damit lassen sich auch ausfahrbare Treppen und ähnliches simulieren.\n"..
"\n"..
@ -1159,7 +1166,7 @@ techage.manual_DE.aText = {
"\n"..
" - Kommando 'on' zum Abspielen eines Sounds\n"..
" - Kommando 'sound <idx>' zur Auswahl eines Sounds über den Index\n"..
" - Kommando 'gain <volume>' zum Einstellen der Lautstärke über den '<volume>' Wert (0 bis 1.0).\n"..
" - Kommando 'gain <volume>' zum Einstellen der Lautstärke über den '<volume>' Wert (1 bis 5).\n"..
"\n"..
"\n"..
"\n",
@ -1198,6 +1205,11 @@ techage.manual_DE.aText = {
"\n"..
"\n"..
"\n",
"Der Lichtdetektor sendet einen 'on'-Kommando\\, wenn der Lichtpegel des darüber liegenden Blocks einen bestimmten Pegel überschreitet\\, der über das Rechtsklickmenü eingestellt werden kann.\n"..
"Mit einen TA4 Lua Controller kann die genaue Lichtstärke mit $get_cmd(num\\, 'light_level') ermitteln werden.\n"..
"\n"..
"\n"..
"\n",
"Bei TA3 existieren die gleichen Maschinen wie bei TA2\\, nur sind diese hier leistungsfähiger und benötigen Strom statt Achsenantrieb.\n"..
"Im folgenden sind daher nur die unterschiedlichen\\, technischen Daten angegeben.\n"..
"\n"..
@ -1680,6 +1692,7 @@ techage.manual_DE.aText = {
"\n"..
" - 'goto <num>' Zu einer Kommandozeile springen und damit den Sequenzer starten\n"..
" - 'stop' Den Sequenzer anhalten\n"..
" - 'on' und 'off' als Alias für 'goto 1' bzw. 'stop'\n"..
"\n"..
"Das 'goto' Kommando wird nur angenommen\\, wenn der Sequenzer gestoppt ist.\n"..
"\n"..
@ -1907,7 +1920,7 @@ techage.manual_DE.aText = {
"\n"..
"Der TA4 Schieber besitzt zwei zusätzliche Kommandos für den Lua Controller:\n"..
"\n"..
" - 'config' dient zur Konfiguration des Schiebers\\, analog zum manuellen Konfiguration über das Menü.\nBeispiel: '$send_cmnd(1234\\, \"config\"\\, \"default:dirt\")'\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"..
"\n"..
"\n"..
@ -2240,6 +2253,7 @@ techage.manual_DE.aItemName = {
"ta3_cartdetector",
"ta3_nodedetector",
"ta3_playerdetector",
"ta3_lightdetector",
"ta3_grinder",
"ta3_pusher",
"ta3_distributor",
@ -2511,6 +2525,7 @@ techage.manual_DE.aPlanTable = {
"",
"",
"",
"",
"ta4_windturbine",
"",
"",

View File

@ -124,6 +124,7 @@ techage.manual_EN.aTitel = {
"3,TA3 Cart Detector",
"3,TA3 Block Detector",
"3,TA3 Player Detector",
"3,TA3 Light Detector",
"2,TA3 Machines",
"3,TA3 Pusher",
"3,TA3 Distributor",
@ -1143,9 +1144,15 @@ techage.manual_EN.aText = {
"\n",
"The Door Controller II can remove and set all types of blocks. To teach in the Door Controller II\\, the \"Record\" button must be pressed. Then all blocks that should be part of the door / gate must be clicked. Then the \"Done\" button must be pressed. Up to 16 blocks can be selected. The removed blocks are saved in the controller's inventory. The function of the controller can be tested manually using the \"Remove\" or \"Set\" buttons. If an 'on' /'off' command is sent to the Door Controller II\\, it removes or sets the blocks as well.\n"..
"\n"..
"Individual blocks can be set\\, removed or replaced by other blocks via an 'exchange' command. The slot number of the inventory (1 .. 16) must be transferred as payload\\, i.e.:\n"..
"With '$send_cmnd(node_number\\, \"exchange\"\\, 2)' individual blocks can be set\\, removed or replaced by other blocks from the inventory. \n"..
"\n"..
" $send_cmnd(node_number\\, \"exchange\"\\, 2)\n"..
"With '$send_cmnd(node_number\\, \"set\"\\, 2)' a block from the inventory can be set explicitly\\, as long as the inventory slot is not empty.\n"..
"\n"..
"A block can be removed again with '$send_cmnd(node_number\\, \"dig\"\\, 2)' if the inventory slot is empty. \n"..
"\n"..
"The name of the set block is returned with '$send_cmnd(node_number\\, \"get\"\\, 2)'.\n"..
"\n"..
"The slot number of the inventory (1 .. 16) must be passed as payload in all three cases.\n"..
"\n"..
"This can also be used to simulate extendable stairs and the like. \n"..
"\n"..
@ -1157,7 +1164,7 @@ techage.manual_EN.aText = {
"\n"..
" - Command 'on' to play a sound\n"..
" - Command 'sound <idx>' to select a sound via the index\n"..
" - Command 'gain <volume>' to adjust the volume via the '<volume>' value (0 to 1.0).\n"..
" - Command 'gain <volume>' to adjust the volume via the '<volume>' value (1 to 5).\n"..
"\n"..
"\n"..
"\n",
@ -1196,6 +1203,11 @@ techage.manual_EN.aText = {
"\n"..
"\n"..
"\n",
"The light detector sends an 'on' command if the light level of the block above exceeds a certain level\\, which can be set through the right-click menu.\n"..
"If you have a TA4 Lua Controller\\, you can get the exact light level with $get_cmd(num\\, 'light_level')\n"..
"\n"..
"\n"..
"\n",
"TA3 has the same machines as TA2\\, only these are more powerful and require electricity instead of axis drive.\n"..
"Therefore\\, only the different technical data are given below.\n"..
"\n"..
@ -1676,6 +1688,7 @@ techage.manual_EN.aText = {
"\n"..
" - 'goto <num>' Jump to a command line and start the sequencer\n"..
" - 'stop' Stop the sequencer\n"..
" - 'on' and 'off' as aliases for 'goto 1' resp. 'stop'\n"..
"\n"..
"The 'goto' command is only accepted when the sequencer is stopped.\n"..
"\n"..
@ -1903,7 +1916,7 @@ techage.manual_EN.aText = {
"\n"..
"The TA4 pusher has two additional commands for the Lua controller:\n"..
"\n"..
" - 'config' is used to configure the pusher\\, analogous to manual configuration via the menu.\nExample: '$send_cmnd(1234\\, \"config\"\\, \"default: dirt\")'\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"..
" - '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"..
"\n"..
@ -2235,6 +2248,7 @@ techage.manual_EN.aItemName = {
"ta3_cartdetector",
"ta3_nodedetector",
"ta3_playerdetector",
"ta3_lightdetector",
"ta3_grinder",
"ta3_pusher",
"ta3_distributor",
@ -2505,6 +2519,7 @@ techage.manual_EN.aPlanTable = {
"",
"",
"",
"",
"ta4_windturbine",
"",
"",

View File

@ -511,8 +511,6 @@ techage.ConstructionPlans["ta5_teleport"] = {
{false, false, false, false, false, false, false, false, false, false, false},
{false, false, false, false, false, false, false, false, false, false, false},
{false, TANK4, PUMP4, TELEP, false, ARROW, false, TELEP, PIPEH, TANK4, false},
{false, false, false, false, false, false, false, false, false, false, false},
{false, TANK4, PIPEH, TELEP, false, ARROW, false, TELEP, PUMP4, TANK4, false},
}
--

View File

@ -3,7 +3,7 @@
TechAge
=======
Copyright (C) 2019-2021 Joachim Stolberg
Copyright (C) 2019-2022 Joachim Stolberg
AGPL v3
See LICENSE.txt for more information
@ -356,6 +356,37 @@ techage.register_node({"techage:heatexchanger2"}, {
return "unsupported"
end
end,
on_beduino_receive_cmnd = function(pos, src, topic, payload)
local nvm = techage.get_nvm(pos)
if topic == 1 and payload[1] == 1 then
start_node(pos, techage.get_nvm(pos))
return 0
elseif topic == 1 and payload[1] == 0 then
stop_node(pos, techage.get_nvm(pos))
return 0
else
return 2, ""
end
end,
on_beduino_request_data = function(pos, src, topic, payload)
local nvm = techage.get_nvm(pos)
if topic == 128 then
return 0, techage.get_node_lvm(pos).name
elseif topic == 129 then -- State
if techage.is_running(nvm) then
return 0, {techage.RUNNING}
else
return 0, {techage.STOPPED}
end
elseif topic == 135 then -- Delivered Power
local data = power.get_network_data(pos, Cable, DOWN)
return 0, {data.consumed - data.provided}
elseif topic == 134 then -- Tank Load Percent
return 0, {techage.power.percent(nvm.capa_max, nvm.capa)}
else
return 2, ""
end
end,
on_node_load = function(pos, node)
local nvm = techage.get_nvm(pos)
if techage.is_running(nvm) then

View File

@ -74,7 +74,7 @@ for idx,ratio in ipairs(lRatio) do
end
end,
use_texture_alpha = true,
use_texture_alpha = techage.BLEND,
inventory_image = "techage_flame.png",
paramtype = "light",
light_source = 13,

View File

@ -3,7 +3,7 @@
TechAge
=======
Copyright (C) 2019-2021 Joachim Stolberg
Copyright (C) 2019-2022 Joachim Stolberg
AGPL v3
See LICENSE.txt for more information
@ -173,6 +173,18 @@ techage.register_node({"techage:furnace_firebox", "techage:furnace_firebox_on"},
return "unsupported"
end
end,
on_beduino_request_data = function(pos, src, topic, payload)
local nvm = techage.get_nvm(pos)
if topic == 128 then
return 0, techage.get_node_lvm(pos).name
elseif topic == 129 then -- State
return 0, {nvm.running and techage.RUNNING or techage.STOPPED}
elseif topic == 132 then -- Fuel Level
return 0, {fuel.get_fuel_amount(nvm)}
else
return 2, ""
end
end,
-- called from furnace_top
on_transfer = function(pos, in_dir, topic, payload)
local nvm = techage.get_nvm(pos)

View File

@ -3,7 +3,7 @@
TechAge
=======
Copyright (C) 2019-2020 Joachim Stolberg
Copyright (C) 2019-2022 Joachim Stolberg
AGPL v3
See LICENSE.txt for more information
@ -257,6 +257,17 @@ local tubing = {
return CRD(pos).State:on_receive_message(pos, topic, payload)
end
end,
on_beduino_receive_cmnd = function(pos, src, topic, payload)
return CRD(pos).State:on_beduino_receive_cmnd(pos, topic, payload)
end,
on_beduino_request_data = function(pos, src, topic, payload)
if topic == 141 then -- Furnace Output
local nvm = techage.get_nvm(pos)
return 0, string.split(nvm.output or "unknown", " ")[1]
else
return CRD(pos).State:on_beduino_request_data(pos, topic, payload)
end
end,
}
local _, node_name_ta3, _ =

View File

@ -46,6 +46,7 @@ local function count_trues(t)
end
local function nucleus(t)
t = techage.tbl_filter(t, function(v, k, t) return type(v) == "table" end)
if #t == 4 then
if vector.equals(t[1], t[2]) and vector.equals(t[3], t[4]) then
return true
@ -268,6 +269,12 @@ techage.register_node({"techage:ta5_fr_controller_pas", "techage:ta5_fr_controll
on_recv_message = function(pos, src, topic, payload)
return State:on_receive_message(pos, topic, payload)
end,
on_beduino_receive_cmnd = function(pos, src, topic, payload)
return State:on_beduino_receive_cmnd(pos, topic, payload)
end,
on_beduino_request_data = function(pos, src, topic, payload)
return State:on_beduino_request_data(pos, topic, payload)
end,
})
power.register_nodes({"techage:ta5_fr_controller_pas", "techage:ta5_fr_controller_act"}, Cable, "con", {"L", "R"})

View File

@ -183,7 +183,7 @@ local function steam_management(pos, nvm)
nvm.temperature = math.min(nvm.temperature + 10, 100)
elseif resp ~= true then
State:fault(pos, nvm, resp)
stop_node(pos, nvm)
State:stop(pos, nvm)
return false
end
@ -325,15 +325,44 @@ techage.register_node({"techage:ta5_heatexchanger2"}, {
local data = power.get_network_data(pos, Cable, DOWN)
return data.consumed - data.provided
elseif topic == "on" then
start_node(pos, techage.get_nvm(pos))
State:start(pos, nvm)
return true
elseif topic == "off" then
stop_node(pos, techage.get_nvm(pos))
State:stop(pos, nvm)
return true
else
return "unsupported"
end
end,
on_beduino_receive_cmnd = function(pos, src, topic, payload)
local nvm = techage.get_nvm(pos)
if topic == 1 and payload[1] == 1 then
start_node(pos, techage.get_nvm(pos))
return 0
elseif topic == 1 and payload[1] == 0 then
stop_node(pos, techage.get_nvm(pos))
return 0
else
return 2, ""
end
end,
on_beduino_request_data = function(pos, src, topic, payload)
local nvm = techage.get_nvm(pos)
if topic == 128 then
return 0, techage.get_node_lvm(pos).name
elseif topic == 129 then -- State
if techage.is_running(nvm) then
return 0, {techage.RUNNING}
else
return 0, {techage.STOPPED}
end
elseif topic == 135 then -- Delivered Power
local data = power.get_network_data(pos, Cable, DOWN)
return 0, {data.consumed - data.provided}
else
return 2, ""
end
end,
on_node_load = function(pos, node)
local nvm = techage.get_nvm(pos)
if techage.is_running(nvm) then
@ -344,7 +373,7 @@ techage.register_node({"techage:ta5_heatexchanger2"}, {
-- Attempt to restart the system as the heat exchanger goes into error state
-- when parts of the storage block are unloaded.
if nvm.techage_state == techage.FAULT then
start_node(pos, nvm)
State:start(pos, nvm)
end
end,
})

View File

@ -170,6 +170,12 @@ techage.register_node({"techage:ta5_pump", "techage:ta5_pump_on"}, {
on_recv_message = function(pos, src, topic, payload)
return State:on_receive_message(pos, topic, payload)
end,
on_beduino_receive_cmnd = function(pos, src, topic, payload)
return State:on_beduino_receive_cmnd(pos, topic, payload)
end,
on_beduino_request_data = function(pos, src, topic, payload)
return State:on_beduino_request_data(pos, topic, payload)
end,
})
-- Pumps have to provide one output and one input side

View File

@ -3,7 +3,7 @@
TechAge
=======
Copyright (C) 2019-2021 Joachim Stolberg
Copyright (C) 2019-2022 Joachim Stolberg
AGPL v3
See LICENSE.txt for more information
@ -197,11 +197,11 @@ local tool_config = {
},
{
type = "dropdown",
choices = "0%,20%,40%,60%,80%",
choices = "0%,20%,40%,60%,80%,98%",
name = "turnoff",
label = S("Turnoff point"),
tooltip = S("If the charge of the storage\nsystem exceeds the configured value,\nthe block switches off"),
default = "0%",
default = "98%",
},
}
@ -332,11 +332,24 @@ techage.register_node({"techage:ta4_electrolyzer", "techage:ta4_electrolyzer_on"
return State:on_receive_message(pos, topic, payload)
end
end,
on_beduino_receive_cmnd = function(pos, src, topic, payload)
return State:on_beduino_receive_cmnd(pos, topic, payload)
end,
on_beduino_request_data = function(pos, src, topic, payload)
local nvm = techage.get_nvm(pos)
if topic == 134 and payload[1] == 1 then
return 0, {techage.power.percent(CAPACITY, (nvm.liquid and nvm.liquid.amount) or 0)}
elseif topic == 135 then
return 0, {math.floor((nvm.provided or 0) + 0.5)}
else
return State:on_beduino_request_data(pos, topic, payload)
end
end,
on_node_load = function(pos, node)
local meta = M(pos)
if not meta:contains("reduction") then
meta:set_string("reduction", "100%")
meta:set_string("turnoff", "0%")
meta:set_string("turnoff", "100%")
end
end,
})

View File

@ -3,7 +3,7 @@
TechAge
=======
Copyright (C) 2019-2021 Joachim Stolberg
Copyright (C) 2019-2022 Joachim Stolberg
AGPL v3
See LICENSE.txt for more information
@ -304,6 +304,19 @@ techage.register_node({"techage:ta4_fuelcell", "techage:ta4_fuelcell_on"}, {
return State:on_receive_message(pos, topic, payload)
end
end,
on_beduino_receive_cmnd = function(pos, src, topic, payload)
return State:on_beduino_receive_cmnd(pos, topic, payload)
end,
on_beduino_request_data = function(pos, src, topic, payload)
local nvm = techage.get_nvm(pos)
if topic == 134 and payload[1] == 1 then
return 0, {techage.power.percent(CAPACITY, (nvm.liquid and nvm.liquid.amount) or 0)}
elseif topic == 135 then
return 0, {math.floor((nvm.provided or 0) + 0.5)}
else
return State:on_beduino_request_data(pos, topic, payload)
end
end,
})
control.register_nodes({"techage:ta4_fuelcell", "techage:ta4_fuelcell_on"}, {

View File

@ -3,7 +3,7 @@
TechAge
=======
Copyright (C) 2019-2020 Joachim Stolberg
Copyright (C) 2019-2022 Joachim Stolberg
AGPL v3
See LICENSE.txt for more information
@ -176,4 +176,12 @@ techage.register_node({"techage:ta4_battery"}, {
return "unsupported"
end
end,
on_beduino_request_data = function(pos, src, topic, payload)
if topic == 134 then
local meta = minetest.get_meta(pos)
return 0, {calc_percent(meta:get_int("content"))}
else
return 2, ""
end
end,
})

View File

@ -153,7 +153,7 @@ techage.icta_register_condition("input", {
return env.input[data.number]
end
local result = function(val)
return techage.compare(val, data.value, data.operand)
return techage.compare(val, tonumber(data.value) or 0, data.operand)
end
return condition, result
end,
@ -196,7 +196,7 @@ techage.icta_register_condition("state", {
return techage.send_single(environ.number, data.number, "state")
end
local result = function(val)
return techage.compare(val, data.value, data.operand)
return techage.compare(val, tonumber(data.value) or 0, data.operand)
end
return condition, result
end,
@ -238,7 +238,7 @@ techage.icta_register_condition("fuel", {
return techage.send_single(environ.number, data.number, "fuel")
end
local result = function(val)
return techage.compare(val, tonumber(data.value), data.operand)
return techage.compare(val, tonumber(data.value) or 0, data.operand)
end
return condition, result
end,
@ -280,7 +280,7 @@ techage.icta_register_condition("load", {
return techage.send_single(environ.number, data.number, "load")
end
local result = function(val)
return techage.compare(val, tonumber(data.value), data.operand)
return techage.compare(val, tonumber(data.value) or 0, data.operand)
end
return condition, result
end,
@ -322,7 +322,7 @@ techage.icta_register_condition("depth", {
return techage.send_single(environ.number, data.number, "depth")
end
local result = function(val)
return techage.compare(val, tonumber(data.value), data.operand)
return techage.compare(val, tonumber(data.value) or 0, data.operand)
end
return condition, result
end,
@ -364,7 +364,7 @@ techage.icta_register_condition("delivered", {
return techage.send_single(environ.number, data.number, "delivered")
end
local result = function(val)
return techage.compare(val, tonumber(data.value), data.operand)
return techage.compare(val, tonumber(data.value) or 0, data.operand)
end
return condition, result
end,
@ -408,7 +408,7 @@ techage.icta_register_condition("chest", {
return techage.send_single(environ.number, data.number, "state")
end
local result = function(val)
return techage.compare(val, data.value, data.operand)
return techage.compare(val, tonumber(data.value) or 0, data.operand)
end
return condition, result
end,
@ -449,7 +449,7 @@ techage.icta_register_condition("signaltower", {
return techage.send_single(environ.number, data.number, "state")
end
local result = function(val)
return techage.compare(val, data.value, data.operand)
return techage.compare(val, tonumber(data.value) or 0, data.operand)
end
return condition, result
end,
@ -919,7 +919,7 @@ techage.icta_register_condition("get_filter", {
return techage.send_single(environ.number, data.number, "port", data.color)
end
local result = function(val)
return techage.compare(val, data.value, data.operand)
return techage.compare(val, tonumber(data.value) or 0, data.operand)
end
return condition, result
end,

View File

@ -3,7 +3,7 @@
TechAge
=======
Copyright (C) 2019-2020 Joachim Stolberg
Copyright (C) 2019-2022 Joachim Stolberg
AGPL v3
See LICENSE.txt for more information
@ -444,4 +444,30 @@ techage.register_node({"techage:ta4_icta_controller"}, {
return "unsupported"
end
end,
on_beduino_receive_cmnd = function(pos, src, topic, payload)
local meta = minetest.get_meta(pos)
local number = meta:get_string("number")
local state = meta:get_int("state")
if state == techage.RUNNING and topic == 1 and payload[1] == 1 then
set_input(pos, number, src, topic)
elseif state == techage.RUNNING and topic == 1 and payload[1] == 0 then
set_input(pos, number, src, topic)
else
return 2
end
return 0
end,
on_beduino_request_data = function(pos, src, topic, payload)
local meta = minetest.get_meta(pos)
local number = meta:get_string("number")
local state = meta:get_int("state")
if topic == 129 then
local state = meta:get_int("state") or 0
return 0, {state or techage.STOPPED}
else
return 2, ""
end
end,
})

View File

@ -3,7 +3,7 @@
TechAge
=======
Copyright (C) 2019-2020 Joachim Stolberg
Copyright (C) 2019-2022 Joachim Stolberg
AGPL v3
See LICENSE.txt for more information
@ -211,13 +211,21 @@ function techage.display.add_line(pos, payload, cycle_time)
table.insert(nvm.text, str)
end
function techage.display.write_row(pos, payload, cycle_time)
function techage.display.write_row(pos, payload, cycle_time, beduino)
local nvm = techage.get_nvm(pos)
local mem = techage.get_mem(pos)
local str, row
nvm.text = nvm.text or {}
mem.ticks = mem.ticks or 0
local str = tostring(payload.get("str")) or "oops"
local row = tonumber(payload.get("row")) or 1
if beduino then
row = tonumber(payload:sub(1,1) or "1") or 1
str = payload:sub(2) or "oops"
else
str = tostring(payload.get("str")) or "oops"
row = tonumber(payload.get("row")) or 1
end
if mem.ticks == 0 then
mem.ticks = cycle_time
@ -254,6 +262,18 @@ techage.register_node({"techage:ta4_display"}, {
techage.display.clear_screen(pos, 1)
end
end,
on_beduino_receive_cmnd = function(pos, src, topic, payload)
if topic == 67 then -- add one line and scroll if necessary
techage.display.add_line(pos, payload, 1)
elseif topic == 68 then -- overwrite the given row
techage.display.write_row(pos, payload, 1, true)
elseif topic == 17 then -- clear the screen
techage.display.clear_screen(pos, 1)
else
return 2
end
return 0
end,
})
techage.register_node({"techage:ta4_displayXL"}, {
@ -266,6 +286,18 @@ techage.register_node({"techage:ta4_displayXL"}, {
techage.display.clear_screen(pos, 2)
end
end,
on_beduino_receive_cmnd = function(pos, src, topic, payload)
if topic == 67 then -- add one line and scroll if necessary
techage.display.add_line(pos, payload, 2)
elseif topic == 68 then -- overwrite the given row
techage.display.write_row(pos, payload, 2, true)
elseif topic == 17 then -- clear the screen
techage.display.clear_screen(pos, 2)
else
return 2
end
return 0
end,
})
lcdlib.register_display_entity("techage:display_entity")

View File

@ -3,7 +3,7 @@
TechAge
=======
Copyright (C) 2019-2020 Joachim Stolberg
Copyright (C) 2019-2022 Joachim Stolberg
AGPL v3
See LICENSE.txt for more information
@ -132,4 +132,27 @@ techage.register_node({"techage:ta4_signaltower",
return meta:get_string("state")
end
end,
on_beduino_receive_cmnd = function(pos, src, topic, payload)
if topic == 2 then
local color = ({"green", "amber", "red"})[payload[1]]
local node = minetest.get_node(pos)
if color then
switch_on(pos, node, color)
else
switch_off(pos, node)
end
return 0
else
return 2 -- unknown or invalid topic
end
end,
on_beduino_request_data = function(pos, src, topic, payload)
if topic == 130 then
local meta = minetest.get_meta(pos)
local color = ({off = 0, green = 1, amber = 2, red = 3})[meta:get_string("state")] or 1
return 0, {color}
else
return 2, "" -- unknown or invalid topic
end
end,
})

View File

@ -3,7 +3,7 @@
TechAge
=======
Copyright (C) 2019-2021 Joachim Stolberg
Copyright (C) 2019-2022 Joachim Stolberg
AGPL v3
See LICENSE.txt for more information
@ -13,7 +13,7 @@
techage = {}
-- Version for compatibility checks, see readme.md/history
techage.version = 1.07
techage.version = 1.08
if minetest.global_exists("tubelib") then
minetest.log("error", "[techage] Techage can't be used together with the mod tubelib!")
@ -285,6 +285,7 @@ dofile(MP.."/logic/timer.lua")
dofile(MP.."/logic/lua_logic.lua") -- old
dofile(MP.."/logic/logic_block.lua") -- new
dofile(MP.."/logic/node_detector.lua")
dofile(MP.."/logic/light_detector.lua")
dofile(MP.."/logic/player_detector.lua")
dofile(MP.."/logic/mba_detector.lua")
dofile(MP.."/logic/cart_detector.lua")
@ -412,8 +413,8 @@ dofile(MP.."/fusion_reactor/generator.lua")
dofile(MP.."/fusion_reactor/turbine.lua")
dofile(MP.."/fusion_reactor/ta5_pump.lua")
-- Beduino extensions
dofile(MP.."/beduino/kv_store.lua")
-- Prevent other mods from using IE
techage.IE = nil
function techage.icta_register_condition(key, tData) end

View File

@ -13,7 +13,7 @@
]]--
local function register_alias(name)
minetest.register_alias("stairs:slab_" ..name, "techage:slab_" ..name)
--minetest.register_alias("stairs:slab_" ..name, "techage:slab_" ..name)
minetest.register_alias("stairs:slab_" ..name.. "_inverted", "techage:slab_" ..name.. "_inverted")
minetest.register_alias("stairs:slab_" ..name.. "_wall", "techage:slab_" ..name.. "_wall")
minetest.register_alias("stairs:slab_" ..name.. "_quarter", "techage:slab_" ..name.. "_quarter")
@ -22,7 +22,7 @@ local function register_alias(name)
minetest.register_alias("stairs:slab_" ..name.. "_three_quarter", "techage:slab_" ..name.. "_three_quarter")
minetest.register_alias("stairs:slab_" ..name.. "_three_quarter_inverted", "techage:slab_" ..name.. "_three_quarter_inverted")
minetest.register_alias("stairs:slab_" ..name.. "_three_quarter_wall", "techage:slab_" ..name.. "_three_quarter_wall")
minetest.register_alias("stairs:stair_" ..name, "techage:stair_" ..name)
--minetest.register_alias("stairs:stair_" ..name, "techage:stair_" ..name)
minetest.register_alias("stairs:stair_" ..name.. "_inverted", "techage:stair_" ..name.. "_inverted")
minetest.register_alias("stairs:stair_" ..name.. "_wall", "techage:stair_" ..name.. "_wall")
minetest.register_alias("stairs:stair_" ..name.. "_wall_half", "techage:stair_" ..name.. "_wall_half")

View File

@ -64,4 +64,7 @@ techage.register_mobs_mods("wildlife")
techage.register_mobs_mods("mobs_skeletons")
techage.register_mobs_mods("mobs_dwarves")
techage.register_mobs_mods("mobf_trader")
techage.register_mobs_mods("ts_vehicles")
techage.register_mobs_mods("ts_vehicles_cars")
-- Used as e.g. crane cable
techage.register_simple_nodes({"techage:power_lineS"}, true)

View File

@ -284,6 +284,17 @@ techage.register_node({"techage:t4_pump", "techage:t4_pump_on"}, {
return State4:on_receive_message(pos, topic, payload)
end
end,
on_beduino_receive_cmnd = function(pos, src, topic, payload)
return State4:on_beduino_receive_cmnd(pos, topic, payload)
end,
on_beduino_request_data = function(pos, src, topic, payload)
if topic == 137 then -- Total Flow Rate
local nvm = techage.get_nvm(pos)
return 0, {nvm.flowrate or 0}
else
return State4:on_beduino_request_data(pos, topic, payload)
end
end,
})
-- Pumps have to provide one output and one input side

View File

@ -3,7 +3,7 @@
TechAge
=======
Copyright (C) 2019-2021 Joachim Stolberg
Copyright (C) 2019-2022 Joachim Stolberg
AGPL v3
See LICENSE.txt for more information
@ -312,6 +312,25 @@ techage.register_node({"techage:ta3_silo", "techage:ta4_silo"}, {
return "unsupported"
end
end,
on_beduino_request_data = function(pos, src, topic, payload)
if topic == 131 then -- Chest State
local meta = M(pos)
local inv = meta:get_inventory()
return 0, {techage.get_inv_state_num(inv, "main")}
elseif topic == 134 then
local inv = M(pos):get_inventory()
local nvm = techage.get_nvm(pos)
nvm.item_count = nvm.item_count or get_item_count(pos)
nvm.capa = nvm.capa or get_silo_capa(pos)
if payload[1] == 1 then
return 0, {techage.power.percent(nvm.capa, nvm.item_count)}
else
return 0, {nvm.item_count}
end
else
return 2, ""
end
end,
on_node_load = function(pos)
local nvm = techage.get_nvm(pos)
nvm.item_count = nil

View File

@ -3,7 +3,7 @@
TechAge
=======
Copyright (C) 2019-2021 Joachim Stolberg
Copyright (C) 2019-2022 Joachim Stolberg
AGPL v3
See LICENSE.txt for more information
@ -139,6 +139,29 @@ techage.register_node({"techage:ta3_valve_closed", "techage:ta3_valve_open"}, {
return "unsupported"
end
end,
on_beduino_receive_cmnd = function(pos, src, topic, payload)
local node = techage.get_node_lvm(pos)
if topic == 1 and payload[1] == 1 and node.name == "techage:ta3_valve_closed" then
liquid.turn_valve_on(pos, Pipe, "techage:ta3_valve_closed", "techage:ta3_valve_open")
return 0
elseif topic == 1 and payload[1] == 0 and node.name == "techage:ta3_valve_open" then
liquid.turn_valve_off(pos, Pipe, "techage:ta3_valve_closed", "techage:ta3_valve_open")
return 0
else
return 2, ""
end
end,
on_beduino_request_data = function(pos, src, topic, payload)
local node = techage.get_node_lvm(pos)
if topic == 142 then -- State
if node.name == "techage:ta3_valve_open" then
return 0, {1}
end
return 0, {0}
else
return 2, ""
end
end,
})
liquid.register_nodes({"techage:ta3_valve_closed"}, Pipe, "special", {}, {})

View File

@ -3,7 +3,7 @@
TechAge
=======
Copyright (C) 2019-2020 Joachim Stolberg
Copyright (C) 2019-2022 Joachim Stolberg
AGPL v3
See LICENSE.txt for more information
@ -158,4 +158,10 @@ techage.register_node({"techage:t4_waterpump"}, {
on_recv_message = function(pos, src, topic, payload)
return State:on_receive_message(pos, topic, payload)
end,
on_beduino_receive_cmnd = function(pos, src, topic, payload)
return State:on_beduino_receive_cmnd(pos, topic, payload)
end,
on_beduino_request_data = function(pos, src, topic, payload)
return State:on_beduino_request_data(pos, topic, payload)
end,
})

View File

@ -127,6 +127,7 @@ Command=Kommando
### button.lua ###
### cart_detector.lua ###
### detector.lua ###
### light_detector.lua ###
### lua_logic.lua ###
### mesecons_converter.lua ###
### node_detector.lua ###
@ -178,6 +179,7 @@ TA4 4x Button=TA4 4x Taster
TA3 Cart Detector=TA3 Wagen Detektor
### cart_detector.lua ###
### light_detector.lua ###
### node_detector.lua ###
accept=akzeptieren
@ -732,6 +734,11 @@ Block has an@nadditional wrench menu=Block besitzt ein@nzusätzliches@nSchrauben
connected with=verbunden mit
### light_detector.lua ###
Send signal if light level is above:=Sende ein Signal wenn der Lichtwert größer ist als:
TA3 Light Detector=TA3 Lichtdetektor
### lighter.lua ###
TA1 Lighter=TA1 Anzünder

View File

@ -127,6 +127,7 @@ Command=
### button.lua ###
### cart_detector.lua ###
### detector.lua ###
### light_detector.lua ###
### lua_logic.lua ###
### mesecons_converter.lua ###
### node_detector.lua ###
@ -178,6 +179,7 @@ TA4 4x Button=
TA3 Cart Detector=
### cart_detector.lua ###
### light_detector.lua ###
### node_detector.lua ###
accept=
@ -732,6 +734,11 @@ Block has an@nadditional wrench menu=
connected with=
### light_detector.lua ###
Send signal if light level is above:=
TA3 Light Detector=
### lighter.lua ###
TA1 Lighter=

View File

@ -55,7 +55,10 @@ local function switch_off(pos, is_button)
elseif name == "techage:ta4_button_on" then
logic.swap_node(pos, "techage:ta4_button_off")
end
local meta = M(pos)
if not meta:contains("command") or meta:get_string("command") == "on" then
logic.send_off(pos, M(pos))
end
if not is_button then
minetest.sound_play("techage_button", {
pos = pos,
@ -149,6 +152,9 @@ local function on_rightclick_on(pos, node, clicker)
if fixed == "true" then
if can_access(pos, clicker) then
switch_on(pos)
local mem = techage.get_mem(pos)
mem.clicker = clicker and clicker:get_player_name()
mem.time = math.floor(minetest.get_us_time() / 100000)
end
end
end
@ -331,3 +337,31 @@ minetest.register_craft({
{"", "", ""},
},
})
techage.register_node({
"techage:ta4_button_off", "techage:ta4_button_on",
}, {
on_recv_message = function(pos, src, topic, payload)
if topic == "name" then
local mem = techage.get_mem(pos)
return mem.clicker or ""
elseif topic == "time" then
local mem = techage.get_mem(pos)
return mem.time or 0
else
return "unsupported"
end
end,
on_beduino_request_data = function(pos, src, topic, payload)
if topic == 144 then -- Player Name
local mem = techage.get_mem(pos)
return 0, mem.clicker
elseif topic == 149 then --time
local mem = techage.get_mem(pos)
return 0, {mem.time or 0}
else
return 2, ""
end
end,
}
)

View File

@ -3,7 +3,7 @@
TechAge
=======
Copyright (C) 2019-2020 Joachim Stolberg
Copyright (C) 2019-2022 Joachim Stolberg
AGPL v3
See LICENSE.txt for more information
@ -151,6 +151,28 @@ techage.register_node({"techage:ta3_cartdetector_off", "techage:ta3_cartdetector
return "unsupported"
end
end,
on_beduino_receive_cmnd = function(pos, src, topic, payload)
if topic == 1 then
local node = minetest.get_node(pos)
local dir = minetest.facedir_to_dir(node.param2)
minecart.punch_cart(pos, nil, 1.6, dir)
return 0
else
return 2
end
end,
on_beduino_request_data = function(pos, src, topic, payload)
if topic == 142 then -- Binary State
local node = techage.get_node_lvm(pos)
if node.name == "techage:ta3_cartdetector_on" then
return 0, {1}
else
return 0, {0}
end
else
return 2, ""
end
end,
on_node_load = function(pos)
minetest.get_node_timer(pos):start(CYCLE_TIME)
end,

View File

@ -3,7 +3,7 @@
TechAge
=======
Copyright (C) 2017-2020 Joachim Stolberg
Copyright (C) 2017-2022 Joachim Stolberg
AGPL v3
See LICENSE.txt for more information
@ -24,6 +24,7 @@ local CYCLE_TIME = 1
local tStates = {stopped = 0, running = 0, standby = 1, blocked = 2, nopower = 3, fault = 4}
local tDropdownPos = {["1 standby"] = 1, ["2 blocked"] = 2, ["3 nopower"] = 3, ["4 fault"] = 4}
local lStates = {[0] = "stopped", "standby", "blocked", "nopower", "fault"}
local TaStates = {running = 1, blocked = 2, standby = 3, nopower = 4, fault = 5, stopped = 6}
local function formspec(nvm, meta)
nvm.poll_numbers = nvm.poll_numbers or {}
@ -207,6 +208,14 @@ techage.register_node({"techage:ta4_collector"}, {
return "unsupported"
end
end,
on_beduino_request_data = function(pos, src, topic, payload)
if topic == 129 then
local nvm = techage.get_nvm(pos)
return 0, {TaStates[lStates[nvm.stored_state or 0]]}
else
return 2, ""
end
end,
on_node_load = function(pos)
minetest.get_node_timer(pos):start(CYCLE_TIME)
end,

View File

@ -3,7 +3,7 @@
TechAge
=======
Copyright (C) 2017-2020 Joachim Stolberg
Copyright (C) 2017-2022 Joachim Stolberg
AGPL v3
See LICENSE.txt for more information
@ -83,12 +83,21 @@ local function formspec(meta)
"button_exit[2,2;3,1;exit;"..S("Save").."]"
end
local function after_place_node(pos, placer)
local function after_place_node3(pos, placer)
local meta = M(pos)
local inv = meta:get_inventory()
inv:set_size('cfg', 4)
logic.after_place_node(pos, placer, "techage:ta3_detector_off", NDEF(pos).description)
logic.infotext(meta, NDEF(pos).description)
logic.after_place_node(pos, placer, "techage:ta3_detector_off", S("TA3 Detector"))
logic.infotext(meta, S("TA3 Detector"))
meta:set_string("formspec", formspec(meta))
end
local function after_place_node4(pos, placer)
local meta = M(pos)
local inv = meta:get_inventory()
inv:set_size('cfg', 4)
logic.after_place_node(pos, placer, "techage:ta4_detector_off", S("TA4 Detector"))
logic.infotext(meta, S("TA4 Detector"))
meta:set_string("formspec", formspec(meta))
end
@ -126,7 +135,7 @@ minetest.register_node("techage:ta3_detector_off", {
"techage_filling_ta3.png^techage_frame_ta3.png^techage_appl_detector.png",
},
after_place_node = after_place_node,
after_place_node = after_place_node3,
on_receive_fields = on_receive_fields,
techage_set_numbers = techage_set_numbers,
after_dig_node = after_dig_node,
@ -179,7 +188,7 @@ minetest.register_node("techage:ta4_detector_off", {
"techage_filling_ta4.png^techage_frame_ta4.png^techage_appl_detector.png",
},
after_place_node = after_place_node,
after_place_node = after_place_node4,
on_receive_fields = on_receive_fields,
techage_set_numbers = techage_set_numbers,
after_dig_node = after_dig_node,
@ -276,4 +285,21 @@ techage.register_node({"techage:ta4_detector_off", "techage:ta4_detector_on"}, {
return "unsupported"
end
end,
on_beduino_receive_cmnd = function(pos, src, topic, payload)
if topic == 6 then -- Detector Block Reset
local nvm = techage.get_nvm(pos)
nvm.counter = 0
return 0
else
return 2
end
end,
on_beduino_request_data = function(pos, src, topic, payload)
if topic == 139 then
local nvm = techage.get_nvm(pos)
return 0, {nvm.counter or 0}
else
return 2, ""
end
end,
})

189
techage/logic/light_detector.lua Executable file
View File

@ -0,0 +1,189 @@
--[[
TechAge
=======
Copyright (C) 2019-2022 Joachim Stolberg
AGPL v3
See LICENSE.txt for more information
Light Detector
]]--
-- for lazy programmers
local M = minetest.get_meta
local S = techage.S
local P2S = function(pos) if pos then return minetest.pos_to_string(pos) end end
local logic = techage.logic
local CYCLE_TIME = 2
local function switch_off(pos)
local node = minetest.get_node(pos)
if node.name == "techage:ta3_lightdetector_on" then
logic.swap_node(pos, "techage:ta3_lightdetector_off")
logic.send_off(pos, M(pos))
end
end
local function switch_on(pos)
logic.swap_node(pos, "techage:ta3_lightdetector_on")
if logic.send_on(pos, M(pos)) then
minetest.after(1, switch_off, pos)
end
end
local function node_timer(pos)
local nvm = techage.get_nvm(pos)
local trigger = nvm.mode or 7
local pos_above = {x = pos.x, y = pos.y + 1, z = pos.z}
if minetest.get_node_light(pos_above, nil) == nil then
switch_off(pos)
return true
end
if minetest.get_node_light(pos_above, nil) > trigger then
switch_on(pos)
else
switch_off(pos)
end
return true
end
local function formspec(meta, nvm)
local numbers = meta:get_string("numbers") or ""
local dropdown_label = "1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15" -- Has to be a cleaner way of doing this, but it's just easier this way
return "size[7.5,4]"..
default.gui_bg..
default.gui_bg_img..
default.gui_slots..
"field[0.5,1;7,1;numbers;"..S("Insert destination node number(s)")..";"..numbers.."]" ..
"label[0.2,1.6;"..S("Send signal if light level is above:").."]"..
"dropdown[0.2,2.1;7.3,1;mode;"..dropdown_label.."; "..(nvm.mode or 7).."]"..
"button_exit[2,3.2;3,1;accept;"..S("accept").."]"
end
local function on_receive_fields(pos, formname, fields, player)
if minetest.is_protected(pos, player:get_player_name()) then
return
end
local meta = minetest.get_meta(pos)
local nvm = techage.get_nvm(pos)
if fields.accept then
nvm.mode = tonumber(fields.mode) or 7
if techage.check_numbers(fields.numbers, player:get_player_name()) then
meta:set_string("numbers", fields.numbers)
logic.infotext(M(pos), S("TA3 Light Detector"))
end
meta:set_string("formspec", formspec(meta, nvm))
end
end
local function techage_set_numbers(pos, numbers, player_name)
local meta = M(pos)
local res = logic.set_numbers(pos, numbers, player_name, S("TA3 Light Detector"))
meta:set_string("formspec", formspec(meta))
return res
end
local function after_dig_node(pos, oldnode, oldmetadata, digger)
techage.remove_node(pos, oldnode, oldmetadata)
end
minetest.register_node("techage:ta3_lightdetector_off", {
description = S("TA3 Light Detector"),
tiles = {
-- up, down, right, left, back, front
"techage_filling_ta3.png^techage_frame_ta3_top.png^techage_appl_lightdetector.png",
"techage_filling_ta3.png^techage_frame_ta3_top.png",
"techage_filling_ta3.png^techage_frame_ta3_top.png^techage_appl_arrow.png^[transformR90",
},
after_place_node = function(pos, placer)
local meta = M(pos)
local nvm = techage.get_nvm(pos)
logic.after_place_node(pos, placer, "techage:ta3_lightdetector_off", S("TA3 Light Detector"))
logic.infotext(meta, S("TA3 Light Detector"))
meta:set_string("formspec", formspec(meta, nvm))
minetest.get_node_timer(pos):start(CYCLE_TIME)
end,
on_receive_fields = on_receive_fields,
on_timer = node_timer,
techage_set_numbers = techage_set_numbers,
after_dig_node = after_dig_node,
paramtype2 = "facedir",
groups = {choppy=2, cracky=2, crumbly=2},
is_ground_content = false,
sounds = default.node_sound_metal_defaults(),
})
minetest.register_node("techage:ta3_lightdetector_on", {
description = "TA3 Light Detector (On)",
tiles = {
-- up, down, right, left, back, front
"techage_filling_ta3.png^techage_frame_ta3_top.png^techage_appl_lightdetector_on.png",
"techage_filling_ta3.png^techage_frame_ta3_top.png",
"techage_filling_ta3.png^techage_frame_ta3_top.png^techage_appl_arrow.png^[transformR90",
},
on_receive_fields = on_receive_fields,
on_timer = node_timer,
techage_set_numbers = techage_set_numbers,
after_dig_node = after_dig_node,
paramtype2 = "facedir",
groups = {choppy=2, cracky=2, crumbly=2, not_in_creative_inventory=1},
is_ground_content = false,
sounds = default.node_sound_wood_defaults(),
drop = "techage:ta3_lightdetector_off"
})
minetest.register_craft({
output = "techage:ta3_lightdetector_off",
recipe = {
{"", "group:wood", "default:glass"},
{"", "default:copper_ingot", "techage:vacuum_tube"},
{"", "group:wood", "default:mese_crystal"},
},
})
techage.register_node({"techage:ta3_lightdetector_off", "techage:ta3_lightdetector_on"}, {
on_recv_message = function(pos, src, topic, payload)
if topic == "state" then
local node = techage.get_node_lvm(pos)
if node.name == "techage:ta3_lightdetector_on" then
return "on"
else
return "off"
end
elseif topic == "light_level" then -- Allow finding the specific light level
local pos_above = {x = pos.x, y = pos.y + 1, z = pos.z}
return minetest.get_node_light(pos_above, nil)
else
return "unsupported"
end
end,
on_beduino_request_data = function(pos, src, topic, payload)
if topic == 142 then -- Binary State
local node = techage.get_node_lvm(pos)
if node.name == "techage:ta3_lightdetector_on" then
return 0, {1}
else
return 0, {0}
end
elseif topic == 143 then -- Allow finding the specific light level
local pos_above = {x = pos.x, y = pos.y + 1, z = pos.z}
return 0, {minetest.get_node_light(pos_above, nil)}
else
return 2, ""
end
end,
on_node_load = function(pos)
minetest.get_node_timer(pos):start(CYCLE_TIME)
end,
})

View File

@ -3,7 +3,7 @@
TechAge
=======
Copyright (C) 2017-2021 Joachim Stolberg
Copyright (C) 2017-2022 Joachim Stolberg
AGPL v3
See LICENSE.txt for more information
@ -407,4 +407,29 @@ techage.register_node({"techage:ta3_logic2"}, {
mem.ttl = techage.SystemTime + (nvm.blocking_time or 0)
end
end,
on_beduino_receive_cmnd = function(pos, src, topic, payload)
local nvm = techage.get_nvm(pos)
local mem = techage.get_mem(pos)
nvm.own_num = nvm.own_num or M(pos):get_string("node_number")
nvm.blocking_time = nvm.blocking_time or M(pos):get_float("blocking_time")
nvm.inp_tbl = nvm.inp_tbl or {}
if src ~= nvm.own_num then
if topic == 1 and payload[1] == 1 then
debug(mem, "(inp) " .. src .. " = on")
nvm.inp_tbl[src] = "on"
return 0
elseif topic == 1 and payload[1] == 0 then
debug(mem, "(inp) " .. src .. " = off")
nvm.inp_tbl[src] = "off"
return 0
else
debug(mem, "(inp) invalid command")
return 2
end
local t = math.max((mem.ttl or 0) - techage.SystemTime, 0.1)
minetest.get_node_timer(pos):start(t)
mem.ttl = techage.SystemTime + (nvm.blocking_time or 0)
end
end,
})

View File

@ -3,7 +3,7 @@
TechAge
=======
Copyright (C) 2017-2020 Joachim Stolberg
Copyright (C) 2017-2022 Joachim Stolberg
AGPL v3
See LICENSE.txt for more information
@ -246,7 +246,19 @@ techage.register_node({"techage:ta3_logic"}, {
end
minetest.get_node_timer(pos):start(0.1)
end,
on_beduino_receive_cmnd = function(pos, src, topic, payload)
if topic == 1 and payload[1] == 1 then
nvm.inp_tbl.inp = true
nvm.inp_tbl["n"..src] = true
return 0
elseif topic == 1 and payload[1] == 0 then
nvm.inp_tbl.inp = false
nvm.inp_tbl["n"..src] = false
return 0
else
return 2
end
end,
on_node_load = function(pos)
end,
})

View File

@ -3,7 +3,7 @@
TechAge
=======
Copyright (C) 2017-2020 Joachim Stolberg
Copyright (C) 2017-2022 Joachim Stolberg
AGPL v3
See LICENSE.txt for more information
@ -92,6 +92,23 @@ techage.register_node({"techage:ta4_mbadetector"}, {
return "unsupported"
end
end,
on_beduino_request_data = function(pos, src, topic, payload)
if topic == 142 then -- Binary State
if minetest.compare_block_status then
if minetest.compare_block_status(pos, "active") then
return 0, {1}
else
return 0, {0}
end
else
local mem = techage.get_mem(pos)
local res = mem.gametime and mem.gametime > (minetest.get_gametime() - 2)
return 0, {res and 1 or 0}
end
else
return 2, ""
end
end,
on_node_load = function(pos)
minetest.get_node_timer(pos):start(1)
end,

View File

@ -3,7 +3,7 @@
TechAge
=======
Copyright (C) 2017-2020 Joachim Stolberg
Copyright (C) 2017-2022 Joachim Stolberg
AGPL v3
See LICENSE.txt for more information
@ -189,20 +189,29 @@ minetest.register_craft({
techage.register_node({"techage:ta3_nodedetector_off", "techage:ta3_nodedetector_on"}, {
on_recv_message = function(pos, src, topic, payload)
if topic == "name" then
local nvm = techage.get_nvm(pos)
return nvm.player_name or ""
elseif topic == "state" then
if topic == "state" then
local node = techage.get_node_lvm(pos)
if node.name == "techage:ta3_nodedetector_off" then
return "on"
else
return "off"
else
return "on"
end
else
return "unsupported"
end
end,
on_beduino_request_data = function(pos, src, topic, payload)
if topic == 142 then
local node = techage.get_node_lvm(pos)
if node.name == "techage:ta3_nodedetector_off" then
return 0, {0}
else
return 0, {1}
end
else
return 2, ""
end
end,
on_node_load = function(pos)
minetest.get_node_timer(pos):start(CYCLE_TIME)
end,

View File

@ -3,7 +3,7 @@
TechAge
=======
Copyright (C) 2017-2020 Joachim Stolberg
Copyright (C) 2017-2022 Joachim Stolberg
AGPL v3
See LICENSE.txt for more information
@ -323,6 +323,22 @@ techage.register_node({
return "unsupported"
end
end,
on_beduino_request_data = function(pos, src, topic, payload)
if topic == 144 then -- Player Name
local nvm = techage.get_nvm(pos)
return 0, nvm.player_name or ""
elseif topic == 142 then -- Binary State
local node = techage.get_node_lvm(pos)
if node.name == "techage:ta3_playerdetector_on" or
node.name == "techage:ta4_playerdetector_on" then
return 0, {1}
else
return 0, {0}
end
else
return 2, ""
end
end,
on_node_load = function(pos)
minetest.get_node_timer(pos):start(CYCLE_TIME)
end,

View File

@ -3,7 +3,7 @@
TechAge
=======
Copyright (C) 2017-2020 Joachim Stolberg
Copyright (C) 2017-2022 Joachim Stolberg
AGPL v3
See LICENSE.txt for more information
@ -278,6 +278,28 @@ techage.register_node({"techage:ta3_sequencer"}, {
return "unsupported"
end
end,
on_beduino_receive_cmnd = function(pos, src, topic, payload)
local nvm = techage.get_nvm(pos)
if topic == 7 then -- TA3 Sequenzer
if payload[1] == 1 then
start_the_sequencer(pos)
return 0
elseif payload[1] == 0 then
-- do not stop immediately
local nvm = techage.get_nvm(pos)
if not nvm.running then
nvm.endless = not (nvm.endless or false)
else
nvm.endless = false
end
return 0
elseif payload[1] == 2 then
stop_the_sequencer(pos)
return 0
end
end
return 2
end,
on_node_load = function(pos)
local nvm = techage.get_nvm(pos)
if nvm.running then

View File

@ -3,7 +3,7 @@
TechAge
=======
Copyright (C) 2017-2021 Joachim Stolberg
Copyright (C) 2017-2022 Joachim Stolberg
AGPL v3
See LICENSE.txt for more information
@ -30,6 +30,7 @@ local HELP = S("Syntax:\n") ..
S(" - 'send <node num> <cmnd>' (techage command)\n") ..
S(" - 'goto <num>' (jump to another line)\n") ..
S(" - 'stop' (stop the execution)\n") ..
S(" - 'nop' (do nothing)\n") ..
S("\n") ..
S("Example:\n") ..
" -- move controller commands\n" ..
@ -108,7 +109,7 @@ local function compile(s, tRes)
tCode[idx] = {next_idx = tonumber(cmnd2) or 1}
elseif cmnd1 == "stop" then
tCode[idx] = false
elseif cmnd1 == nil then
elseif cmnd1 == nil or cmnd1 == "nop" then
tCode[idx] = {}
end
old_idx = idx
@ -290,18 +291,18 @@ minetest.register_craft({
},
})
local INFO = [[Commands: 'goto <num>', 'stop']]
local INFO = [[Commands: 'goto <num>', 'stop', 'on', 'off']]
techage.register_node({"techage:ta4_sequencer"}, {
on_recv_message = function(pos, src, topic, payload)
local nvm = techage.get_nvm(pos)
if topic == "goto" and not nvm.running then
if (topic == "goto" or topic == "on") and not nvm.running then
local mem = techage.get_mem(pos)
nvm.running = true
mem.idx = tonumber(payload or 1) or 1
restart_timer(pos, 0.1)
logic.infotext(M(pos), S("TA4 Sequencer"), S("running"))
elseif topic == "stop" then
elseif topic == "stop" or topic == "off" then
nvm.running = false
minetest.get_node_timer(pos):stop()
logic.infotext(M(pos), S("TA4 Sequencer"), S("stopped"))
@ -311,4 +312,23 @@ techage.register_node({"techage:ta4_sequencer"}, {
return "unsupported"
end
end,
on_beduino_receive_cmnd = function(pos, src, topic, payload)
local nvm = techage.get_nvm(pos)
if topic == 13 then
if payload[1] ~= 0 and not nvm.running then
local mem = techage.get_mem(pos)
nvm.running = true
mem.idx = tonumber(payload or 1) or 1
restart_timer(pos, 0.1)
logic.infotext(M(pos), S("TA4 Sequencer"), S("running"))
return 0
elseif payload[1] == 0 then
nvm.running = false
minetest.get_node_timer(pos):stop()
logic.infotext(M(pos), S("TA4 Sequencer"), S("stopped"))
return 0
end
end
return 2
end,
})

View File

@ -3,7 +3,7 @@
TechAge
=======
Copyright (C) 2020 Joachim Stolberg
Copyright (C) 2022 Joachim Stolberg
AGPL v3
See LICENSE.txt for more information
@ -121,6 +121,19 @@ techage.register_node({"techage:signal_lamp_off", "techage:signal_lamp_on"}, {
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({

View File

@ -3,7 +3,7 @@
TechAge
=======
Copyright (C) 2017-2021 Joachim Stolberg
Copyright (C) 2017-2022 Joachim Stolberg
AGPL v3
See LICENSE.txt for more information
@ -17,9 +17,9 @@ local M = minetest.get_meta
local S = techage.S
local OFF = 0
local RED = 1
local GREEN = 2
local AMBER = 3
local GREEN = 1
local AMBER = 2
local RED = 3
local WRENCH_MENU = {
{
@ -139,6 +139,19 @@ techage.register_node({"techage:ta4_signallamp_2x"}, {
lcdlib.update_entities(pos)
end
end,
on_beduino_receive_cmnd = function(pos, src, topic, payload)
local nvm = techage.get_nvm(pos)
nvm.lamp = nvm.lamp or {}
if topic == 3 then -- Signal Lamp
local num = math.min(payload[1] or 1, 2)
local color = math.min(payload[2] or 0, 3)
nvm.lamp[num] = color
lcdlib.update_entities(pos)
return 0
else
return 2
end
end,
})
minetest.register_craft({

View File

@ -3,7 +3,7 @@
TechAge
=======
Copyright (C) 2017-2021 Joachim Stolberg
Copyright (C) 2017-2022 Joachim Stolberg
AGPL v3
See LICENSE.txt for more information
@ -17,9 +17,9 @@ local M = minetest.get_meta
local S = techage.S
local OFF = 0
local RED = 1
local GREEN = 2
local AMBER = 3
local GREEN = 1
local AMBER = 2
local RED = 3
local WRENCH_MENU = {
{
@ -170,6 +170,19 @@ techage.register_node({"techage:ta4_signallamp_4x"}, {
lcdlib.update_entities(pos)
end
end,
on_beduino_receive_cmnd = function(pos, src, topic, payload)
local nvm = techage.get_nvm(pos)
nvm.lamp = nvm.lamp or {}
if topic == 3 then -- Signal Lamp
local num = math.min(payload[1] or 1, 4)
local color = math.min(payload[2] or 0, 3)
nvm.lamp[num] = color
lcdlib.update_entities(pos)
return 0
else
return 2
end
end,
})
minetest.register_craft({

View File

@ -3,7 +3,7 @@
TechAge
=======
Copyright (C) 2019-2020 Joachim Stolberg
Copyright (C) 2019-2022 Joachim Stolberg
AGPL v3
See LICENSE.txt for more information
@ -654,4 +654,27 @@ techage.register_node({"techage:ta4_lua_controller"}, {
return "unsupported"
end
end,
on_beduino_receive_cmnd = function(pos, src, topic, payload)
local meta = minetest.get_meta(pos)
local number = meta:get_string("number")
if topic == 1 and payload[1] == 1 then
set_input(pos, number, src, "on")
elseif topic == 1 and payload[1] == 0 then
set_input(pos, number, src, "off")
else
return 2
end
return 0
end,
on_beduino_request_data = function(pos, src, topic, payload)
local meta = minetest.get_meta(pos)
if topic == 142 then
local running = meta:get_int("running") or STATE_STOPPED
return 0, {running}
else
return 2, ""
end
end,
})

View File

@ -3,7 +3,7 @@
TechAge
=======
Copyright (C) 2019-2020 Joachim Stolberg
Copyright (C) 2019-2022 Joachim Stolberg
AGPL v3
See LICENSE.txt for more information
@ -46,6 +46,13 @@ local function send_command(pos)
end
end
local function get_stack(pos, idx)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
local stack = inv:get_stack("main", idx)
return stack:get_name(), stack:get_count()
end
local function get_stacks(pos)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
@ -215,7 +222,7 @@ techage.register_node({"techage:ta4_sensor_chest"}, {
elseif topic == "action" then
local meta = minetest.get_meta(pos)
local number = meta:get_string("node_number")
return PlayerActions[number][1], PlayerActions[number][2]
return (PlayerActions[number] or {})[1], (PlayerActions[number] or {})[2]
elseif topic == "stacks" then
return get_stacks(pos)
elseif topic == "text" then
@ -226,6 +233,40 @@ techage.register_node({"techage:ta4_sensor_chest"}, {
return "unsupported"
end
end,
on_beduino_receive_cmnd = function(pos, src, topic, payload)
if topic == 66 then
local meta = minetest.get_meta(pos)
meta:set_string("text", tostring(payload))
meta:set_string("formspec", formspec2(pos))
return 0
else
return 2
end
end,
on_beduino_request_data = function(pos, src, topic, payload)
if topic == 131 then -- Chest State
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
return 0, {techage.get_inv_state_num(inv, "main")}
elseif topic == 138 and payload[1] == 1 then -- Sensor Chests State (action)
local meta = minetest.get_meta(pos)
local number = meta:get_string("node_number")
local action = (PlayerActions[number] or {})[2] or "None"
return 0, {({put = 1, get = 2})[action] or 0}
elseif topic == 138 and payload[1] == 2 then -- Sensor Chests State (player name)
local meta = minetest.get_meta(pos)
local number = meta:get_string("node_number")
return 0, (PlayerActions[number] or {})[1]
elseif topic == 138 and payload[1] == 3 then -- Sensor Chests State (stack item name)
local name, _ = get_stack(pos, payload[2] or 1)
return 0, name
elseif topic == 138 and payload[1] == 4 then -- Sensor Chests State (stack item count)
local _, count = get_stack(pos, payload[2] or 1)
return 0, {count}
else
return 2, ""
end
end,
})
minetest.register_craft({

View File

@ -661,11 +661,15 @@ Der Tür Controller II kann alle Arten von Blöcken entfernen und wieder setzen.
Wird ein `on` / `off` Kommando an den Tür Controller II gesendet, entfernt bzw. setzt er die Blöcke ebenfalls.
Über ein `exchange` Kommando können einzelne Böcke gesetzt, entfernt, bzw. durch andere Blöcke ersetzt werden. Die Slot-Nummer des Inventars (1 .. 16) muss als payload übergeben werden, also:
Mit `$send_cmnd(node_number, "exchange", 2)` können einzelne Böcke gesetzt, entfernt, bzw. durch andere Blöcke aus dem Inventar ersetzt werden.
```
$send_cmnd(node_number, "exchange", 2)
```
Mit `$send_cmnd(node_number, "set", 2)` kann ein Block aus dem Inventory explizit gesetzt werden, sofern der Inventory Slot nicht leer ist.
Mit `$send_cmnd(node_number, "dig", 2)` kann ein Block wieder entfernt werden, sofern der Inventory Slot leer ist.
Mit `$send_cmnd(node_number, "get", 2)` wird der Name des gesetzten Blocks zurückgeliefert.
Die Slot-Nummer des Inventars (1 .. 16) muss in allen drei Fällen als payload übergeben werden.
Damit lassen sich auch ausfahrbare Treppen und ähnliches simulieren.
@ -679,7 +683,7 @@ Die Sounds können über das Menü und über ein Kommando ausgewählt und abgesp
- Kommando `on` zum Abspielen eines Sounds
- Kommando `sound <idx>` zur Auswahl eines Sounds über den Index
- Kommando `gain <volume>` zum Einstellen der Lautstärke über den `<volume>` Wert (0 bis 1.0).
- Kommando `gain <volume>` zum Einstellen der Lautstärke über den `<volume>` Wert (1 bis 5).
[ta3_soundblock|image]
@ -737,6 +741,14 @@ Soll die Suche auf bestimmte Spieler eingegrenzt werden, so können diese Spiele
[ta3_playerdetector|image]
### TA3 Lichtdetektor
Der Lichtdetektor sendet einen `on`-Kommando, wenn der Lichtpegel des darüber liegenden Blocks einen bestimmten Pegel überschreitet, der über das Rechtsklickmenü eingestellt werden kann.
Mit einen TA4 Lua Controller kann die genaue Lichtstärke mit $get_cmd(num, 'light_level') ermitteln werden.
[ta3_lightdetector|image]
## TA3 Maschinen
Bei TA3 existieren die gleichen Maschinen wie bei TA2, nur sind diese hier leistungsfähiger und benötigen Strom statt Achsenantrieb.

View File

@ -654,11 +654,15 @@ The door controller is used to control the TA3 door/gate blocks. With the door c
The Door Controller II can remove and set all types of blocks. To teach in the Door Controller II, the "Record" button must be pressed. Then all blocks that should be part of the door / gate must be clicked. Then the "Done" button must be pressed. Up to 16 blocks can be selected. The removed blocks are saved in the controller's inventory. The function of the controller can be tested manually using the "Remove" or "Set" buttons. If an `on` /`off` command is sent to the Door Controller II, it removes or sets the blocks as well.
Individual blocks can be set, removed or replaced by other blocks via an `exchange` command. The slot number of the inventory (1 .. 16) must be transferred as payload, i.e.:
With `$send_cmnd(node_number, "exchange", 2)` individual blocks can be set, removed or replaced by other blocks from the inventory.
```
$send_cmnd(node_number, "exchange", 2)
```
With `$send_cmnd(node_number, "set", 2)` a block from the inventory can be set explicitly, as long as the inventory slot is not empty.
A block can be removed again with `$send_cmnd(node_number, "dig", 2)` if the inventory slot is empty.
The name of the set block is returned with `$send_cmnd(node_number, "get", 2)`.
The slot number of the inventory (1 .. 16) must be passed as payload in all three cases.
This can also be used to simulate extendable stairs and the like.
@ -672,7 +676,7 @@ The sounds can be selected and played via the menu and via command.
- Command `on` to play a sound
- Command `sound <idx>` to select a sound via the index
- Command `gain <volume>` to adjust the volume via the `<volume>` value (0 to 1.0).
- Command `gain <volume>` to adjust the volume via the `<volume>` value (1 to 5).
[ta3_soundblock|image]
@ -730,6 +734,12 @@ If the search should be limited to specific players, these player names can also
[ta3_playerdetector|image]
### TA3 Light Detector
The light detector sends an `on` command if the light level of the block above exceeds a certain level, which can be set through the right-click menu.
If you have a TA4 Lua Controller, you can get the exact light level with $get_cmd(num, 'light_level')
[ta3_lightdetector|image]
## TA3 Machines

View File

@ -550,6 +550,7 @@ Der TA4 Sequenzer unterstützt folgende techage Kommandos:
- `goto <num>` Zu einer Kommandozeile springen und damit den Sequenzer starten
- `stop` Den Sequenzer anhalten
- `on` und `off` als Alias für `goto 1` bzw. `stop`
Das `goto` Kommando wird nur angenommen, wenn der Sequenzer gestoppt ist.
@ -843,6 +844,7 @@ Der TA4 Schieber besitzt zwei zusätzliche Kommandos für den Lua Controller:
- `config` dient zur Konfiguration des Schiebers, analog zum manuellen Konfiguration über das Menü.
Beispiel: `$send_cmnd(1234, "config", "default:dirt")`
Mit `$send_cmnd(1234, "config", "")` wird die Konfiguration gelöscht
- `pull` dient zum Absetzen eines Auftrags an den Schieber:
Beispiel: `$send_cmnd(1234, "pull", "default:dirt 8")`
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.

View File

@ -542,6 +542,7 @@ The TA4 sequencer supports the following techage commands:
- `goto <num>` Jump to a command line and start the sequencer
- `stop` Stop the sequencer
- `on` and `off` as aliases for `goto 1` resp. `stop`
The `goto` command is only accepted when the sequencer is stopped.
@ -835,6 +836,7 @@ The TA4 pusher has two additional commands for the Lua controller:
- `config` is used to configure the pusher, analogous to manual configuration via the menu.
Example: `$send_cmnd(1234, "config", "default: dirt")`
With `$send_cmnd(1234, "config", "")` the configuration is deleted
- `pull` is used to send an order to the pusher:
Example: `$send_cmnd(1234, "pull", "default: dirt 8")`
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.

View File

@ -374,7 +374,9 @@ Please note, that this is not a technical distinction, only a logical.
| "count" | number of items | Read the total amount of TA4 chest items. An optional number as `add_data` is used to address only one inventory slot (1..8, from left to right). |
| "itemstring" | item string of the given slot | Specific command for the TA4 8x2000 Chest to read the item type (technical name) of one chest slot, specified via `add_data` (1..8).<br />Example: s = $send_cmnd("223", "itemstring", 1) |
| "output" | recipe output string, <br />e.g.: "default:glass" | Only for the Industrial Furnace. If no recipe is active, the command returns "unknown" |
| "input" | `<index>` | Read a recipe from the TA4 Recipe Block. `<index>` is the number of the recipe. The block return a list of recipe items. |
| "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. |
| "name" | \<player name> | Player name of the TA3/TA4 Player Detector or TA4 Button |
| "time" | number | Time in system ticks (norm. 100 ms) when the TA4 Button is clicked |
@ -390,14 +392,19 @@ Please note, that this is not a technical distinction, only a logical.
| "red, "amber", "green", "off" | nil | set Signal Tower color |
| "red, "amber", "green", "off" | lamp number (1..4) | Set the signal lamp color. Valid for "TA4 2x Signal Lamp" and "TA4 4x Signal Lamp" |
| "port" | string<br />`<color>=on/off` | Enable/disable a Distributor filter slot..<br />Example: `"yellow=on"`<br />colors: red, green, blue, yellow |
| "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 |
| "reset" | nil | Reset the item counter of the TA4 Item Detector block |
| "pull" | item string | Start the TA4 pusher to pull/push items.<br /> Example: `default:dirt 8` |
| "config" | item string | Configure the TA4 pusher.<br />Example: `wool:blue` |
| "exchange" | inventory slot number | place/remove/exchange an block by means of the TA3 Door Controller II (techage:ta3_doorcontroller2) |
| "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 |
| "dig" | inventory slot number | TA3 Door Controller II (techage:ta3_doorcontroller2)<br />Dig/remove a block<br />*idx* is the empty inventory slot number (1..n) for the block |
| "a2b" | nil | TA4 Move Controller command to move the block(s) from position A to B |
| "b2a" | nil | TA4 Move Controller command to move the block(s) from position B to A |
| "move" | nil | TA4 Move Controller command to move the block(s) to the opposite position |
| "move2" | x,y,z | TA4 Move Controller command to move the block(s) by the given<br /> x/y/z-distance. Valid ranges for x, y, and z are -100 to 100. |
| "reset" | nil | Reset TA4 Move Controller (move block(s) to start position) |
| "left" | nil | TA4 Turn Controller command to turn the block(s) to the left |
| "right" | nil | TA4 Turn Controller command to turn the block(s) to the right |
| "uturn" | nil | TA4 Turn Controller command to turn the block(s) 180 degrees |

85
techage/manuals/ta_iom.md Normal file
View File

@ -0,0 +1,85 @@
# Techage/Beduino I/O Module
I/O modules support the following functions:
### event
Every signal that is sent to an I/O module triggers an event on the controller.
Events can be queried using the `event()` function.
If the function returns the value `1`, one or more signals have been received.
Calling `event()` resets the event flag.
```c
event()
```
### read
Read a value from a remote techage block.
- *port* is the I/O module port number
- *cmnd* is the command, like `IO_STATE` (see example code "ta_cmnd.c")
```c
read(port, cmnd)
```
### send_cmnd
Send a command to a techage block (see [commands](https://github.com/joe7575/beduino/blob/main/BEPs/bep-005_ta_cmnd.md)).
- *port* is the I/O module port number
- *topic* is a number from the list of [Beduino commands](https://github.com/joe7575/beduino/blob/main/BEPs/bep-005_ta_cmnd.md)
- *payload* is an array or a string with additional information, depending on the command. If no additional commands are required, "" can be used.
```c
send_cmnd(port, topic, payload)
```
### request_data
Request information from a techage block (see [commands](https://github.com/joe7575/beduino/blob/main/BEPs/bep-005_ta_cmnd.md)).
- *port* is the I/O module port number
- *topic* is a number from the list of [Beduino commands](https://github.com/joe7575/beduino/blob/main/BEPs/bep-005_ta_cmnd.md)
- *payload* is an array or a string with additional information, depending on the command. If no additional commands are required, "" can be used.
- *resp* is an array for the response data. The array must be defined large enough to hold the response data.
```c
request_data(port, topic, payload, resp)
```
## Functions for TA4 Display and TA4 Display XL
### clear_screen
Clear the display.
- *port* is the I/O module port number
```c
clear_screen(port)
```
### append_line
Add a new line to the display.
- *port* is the I/O module port number
- *text* is the text for one line
```c
append_line(port, text)
```
### write_line
Overwrite a text line with the given string.
- *port* is the I/O module port number
- *row* ist the display line/row (1-5)
- *text* is the text for one line
```c
write_line(port, row, text)
```

Some files were not shown because too many files have changed in this diff Show More