diff --git a/autobahn/init.lua b/autobahn/init.lua index 47caab1..9378b57 100644 --- a/autobahn/init.lua +++ b/autobahn/init.lua @@ -13,6 +13,7 @@ 2020-07-02 v0.04 further slope nodes added ]]-- +local S = minetest.get_translator("autobahn") autobahn = {} @@ -215,7 +216,7 @@ end local function register_node(name, tiles, drawtype, mesh, box, drop) minetest.register_node("autobahn:"..name, { - description = "Autobahn", + description = S("Autobahn"), tiles = tiles, drawtype = drawtype, mesh = mesh, @@ -290,7 +291,7 @@ end minetest.register_craftitem("autobahn:stripes", { - description = "Autobahn Stripe", + description = S("Autobahn Stripe"), inventory_image = 'autobahn_stripes.png', }) @@ -337,7 +338,7 @@ else recipe = "default:pine_tree", }) minetest.register_node("autobahn:tar", { - description = "Tar", + description = S("Tar"), tiles = {"autobahn1.png^[colorize:#000000:80"}, is_ground_content = false, groups = {cracky = 2}, diff --git a/autobahn/locale/autobahn.ru.tr b/autobahn/locale/autobahn.ru.tr new file mode 100644 index 0000000..f85073a --- /dev/null +++ b/autobahn/locale/autobahn.ru.tr @@ -0,0 +1,5 @@ +# textdomain: autobahn + +Autobahn=Шоссе +Autobahn Stripe=Дорожная Разметка +Tar=Дёготь diff --git a/autobahn/locale/template.txt b/autobahn/locale/template.txt new file mode 100644 index 0000000..e130010 --- /dev/null +++ b/autobahn/locale/template.txt @@ -0,0 +1,5 @@ +# textdomain: autobahn + +Autobahn= +Autobahn Stripe= +Tar= diff --git a/compost/init.lua b/compost/init.lua index 60d8f7d..71fc59d 100644 --- a/compost/init.lua +++ b/compost/init.lua @@ -1,3 +1,5 @@ +local S = minetest.get_translator("compost") + compost = {} -- Version for compatibility checks @@ -112,7 +114,7 @@ local function minecart_hopper_untakeitem(pos, in_dir, stack) end minetest.register_node("compost:wood_barrel", { - description = "Wood Barrel", + description = S("Wood Barrel"), tiles = {"default_wood.png"}, drawtype = "nodebox", node_box = { @@ -143,7 +145,7 @@ minetest.register_node("compost:wood_barrel", { }) minetest.register_node("compost:wood_barrel_1", { - description = "Wood Barrel with compost", + description = S("Wood Barrel with compost"), tiles = {"default_wood.png^compost_compost_1.png", "default_wood.png"}, drawtype = "nodebox", node_box = { @@ -164,7 +166,7 @@ minetest.register_node("compost:wood_barrel_1", { }) minetest.register_node("compost:wood_barrel_2", { - description = "Wood Barrel with compost", + description = S("Wood Barrel with compost"), tiles = {"default_wood.png^compost_compost_2.png", "default_wood.png"}, drawtype = "nodebox", node_box = { @@ -185,7 +187,7 @@ minetest.register_node("compost:wood_barrel_2", { }) minetest.register_node("compost:wood_barrel_3", { - description = "Wood Barrel", + description = S("Wood Barrel"), tiles = {"default_wood.png^compost_compost_3.png", "default_wood.png"}, drawtype = "nodebox", node_box = { @@ -238,14 +240,14 @@ minetest.register_craft({ }) minetest.register_node("compost:compost", { - description = "Compost", + description = S("Compost"), tiles = {"compost_compost.png"}, groups = {crumbly = 3}, sounds = default.node_sound_dirt_defaults(), }) minetest.register_node("compost:garden_soil", { - description = "Garden Soil", + description = S("Garden Soil"), tiles = {"compost_garden_soil.png"}, groups = {crumbly = 3, soil=3, grassland = 1, wet = 1}, sounds = default.node_sound_dirt_defaults(), diff --git a/compost/locale/compost.ru.tr b/compost/locale/compost.ru.tr new file mode 100644 index 0000000..f975d58 --- /dev/null +++ b/compost/locale/compost.ru.tr @@ -0,0 +1,6 @@ +# textdomain: compost + +Wood Barrel=Деревянная Бочка +Wood Barrel with compost=Деревянная Бочка с компостом +Compost=Компост +Garden Soil=Садовая Почва diff --git a/compost/locale/template.txt b/compost/locale/template.txt new file mode 100644 index 0000000..61ecaae --- /dev/null +++ b/compost/locale/template.txt @@ -0,0 +1,6 @@ +# textdomain: compost + +Wood Barrel= +Wood Barrel with compost= +Compost= +Garden Soil= \ No newline at end of file diff --git a/hyperloop/zh_CN.txt b/hyperloop/zh_CN.txt new file mode 100644 index 0000000..f1054d6 --- /dev/null +++ b/hyperloop/zh_CN.txt @@ -0,0 +1,79 @@ +Station data is corrupted. Please rebuild the station!=站点数据已损坏。请重建车站! +Station is still blocked. Please try again in a few seconds!=车站仍被封锁。请稍后再试! +Additional station information=附加电台信息 +Hyperloop Booking Machine=超级高铁订票机 +Invalid station name!=站名无效! +Please enter the station name to@nwhich this booking machine belongs.=请输入站名致@nwhich这台订票机属于。 +Station has already a booking machine!=车站已经有一台订票机了! +Station name=车站名称 +Select your destination=选择您的目的地 +=<未知> +Hyperloop Promo Poster =Hyperloop促销海报 +Hyperloop Station Sign=超级高铁站标志 +Hyperloop Station Sign Left=超级高铁站左标志 +Hyperloop Station Sign Right=右超级高铁线车站标志 +Hyperloop Door Bottom=Hyperloop门底 +Hyperloop Door Top=Hyperloop门套 +The Booking Machine for this station is missing!=这个车站的订票机不见了! +(current position)=(当前位置) +Base=基地 +Destination=目的地 +Floor=地板 +Floor name=楼层名称 +Hyperloop Elevator=超级高铁行电梯 +Hyperloop Elevator Shaft=超级高铁行电梯井 +Please insert floor name=请插入楼层名称 +Save=保存 +Hyperloop Junction Block=超级高铁型接线盒 +Hyperloop Pillar=超级高铁带支柱 +Junction connected with =连接 +Station connected with =连接的站点 +Junction=接合 +Hyperloop Display=超级高铁显示屏 + | | << Hyperloop >> | be anywhere=| | << 超级高铁 >>|随时随地 +Close=关闭 +Conn. with=连接 +Dist.=距离。 +Hyperloop Station Book=超级高铁线站点列表 +Owner=所有者 +Position=位置 +Station/Junction=车站/路口 +Hyperloop Legacy Tube=超级高铁传统管 +unknown=未知的 +Hypersteel Ingot=高铁钢锭 + | Welcome at | | =| 欢迎光临 || +Arrival in:=到达时间: +Destination:=目的地: +Distance:=距离: +Hyperloop Pod Seat=Hyperloop吊舱座椅 +Thank you | for | travelling | with | Hyperloop.=感谢您乘坐Hyperloop旅行。 +[Hyperloop] No booking entered!=[Hyperloop]没有预订! +Area is protected!=区域受到保护! +Blue Wool=蓝色羊毛 +Build Station=建立站点 +Destroy Station=摧毁站点 +Glass=玻璃 +Hyperloop Pod Shell=超级高铁吊舱外壳 +Hyperloop Station Block=超级高铁车站方块 +Hyperloop Station Pod Builder=超级高铁吊舱建造者 +Not enough inventory items to build the station!=没有足够的库存物品来建造车站! +Not enough space to build the station!=没有足够的空间建造车站! +Station=车站 +Station completed. Now place the Booking Machine!=车站已完工。现在把订票机放好! +Do you really want to start a new network?!=你真的想建立一个新的网络吗?! +Hyperloop Tube=超级高铁行管 +Junction at =交叉口 +Open end at =开口端在 +Station '=车站' +Station at =车站 +There is no station/junction on this level. =这一层没有车站/交叉口。 + left: remove node@n=左:移除节点@n + right: repair tube/shaft line@n=右:维修管/轴线@n +Hyperloop Tube Crowbar=高铁管子撬棍 +Repair via WorldEdit placed Hyperloop tubes by reusing WorldEdit pos1/pos2=通过重用WorldEdit pos1/pos2通过WorldEdit放置的超循环管进行修复 +Rights to remove tube nodes by means of the crowbar=使用撬棍移除管节点的权限 +You don't have the necessary privs!=你没有必要的权限! +[Crowbar Help]@n=【撬棍帮助】@n +Hyperloop Waypoint=超级高铁航线路点 +Enter channel string=输入通道字符串 +Hyperloop WiFi Tube=Hyperloop WiFi管 diff --git a/lcdlib/init.lua b/lcdlib/init.lua index f3fd593..058ce7e 100644 --- a/lcdlib/init.lua +++ b/lcdlib/init.lua @@ -68,7 +68,7 @@ local function get_next_char(text, pos) end -- 2 bytes char (little endian) - if char >= 0xC2 then + if char >= 0xC2 and #text > pos then pos = pos + 1 return (char - 0xC2) * 0x40 + text:sub(pos, pos):byte(), pos end diff --git a/minecart/README.md b/minecart/README.md index 50e6ffe..800c0e0 100644 --- a/minecart/README.md +++ b/minecart/README.md @@ -115,4 +115,5 @@ History 2020-05-14 v1.05 API changed to be able to register carts 2020-06-14 v1.06 API changed and chat command added 2020-06-27 v1.07 Route storage and cart command bugfixes +2020-07-24 V1.08 Adapted to new techage ICTA style diff --git a/minecart/cart_lib1.lua b/minecart/cart_lib1.lua index aa4ea0e..92f3c76 100644 --- a/minecart/cart_lib1.lua +++ b/minecart/cart_lib1.lua @@ -309,7 +309,7 @@ local function rail_on_step(self, dtime) end -- Slow down or speed up.. - local acc = dir.y * -2.0 + local acc = dir.y * -1.5 -- Get rail for corrected position railparams = get_railparams(pos) diff --git a/minecart/init.lua b/minecart/init.lua index 37e3a9d..a7f7ac4 100644 --- a/minecart/init.lua +++ b/minecart/init.lua @@ -13,7 +13,7 @@ minecart = {} -- Version for compatibility checks, see readme.md/history -minecart.version = 1.07 +minecart.version = 1.08 minecart.hopper_enabled = minetest.settings:get_bool("minecart_hopper_enabled") ~= false diff --git a/minecart/monitoring.lua b/minecart/monitoring.lua index 34fb726..5f6f3fd 100644 --- a/minecart/monitoring.lua +++ b/minecart/monitoring.lua @@ -288,10 +288,15 @@ minetest.register_on_mods_loaded(function() local number = tonumber(data.number) or 0 return 'cart_state('..number..')' end, - code = function(data, environ) - local s = 'minecart.cmnd_cart_state("%s", %u)' - local number = tonumber(data.number) or 0 - return string.format(s, environ.owner, number), "~= 0" + code = function(data, environ) + local condition = function(env, idx) + local number = tonumber(data.number) or 0 + return minecart.cmnd_cart_state(environ.owner, number) + end + local result = function(val) + return val ~= 0 + end + return condition, result end, }) techage.icta_register_condition("cart_location", { @@ -313,10 +318,15 @@ minetest.register_on_mods_loaded(function() local number = tonumber(data.number) or 0 return 'cart_loc('..number..')' end, - code = function(data, environ) - local s = 'minecart.cmnd_cart_location("%s", %u, env.pos)' - local number = tonumber(data.number) or 0 - return string.format(s, environ.owner, number), "~= 0" + code = function(data, environ) + local condition = function(env, idx) + local number = tonumber(data.number) or 0 + return minecart.cmnd_cart_location(environ.owner, number, env.pos) + end + local result = function(val) + return val ~= 0 + end + return condition, result end, }) techage.lua_ctlr.register_function("cart_state", { diff --git a/safer_lua/environ.lua b/safer_lua/environ.lua index 4a0fb51..f038f4f 100644 --- a/safer_lua/environ.lua +++ b/safer_lua/environ.lua @@ -14,7 +14,7 @@ safer_lua.MaxCodeSize = 5000 -- size if source code in bytes safer_lua.MaxTableSize = 1000 -- sum over all table sizes -safer_lua.MaxExeTime = 5000 -- max. execution time in us +safer_lua.MaxExeTime = 20000 -- max. execution time in us local function memsize() return safer_lua.MaxTableSize @@ -57,7 +57,10 @@ local BASE_ENV = { rep = string.rep, sub = string.sub, upper = string.upper, - split = string.split, + split = function(str, separator, include_empty, max_splits, sep_is_pattern) + if separator == "" then separator = " " end + return safer_lua.Array(unpack(string.split(str, separator, include_empty, max_splits, sep_is_pattern))) + end, trim = string.trim, }, tonumber = tonumber, diff --git a/signs_bot/cmd_sign.lua b/signs_bot/cmd_sign.lua index 57ff3ce..811b276 100644 --- a/signs_bot/cmd_sign.lua +++ b/signs_bot/cmd_sign.lua @@ -47,6 +47,7 @@ local function formspec1(meta) default.gui_bg.. default.gui_bg_img.. default.gui_slots.. + "style_type[textarea,table;font=mono]".. "tabheader[0,0;tab;"..I("Commands,Help")..";1;;true]".. "field[0.3,0.5;9,1;name;"..I("Sign name:")..";"..name.."]".. "textarea[0.3,1.2;9,7.2;cmnd;;"..cmnd.."]".. @@ -60,6 +61,7 @@ local function formspec2(pos, text) default.gui_bg.. default.gui_bg_img.. default.gui_slots.. + "style_type[textarea,table;font=mono]".. "tabheader[0,0;tab;"..I("Commands,Help")..";2;;true]".. "table[0.1,0;8.6,4;command;"..sCmnds..";"..pos.."]".. "textarea[0.3,4.5;9,3.5;help;Help:;"..text.."]".. diff --git a/signs_bot/techage.lua b/signs_bot/techage.lua index 44aa6b6..6aa7ee6 100644 --- a/signs_bot/techage.lua +++ b/signs_bot/techage.lua @@ -69,7 +69,7 @@ if minetest.get_modpath("techage") then mod = "techage", params = "", num_param = 1, - description = S("Turn the bot off if the\nbattery power is below the\ngiven value (1..99)"), + description = S("Turns the bot off if the\nbattery power is below the\ngiven value in percent (1..99)"), check = function(val) val = tonumber(val) or 5 return val and val > 0 and val < 100 @@ -81,7 +81,7 @@ if minetest.get_modpath("techage") then signs_bot.stop_robot(base_pos, mem) return signs_bot.TURN_OFF end - return true + return signs_bot.DONE end, }) diff --git a/techage/README.md b/techage/README.md index a34fc71..6bbdd8e 100644 --- a/techage/README.md +++ b/techage/README.md @@ -31,6 +31,8 @@ Copyright (C) 2019-2020 Joachim Stolberg Code: Licensed under the GNU GPL version 3 or later. See LICENSE.txt Textures: CC BY-SA 3.0 +Many thanks to Thomas-S for his contributions + ### Dependencies Required: default, doors, bucket, stairs, screwdriver, basic_materials, tubelib2, minecart, lcdlib, safer_lua @@ -75,6 +77,23 @@ Available worlds will be converted to 'lsqlite3', but there is no way back, so: ### History +**2020-08-08 V0.21** +- Pull request #18: Add a simple Digtron battery (from Thomas-S) +- Pull request #23: Lua Controller: Fix $item_description() documentation and translation (from Thomas-S) +- Pull request #24: Distributor: improve fairness by using random spread (from realmicu) +- Bugfix: TA1 meridian hammer did not glow (from realmicu) +- Bugfix: power.power_available() did not check the network state + +**2020-07-31 V0.20** +- Pull request #21: Lua Controller: Allow to get itemstring and description of 8x2000 chest contents (from Thomas-S) +- Pull request #22: Trowel: Prevent hidden nodes from being dug (from Thomas-S) +- Improvement: TA3 Power Terminal: Outputs max needed power in addition +- Bugfix: Quarry: Shall not dig Techage Light Blocks + +**2020-07-24 V0.19** +- Pull request #19: Refactor ICTA to use functions instead of loadstring (from Thomas-S) +- State command added for cart-, node-, and player detectors + **2020-07-21 V0.18** - Pull request #13: Use Monospace Font for Code-Related Formspecs (from Thomas-S) - Pull request #14: Don't allow to put items with meta or wear information into the 8x2000 chest (from Thomas-S) diff --git a/techage/basic_machines/consumer.lua b/techage/basic_machines/consumer.lua index 53abb76..e7f1c95 100644 --- a/techage/basic_machines/consumer.lua +++ b/techage/basic_machines/consumer.lua @@ -176,6 +176,10 @@ function techage.register_consumer(base_name, inv_name, tiles, tNode, validState local node = minetest.get_node(pos) meta:set_int("push_dir", techage.side_to_indir("L", node.param2)) meta:set_int("pull_dir", techage.side_to_indir("R", node.param2)) + -- Delete existing node number. Needed for Digtron compatibility. + if (meta:contains("node_number")) then + meta:set_string("node_number", "") + end local number = "-" if stage > 2 then number = techage.add_node(pos, name_pas) @@ -240,6 +244,7 @@ function techage.register_consumer(base_name, inv_name, tiles, tNode, validState paramtype = tNode.paramtype, paramtype2 = "facedir", + drop = tNode.drop, groups = table.copy(tNode.groups), is_ground_content = false, sounds = tNode.sounds, diff --git a/techage/basic_machines/distributor.lua b/techage/basic_machines/distributor.lua index fb23c52..e4f9e27 100644 --- a/techage/basic_machines/distributor.lua +++ b/techage/basic_machines/distributor.lua @@ -35,6 +35,19 @@ local SlotColors = {"red", "green", "blue", "yellow"} local Num2Ascii = {"B", "L", "F", "R"} local FilterCache = {} -- local cache for filter settings +-- Permutation table to improve distribution between ports (number of ports: 1-4) +-- Usage: permIdx[num_ports][math.random(1, #permIdx[num_ports])][idx] +local permIdx = { + { { 1 } }, + { { 1, 2 }, { 2, 1 } }, + { { 1, 2, 3 }, { 1, 3, 2 }, { 2, 1, 3 }, { 2, 3, 1 }, { 3, 1, 2 }, { 3, 2, 1 } }, + { { 1, 2, 3, 4 }, { 1, 2, 4, 3 }, { 1, 3, 2, 4 }, { 1, 3, 4, 2 }, { 1, 4, 2, 3 }, + { 1, 4, 3, 2 }, { 2, 1, 3, 4 }, { 2, 1, 4, 3 }, { 2, 3, 1, 4 }, { 2, 3, 4, 1 }, + { 2, 4, 1, 3 }, { 2, 4, 3, 1 }, { 3, 1, 2, 4 }, { 3, 1, 4, 2 }, { 3, 2, 1, 4 }, + { 3, 2, 4, 1 }, { 3, 4, 1, 2 }, { 3, 4, 2, 1 }, { 4, 1, 2, 3 }, { 4, 1, 3, 2 }, + { 4, 2, 1, 3 }, { 4, 2, 3, 1 }, { 4, 3, 1, 2 }, { 4, 3, 2, 1 }, } +} + local function filter_settings(pos) local meta = M(pos) local param2 = techage.get_node_lvm(pos).param2 @@ -206,11 +219,12 @@ local function push_item(pos, filter, item_name, num_items, nvm) local idx = 1 local num_pushed = 0 local num_ports = #filter + local randidx = permIdx[num_ports][math.random(1, #permIdx[num_ports])] local amount = math.floor(math.max((num_items + 1) / num_ports, 1)) local num_of_trials = 0 while num_pushed < num_items and num_of_trials <= 8 do num_of_trials = num_of_trials + 1 - local push_dir = filter[idx] + local push_dir = filter[randidx[idx]] local num_to_push = math.min(amount, num_items - num_pushed) if techage.push_items(pos, push_dir, ItemStack(item_name.." "..num_to_push)) then num_pushed = num_pushed + num_to_push diff --git a/techage/basic_machines/source.lua b/techage/basic_machines/source.lua index 441c0eb..39bdc94 100644 --- a/techage/basic_machines/source.lua +++ b/techage/basic_machines/source.lua @@ -26,7 +26,7 @@ local networks = techage.networks local STANDBY_TICKS = 4 local COUNTDOWN_TICKS = 4 local CYCLE_TIME = 2 -local PWR_CAPA = 20 +local PWR_CAPA = 100 local function formspec(self, pos, nvm) return "size[4,4]".. diff --git a/techage/basic_machines/ta4_chest.lua b/techage/basic_machines/ta4_chest.lua index a9a0d86..868ebfa 100644 --- a/techage/basic_machines/ta4_chest.lua +++ b/techage/basic_machines/ta4_chest.lua @@ -65,6 +65,16 @@ local function get_count(nvm, idx) end end +local function get_itemstring(nvm, idx) + if idx and idx > 0 then + nvm.inventory = nvm.inventory or {} + if nvm.inventory[idx] then + return nvm.inventory[idx].name or "" + end + end + return "" +end + local function inv_empty(nvm) for _,item in ipairs(nvm.inventory or {}) do if item.count and item.count > 0 then @@ -552,6 +562,9 @@ techage.register_node({"techage:ta4_chest"}, { if topic == "count" then local nvm = techage.get_nvm(pos) return get_count(nvm, tonumber(payload) or 0) + elseif topic == "itemstring" then + local nvm = techage.get_nvm(pos) + return get_itemstring(nvm, tonumber(payload) or 0) elseif topic == "state" then local nvm = techage.get_nvm(pos) return inv_state(nvm) diff --git a/techage/basis/command.lua b/techage/basis/command.lua index 12fe9d1..ae850b3 100644 --- a/techage/basis/command.lua +++ b/techage/basis/command.lua @@ -219,7 +219,7 @@ end function techage.remove_node(pos, oldnode, oldmetadata) local number = oldmetadata and oldmetadata.fields and oldmetadata.fields.node_number number = number or get_number(pos) - if number then + if number and tonumber(number) then local key = minetest.hash_node_position(pos) NumbersToBeRecycled[key] = number local ninfo = NodeInfoCache[number] or update_nodeinfo(number) diff --git a/techage/basis/lib.lua b/techage/basis/lib.lua index 1493fa6..4f50747 100644 --- a/techage/basis/lib.lua +++ b/techage/basis/lib.lua @@ -164,6 +164,7 @@ end function techage.dropped_node(node, ndef) if node.name == "air" then return end --if ndef.buildable_to == true then return end + if not ndef.diggable then return end if ndef.drop == "" then return end if type(ndef.drop) == "table" then return handle_drop(ndef.drop) diff --git a/techage/digtron/battery.lua b/techage/digtron/battery.lua new file mode 100644 index 0000000..ba09deb --- /dev/null +++ b/techage/digtron/battery.lua @@ -0,0 +1,182 @@ +--[[ + + TechAge + ======= + + Copyright (C) 2019-2020 Joachim Stolberg + Copyright (C) 2020 Thomas S. + + GPL v3 + See LICENSE.txt for more information + + Electricity powered battery for Digtron + +]]-- + +-- for lazy programmers +local M = minetest.get_meta +local S = techage.S + +-- Consumer Related Data +local CRD = function(pos) return (minetest.registered_nodes[techage.get_node_lvm(pos).name] or {}).consumer end +local power = techage.power + +local STANDBY_TICKS = 3 +local COUNTDOWN_TICKS = 4 +local CYCLE_TIME = 4 +local INV_SIZE = 4 +local FUEL = "default:coal_lump" +local FUEL_STACK_MAX = ItemStack(FUEL):get_stack_max() +local TOTAL_MAX = INV_SIZE * FUEL_STACK_MAX + +local function count_coal(metadata) + local total = 0 + for _,stack in pairs(metadata.inventory.fuel) do + total = total + stack:get_count() + end + return total +end + +local function formspec(self, pos, nvm) + local meta = M(pos):to_table() + local total = 0 + if meta.inventory then + total = count_coal(meta) + end + return "size[5,4]".. + default.gui_bg.. + default.gui_bg_img.. + default.gui_slots.. + "box[0,-0.1;4.8,0.5;#c6e8ff]".. + "label[1,-0.1;"..minetest.colorize("#000000", S("Digtron Battery")).."]".. + power.formspec_label_bar(0, 0.8, S("Load"), TOTAL_MAX, total, S("Coal Equivalents")).. + "image_button[2.6,2;1,1;".. self:get_state_button_image(nvm) ..";state_button;]".. + "tooltip[2.6,2;1,1;"..self:get_state_tooltip(nvm).."]".. + "image[3.75,2;1,1;"..techage.get_power_image(pos, nvm).."]" +end + +local function allow_metadata_inventory_put(pos, listname, index, stack, player) + return 0 +end + +local function allow_metadata_inventory_move(pos, from_list, from_index, to_list, to_index, count, player) + return 0 +end + +local function allow_metadata_inventory_take(pos, listname, index, stack, player) + return 0 +end + +local function produce_coal(pos, crd, nvm, inv) + local stack = ItemStack(FUEL) + if inv:room_for_item("fuel", stack) then + inv:add_item("fuel", stack) + crd.State:keep_running(pos, nvm, COUNTDOWN_TICKS) + else + crd.State:idle(pos, nvm) + end +end + +local function keep_running(pos, elapsed) + local nvm = techage.get_nvm(pos) + local crd = CRD(pos) + local inv = M(pos):get_inventory() + produce_coal(pos, crd, nvm, inv) + + if techage.is_activeformspec(pos) then + M(pos):set_string("formspec", formspec(CRD(pos).State, pos, nvm)) + end +end + +local function on_receive_fields(pos, formname, fields, player) + if minetest.is_protected(pos, player:get_player_name()) then + return + end + local nvm = techage.get_nvm(pos) + CRD(pos).State:state_button_event(pos, nvm, fields) +end + + +local tiles = {} +-- '#' will be replaced by the stage number +-- '{power}' will be replaced by the power PNG + +tiles = { + -- up, down, right, left, back, front + "digtron_plate.png^digtron_core.png", + "digtron_plate.png^digtron_core.png", + "digtron_plate.png^digtron_battery.png", + "digtron_plate.png^digtron_battery.png", + "digtron_plate.png^digtron_battery.png", + "digtron_plate.png^digtron_battery.png", +} + +local tubing = { + on_recv_message = function(pos, src, topic, payload) + return CRD(pos).State:on_receive_message(pos, topic, payload) + end, +} + +local node_name_ta2, node_name_ta3, node_name_ta4 = +techage.register_consumer("digtron_battery", S("Digtron Battery"), { act = tiles, pas = tiles }, { + drawtype = "normal", + paramtype = "light", + cycle_time = CYCLE_TIME, + standby_ticks = STANDBY_TICKS, + formspec = formspec, + tubing = tubing, + after_place_node = function(pos, placer, itemstack) + local inv = M(pos):get_inventory() + inv:set_size('fuel', INV_SIZE) + if itemstack then + local stack_meta = itemstack:get_meta() + if stack_meta then + local coal_amount = techage.in_range(stack_meta:get_int("coal"), 0, TOTAL_MAX) + while coal_amount > 0 do + local amount = math.min(coal_amount, FUEL_STACK_MAX) + inv:add_item("fuel", ItemStack(FUEL.." "..amount)) + coal_amount = coal_amount - amount; + end + end + end + end, + after_dig_node = function(pos, oldnode, oldmetadata, digger) + local node = ItemStack(oldnode.name) + if oldmetadata.inventory then + local total = count_coal(oldmetadata) + local meta = node:get_meta() + meta:set_int("coal", total) + local text = S("Digtron Battery").." ("..math.floor(total/TOTAL_MAX * 100).." %)" + meta:set_string("description", text) + end + local inv = minetest.get_inventory({type="player", name=digger:get_player_name()}) + local left_over = inv:add_item("main", node) + if left_over:get_count() > 0 then + minetest.add_item(pos, node) + end + end, + on_rightclick = function(pos, node, clicker) + techage.set_activeformspec(pos, clicker) + local nvm = techage.get_nvm(pos) + M(pos):set_string("formspec", formspec(CRD(pos).State, pos, nvm)) + end, + drop = "", + node_timer = keep_running, + on_receive_fields = on_receive_fields, + allow_metadata_inventory_put = allow_metadata_inventory_put, + allow_metadata_inventory_move = allow_metadata_inventory_move, + allow_metadata_inventory_take = allow_metadata_inventory_take, + groups = {choppy=2, cracky=2, crumbly=2, digtron=5}, + sounds = default.node_sound_wood_defaults(), + power_consumption = {0,25,25,25}, + power_sides = techage.networks.AllSides, +}, {false, false, true, false}) + +minetest.register_craft({ + output = node_name_ta3, + recipe = { + {"group:wood", "default:copper_ingot", "group:wood"}, + {"techage:electric_cableS", "default:tin_ingot", "digtron:digtron_core"}, + {"group:wood", "default:copper_ingot", "group:wood"}, + }, +}) diff --git a/techage/icta_controller/action.lua b/techage/icta_controller/action.lua index 2a44b17..e10e370 100644 --- a/techage/icta_controller/action.lua +++ b/techage/icta_controller/action.lua @@ -99,9 +99,10 @@ techage.icta_register_action("print", { return 'print("'..data.text:sub(1,12)..'")' end, code = function(data, environ) - local s1 = 'local text = string.gsub("'..(techage.icta_escape(data.text))..'", "*", env.result[#])' - local s2 = 'output(env.pos, text)' - return s1.."\n\t"..s2 + return function(env, output, idx) + local text = string.gsub(data.text, "*", tostring(env.result[idx])) + output(env.pos, text) + end end, }) diff --git a/techage/icta_controller/commands.lua b/techage/icta_controller/commands.lua index 64b1332..4aff35c 100644 --- a/techage/icta_controller/commands.lua +++ b/techage/icta_controller/commands.lua @@ -16,32 +16,19 @@ local M = minetest.get_meta local S = techage.S local logic = techage.logic - -local function send_single_string(environ, number, topic, payload) - payload = payload or "nil" - local s = 'techage.send_single("%s", "%s", "%s", %s)' - return string.format(s, environ.number, number, topic, payload) -end - -local function send_multi_string(environ, numbers, topic, payload) - payload = payload or "nil" - local s = 'techage.send_multi("%s", "%s", "%s", %s)' - return string.format(s, environ.number, numbers, topic, payload) -end -function techage.operand(s) - if s == "is" then - return "== " - elseif s == "is not" then - return "~= " - elseif s == "greater" then - return "> " - elseif s == "less" then - return "< " +function techage.compare(op1, op2, method) + if method == "is" then + return op1 == op2 + elseif method == "is not" then + return op1 ~= op2 + elseif method == "greater" then + return op1 > op2 + elseif method == "less" then + return op1 < op2 end end - function techage.fmt_number(num) local mtch = num:match('^(%d+).*') if mtch and num ~= mtch then @@ -50,13 +37,6 @@ function techage.fmt_number(num) return num end --- '#' is used as placeholder for rule numbers and has to be escaped -function techage.icta_escape(s) - s = tostring(s) - s = s:gsub('"', '\\"') -- to prevent code injection!!! - return s:gsub("#", '"..string.char(35).."') -end - techage.icta_register_condition("initial", { title = "initial", @@ -69,8 +49,14 @@ techage.icta_register_condition("initial", { }, -- Return two chunks of executable Lua code for the controller, according: -- return , - code = function(data, environ) - return 'env.ticks', '== 1' + code = function(data, environ) + local condition = function(env, idx) + return env.ticks + end + local result = function(val) + return val == 1 + end + return condition, result end, button = function(data, environ) return "Initial after start" end, }) @@ -84,8 +70,14 @@ techage.icta_register_condition("true", { label = "Condition is always true.", }, }, - code = function(data, environ) - return '"true"', '== "true"' + code = function(data, environ) + local condition = function(env, idx) + return true + end + local result = function(val) + return val == true + end + return condition, result end, button = function(data, environ) return "true" end, }) @@ -113,13 +105,15 @@ techage.icta_register_condition("condition", { label = "Used to execute two or more\nactions based on one condition.", }, }, - code = function(data, environ) - local idx = data.condition:byte(-1) - 0x30 - local expected_result = "== false" - if data.operand == "was true" then - expected_result = "== true" + code = function(data, environ) + local condition = function(env, idx) + local index = data.condition:byte(-1) - 0x30 + return env.condition[index] end - return "env.condition["..idx.."]", expected_result + local result = function(val) + return val == (data.operand == "was true") + end + return condition, result end, button = function(data, environ) return "cond("..data.condition:sub(-1,-1)..","..data.operand..")" end, }) @@ -154,9 +148,14 @@ techage.icta_register_condition("input", { button = function(data, environ) -- default button label return 'inp('..techage.fmt_number(data.number)..','..data.operand.." "..data.value..')' end, - code = function(data, environ) - return 'env.input["'..data.number..'"]', - techage.operand(data.operand)..'"'..data.value..'"' + code = function(data, environ) + local condition = function(env, idx) + return env.input[data.number] + end + local result = function(val) + return techage.compare(val, data.value, data.operand) + end + return condition, result end, }) @@ -192,9 +191,14 @@ techage.icta_register_condition("state", { button = function(data, environ) -- default button label return 'sts('..techage.fmt_number(data.number)..","..data.operand..' '..data.value..')' end, - code = function(data, environ) - return send_single_string(environ, data.number, "state"), - techage.operand(data.operand)..'"'..data.value..'"' + code = function(data, environ) + local condition = function(env, idx) + return techage.send_single(environ.number, data.number, "state") + end + local result = function(val) + return techage.compare(val, data.value, data.operand) + end + return condition, result end, }) @@ -229,9 +233,14 @@ techage.icta_register_condition("fuel", { button = function(data, environ) return 'fuel('..techage.fmt_number(data.number)..","..data.operand..' '..data.value..')' end, - code = function(data, environ) - return send_single_string(environ, data.number, "fuel"), - techage.operand(data.operand)..tonumber(data.value) + code = function(data, environ) + local condition = function(env, idx) + return techage.send_single(environ.number, data.number, "fuel") + end + local result = function(val) + return techage.compare(val, tonumber(data.value), data.operand) + end + return condition, result end, }) @@ -266,9 +275,14 @@ techage.icta_register_condition("load", { button = function(data, environ) return 'load('..techage.fmt_number(data.number)..","..data.operand..' '..data.value..')' end, - code = function(data, environ) - return send_single_string(environ, data.number, "load"), - techage.operand(data.operand)..tonumber(data.value) + code = function(data, environ) + local condition = function(env, idx) + return techage.send_single(environ.number, data.number, "load") + end + local result = function(val) + return techage.compare(val, tonumber(data.value), data.operand) + end + return condition, result end, }) @@ -303,9 +317,14 @@ techage.icta_register_condition("depth", { button = function(data, environ) return 'depth('..techage.fmt_number(data.number)..","..data.operand..' '..data.value..')' end, - code = function(data, environ) - return send_single_string(environ, data.number, "depth"), - techage.operand(data.operand)..tonumber(data.value) + code = function(data, environ) + local condition = function(env, idx) + return techage.send_single(environ.number, data.number, "depth") + end + local result = function(val) + return techage.compare(val, tonumber(data.value), data.operand) + end + return condition, result end, }) @@ -340,9 +359,14 @@ techage.icta_register_condition("delivered", { button = function(data, environ) return 'deliv('..techage.fmt_number(data.number)..","..data.operand..' '..data.value..')' end, - code = function(data, environ) - return send_single_string(environ, data.number, "delivered"), - techage.operand(data.operand)..tonumber(data.value) + code = function(data, environ) + local condition = function(env, idx) + return techage.send_single(environ.number, data.number, "delivered") + end + local result = function(val) + return techage.compare(val, tonumber(data.value), data.operand) + end + return condition, result end, }) @@ -379,9 +403,14 @@ techage.icta_register_condition("chest", { button = function(data, environ) -- default button label return 'chest('..techage.fmt_number(data.number)..","..data.operand..' '..data.value..')' end, - code = function(data, environ) - return send_single_string(environ, data.number, "state"), - techage.operand(data.operand)..'"'..data.value..'"' + code = function(data, environ) + local condition = function(env, idx) + return techage.send_single(environ.number, data.number, "state") + end + local result = function(val) + return techage.compare(val, data.value, data.operand) + end + return condition, result end, }) @@ -415,9 +444,14 @@ techage.icta_register_condition("signaltower", { button = function(data, environ) -- default button label return 'tower('..techage.fmt_number(data.number)..","..data.operand..' '..data.value..')' end, - code = function(data, environ) - return send_single_string(environ, data.number, "state"), - techage.operand(data.operand)..'"'..data.value..'"' + code = function(data, environ) + local condition = function(env, idx) + return techage.send_single(environ.number, data.number, "state") + end + local result = function(val) + return techage.compare(val, data.value, data.operand) + end + return condition, result end, }) @@ -447,7 +481,9 @@ techage.icta_register_action("signaltower", { return 'tower('..techage.fmt_number(data.number)..","..data.value..')' end, code = function(data, environ) - return send_multi_string(environ, data.number, data.value) + return function(env, output, idx) + techage.send_multi(environ.number, data.number, data.value) + end end, }) @@ -477,7 +513,9 @@ techage.icta_register_action("switch", { return 'turn('..techage.fmt_number(data.number)..","..data.value..')' end, code = function(data, environ) - return send_multi_string(environ, data.number, data.value) + return function(env, output, idx) + techage.send_multi(environ.number, data.number, data.value) + end end, }) @@ -509,11 +547,14 @@ techage.icta_register_action("display", { label = "Use a '*' character as reference\nto any condition result", }, }, - code = function(data, environ) - local s1 = string.format('local text = string.gsub("%s", "*", tostring(env.result[#]))', techage.icta_escape(data.text)) - local s2 = string.format('local payload = {row = %s, str = text}', data.row) - local s3 = send_multi_string(environ, data.number, "set", "payload") - return s1.."\n\t"..s2.."\n\t"..s3 + code = function(data, environ) + return function(env, output, idx) + local text = string.gsub(data.text, "*", tostring(env.result[idx])) + local payload = safer_lua.Store() + payload.set("row", data.row) + payload.set("str", text) + techage.send_multi(environ.number, data.number, "set", payload) + end end, button = function(data, environ) return "lcd("..techage.fmt_number(data.number)..","..data.row..',"'..data.text..'")' @@ -530,8 +571,10 @@ techage.icta_register_action("cleardisplay", { default = "", }, }, - code = function(data, environ) - return send_multi_string(environ, data.number, "clear") + code = function(data, environ) + return function(env, output, idx) + techage.send_multi(environ.number, data.number, "clear") + end end, button = function(data, environ) return "clear lcd("..techage.fmt_number(data.number)..")" @@ -553,8 +596,10 @@ techage.icta_register_action("chat", { label = "The chat message is send to the\nController owner, only.", }, }, - code = function(data, environ) - return 'minetest.chat_send_player("'..environ.owner..'", "[TA4 ICTA Controller] '..techage.icta_escape(data.text)..' ")' + code = function(data, environ) + return function(env, output, idx) + minetest.chat_send_player(environ.owner, "[TA4 ICTA Controller] "..data.text) + end end, button = function(data, environ) return 'chat("'..data.text:sub(1,12)..'")' @@ -602,8 +647,10 @@ techage.icta_register_action("door", { "Use the Techage Info Tool to\neasily determine a door position.", }, }, - code = function(data, environ) - return 'techage.icta_door_toggle("'..data.pos..'", "'..environ.owner..'", "'..data.door_state..'")' + code = function(data, environ) + return function(env, output, idx) + techage.icta_door_toggle(data.pos, environ.owner, data.door_state) + end end, button = function(data, environ) return 'door("'..data.pos..'",'..data.door_state..")" @@ -644,8 +691,14 @@ techage.icta_register_condition("playerdetector", { }, }, - code = function(data, environ) - return 'techage.icta_player_detect("'..environ.number..'", "'..data.number..'", "'..techage.icta_escape(data.name)..'")', "~= nil" + code = function(data, environ) + local condition = function(env, idx) + return techage.icta_player_detect(environ.number, data.number, data.name) + end + local result = function(val) + return val ~= nil + end + return condition, result end, button = function(data, environ) return "detector("..techage.fmt_number(data.number)..","..data.name:sub(1,8)..")" @@ -685,7 +738,9 @@ techage.icta_register_action("set_filter", { return 'turn('..techage.fmt_number(data.number)..","..data.color..","..data.value..')' end, code = function(data, environ) - local payload = '{slot = "'..data.color..'", val = "'..data.value..'"}' - return send_single_string(environ, data.number, "filter", payload) + return function(env, output, idx) + local payload = data.color.."="..data.value + techage.send_single(environ.number, data.number, "port", payload) + end end, }) diff --git a/techage/icta_controller/condition.lua b/techage/icta_controller/condition.lua index 4e025d0..6d560ee 100644 --- a/techage/icta_controller/condition.lua +++ b/techage/icta_controller/condition.lua @@ -71,7 +71,15 @@ end techage.icta_register_condition("default", { title = "", formspec = {}, - code = function(data, environ) return false, false end, + code = function(data, environ) + local condition = function(env, idx) + return false + end + local result = function(val) + return false + end + return condition, result + end, button = function(data, environ) return "..." end, }) diff --git a/techage/icta_controller/controller.lua b/techage/icta_controller/controller.lua index 9b41145..0721e4a 100644 --- a/techage/icta_controller/controller.lua +++ b/techage/icta_controller/controller.lua @@ -57,100 +57,51 @@ local function output(pos, text, flush_buffer) meta:set_string("formspec", techage.formspecOutput(meta)) end ------------------ template ------------------------------- --- -- Rule 1 --- if env.blocked[1] == false and env.ticks % == 0 then --- env.result[1] = --- env.blocked[1] = env.result[1] --- if env.blocked[1] then --- env.timer[1] = env.ticks + --- end --- env.conditions[1] = env.blocked[1] --- else --- env.conditions[1] = false --- end --- if env.blocked[1] and env.timer[1] == env.ticks then --- --- env.blocked[1] = false --- end - --- -- Callback variant --- if env.blocked[1] == false and env.ticks % == 0 then --- env.result[1], env.blocked[1] = --- if env.blocked[1] then --- env.timer[1] = env.ticks + --- end --- env.conditions[1] = env.blocked[1] --- else --- env.conditions[1] = false --- end --- if env.blocked[1] and env.timer[1] == env.ticks then --- --- env.blocked[1] = false --- end - - -- cyclic execution (cycle, cond, result, after, actn) -local TemplCyc = [[ --- Rule # -if env.blocked[#] == false and env.ticks %% %s == 0 then - env.result[#] = %s - env.blocked[#] = env.result[#] %s - if env.blocked[#] then - env.timer[#] = env.ticks + %s +local function TemplCyc(cycle, cond, result, after, actn, idx) + return function(env, output) + if env.blocked[idx] == false and env.ticks % cycle == 0 then + env.result[idx] = cond(env, idx) + env.blocked[idx] = result(env.result[idx]) + if env.blocked[idx] then + env.timer[idx] = env.ticks + after + end + env.condition[idx] = env.blocked[idx] + else + env.condition[idx] = false + end + if env.blocked[idx] and env.timer[idx] == env.ticks then + actn(env, output, idx) + env.blocked[idx] = false + end end - env.condition[#] = env.blocked[#] -else - env.condition[#] = false end -if env.blocked[#] and env.timer[#] == env.ticks then - %s - env.blocked[#] = false -end -]] -- event based execution -local TemplEvt = [[ --- Rule # -if env.blocked[#] == false and env.event then - env.result[#] = %s - env.blocked[#] = env.result[#] %s - if env.blocked[#] then - env.timer[#] = env.ticks + %s +local function TemplEvt(cond, result, after, actn, idx) + return function(env, output) + if env.blocked[idx] == false and env.event then + env.result[idx] = cond(env, idx) + env.blocked[idx] = result(env.result[idx]) + if env.blocked[idx] then + env.timer[idx] = env.ticks + after + end + env.condition[idx] = env.blocked[idx] + else + env.condition[idx] = false + end + if env.blocked[idx] and env.timer[idx] == env.ticks then + actn(env, output, idx) + env.blocked[idx] = false + end end - env.condition[#] = env.blocked[#] -else - env.condition[#] = false -end -if env.blocked[#] and env.timer[#] == env.ticks then - %s - env.blocked[#] = false -end -]] --- event based execution of callback function -local TemplEvtClbk = [[ --- Rule # -if env.blocked[#] == false and env.event then - env.result[#], env.blocked[#] = %s(env, %s) - if env.blocked[#] then - env.timer[#] = env.ticks + %s - end - env.condition[#] = env.blocked[#] -else - env.condition[#] = false end -if env.blocked[#] and env.timer[#] == env.ticks then - %s - env.blocked[#] = false -end -]] -- generate the Lua code from the NUM_RULES rules local function generate(pos, meta, environ) local fs_data = minetest.deserialize(meta:get_string("fs_data")) or FS_DATA - -- chunks are compiled as vararg functions. Parameters are available via: local a, b, c = ... - local tbl = {"local env, output = ...\n"} + local tbl = {} for idx = 1,techage.NUM_RULES do local cycle = integer(fs_data[idx].cycle, 0, 1000) local cond, result = techage.code_condition(fs_data[idx].cond, environ) @@ -159,26 +110,21 @@ local function generate(pos, meta, environ) -- valid rule? if cycle and cond and after and actn then -- add rule number - local s - if cycle == 0 then -- event? - if result then - s = string.format(TemplEvt, cond, result, after, actn) - else -- callback function - local data = dump(fs_data[idx].cond) - s = string.format(TemplEvtClbk, cond, data, after, actn) - end + local f + if cycle == 0 then -- event + f = TemplEvt(cond, result, after, actn, idx) else -- cyclic - s = string.format(TemplCyc, cycle, cond, result, after, actn) + f = TemplCyc(cycle, cond, result, after, actn, idx) end -- add to list of rules - tbl[#tbl+1] = s:gsub("#", idx) + tbl[#tbl+1] = f elseif cond ~= nil and actn == nil then output(pos, "Error in action in rule "..idx) elseif cond == nil and actn ~= nil then output(pos, "Error in condition in rule "..idx) end end - return table.concat(tbl) + return tbl end local function runtime_environ(pos) @@ -200,21 +146,12 @@ local function compile(pos, meta, number) number = number, owner = meta:get_string("owner"), } - local text = generate(pos, meta, gen_environ) - if text then - local code, err = loadstring(text) - if code then - Cache[number] = { - code = code, - env = runtime_environ(pos), - } - return true - else - output(pos, err) - return false - end - end - return false + local functions = generate(pos, meta, gen_environ) + Cache[number] = { + code = functions, + env = runtime_environ(pos), + } + return true end local function execute(pos, number, event) @@ -226,10 +163,12 @@ local function execute(pos, number, event) env.event = false env.ticks = env.ticks + 1 end - local res, err = pcall(code, env, output) - if not res then - output(pos, err) - return false + for _,func in ipairs(code) do + local res, err = pcall(func, env, output) + if not res then + output(pos, err) + return false + end end return true end diff --git a/techage/icta_controller/display.lua b/techage/icta_controller/display.lua index 04640c5..8add063 100644 --- a/techage/icta_controller/display.lua +++ b/techage/icta_controller/display.lua @@ -211,8 +211,8 @@ local function write_row(pos, payload, cycle_time) local mem = techage.get_mem(pos) nvm.text = nvm.text or {} mem.ticks = mem.ticks or 0 - local str = tostring(payload.str) or "oops" - local row = tonumber(payload.row) or 1 + local str = tostring(payload.get("str")) or "oops" + local row = tonumber(payload.get("row")) or 1 if mem.ticks == 0 then mem.ticks = cycle_time diff --git a/techage/init.lua b/techage/init.lua index a065d67..ef8b2a1 100644 --- a/techage/init.lua +++ b/techage/init.lua @@ -13,7 +13,7 @@ techage = {} -- Version for compatibility checks, see readme.md/history -techage.version = 0.18 +techage.version = 0.21 if minetest.global_exists("tubelib") then minetest.log("error", "[techage] Techage can't be used together with the mod tubelib!") @@ -27,8 +27,8 @@ elseif minetest.global_exists("techpack") then elseif minetest.global_exists("tubelib2") and tubelib2.version < 1.9 then minetest.log("error", "[techage] Techage requires tubelib2 version 1.9 or newer!") return -elseif minetest.global_exists("minecart") and minecart.version < 1.06 then - minetest.log("error", "[techage] Techage requires minecart version 1.06 or newer!") +elseif minetest.global_exists("minecart") and minecart.version < 1.08 then + minetest.log("error", "[techage] Techage requires minecart version 1.08 or newer!") return elseif minetest.global_exists("lcdlib") and lcdlib.version < 1.0 then minetest.log("error", "[techage] Techage requires lcdlib version 1.0 or newer!") @@ -55,6 +55,14 @@ techage.S = minetest.get_translator("techage") -- Load mod storage techage.storage = minetest.get_mod_storage() +-- Ensure compatibility with older Minetest versions by providing +-- a dummy implementation of `minetest.get_translated_string`. +if not minetest.get_translated_string then + minetest.get_translated_string = function(lang_code, string) + return string + end +end + -- Basis features local MP = minetest.get_modpath("techage") dofile(MP.."/basis/lib.lua") -- helper functions @@ -206,6 +214,11 @@ dofile(MP.."/oil/reboiler.lua") dofile(MP.."/ta3_power/tiny_generator.lua") dofile(MP.."/ta3_power/akkubox.lua") +-- Digtron +if minetest.global_exists("digtron") then + dofile(MP.."/digtron/battery.lua") +end + -- Logic dofile(MP.."/logic/lib.lua") dofile(MP.."/logic/terminal.lua") diff --git a/techage/iron_age/hammer.lua b/techage/iron_age/hammer.lua index 879baa3..dfbbf73 100644 --- a/techage/iron_age/hammer.lua +++ b/techage/iron_age/hammer.lua @@ -156,6 +156,7 @@ if minetest.global_exists("wielded_light") then damage_groups = {fleshy=4}, }, sound = {breaks = "default_tool_breaks"}, + light_source = 12, after_use = function(itemstack, user, node, digparams) minetest.after(0.01, handler, user:get_player_name(), node) itemstack:add_wear(digparams.wear) diff --git a/techage/lamps/lightblock.lua b/techage/lamps/lightblock.lua index b4f089a..93a064b 100644 --- a/techage/lamps/lightblock.lua +++ b/techage/lamps/lightblock.lua @@ -39,6 +39,7 @@ minetest.register_node("techage:lightblock", { floodable = true, is_ground_content = false, groups = {not_in_creative_inventory=1}, + drop = "", }) function techage.light_ring(center_pos, on, large) diff --git a/techage/locale/techage.de.tr b/techage/locale/techage.de.tr index 8b0753b..fce382b 100644 --- a/techage/locale/techage.de.tr +++ b/techage/locale/techage.de.tr @@ -1,5 +1,6 @@ # textdomain: techage + ku is needed!)= ku wird benötigt!) #### TA3 Terminal ####@n@nSend commands to your machines@nand output text messages from your@nmachines to the Terminal.@n@nCommand syntax:@n cmd @n@nexample: cmd 181 on@n is the number of the node to which the command is sent@n'on' is the command to turn machines/nodes on@nFurther commands can be retrieved by clicking on@nmachines/nodes with the Techage Info Tool.@n@nLocal commands:@n- clear @= clear screen@n- help @= this message@n- pub @= switch to public use@n- priv @= switch to private use@nTo program a user button with a command:@n set @ne.g. 'set 1 ON cmd 123 on'@n= Accu Box=Akkublock Active:=Aktiv: @@ -35,6 +36,7 @@ Build derrick=Errichte Ölturm Catalyst=Katalysator Cement Block=Zement Block Cement Powder=Zement Pulver +Coal Equivalents=Kohleeinheiten Compressed Gravel=Komprimiertes Kies Configure up to 8 items @nto be pushed by the injector=Konfiguriere bis zu 8 Gegenstände \n die vom Injektor weitergegeben werden sollen Consum. 1=Konsum. 1 @@ -42,6 +44,7 @@ Consum. 2=Konsum. 2 Current power:=Strom aktuell: Depth=Tiefe Digging depth=Grabungstiefe +Digtron Battery=Digtron Akku Dirt with Ash=Erde mit Asche Display no: = Display Nr. Distributor=Verteiler @@ -102,6 +105,7 @@ Load=Ladung Lye=Lauge Lye Barrel=Lauge Fass Lye Canister=Lauge Kanister +Max. needed power=Max. benötigter Strom Maximum power:=Maximalstrom: Melting Guide=Schmelzführer Melting Pot active (heat@==Schmelztiegel aktiv (Hitze@= @@ -147,6 +151,7 @@ Power Source=Stromquelle Power grid total=Stromnetz gesammt Power station=Kraftwerk Priv missing=Rechte fehlen +Probably too many consumers (=Vermutlich zu viele Verbraucher ( Propane Cylinder Large=Propangasflasche groß Propane Cylinder Small=Propangasflasche klein Pumpjack=Ölpumpe @@ -385,6 +390,7 @@ Type=Typ Unlock=Entsperren Unlock connected chest@nif all slots are below 2000=Nachfolgende Kiste entsperren,@nsofern alle Speicherplätze <= 2000 Update=Update +Use a trowel to remove the node.=Verwende eine Kelle, um den Block zu entfernen. Usmium Nuggets=Usmium Nuggets Usmium Powder=Usmium Pulver WLAN Chip=WLAN Chip diff --git a/techage/locale/template.txt b/techage/locale/template.txt index f14a696..a6aeb79 100644 --- a/techage/locale/template.txt +++ b/techage/locale/template.txt @@ -1,3 +1,4 @@ + ku is needed!)= #### TA3 Terminal ####@n@nSend commands to your machines@nand output text messages from your@nmachines to the Terminal.@n@nCommand syntax:@n cmd @n@nexample: cmd 181 on@n is the number of the node to which the command is sent@n'on' is the command to turn machines/nodes on@nFurther commands can be retrieved by clicking on@nmachines/nodes with the Techage Info Tool.@n@nLocal commands:@n- clear @= clear screen@n- help @= this message@n- pub @= switch to public use@n- priv @= switch to private use@nTo program a user button with a command:@n set @ne.g. 'set 1 ON cmd 123 on'@n= Accu Box= Active:= @@ -33,6 +34,7 @@ Build derrick= Catalyst= Cement Block= Cement Powder= +Coal Equivalents= Compressed Gravel= Configure up to 8 items @nto be pushed by the injector= Consum. 1= @@ -40,6 +42,7 @@ Consum. 2= Current power:= Depth= Digging depth= +Digtron Battery= Dirt with Ash= Display no: = Distributor= @@ -100,6 +103,7 @@ Load= Lye= Lye Barrel= Lye Canister= +Max. needed power= Maximum power:= Melting Guide= Melting Pot active (heat@== @@ -145,6 +149,7 @@ Power Source= Power grid total= Power station= Priv missing= +Probably too many consumers (= Propane Cylinder Large= Propane Cylinder Small= Pumpjack= @@ -383,6 +388,7 @@ Type= Unlock= Unlock connected chest@nif all slots are below 2000= Update= +Use a trowel to remove the node.= Usmium Nuggets= Usmium Powder= WLAN Chip= diff --git a/techage/logic/cart_detector.lua b/techage/logic/cart_detector.lua index e4cc429..3c672e8 100644 --- a/techage/logic/cart_detector.lua +++ b/techage/logic/cart_detector.lua @@ -136,6 +136,13 @@ techage.register_node({"techage:ta3_cartdetector_off", "techage:ta3_cartdetector local node = minetest.get_node(pos) local dir = minetest.facedir_to_dir(node.param2) minecart.punch_cart(pos, nil, 1.5, dir) + elseif topic == "state" then + local node = techage.get_node_lvm(pos) + if node.name == "techage:ta3_cartdetector_on" then + return "on" + else + return "off" + end else return "unsupported" end diff --git a/techage/logic/node_detector.lua b/techage/logic/node_detector.lua index 34cea52..6025598 100644 --- a/techage/logic/node_detector.lua +++ b/techage/logic/node_detector.lua @@ -187,6 +187,21 @@ 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 + local node = techage.get_node_lvm(pos) + if node.name == "techage:ta3_nodedetector_off" then + return "on" + else + return "off" + end + else + return "unsupported" + end + end, on_node_load = function(pos) minetest.get_node_timer(pos):start(CYCLE_TIME) end, diff --git a/techage/logic/player_detector.lua b/techage/logic/player_detector.lua index ef4a120..8013044 100644 --- a/techage/logic/player_detector.lua +++ b/techage/logic/player_detector.lua @@ -311,6 +311,14 @@ techage.register_node({ if topic == "name" then local nvm = techage.get_nvm(pos) return nvm.player_name or "" + elseif topic == "state" then + local node = techage.get_node_lvm(pos) + if node.name == "techage:ta3_playerdetector_on" or + node.name == "techage:ta4_playerdetector_on" then + return "on" + else + return "off" + end else return "unsupported" end diff --git a/techage/lua_controller/commands.lua b/techage/lua_controller/commands.lua index 47b36d3..2c20e72 100644 --- a/techage/lua_controller/commands.lua +++ b/techage/lua_controller/commands.lua @@ -39,16 +39,17 @@ techage.lua_ctlr.register_function("get_input", { }) techage.lua_ctlr.register_function("read_data", { - cmnd = function(self, num, ident, add_data) + cmnd = function(self, num, cmnd, data) num = tostring(num or "") - return techage.send_single(self.meta.number, num, ident, add_data) + cmnd = tostring(cmnd or "") + if not_protected(self.meta.owner, num) then + return techage.send_single(self.meta.number, num, cmnd, data) + end end, - help = " $read_data(num, ident, add_data)\n".. - " Read any kind of data from another block.\n".. - ' "num" is the block number\n'.. - ' "ident" specifies the data to be read\n'.. - ' "add_data" is additional data (optional)\n'.. - ' example: sts = $read_data("1234", "state")' + help = " $read_data(num, cmnd, add_data)\n".. + " This function is deprecated.\n".. + " It will be removed in future releases.\n".. + " Use $send_cmnd(num, cmnd, add_data) instead." }) techage.lua_ctlr.register_function("time_as_str", { @@ -96,7 +97,7 @@ techage.lua_ctlr.register_action("set_filter", { slot = tostring(slot or "red") val = tostring(val or "on") if not_protected(self.meta.owner, num) then - techage.send_single(self.meta.number, num, "filter", {slot=slot, val=val}) + techage.send_single(self.meta.number, num, "port", slot.."="..val) end end, help = " $set_filter(num, slot, val)\n".. @@ -119,7 +120,10 @@ techage.lua_ctlr.register_action("display", { if row == 0 then -- add line? techage.send_single(self.meta.number, num, "add", text) else - techage.send_single(self.meta.number, num, "set", {row = row, str = text}) + local payload = safer_lua.Store() + payload.set("row", row) + payload.set("str", text) + techage.send_single(self.meta.number, num, "set", payload) end end end, @@ -181,6 +185,19 @@ techage.lua_ctlr.register_action("door", { " Hint: Use the Techage Programmer to\ndetermine the door position." }) +techage.lua_ctlr.register_function("item_description", { + cmnd = function(self, itemstring) + local item_def = minetest.registered_items[itemstring] + if item_def and item_def.description then + return minetest.get_translated_string("en", item_def.description) + end + return "" + end, + help = " $item_description(itemstring)\n".. + " Get the description for a specified itemstring.\n".. + ' example: desc = $item_description("default:apple")' +}) + -- function not_protected(owner, number(s)) techage.lua_ctlr.not_protected = not_protected diff --git a/techage/manuals/ta4_lua_controller_EN.md b/techage/manuals/ta4_lua_controller_EN.md index b98a477..297989c 100644 --- a/techage/manuals/ta4_lua_controller_EN.md +++ b/techage/manuals/ta4_lua_controller_EN.md @@ -350,19 +350,20 @@ In addition to Lua standard function the Lua Controller provides the following f _add_data_ is for additional data and normally not needed. The result is block dependent (see table below): -| ident | returned data | comment | -| ----------- | ------------------------------------------------------------ | ------------------------------------------------------------ | -| "state" | one of: "running", "stopped", "blocked", "standby", "fault", or "unloaded" | Techage machine state, used by many machines | -| "state" | one of: "red", "amber", "green", "off" | Signal Tower state | -| "state" | one of: "empty", "loaded", "full" | State of a chest or Sensor Chest | -| "fuel" | number | fuel value of a fuel consuming block | -| "depth" | number | Read the current depth value of a quarry block (1..80) | -| "load" | number | Read the load value in percent (0..100) of a tank/storage block, an accu block, of of the Signs Bot Box. | -| "delivered" | number | Read the current delivered power value of a generator block. A power consuming block (accu) provides a negative value | -| "action" | player-name, action-string | only for Sensor Chests | -| "stacks" | Array with up to 4 Stores with the inventory content (see example) | only for Sensor Chests | -| "count" | number | Read the item counter of the TA4 Item Detector block | -| "count" | number of items | Read the total amount of TA4 chest items. An optional number as `add_data` is used to address only on inventory slot (1..8, from left to right). | +| ident | returned data | comment | +| ------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | +| "state" | one of: "running", "stopped", "blocked", "standby", "fault", or "unloaded" | Techage machine state, used by many machines | +| "state" | one of: "red", "amber", "green", "off" | Signal Tower state | +| "state" | one of: "empty", "loaded", "full" | State of a chest or Sensor Chest | +| "fuel" | number | fuel value of a fuel consuming block | +| "depth" | number | Read the current depth value of a quarry block (1..80) | +| "load" | number | Read the load value in percent (0..100) of a tank/storage block, an accu block, of of the Signs Bot Box. | +| "delivered" | number | Read the current delivered power value of a generator block. A power consuming block (accu) provides a negative value | +| "action" | player-name, action-string | only for Sensor Chests | +| "stacks" | Array with up to 4 Stores with the inventory content (see example) | only for Sensor Chests | +| "count" | number | Read the item counter of the TA4 Item Detector block | +| "count" | number of items | Read the total amount of TA4 chest items. An optional number as `add_data` is used to address only on 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).
Example: s = $read_data("223", "itemstring", 1) | @@ -410,11 +411,17 @@ Messages are used to transport data between Controllers. Messages are text strin * `$chat(text)` - Send yourself a chat message. _text_ is a text string. + * `$door(pos, text)` - Open/Close a door at position "pos". Example: `$door("123,7,-1200", "close")`. Hint: Use the Techage Info Tool to determine the door position. + +* `$item_description("default:apple")` + Get the description (item name) for a specified itemstring, e. g. determined via the TA4 8x2000 Chest command `itemstring`: + `str = $read_data("223", "itemstring", 1)` + `descr = $item_description(str)` - + ## Example Scripts diff --git a/techage/manuals/ta4_lua_controller_EN.pdf b/techage/manuals/ta4_lua_controller_EN.pdf index 62ffe0b..1273eb1 100644 Binary files a/techage/manuals/ta4_lua_controller_EN.pdf and b/techage/manuals/ta4_lua_controller_EN.pdf differ diff --git a/techage/mod.conf b/techage/mod.conf index 66b1420..517295f 100644 --- a/techage/mod.conf +++ b/techage/mod.conf @@ -1,4 +1,4 @@ name = techage depends = default,doors,flowers,tubelib2,basic_materials,bucket,stairs,screwdriver,minecart,lcdlib,safer_lua -optional_depends = unified_inventory,wielded_light,unifieddyes,moreores,ethereal,mesecon +optional_depends = unified_inventory,wielded_light,unifieddyes,moreores,ethereal,mesecon,digtron description = Techage, go through 4 tech ages in search of wealth and power! diff --git a/techage/power/distribution.lua b/techage/power/distribution.lua index 0c624a5..610e7e0 100644 --- a/techage/power/distribution.lua +++ b/techage/power/distribution.lua @@ -147,3 +147,16 @@ function techage.power.power_distribution(network, tlib_type, netID, cycle_time) set_taken_values(network.con2, 0, tlib_type) end end + +-- determine the maxiumum needed power of all con1 consumers +function techage.power.get_con1_sum(network, tlib_type) + local sum = 0 + for _,v in ipairs(network.con1 or {}) do + local nvm = techage.get_nvm(v.pos) + local def = nvm[tlib_type] -- power related network data + if def and def["cstate"] ~= STOPPED then + sum = sum + v.nominal + end + end + return sum +end diff --git a/techage/power/node_api.lua b/techage/power/node_api.lua index a5db533..d7f9996 100644 --- a/techage/power/node_api.lua +++ b/techage/power/node_api.lua @@ -144,7 +144,8 @@ function techage.power.power_available(pos, Cable) local nvm = techage.get_nvm(pos) local tlib_type = Cable.tube_type local netID = nvm[Cable.tube_type] and nvm[Cable.tube_type]["netID"] - return networks.has_network(tlib_type, netID) + local netw = networks.has_network(tlib_type, netID) + return netw and netw.on and netw.alive and netw.alive > 0 end -- this is more a try to start, the start will be performed by on_power() diff --git a/techage/power/power_terminal2.lua b/techage/power/power_terminal2.lua index 01fcb7e..6bb61cc 100644 --- a/techage/power/power_terminal2.lua +++ b/techage/power/power_terminal2.lua @@ -188,11 +188,14 @@ end local function get_state(netw) local state = "" + local needed = techage.power.get_con1_sum(netw, "ele1") or 0 if #(netw.gen1 or {}) + #(netw.gen2 or {}) == 0 then state = S("No power grid or running generator!") + elseif needed > (netw.available1 or 0) then + state = S("Probably too many consumers (")..needed..S(" ku is needed!)") elseif (netw.num_nodes or 0) < techage.networks.MAX_NUM_NODES then - state = S("Number of power grid blocks")..": "..(netw.num_nodes or 0) + state = S("Number of power grid blocks")..": "..(netw.num_nodes or 0)..", "..S("Max. needed power")..": "..needed.. " ku" else state = S("To many blocks in the power grid!") end diff --git a/techage/tools/trowel.lua b/techage/tools/trowel.lua index 0782dbb..69e9684 100644 --- a/techage/tools/trowel.lua +++ b/techage/tools/trowel.lua @@ -116,3 +116,35 @@ minetest.register_craft({ {"", "", "default:stick"}, }, }) + +local function get_new_can_dig(old_can_dig) + return function(pos, player, ...) + if M(pos):get_string("techage_hidden_nodename") ~= "" then + if player and player.get_player_name then + minetest.chat_send_player(player:get_player_name(), S("Use a trowel to remove the node.")) + end + return false + end + if old_can_dig then + return old_can_dig(pos, player, ...) + else + return true + end + end +end + +-- Change can_dig for already registered nodes. +for _, ndef in pairs(minetest.registered_nodes) do + local old_can_dig = ndef.can_dig + minetest.override_item(ndef.name, { + can_dig = get_new_can_dig(old_can_dig) + }) +end + +-- Change can_dig for all nodes that are going to be registered in the future. +local old_register_node = minetest.register_node +minetest.register_node = function(name, def) + local old_can_dig = def.can_dig + def.can_dig = get_new_can_dig(old_can_dig) + return old_register_node(name, def) +end