diff --git a/README.md b/README.md index 22612d2..64abfb4 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,27 @@ -# TechPack V1.16 +# TechPack V2.00 (WIP) + +**THIS IS WORK IN PROGRESS** + +**For your world use the stable release ![v1.16](https://github.com/joe7575/techpack/releases/tag/v1.16)** + + +## Planned for v2 +- switch to library tubelib2 +- introduce a new machine state model +- add new machine state "defect" +- add a tubelib Repair Kit for defect blocks +- Forceload block as part of tubelib +- support for intllib + +## Current state +- Switch to tubelib2 is done (not fully tested). +- Pusher, Distributor, and Grinder already support the new state 'defect'. The AGING_VALUE is currently much to low. This is for testing only. +- The Repair Kit is available and can be used to repair defect machines. +- The mod 'basic_materials' is now needed for the Repair Kit. +- Due to server crashes I can happen that all loaded nodes loose their timers. Therefore, all "timed" nodes got an "on_node_load" function, which is used to restart the timer. + + + TechPack, a Mining, Crafting, & Farming Modpack for Minetest. diff --git a/gravelsieve/hammer.lua b/gravelsieve/hammer.lua index 5809e49..bcd8214 100644 --- a/gravelsieve/hammer.lua +++ b/gravelsieve/hammer.lua @@ -3,16 +3,6 @@ Gravel Sieve Mod ================ - v0.01 by JoSt - Derived from the work of RealBadAngel, Maciej Kasatkin (screwdriver) - - Copyright (C) 2017 Joachim Stolberg - Copyright (C) 2013-2016 RealBadAngel, Maciej Kasatkin - Copyright (C) 2013-2016 Various Minetest developers and contributors - - LGPLv2.1+ - See LICENSE.txt for more information - ]]-- @@ -45,6 +35,7 @@ gravelsieve.handler = function(itemstack, user, pointed_thing) loop=false}) end + itemstack:add_wear(65535 / (500 - 1)) return itemstack end @@ -52,8 +43,7 @@ minetest.register_tool("gravelsieve:hammer", { description = "Hammer converts Cobblestone into Gravel", inventory_image = "gravelsieve_hammer.png", on_use = function(itemstack, user, pointed_thing) - gravelsieve.handler(itemstack, user, pointed_thing) - return itemstack + return gravelsieve.handler(itemstack, user, pointed_thing) end, }) diff --git a/gravelsieve/init.lua b/gravelsieve/init.lua index d29a88a..69b38fc 100644 --- a/gravelsieve/init.lua +++ b/gravelsieve/init.lua @@ -424,12 +424,8 @@ if minetest.global_exists("tubelib") then local meta = minetest.get_meta(pos) return tubelib.put_item(meta, "dst", item) end, - on_recv_message = function(pos, topic, payload) - if topic == "on" then - start_the_machine(pos) - elseif topic == "off" then - stop_the_machine(pos) - end + on_node_load = function(pos) + minetest.get_node_timer(pos):start(1.0) end, }) end diff --git a/sl_controller/controller.lua b/sl_controller/controller.lua index a3fdf0c..5e747fa 100644 --- a/sl_controller/controller.lua +++ b/sl_controller/controller.lua @@ -491,4 +491,10 @@ tubelib.register_node("sl_controller:controller", {}, { return "unsupported" end end, + on_node_load = function(pos) + local meta = minetest.get_meta(pos) + if meta:get_int("running") ~= tubelib.STATE_STOPPED then + minetest.get_node_timer(pos):start(1) + end + end, }) diff --git a/sl_controller/server.lua b/sl_controller/server.lua index c653b3d..783b5a8 100644 --- a/sl_controller/server.lua +++ b/sl_controller/server.lua @@ -150,6 +150,9 @@ tubelib.register_node("sl_controller:server", {}, { end end end, + on_node_load = function(pos) + minetest.get_node_timer(pos):start(20) + end, }) diff --git a/smartline/controller.lua b/smartline/controller.lua index f9b10f7..22b40f8 100644 --- a/smartline/controller.lua +++ b/smartline/controller.lua @@ -885,6 +885,12 @@ tubelib.register_node("smartline:controller", {}, { return "unsupported" end end, + on_node_load = function(pos) + local meta = minetest.get_meta(pos) + if meta:get_int("state") == tubelib.RUNNING then + minetest.get_node_timer(pos):start(1) + end + end, }) -- List of Controller actions and conditions is dependent on loaded mods. diff --git a/smartline/depends.txt b/smartline/depends.txt index 064149e..32cfef9 100644 --- a/smartline/depends.txt +++ b/smartline/depends.txt @@ -2,5 +2,6 @@ default doors tubelib lcdlib +sl_controller mail? diff --git a/smartline/icta/battery.lua b/smartline/icta/battery.lua index 6380664..cca063c 100644 --- a/smartline/icta/battery.lua +++ b/smartline/icta/battery.lua @@ -156,3 +156,10 @@ else }) end +tubelib.register_node("smartline:battery", + {"smartline:battery25", "smartline:battery50", "smartline:battery75"}, + { + on_node_load = function(pos) + minetest.get_node_timer(pos):start(30) + end, +}) diff --git a/smartline/icta/controller.lua b/smartline/icta/controller.lua index e7a86f0..661553f 100644 --- a/smartline/icta/controller.lua +++ b/smartline/icta/controller.lua @@ -505,5 +505,11 @@ tubelib.register_node("smartline:controller2", {}, { return "unsupported" end end, + on_node_load = function(pos) + local meta = minetest.get_meta(pos) + if meta:get_int("state") == tubelib.RUNNING then + minetest.get_node_timer(pos):start(1) + end + end, }) diff --git a/smartline/playerdetector.lua b/smartline/playerdetector.lua index 26a7dac..8c3f751 100644 --- a/smartline/playerdetector.lua +++ b/smartline/playerdetector.lua @@ -220,5 +220,8 @@ tubelib.register_node("smartline:playerdetector", {"smartline:playerdetector_act return meta:get_string("player_name") end end, + on_node_load = function(pos) + minetest.get_node_timer(pos):start(1.0) + end, }) diff --git a/smartline/repeater.lua b/smartline/repeater.lua index b44d604..7ba153e 100644 --- a/smartline/repeater.lua +++ b/smartline/repeater.lua @@ -124,4 +124,7 @@ tubelib.register_node("smartline:repeater", {}, { return tubelib.send_message(numbers, owner, nil, topic, payload) end end, + on_node_load = function(pos) + minetest.get_node_timer(pos):start(1) + end, }) diff --git a/smartline/sequencer.lua b/smartline/sequencer.lua index 64cff76..440b624 100644 --- a/smartline/sequencer.lua +++ b/smartline/sequencer.lua @@ -137,7 +137,7 @@ local function start_the_sequencer(pos) local node = minetest.get_node(pos) local meta = minetest.get_meta(pos) local number = meta:get_string("number") - meta:set_int("running", 1) + meta:set_int("running", RUNNING_STATE) meta:set_int("index", 1) meta:set_string("infotext", "SmartLine Sequencer "..number..": running (1/"..NUM_SLOTS..")") local rules = minetest.deserialize(meta:get_string("rules")) @@ -282,4 +282,11 @@ tubelib.register_node("smartline:sequencer", {}, { meta:set_int("endless", 0) end end, + on_node_load = function(pos) + local meta = minetest.get_meta(pos) + if meta:get_int("running") ~= STOP_STATE then + meta:set_int("running", RUNNING_STATE) + minetest.get_node_timer(pos):start(1) + end + end, }) diff --git a/smartline/timer.lua b/smartline/timer.lua index 0053b15..5315676 100644 --- a/smartline/timer.lua +++ b/smartline/timer.lua @@ -215,6 +215,17 @@ minetest.register_node("smartline:timer", { is_ground_content = false, }) +tubelib.register_node("smartline:timer", {}, { + on_node_load = function(pos) + local meta = minetest.get_meta(pos) + minetest.get_node_timer(pos):start(CYCLE_TIME) + -- check rules for just loaded areas + local done = {false,false,false,false,false,false} + meta:set_string("done", minetest.serialize(done)) + check_rules(pos,0) + end, +}) + minetest.register_craft({ output = "smartline:timer", @@ -224,20 +235,3 @@ minetest.register_craft({ {"", "default:mese_crystal", ""}, }, }) - -minetest.register_lbm({ - label = "[SmartLine] Timer update", - name = "smartline:update", - nodenames = {"smartline:timer"}, - run_at_every_load = true, - action = function(pos, node) - local meta = minetest.get_meta(pos) - -- check rules for just loaded areas - local done = {false,false,false,false,false,false} - meta:set_string("done", minetest.serialize(done)) - check_rules(pos,0) - end -}) - - - diff --git a/tubelib/README.md b/tubelib/README.md index 63ded96..b2687ee 100644 --- a/tubelib/README.md +++ b/tubelib/README.md @@ -29,12 +29,11 @@ Download: ![GitHub](https://github.com/joe7575/Minetest-Tubelib/archive/master.z ## Dependencies default +tubelib2 +basic_materials + # License Copyright (C) 2017-2018 Joachim Stolberg Code: Licensed under the GNU LGPL version 2.1 or later. See LICENSE.txt and http://www.gnu.org/licenses/lgpl-2.1.txt Textures: CC0 - -## Dependencies -default - diff --git a/tubelib/command.lua b/tubelib/command.lua index 7b59e53..50aea26 100644 --- a/tubelib/command.lua +++ b/tubelib/command.lua @@ -14,7 +14,12 @@ ]]-- -------------------------------------------------------------------- +--- for lazy programmers +local S = function(pos) if pos then return minetest.pos_to_string(pos) end end +local P = minetest.string_to_pos +local M = minetest.get_meta + +------------------------------------------------------------------ -- Data base storage ------------------------------------------------------------------- local storage = minetest.get_mod_storage() @@ -53,12 +58,7 @@ local Name2Name = {} -- translation table local string_find = string.find local string_split = string.split local tubelib_NodeDef = tubelib.NodeDef -local get_neighbor_pos = tubelib.get_neighbor_pos -local read_node_with_vm = tubelib.read_node_with_vm - --- Translate from facedir to contact side of the other node --- (left for one is right for the other node) -local FacedirToSide = {[0] = "F", "L", "B", "R", "U", "D"} +local Tube = tubelib.Tube -- Generate a key string based on the given pos table, -- Used internaly as table key, @@ -77,16 +77,6 @@ local function get_number(pos) return string.format("%.04u", Key2Number[key]) end --- Determine the contact side of the node at the given pos --- param facedir: facedir to the node -local function get_node_side(npos, facedir) - local node = minetest.get_node_or_nil(npos) or read_node_with_vm(npos) - if facedir < 4 then - facedir = (facedir - node.param2 + 4) % 4 - end - return FacedirToSide[facedir], node -end - local function generate_Key2Number() local key for num,item in pairs(Number2Pos) do @@ -109,6 +99,50 @@ local function not_protected(pos, placer_name, clicker_name) return false end +local function register_lbm(name, nodenames) + minetest.register_lbm({ + label = "[Tubelib] Node update", + name = name.."update", + nodenames = nodenames, + run_at_every_load = true, + action = function(pos, node) + local name = Name2Name[node.name] + if tubelib_NodeDef[name] and tubelib_NodeDef[name].on_node_load then + tubelib_NodeDef[name].on_node_load(pos) + end + end + }) +end + + +local DirToSide = {"B", "R", "F", "L", "D", "U"} + +local function dir_to_side(dir, param2) + if dir < 5 then + dir = (((dir - 1) - (param2 % 4)) % 4) + 1 + end + return DirToSide[dir] +end + +local SideToDir = {B=1, R=2, F=3, L=4, D=5, U=6} + +local function side_to_dir(side, param2) + local dir = SideToDir[side] + if dir < 5 then + dir = (((dir - 1) + (param2 % 4)) % 4) + 1 + end + return dir +end + +local function get_dest_node(pos, side) + local _,node = Tube:get_node(pos) + local dir = side_to_dir(side, node.param2) + local spos, sdir = Tube:get_connected_node_pos(pos, dir) + _,node = Tube:get_node(spos) + local in_side = dir_to_side(sdir, node.param2) + return spos, in_side, Name2Name[node.name] or node.name +end + ------------------------------------------------------------------- -- API helper functions ------------------------------------------------------------------- @@ -213,6 +247,8 @@ end -- on_push_item = func(pos, side, item, player_name), -- on_unpull_item = func(pos, side, item, player_name), -- on_recv_message = func(pos, topic, payload), +-- on_node_load = func(pos), -- LBM function +-- on_node_repair = func(pos), -- repair defect (feature!) nodes -- } function tubelib.register_node(name, add_names, node_definition) tubelib_NodeDef[name] = node_definition @@ -223,11 +259,22 @@ function tubelib.register_node(name, add_names, node_definition) end if node_definition.on_pull_item or node_definition.on_push_item or node_definition.is_pusher then + Tube:add_secondary_node_names({name}) + Tube:add_secondary_node_names(add_names) + tubelib.KnownNodes[name] = true for _,n in ipairs(add_names) do tubelib.KnownNodes[n] = true end end + -- register LBM + if node_definition.on_node_load then + local nodenames = {name} + for _,n in ipairs(add_names) do + nodenames[#nodenames + 1] = n + end + register_lbm(name, nodenames) + end end ------------------------------------------------------------------- @@ -257,15 +304,23 @@ function tubelib.send_request(number, topic, payload) return false end +-- for defect nodes +function tubelib.repair_node(pos) + local node = minetest.get_node(pos) + local name = Name2Name[node.name] + if tubelib_NodeDef[name] and tubelib_NodeDef[name].on_node_repair then + return tubelib_NodeDef[name].on_node_repair(pos) + end + return false +end + ------------------------------------------------------------------- -- Client side Push/Pull item functions ------------------------------------------------------------------- function tubelib.pull_items(pos, side, player_name) - local npos, facedir = get_neighbor_pos(pos, side) + local npos, nside, name = get_dest_node(pos, side) if npos == nil then return end - local nside, node = get_node_side(npos, facedir) - local name = Name2Name[node.name] if tubelib_NodeDef[name] and tubelib_NodeDef[name].on_pull_item then return tubelib_NodeDef[name].on_pull_item(npos, nside, player_name) end @@ -273,13 +328,11 @@ function tubelib.pull_items(pos, side, player_name) end function tubelib.push_items(pos, side, items, player_name) - local npos, facedir = get_neighbor_pos(pos, side) + local npos, nside, name = get_dest_node(pos, side) if npos == nil then return end - local nside, node = get_node_side(npos, facedir) - local name = Name2Name[node.name] if tubelib_NodeDef[name] and tubelib_NodeDef[name].on_push_item then return tubelib_NodeDef[name].on_push_item(npos, nside, items, player_name) - elseif node.name == "air" then + elseif name == "air" then minetest.add_item(npos, items) return true end @@ -287,10 +340,8 @@ function tubelib.push_items(pos, side, items, player_name) end function tubelib.unpull_items(pos, side, items, player_name) - local npos, facedir = get_neighbor_pos(pos, side) + local npos, nside, name = get_dest_node(pos, side) if npos == nil then return end - local nside, node = get_node_side(npos, facedir) - local name = Name2Name[node.name] if tubelib_NodeDef[name] and tubelib_NodeDef[name].on_unpull_item then return tubelib_NodeDef[name].on_unpull_item(npos, nside, items, player_name) end @@ -298,10 +349,8 @@ function tubelib.unpull_items(pos, side, items, player_name) end function tubelib.pull_stack(pos, side, player_name) - local npos, facedir = get_neighbor_pos(pos, side) + local npos, nside, name = get_dest_node(pos, side) if npos == nil then return end - local nside, node = get_node_side(npos, facedir) - local name = Name2Name[node.name] if tubelib_NodeDef[name] then if tubelib_NodeDef[name].on_pull_stack then return tubelib_NodeDef[name].on_pull_stack(npos, nside, player_name) @@ -483,6 +532,6 @@ generate_Key2Number() -- maintain data after one minute -- (minetest.get_day_count() will not be valid at start time) -minetest.after(60, data_maintenance) +minetest.after(5, data_maintenance) diff --git a/tubelib/depends.txt b/tubelib/depends.txt index 4ad96d5..6bd4325 100644 --- a/tubelib/depends.txt +++ b/tubelib/depends.txt @@ -1 +1,4 @@ default +tubelib2 +basic_materials + diff --git a/tubelib/distributor.lua b/tubelib/distributor.lua index 5715e9e..396b385 100644 --- a/tubelib/distributor.lua +++ b/tubelib/distributor.lua @@ -12,20 +12,63 @@ A more complex node acting as server and client. This node claims a position number and registers its message and items interface. - The Distributor supports the following messages: + The Distributor is based on the class NodeStates and supports the following messages: - topic = "on", payload = nil - topic = "off" , payload = nil - topic = "state", payload = nil, response is "running", "stopped", "standby", or "not supported" ]]-- +-- for lazy programmers +local S = function(pos) if pos then return minetest.pos_to_string(pos) end end +local P = minetest.string_to_pos +local M = minetest.get_meta + local MAX_NUM_PER_CYC = 20 -- maximum number of items, which can be pushed per slot local NUM_FILTER_ELEM = 6 local NUM_FILTER_SLOTS = 4 -local TICKS_TO_SLEEP = 5 + +local COUNTDOWN_TICKS = 6 +local STANDBY_TICKS = 4 local CYCLE_TIME = 2 -local STOP_STATE = 0 -local STANDBY_STATE = -1 + +local State = tubelib.NodeStates:new({ + node_name_passive = "tubelib:distributor", + node_name_active = "tubelib:distributor_active", + node_name_defect = "tubelib:distributor_defect", + infotext_name = "Tubelib Distributor", + cycle_time = CYCLE_TIME, + standby_ticks = STANDBY_TICKS, + aging_factor = 10, +}) + +local function formspec(pos, meta) + local filter = minetest.deserialize(meta:get_string("filter")) + return "size[10.5,8.5]".. + default.gui_bg.. + default.gui_bg_img.. + default.gui_slots.. + "list[context;src;0,0;2,4;]".. + "image[2,1.5;1,1;tubelib_gui_arrow.png]".. + "image_button[2,3;1,1;"..State:get_state_button_image(meta)..";state_button;]".. + "checkbox[3,0;filter1;On;"..dump(filter[1]).."]".. + "checkbox[3,1;filter2;On;"..dump(filter[2]).."]".. + "checkbox[3,2;filter3;On;"..dump(filter[3]).."]".. + "checkbox[3,3;filter4;On;"..dump(filter[4]).."]".. + "image[4,0;0.3,1;tubelib_red.png]".. + "image[4,1;0.3,1;tubelib_green.png]".. + "image[4,2;0.3,1;tubelib_blue.png]".. + "image[4,3;0.3,1;tubelib_yellow.png]".. + "list[context;red;4.5,0;6,1;]".. + "list[context;green;4.5,1;6,1;]".. + "list[context;blue;4.5,2;6,1;]".. + "list[context;yellow;4.5,3;6,1;]".. + "list[current_player;main;1.25,4.5;8,4;]".. + "listring[context;src]".. + "listring[current_player;main]" +end + +State:register_formspec_func(formspec) -- Return a key/value table with all items and the corresponding stack numbers local function invlist_content_as_kvlist(list) @@ -83,34 +126,9 @@ local function num_items(moved_items, name, filter_item_names, rejected_item_nam end end end - -local function distributor_formspec(state, filter) - return "size[10.5,8.5]".. - default.gui_bg.. - default.gui_bg_img.. - default.gui_slots.. - "list[context;src;0,0;2,4;]".. - "image[2,1.5;1,1;tubelib_gui_arrow.png]".. - "image_button[2,3;1,1;".. tubelib.state_button(state) ..";button;]".. - "checkbox[3,0;filter1;On;"..dump(filter[1]).."]".. - "checkbox[3,1;filter2;On;"..dump(filter[2]).."]".. - "checkbox[3,2;filter3;On;"..dump(filter[3]).."]".. - "checkbox[3,3;filter4;On;"..dump(filter[4]).."]".. - "image[4,0;0.3,1;tubelib_red.png]".. - "image[4,1;0.3,1;tubelib_green.png]".. - "image[4,2;0.3,1;tubelib_blue.png]".. - "image[4,3;0.3,1;tubelib_yellow.png]".. - "list[context;red;4.5,0;6,1;]".. - "list[context;green;4.5,1;6,1;]".. - "list[context;blue;4.5,2;6,1;]".. - "list[context;yellow;4.5,3;6,1;]".. - "list[current_player;main;1.25,4.5;8,4;]".. - "listring[context;src]".. - "listring[current_player;main]" -end local function allow_metadata_inventory_put(pos, listname, index, stack, player) - local meta = minetest.get_meta(pos) + local meta = M(pos) local inv = meta:get_inventory() local list = inv:get_list(listname) @@ -118,6 +136,9 @@ local function allow_metadata_inventory_put(pos, listname, index, stack, player) return 0 end if listname == "src" then + if State:get_state(M(pos)) == tubelib.STANDBY then + State:start(pos, meta) + end return stack:get_count() elseif invlist_num_entries(list) < MAX_NUM_PER_CYC then return stack:get_count() @@ -133,7 +154,7 @@ local function allow_metadata_inventory_take(pos, listname, index, stack, player end local function allow_metadata_inventory_move(pos, from_list, from_index, to_list, to_index, count, player) - local meta = minetest.get_meta(pos) + local meta = M(pos) local inv = meta:get_inventory() local stack = inv:get_stack(from_list, from_index) return allow_metadata_inventory_put(pos, to_list, to_index, stack, player) @@ -145,7 +166,7 @@ local FilterCache = {} -- local cache for filter settings local function filter_settings(pos) local hash = minetest.hash_node_position(pos) - local meta = minetest.get_meta(pos) + local meta = M(pos) local inv = meta:get_inventory() local filter = minetest.deserialize(meta:get_string("filter")) or {false,false,false,false} local kvFilterItemNames = {} -- { = true,...} @@ -169,54 +190,9 @@ local function filter_settings(pos) } end -local function start_the_machine(pos) - local node = minetest.get_node(pos) - local meta = minetest.get_meta(pos) - local number = meta:get_string("number") - meta:set_int("running", TICKS_TO_SLEEP) - node.name = "tubelib:distributor_active" - minetest.swap_node(pos, node) - meta:set_string("infotext", "Tubelib Distributor "..number..": running") - local filter = minetest.deserialize(meta:get_string("filter")) - meta:set_string("formspec", distributor_formspec(tubelib.RUNNING, filter)) - minetest.get_node_timer(pos):start(CYCLE_TIME) - return false -end - -local function stop_the_machine(pos) - local node = minetest.get_node(pos) - local meta = minetest.get_meta(pos) - local number = meta:get_string("number") - meta:set_int("running", STOP_STATE) - node.name = "tubelib:distributor" - minetest.swap_node(pos, node) - meta:set_string("infotext", "Tubelib Distributor "..number..": stopped") - local filter = minetest.deserialize(meta:get_string("filter")) - meta:set_string("formspec", distributor_formspec(tubelib.STOPPED, filter)) - minetest.get_node_timer(pos):stop() - return false -end - -local function goto_sleep(pos) - local node = minetest.get_node(pos) - local meta = minetest.get_meta(pos) - local number = meta:get_string("number") - meta:set_int("running", STANDBY_STATE) - node.name = "tubelib:distributor" - minetest.swap_node(pos, node) - meta:set_string("infotext", "Tubelib Distributor "..number..": standby") - local filter = minetest.deserialize(meta:get_string("filter")) - meta:set_string("formspec", distributor_formspec(tubelib.STANDBY, filter)) - minetest.get_node_timer(pos):start(CYCLE_TIME * TICKS_TO_SLEEP) - return false -end - --- move items to the output slots -local function keep_running(pos, elapsed) - local meta = minetest.get_meta(pos) - local running = meta:get_int("running") - 1 +-- move items from configured filters to the output +local function distributing(pos, meta) local player_name = meta:get_string("player_name") - --print("running", running) local slot_idx = meta:get_int("slot_idx") or 1 meta:set_int("slot_idx", (slot_idx + 1) % NUM_FILTER_SLOTS) local side = Num2Ascii[slot_idx+1] @@ -243,11 +219,10 @@ local function keep_running(pos, elapsed) if items == nil then -- this slot is empty - return true + return false end local busy = false - -- move items from configured filters to the output if next(items) then for _,item in ipairs(items) do local name, num = item[1], item[2] @@ -289,30 +264,26 @@ local function keep_running(pos, elapsed) FilterCache[hash].kvRejectedItemNames = {} end end - - if busy == true then - if running <= 0 then - return start_the_machine(pos) - else - running = TICKS_TO_SLEEP - end - else - if running <= 0 then - return goto_sleep(pos) - end - end - meta:set_string("item_counter", minetest.serialize(counter)) - meta:set_int("running", running) - return true + return busy +end + +-- move items to the output slots +local function keep_running(pos, elapsed) + local meta = M(pos) + if distributing(pos, meta) then + State:keep_running(pos, meta, COUNTDOWN_TICKS) + else + State:idle(pos, meta) + end + return State:is_active(meta) 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 running = meta:get_int("running") + local meta = M(pos) local filter = minetest.deserialize(meta:get_string("filter")) if fields.filter1 ~= nil then filter[1] = fields.filter1 == "true" @@ -327,21 +298,13 @@ local function on_receive_fields(pos, formname, fields, player) filter_settings(pos) - if fields.button ~= nil then - if running > STOP_STATE then - stop_the_machine(pos) - else - start_the_machine(pos) - end - else - meta:set_string("formspec", distributor_formspec(tubelib.state(running), filter)) - end + State:state_button_event(pos, fields) end -- tubelib 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 = minetest.get_meta(pos) + local meta = M(pos) local filter = minetest.deserialize(meta:get_string("filter")) local num = slots[slot] or 1 if num >= 1 and num <= 4 then @@ -351,8 +314,7 @@ local function change_filter_settings(pos, slot, val) filter_settings(pos) - local running = meta:get_int("running") - meta:set_string("formspec", distributor_formspec(tubelib.state(running), filter)) + meta:set_string("formspec", formspec(pos, meta)) return true end @@ -369,15 +331,13 @@ minetest.register_node("tubelib:distributor", { }, after_place_node = function(pos, placer) + local meta = M(pos) local number = tubelib.add_node(pos, "tubelib:distributor") -- <<=== tubelib - local meta = minetest.get_meta(pos) + local filter = {false,false,false,false} + meta:set_string("filter", minetest.serialize(filter)) + State:node_init(pos, number) meta:set_string("player_name", placer:get_player_name()) - local filter = {false,false,false,false} - meta:set_string("formspec", distributor_formspec(tubelib.STOPPED, filter)) - meta:set_string("filter", minetest.serialize(filter)) - meta:set_string("number", number) - meta:set_string("infotext", "Tubelib Distributor "..number..": stopped") local inv = meta:get_inventory() inv:set_size('src', 8) inv:set_size('yellow', 6) @@ -393,7 +353,7 @@ minetest.register_node("tubelib:distributor", { if minetest.is_protected(pos, puncher:get_player_name()) then return end - local meta = minetest.get_meta(pos) + local meta = M(pos) local inv = meta:get_inventory() if inv:is_empty("src") then minetest.node_dig(pos, node, puncher, pointed_thing) @@ -401,6 +361,10 @@ minetest.register_node("tubelib:distributor", { end end, + after_dig_node = function(pos, oldnode, oldmetadata, digger) + State:after_dig_node(pos, oldnode, oldmetadata, digger) + end, + allow_metadata_inventory_put = allow_metadata_inventory_put, allow_metadata_inventory_take = allow_metadata_inventory_take, allow_metadata_inventory_move = allow_metadata_inventory_move, @@ -455,6 +419,53 @@ minetest.register_node("tubelib:distributor_active", { sounds = default.node_sound_wood_defaults(), }) +minetest.register_node("tubelib:distributor_defect", { + description = "Tubelib Distributor", + tiles = { + -- up, down, right, left, back, front + 'tubelib_distributor.png', + 'tubelib_distributor.png', + 'tubelib_distributor_yellow.png^tubelib_defect.png', + 'tubelib_distributor_green.png^tubelib_defect.png', + "tubelib_distributor_red.png^tubelib_defect.png", + "tubelib_distributor_blue.png^tubelib_defect.png", + }, + + after_place_node = function(pos, placer) + local meta = M(pos) + local number = tubelib.add_node(pos, "tubelib:distributor") -- <<=== tubelib + State:node_init(pos, number) + meta:set_string("player_name", placer:get_player_name()) + + local filter = {false,false,false,false} + meta:set_string("filter", minetest.serialize(filter)) + local inv = meta:get_inventory() + inv:set_size('src', 8) + inv:set_size('yellow', 6) + inv:set_size('green', 6) + inv:set_size('red', 6) + inv:set_size('blue', 6) + meta:set_string("item_counter", minetest.serialize({red=0, green=0, blue=0, yellow=0})) + State:defect(pos, meta) + end, + + on_receive_fields = on_receive_fields, + + allow_metadata_inventory_put = allow_metadata_inventory_put, + allow_metadata_inventory_take = allow_metadata_inventory_take, + allow_metadata_inventory_move = allow_metadata_inventory_move, + + on_rotate = screwdriver.disallow, + + paramtype = "light", + sunlight_propagates = true, + paramtype2 = "facedir", + groups = {crumbly=0, not_in_creative_inventory=1}, + is_ground_content = false, + sounds = default.node_sound_wood_defaults(), +}) + + minetest.register_craft({ output = "tubelib:distributor 2", recipe = { @@ -466,29 +477,19 @@ minetest.register_craft({ --------------------------------------------------------------- tubelib -tubelib.register_node("tubelib:distributor", {"tubelib:distributor_active"}, { +tubelib.register_node("tubelib:distributor", + {"tubelib:distributor_active", "tubelib:distributor_defect"}, { on_pull_item = function(pos, side) - local meta = minetest.get_meta(pos) - return tubelib.get_item(meta, "src") + return tubelib.get_item(M(pos), "src") end, on_push_item = function(pos, side, item) - local meta = minetest.get_meta(pos) - return tubelib.put_item(meta, "src", item) + return tubelib.put_item(M(pos), "src", item) end, on_unpull_item = function(pos, side, item) - local meta = minetest.get_meta(pos) - return tubelib.put_item(meta, "src", item) + return tubelib.put_item(M(pos), "src", item) end, on_recv_message = function(pos, topic, payload) - if topic == "on" then - return start_the_machine(pos) - elseif topic == "off" then - return stop_the_machine(pos) - elseif topic == "state" then - local meta = minetest.get_meta(pos) - local running = meta:get_int("running") - return tubelib.statestring(running) - elseif topic == "filter" then + if topic == "filter" then return change_filter_settings(pos, payload.slot, payload.val) elseif topic == "counter" then local meta = minetest.get_meta(pos) @@ -497,9 +498,21 @@ tubelib.register_node("tubelib:distributor", {"tubelib:distributor_active"}, { elseif topic == "clear_counter" then local meta = minetest.get_meta(pos) meta:set_string("item_counter", minetest.serialize({red=0, green=0, blue=0, yellow=0})) - else - return "unsupported" + else + local resp = State:on_receive_message(pos, topic, payload) + if resp then + return resp + else + return "unsupported" + end end end, + + on_node_load = function(pos) + State:on_node_load(pos) + end, + on_node_repair = function(pos) + return State:on_node_repair(pos) + end, }) --------------------------------------------------------------- tubelib diff --git a/tubelib/init.lua b/tubelib/init.lua index 9621d6a..e8e1444 100644 --- a/tubelib/init.lua +++ b/tubelib/init.lua @@ -24,6 +24,7 @@ - new tubing algorithm - tubelib.pull_stack()/tubelib.get_stack() added - item counter for pusher/distributor added + 2018-12-21 v2.00 Switch to tubelib2, "defect" nodes and "repair kit" added ]]-- @@ -32,7 +33,7 @@ tubelib = { NodeDef = {}, -- node registration info } -tubelib.version = 1.00 +tubelib.version = 2.00 --------------------------- conversion to v0.04 @@ -87,14 +88,17 @@ minetest.register_craft({ }) -dofile(minetest.get_modpath("tubelib") .. "/tubes1.lua") -dofile(minetest.get_modpath("tubelib") .. "/tubes2.lua") +dofile(minetest.get_modpath("tubelib") .. "/tubes.lua") dofile(minetest.get_modpath("tubelib") .. "/command.lua") +-- conversion from v1.16 to v2.00 +dofile(minetest.get_modpath("tubelib") .. "/migrate.lua") dofile(minetest.get_modpath("tubelib") .. "/states.lua") +dofile(minetest.get_modpath("tubelib") .. "/node_states.lua") dofile(minetest.get_modpath("tubelib") .. "/pusher.lua") dofile(minetest.get_modpath("tubelib") .. "/blackhole.lua") dofile(minetest.get_modpath("tubelib") .. "/button.lua") dofile(minetest.get_modpath("tubelib") .. "/lamp.lua") dofile(minetest.get_modpath("tubelib") .. "/distributor.lua") dofile(minetest.get_modpath("tubelib") .. "/legacy_nodes.lua") +dofile(minetest.get_modpath("tubelib") .. "/repairkit.lua") diff --git a/tubelib/migrate.lua b/tubelib/migrate.lua new file mode 100644 index 0000000..c8a3172 --- /dev/null +++ b/tubelib/migrate.lua @@ -0,0 +1,74 @@ +-- for lazy programmers +local S = function(pos) if pos then return minetest.pos_to_string(pos) end end +local P = minetest.string_to_pos +local M = minetest.get_meta + +local Tube = tubelib.Tube + +local TubesTranslation = { + ["tubelib:tube1"] = {[0]= + {12, "S"}, + {21, "S"}, + }, + ["tubelib:tube2"] = {[0]= + { 4, "S"}, + }, + ["tubelib:tube3"] = {[0]= + { 5, "A"}, + {14, "A"}, + {11, "A"}, + { 7, "A"}, + }, + ["tubelib:tube4"] = {[0]= + { 0, "A"}, + {15, "A"}, + { 8, "A"}, + { 3, "A"}, + }, + ["tubelib:tube5"] = {[0]= + {20, "A"}, + {13, "A"}, + {10, "A"}, + {19, "A"}, + }, +} + +minetest.register_lbm({ + label = "[Tubelib] tubes migration", + name = "tubelib:migrate", + nodenames = { + "tubelib:tube1", + "tubelib:tube2", + "tubelib:tube3", + "tubelib:tube4", + "tubelib:tube5", + "tubelib_addons3:teleporter", + }, + run_at_every_load = true, + action = function(pos, node) + if node.name == "tubelib_addons3:teleporter" then + local meta = M(pos) + local peer = meta:get_string("peer") + if peer ~= "" then + meta:set_string("tele_pos", peer) + local peer_pos = P(peer) + local _,node = Tube:get_node(peer_pos) + local tube_dir = ((3 + (node.param2 % 4)) % 4) + 1 + print("migration", peer, tube_dir) + if tube_dir then + meta:set_int("tube_dir", tube_dir) + end + tube_dir = Tube:get_primary_dir(pos) + Tube:tool_repair_tube(Tube:get_pos(pos, tube_dir)) + end + else + local items = TubesTranslation[node.name][node.param2] + if items then + local param2, ntype = items[1], items[2] + minetest.set_node(pos, {name = "tubelib:tube"..ntype, param2 = param2}) + end + end + end +}) + +minetest.register_node("tubelib:tube1", minetest.registered_nodes["tubelib:tubeS"]) diff --git a/tubelib/node_states.lua b/tubelib/node_states.lua new file mode 100644 index 0000000..e1cf36b --- /dev/null +++ b/tubelib/node_states.lua @@ -0,0 +1,427 @@ +--[[ + + Tube Library + ============ + + Copyright (C) 2017 Joachim Stolberg + + LGPLv2.1+ + See LICENSE.txt for more information + + node_states.lua: + + A state model/class for tubelib nodes. + +]]-- + + +--[[ + +Node states: + + +-----------------------------------+ +------------+ + | | | | + | V V | + | +---------+ | + | | | | + | +---------| STOPPED | | + | | | | | + | button | +---------+ | + | | ^ | + repair | V | button | + | +---------+ | | button + | | |---------+ | + | | RUNNING | | + | +--------| |---------+ | + | | +---------+ | | + | | ^ | | | + | | | | | | + | V | V V | + | +---------+ +----------+ +---------+ | + | | | | | | | | + +---| DEFECT | | STANDBY/ | | FAULT |----------+ + | | | BLOCKED | | | + +---------+ +----------+ +---------+ + +Node metadata: + "tubelib_number" - string with tubelib number, like "0123" + "tubelib_state" - node state, like "RUNNING" + "tubelib_item_meter" - node item/runtime counter + "tubelib_countdown" - countdown to stadby mode + "tubelib_aging" - aging counter +]]-- + +-- for lazy programmers +local S = function(pos) if pos then return minetest.pos_to_string(pos) end end +local P = minetest.string_to_pos +local M = minetest.get_meta + + +local AGING_VALUE = 10 -- start aging value +local AGING_FACTOR = 3 -- defect random factor + +-- +-- Local States +-- +local STOPPED = tubelib.STOPPED +local RUNNING = tubelib.RUNNING +local STANDBY = tubelib.STANDBY +local FAULT = tubelib.FAULT +local BLOCKED = tubelib.BLOCKED +local DEFECT = tubelib.DEFECT + + +-- +-- NodeStates Class Functions +-- +tubelib.NodeStates = {} +local NodeStates = tubelib.NodeStates + +function NodeStates:new(attr) + local o = { + -- mandatory + cycle_time = attr.cycle_time, -- for running state + standby_ticks = attr.standby_ticks, -- for standby state + has_item_meter = attr.has_item_meter, -- true/false + -- optional + node_name_passive = attr.node_name_passive, + node_name_active = attr.node_name_active, + node_name_defect = attr.node_name_defect, + infotext_name = attr.infotext_name, + } + if attr.aging_factor then + o.aging_level1 = attr.aging_factor * AGING_VALUE + o.aging_level2 = attr.aging_factor * AGING_VALUE * AGING_FACTOR + end + setmetatable(o, self) + self.__index = self + return o +end + +function NodeStates:register_formspec_func(func) + self.formspec_func = func +end + +function NodeStates:node_init(pos, number) + local meta = M(pos) + meta:set_int("tubelib_state", STOPPED) + meta:set_string("tubelib_number", number) + if self.infotext_name then + meta:set_string("infotext", self.infotext_name.." "..number..": stopped") + end + if self.has_item_meter then + meta:set_int("tubelib_item_meter", 0) + end + if self.aging_level1 then + meta:set_int("tubelib_aging", 0) + end + if self.formspec_func then + meta:set_string("formspec", self.formspec_func(pos, meta)) + end +end + +function NodeStates:stop(pos, meta) + if meta:get_int("tubelib_state") ~= DEFECT then + meta:set_int("tubelib_state", STOPPED) + if self.node_name_passive then + local node = minetest.get_node(pos) + node.name = self.node_name_passive + minetest.swap_node(pos, node) + end + if self.infotext_name then + local number = meta:get_string("tubelib_number") + meta:set_string("infotext", self.infotext_name.." "..number..": stopped") + end + if self.formspec_func then + meta:set_string("formspec", self.formspec_func(pos, meta)) + end + minetest.get_node_timer(pos):stop() + return true + end + return false +end + +function NodeStates:start(pos, meta, called_from_on_timer) + local state = meta:get_int("tubelib_state") + if state == STOPPED or state == STANDBY or state == BLOCKED then + meta:set_int("tubelib_state", RUNNING) + if called_from_on_timer then + -- timer has to be stopped once to be able to be restarted + self.stop_timer = true + end + if self.node_name_active then + local node = minetest.get_node(pos) + node.name = self.node_name_active + minetest.swap_node(pos, node) + end + if self.infotext_name then + local number = meta:get_string("tubelib_number") + meta:set_string("infotext", self.infotext_name.." "..number..": running") + end + if self.formspec_func then + meta:set_string("formspec", self.formspec_func(pos, meta)) + end + minetest.get_node_timer(pos):start(self.cycle_time) + return true + end + return false +end + +function NodeStates:standby(pos, meta) + if meta:get_int("tubelib_state") == RUNNING then + meta:set_int("tubelib_state", STANDBY) + -- timer has to be stopped once to be able to be restarted + self.stop_timer = true + if self.node_name_passive then + local node = minetest.get_node(pos) + node.name = self.node_name_passive + minetest.swap_node(pos, node) + end + if self.infotext_name then + local number = meta:get_string("tubelib_number") + meta:set_string("infotext", self.infotext_name.." "..number..": standby") + end + if self.formspec_func then + meta:set_string("formspec", self.formspec_func(pos, meta)) + end + minetest.get_node_timer(pos):start(self.cycle_time * self.standby_ticks) + return true + end + return false +end + +-- special case of standby for pushing nodes +function NodeStates:blocked(pos, meta) + if meta:get_int("tubelib_state") == RUNNING then + meta:set_int("tubelib_state", BLOCKED) + -- timer has to be stopped once to be able to be restarted + self.stop_timer = true + if self.node_name_passive then + local node = minetest.get_node(pos) + node.name = self.node_name_passive + minetest.swap_node(pos, node) + end + if self.infotext_name then + local number = meta:get_string("tubelib_number") + meta:set_string("infotext", self.infotext_name.." "..number..": blocked") + end + if self.formspec_func then + meta:set_string("formspec", self.formspec_func(pos, meta)) + end + minetest.get_node_timer(pos):start(self.cycle_time * self.standby_ticks) + return true + end + return false +end + +function NodeStates:fault(pos, meta) + if meta:get_int("tubelib_state") == RUNNING then + meta:set_int("tubelib_state", FAULT) + if self.node_name_passive then + local node = minetest.get_node(pos) + node.name = self.node_name_passive + minetest.swap_node(pos, node) + end + if self.infotext_name then + local number = meta:get_string("tubelib_number") + meta:set_string("infotext", self.infotext_name.." "..number..": fault") + end + if self.formspec_func then + meta:set_string("formspec", self.formspec_func(pos, meta)) + end + minetest.get_node_timer(pos):stop() + return true + end + return false +end + +function NodeStates:defect(pos, meta) + meta:set_int("tubelib_state", DEFECT) + if self.node_name_defect then + local node = minetest.get_node(pos) + node.name = self.node_name_defect + minetest.swap_node(pos, node) + end + if self.infotext_name then + local number = meta:get_string("tubelib_number") + meta:set_string("infotext", self.infotext_name.." "..number..": defect") + end + if self.formspec_func then + meta:set_string("formspec", self.formspec_func(pos, meta)) + end + minetest.get_node_timer(pos):stop() + return true +end + +function NodeStates:get_state(meta) + return meta:get_int("tubelib_state") +end + +function NodeStates:get_state_string(meta) + return tubelib.StateStrings[meta:get_int("tubelib_state")] +end + +function NodeStates:is_active(meta) + local state = meta:get_int("tubelib_state") + if self.stop_timer == true then + self.stop_timer = false + return false + end + return state == RUNNING or state == STANDBY or state == BLOCKED +end + +-- To be called if node is idle. +-- If countdown reaches zero, the node is set to STANDBY. +function NodeStates:idle(pos, meta) + local countdown = meta:get_int("tubelib_countdown") - 1 + meta:set_int("tubelib_countdown", countdown) + if countdown < 0 then + self:standby(pos, meta) + end +end + +-- To be called after successful node action to raise the timer +-- and keep the node in state RUNNING +function NodeStates:keep_running(pos, meta, val) + -- set to RUNNING if not already done + self:start(pos, meta, true) + meta:set_int("tubelib_countdown", val) + meta:set_int("tubelib_item_meter", meta:get_int("tubelib_item_meter") + 1) + if self.aging_level1 then + local cnt = meta:get_int("tubelib_aging") + 1 + meta:set_int("tubelib_aging", cnt) + if cnt > (self.aging_level1) and math.random(self.aging_level2) == 1 then + self:defect(pos, meta) + end + end +end + +-- Start/stop node based on button events. +-- if function returns false, no button was pressed +function NodeStates:state_button_event(pos, fields) + if fields.state_button ~= nil then + local state = self:get_state(M(pos)) + if state == STOPPED or state == STANDBY or state == BLOCKED then + self:start(pos, M(pos)) + elseif state == RUNNING or state == FAULT then + self:stop(pos, M(pos)) + end + return true + end + return false +end + +function NodeStates:get_state_button_image(meta) + local state = meta:get_int("tubelib_state") + return tubelib.state_button(state) +end + +-- command interface +function NodeStates:on_receive_message(pos, topic, payload) + if topic == "on" then + self:start(pos, M(pos)) + return true + elseif topic == "off" then + self:stop(pos, M(pos)) + return true + elseif topic == "state" then + local node = minetest.get_node(pos) + if node.name == "ignore" then -- unloaded node? + return "blocked" + end + return self:get_state_string(M(pos)) + elseif self.has_item_meter and topic == "counter" then + return M(pos):get_int("tubelib_item_meter") + elseif self.has_item_meter and topic == "clear_counter" then + M(pos):set_int("tubelib_item_meter", 0) + return true + elseif self.aging_level1 and topic == "aging" then + return M(pos):get_int("tubelib_aging") + end +end + +-- repair corrupt node data and/or migrate node to state2 +function NodeStates:on_node_load(pos) + local meta = minetest.get_meta(pos) + + -- legacy node number/state/counter? + local number = meta:get_string("number") + if number ~= "" then + meta:set_string("tubelib_number", number) + meta:set_int("tubelib_state", tubelib.state(meta:get_int("running"))) + if self.has_item_meter then + meta:set_int("tubelib_item_meter", meta:get_int("counter")) + end + if self.aging_level1 then + meta:set_int("tubelib_aging", 0) + end + meta:set_string("number", nil) + meta:set_int("running", 0) + meta:set_int("counter", 0) + end + + -- node number corrupt? + number = meta:get_string("tubelib_number") + if number == "" then + number = tubelib.add_node(pos, self.node_name_passive) + meta:set_string("tubelib_number", number) + else + local info = tubelib.get_node_info(number) + if not info or info.pos ~= pos then + number = tubelib.add_node(pos, self.node_name_passive) + meta:set_string("tubelib_number", number) + end + end + + -- state corrupt? + local state = meta:get_int("tubelib_state") + if state == 0 then + if minetest.get_node_timer(pos):is_started() then + meta:set_int("tubelib_state", RUNNING) + else + meta:set_int("tubelib_state", STOPPED) + end + elseif state == RUNNING then + minetest.get_node_timer(pos):start(self.cycle_time) + elseif state == STANDBY then + minetest.get_node_timer(pos):start(self.cycle_time * self.standby_ticks) + elseif state == BLOCKED then + minetest.get_node_timer(pos):start(self.cycle_time * self.standby_ticks) + end +end + +-- Repair of defect (feature!) nodes +function NodeStates:on_node_repair(pos) + local meta = M(pos) + if meta:get_int("tubelib_state") == DEFECT then + meta:set_int("tubelib_state", STOPPED) + if self.node_name_passive then + local node = minetest.get_node(pos) + node.name = self.node_name_passive + minetest.swap_node(pos, node) + end + if self.aging_level1 then + meta:set_int("tubelib_aging", 0) + end + if self.infotext_name then + local number = meta:get_string("tubelib_number") + meta:set_string("infotext", self.infotext_name.." "..number..": stopped") + end + if self.formspec_func then + meta:set_string("formspec", self.formspec_func(pos, meta)) + end + return true + end + return false +end + +function NodeStates:after_dig_node(pos, oldnode, oldmetadata, digger) + local inv = minetest.get_inventory({type="player", name=digger:get_player_name()}) + local cnt = oldmetadata.fields.tubelib_aging and tonumber(oldmetadata.fields.tubelib_aging) or 0 + local is_defect = cnt > self.aging_level1 and math.random(self.aging_level2 / cnt) == 1 + if self.node_name_defect and is_defect then + inv:add_item("main", ItemStack(self.node_name_defect)) + else + inv:add_item("main", ItemStack(self.node_name_passive)) + end +end diff --git a/tubelib/pusher.lua b/tubelib/pusher.lua index 693a303..58fb4fa 100644 --- a/tubelib/pusher.lua +++ b/tubelib/pusher.lua @@ -13,7 +13,7 @@ Simple node for push/pull operation of StackItems from chests or other inventory/server nodes to tubes or other inventory/server nodes. - The Pusher supports the following messages: + The Pusher is based on the class NodeStates and supports the following messages: - topic = "on", payload = nil - topic = "off", payload = nil - topic = "state", payload = nil, @@ -29,83 +29,48 @@ -- | |/ -- +--------+ -local RUNNING_STATE = 10 +-- for lazy programmers +local S = function(pos) if pos then return minetest.pos_to_string(pos) end end +local P = minetest.string_to_pos +local M = minetest.get_meta -local function switch_on(pos, node) - local meta = minetest.get_meta(pos) - local number = meta:get_string("number") - meta:set_int("running", RUNNING_STATE) - meta:set_string("infotext", "Pusher "..number..": running") - node.name = "tubelib:pusher_active" - minetest.swap_node(pos, node) - minetest.get_node_timer(pos):start(2) - return false -end +local STANDBY_TICKS = 5 +local COUNTDOWN_TICKS = 5 +local CYCLE_TIME = 2 -local function switch_off(pos, node) - local meta = minetest.get_meta(pos) - local number = meta:get_string("number") - meta:set_int("running", tubelib.STATE_STOPPED) - meta:set_string("infotext", "Pusher "..number..": stopped") - node.name = "tubelib:pusher" - minetest.swap_node(pos, node) - minetest.get_node_timer(pos):stop() - return false -end +local State = tubelib.NodeStates:new({ + node_name_passive = "tubelib:pusher", + node_name_active = "tubelib:pusher_active", + node_name_defect = "tubelib:pusher_defect", + infotext_name = "Tubelib Pusher", + cycle_time = CYCLE_TIME, + standby_ticks = STANDBY_TICKS, + has_item_meter = true, + aging_factor = 10, +}) -local function goto_standby(pos, node) - local meta = minetest.get_meta(pos) - local number = meta:get_string("number") - meta:set_int("running", tubelib.STATE_STANDBY) - meta:set_string("infotext", "Pusher "..number..": standby") - node.name = "tubelib:pusher" - minetest.swap_node(pos, node) - minetest.get_node_timer(pos):start(20) - return false -end - -local function goto_blocked(pos, node) - local meta = minetest.get_meta(pos) - local number = meta:get_string("number") - meta:set_int("running", tubelib.STATE_BLOCKED) - meta:set_string("infotext", "Pusher "..number..": blocked") - node.name = "tubelib:pusher" - minetest.swap_node(pos, node) - minetest.get_node_timer(pos):start(20) - return false -end - -local function keep_running(pos, elapsed) - local meta = minetest.get_meta(pos) - local number = meta:get_string("number") - local running = meta:get_int("running") - 1 +local function pushing(pos, meta) local player_name = meta:get_string("player_name") local items = tubelib.pull_items(pos, "L", player_name) -- <<=== tubelib if items ~= nil then if tubelib.push_items(pos, "R", items, player_name) == false then -- <<=== tubelib -- place item back tubelib.unpull_items(pos, "L", items, player_name) -- <<=== tubelib - local node = minetest.get_node(pos) - return goto_blocked(pos, node) - end - meta:set_int("item_counter", meta:get_int("item_counter") + 1) - if running <= 0 then - local node = minetest.get_node(pos) - return switch_on(pos, node) - else - -- reload running state - running = RUNNING_STATE - end - else - if running <= 0 then - local node = minetest.get_node(pos) - return goto_standby(pos, node) + State:blocked(pos, meta) + return end + State:keep_running(pos, meta, COUNTDOWN_TICKS) + return end - meta:set_int("running", running) - return true + State:idle(pos, meta) end +local function keep_running(pos, elapsed) + local meta = M(pos) + pushing(pos, meta) + return State:is_active(meta) +end + minetest.register_node("tubelib:pusher", { description = "Tubelib Pusher", tiles = { @@ -122,24 +87,24 @@ minetest.register_node("tubelib:pusher", { local meta = minetest.get_meta(pos) meta:set_string("player_name", placer:get_player_name()) local number = tubelib.add_node(pos, "tubelib:pusher") -- <<=== tubelib - meta:set_string("number", number) - meta:set_string("infotext", "Pusher "..number..": stopped") - meta:set_int("item_counter", 0) + State:node_init(pos, number) end, on_rightclick = function(pos, node, clicker) if not minetest.is_protected(pos, clicker:get_player_name()) then - switch_on(pos, node) + State:start(pos, M(pos)) end end, - after_dig_node = function(pos) + after_dig_node = function(pos, oldnode, oldmetadata, digger) tubelib.remove_node(pos) -- <<=== tubelib + State:after_dig_node(pos, oldnode, oldmetadata, digger) end, on_timer = keep_running, on_rotate = screwdriver.disallow, + drop = "", paramtype = "light", sunlight_propagates = true, paramtype2 = "facedir", @@ -199,7 +164,7 @@ minetest.register_node("tubelib:pusher_active", { on_rightclick = function(pos, node, clicker) if not minetest.is_protected(pos, clicker:get_player_name()) then - switch_off(pos, node) + State:stop(pos, M(pos)) end end, @@ -214,6 +179,42 @@ minetest.register_node("tubelib:pusher_active", { sounds = default.node_sound_wood_defaults(), }) +minetest.register_node("tubelib:pusher_defect", { + description = "Tubelib Pusher", + tiles = { + -- up, down, right, left, back, front + 'tubelib_pusher1.png', + 'tubelib_pusher1.png', + 'tubelib_outp.png^tubelib_defect.png', + 'tubelib_inp.png^tubelib_defect.png', + "tubelib_pusher1.png^[transformR180]^tubelib_defect.png", + "tubelib_pusher1.png^tubelib_defect.png", + }, + + after_place_node = function(pos, placer) + local meta = minetest.get_meta(pos) + meta:set_string("player_name", placer:get_player_name()) + local number = tubelib.add_node(pos, "tubelib:pusher") -- <<=== tubelib + State:node_init(pos, number) + State:defect(pos, meta) + end, + + after_dig_node = function(pos) + tubelib.remove_node(pos) -- <<=== tubelib + end, + + on_timer = keep_running, + on_rotate = screwdriver.disallow, + + paramtype = "light", + sunlight_propagates = true, + paramtype2 = "facedir", + groups = {choppy=2, cracky=2, crumbly=2, not_in_creative_inventory=1}, + is_ground_content = false, + sounds = default.node_sound_wood_defaults(), +}) + + minetest.register_craft({ output = "tubelib:pusher 2", recipe = { @@ -224,34 +225,26 @@ minetest.register_craft({ }) --------------------------------------------------------------- tubelib -tubelib.register_node("tubelib:pusher", {"tubelib:pusher_active"}, { +tubelib.register_node("tubelib:pusher", + {"tubelib:pusher_active", "tubelib:pusher_defect"}, { on_pull_item = nil, -- pusher has no inventory on_push_item = nil, -- pusher has no inventory on_unpull_item = nil, -- pusher has no inventory is_pusher = true, -- is a pulling/pushing node on_recv_message = function(pos, topic, payload) - local node = minetest.get_node(pos) - if topic == "on" then - return switch_on(pos, node) - elseif topic == "off" then - return switch_off(pos, node) - elseif topic == "state" then - if node.name == "ignore" then -- unloaded pusher? - return "blocked" - end - local meta = minetest.get_meta(pos) - local running = meta:get_int("running") or tubelib.STATE_STOPPED - return tubelib.statestring(running) - elseif topic == "counter" then - local meta = minetest.get_meta(pos) - return meta:get_int("item_counter") - elseif topic == "clear_counter" then - local meta = minetest.get_meta(pos) - return meta:set_int("item_counter", 0) + local resp = State:on_receive_message(pos, topic, payload) + if resp then + return resp else - return "not supported" + return "unsupported" end end, + on_node_load = function(pos) + State:on_node_load(pos) + end, + on_node_repair = function(pos) + return State:on_node_repair(pos) + end, }) --------------------------------------------------------------- tubelib diff --git a/tubelib/repairkit.lua b/tubelib/repairkit.lua new file mode 100644 index 0000000..7d6f126 --- /dev/null +++ b/tubelib/repairkit.lua @@ -0,0 +1,82 @@ +--[[ + + Tube Library + ============ + + Copyright (C) 2017-2018 Joachim Stolberg + + LGPLv2.1+ + See LICENSE.txt for more information + + repairkit.lua: +]]-- + +-- for lazy programmers +local S = function(pos) if pos then return minetest.pos_to_string(pos) end end +local P = minetest.string_to_pos +local M = minetest.get_meta + + +local function repair_node(itemstack, user, pointed_thing) + local pos = pointed_thing.under + if pos then + if tubelib.repair_node(pos) then + minetest.chat_send_player(user:get_player_name(), "[Tubelib] Node repaired") + itemstack:take_item() + return itemstack + end + end + return +end + +local function read_state(itemstack, user, pointed_thing) + local pos = pointed_thing.under + if pos then + local number = tubelib.get_node_number(pos) + if number then + local state = tubelib.send_request(number, "state", nil) + local counter = tubelib.send_request(number, "counter", nil) + local aging = tubelib.send_request(number, "aging", nil) + if state and counter and aging then + minetest.chat_send_player(user:get_player_name(), "[Tubelib] state ="..state..", counter = "..counter..", aging = "..aging) + end + end + end +end + +minetest.register_craftitem("tubelib:repairkit", { + description = "Tubelib Repair Kit", + inventory_image = "tubelib_repairkit.png", + wield_image = "tubelib_repairkit.png^[transformR270", + groups = {cracky=1, book=1}, + on_use = repair_node, + node_placement_prediction = "", +}) + + +minetest.register_node("tubelib:end_wrench", { + description = "Tubelib End Wrench", + inventory_image = "tubelib_end_wrench.png", + wield_image = "tubelib_end_wrench.png", + groups = {cracky=1, book=1}, + on_use = read_state, + node_placement_prediction = "", +}) + +minetest.register_craft({ + output = "tubelib:repairkit", + recipe = { + {"", "basic_materials:gear_steel", ""}, + {"", "tubelib:end_wrench", ""}, + {"", "basic_materials:oil_extract", ""}, + }, +}) + +minetest.register_craft({ + output = "tubelib:end_wrench 4", + recipe = { + {"", "", "default:steel_ingot"}, + {"", "default:tin_ingot", ""}, + {"default:steel_ingot", "", ""}, + }, +}) diff --git a/tubelib/states.lua b/tubelib/states.lua index a3dbe27..bae0b9a 100644 --- a/tubelib/states.lua +++ b/tubelib/states.lua @@ -15,35 +15,41 @@ ]]-- -- --- Inventory Button States +-- Tubelib machine states -- - -tubelib.STOPPED = 1 -- not operational -tubelib.RUNNING = 2 -- in normal operation -tubelib.STANDBY = 3 -- nothing to do or blocked anyhow -tubelib.FAULT = 4 -- any fault state, which has to be fixed by the player +tubelib.STOPPED = 1 -- not operational/turned off +tubelib.RUNNING = 2 -- in normal operation/turned on +tubelib.STANDBY = 3 -- nothing to do (e.g. no input items), or blocked anyhow (output jammed), + -- or node (world) not loaded +tubelib.FAULT = 4 -- any fault state (e.g. no fuel), which can be fixed by the player +tubelib.BLOCKED = 5 -- a pushing node is blocked due to a full destination inventory +tubelib.DEFECT = 6 -- a defect (broken), which has to be repaired by the player tubelib.StatesImg = { "tubelib_inv_button_off.png", "tubelib_inv_button_on.png", "tubelib_inv_button_standby.png", - "tubelib_inv_button_error.png" + "tubelib_inv_button_error.png", + "tubelib_inv_button_error.png", + "tubelib_inv_button_off.png", } -- Return state button image for the node inventory function tubelib.state_button(state) - if state and state < 5 and state > 0 then + if state and state < 7 and state > 0 then return tubelib.StatesImg[state] end - return tubelib.StatesImg[tubelib.FAULT] + return "tubelib_inv_button_off.png" end -- State string based on button states -tubelib.states = {"stopped", "running", "standby", "fault"} +tubelib.StateStrings = {"stopped", "running", "standby", "fault", "blocked", "defect"} + + -- --- 'running' variable States +-- 'running' variable States (deprecated) -- tubelib.STATE_RUNNING = 1 -- in normal operation diff --git a/tubelib/textures/tubelib_blue.png b/tubelib/textures/tubelib_blue.png index 71c47fa..b8d75c1 100644 Binary files a/tubelib/textures/tubelib_blue.png and b/tubelib/textures/tubelib_blue.png differ diff --git a/tubelib/textures/tubelib_defect.png b/tubelib/textures/tubelib_defect.png new file mode 100644 index 0000000..bf830f6 Binary files /dev/null and b/tubelib/textures/tubelib_defect.png differ diff --git a/tubelib/textures/tubelib_distributor_blue.png b/tubelib/textures/tubelib_distributor_blue.png index fb3d47c..f43e2b6 100644 Binary files a/tubelib/textures/tubelib_distributor_blue.png and b/tubelib/textures/tubelib_distributor_blue.png differ diff --git a/tubelib/textures/tubelib_distributor_green.png b/tubelib/textures/tubelib_distributor_green.png index c96487a..92e9276 100644 Binary files a/tubelib/textures/tubelib_distributor_green.png and b/tubelib/textures/tubelib_distributor_green.png differ diff --git a/tubelib/textures/tubelib_distributor_red.png b/tubelib/textures/tubelib_distributor_red.png index cd11bb9..6ec1e03 100644 Binary files a/tubelib/textures/tubelib_distributor_red.png and b/tubelib/textures/tubelib_distributor_red.png differ diff --git a/tubelib/textures/tubelib_distributor_yellow.png b/tubelib/textures/tubelib_distributor_yellow.png index c38d77c..0573c7d 100644 Binary files a/tubelib/textures/tubelib_distributor_yellow.png and b/tubelib/textures/tubelib_distributor_yellow.png differ diff --git a/tubelib/textures/tubelib_end_wrench.png b/tubelib/textures/tubelib_end_wrench.png new file mode 100644 index 0000000..60d23f5 Binary files /dev/null and b/tubelib/textures/tubelib_end_wrench.png differ diff --git a/tubelib/textures/tubelib_front.png b/tubelib/textures/tubelib_front.png index 5b550f1..d3f9b7a 100644 Binary files a/tubelib/textures/tubelib_front.png and b/tubelib/textures/tubelib_front.png differ diff --git a/tubelib/textures/tubelib_green.png b/tubelib/textures/tubelib_green.png index 02a3cc8..014a96e 100644 Binary files a/tubelib/textures/tubelib_green.png and b/tubelib/textures/tubelib_green.png differ diff --git a/tubelib/textures/tubelib_gui_arrow.png b/tubelib/textures/tubelib_gui_arrow.png index 3664259..f5565f7 100644 Binary files a/tubelib/textures/tubelib_gui_arrow.png and b/tubelib/textures/tubelib_gui_arrow.png differ diff --git a/tubelib/textures/tubelib_hole.png b/tubelib/textures/tubelib_hole.png index 125b055..6d61205 100644 Binary files a/tubelib/textures/tubelib_hole.png and b/tubelib/textures/tubelib_hole.png differ diff --git a/tubelib/textures/tubelib_red.png b/tubelib/textures/tubelib_red.png index 04c293f..4e4cd2a 100644 Binary files a/tubelib/textures/tubelib_red.png and b/tubelib/textures/tubelib_red.png differ diff --git a/tubelib/textures/tubelib_repairkit.png b/tubelib/textures/tubelib_repairkit.png new file mode 100644 index 0000000..8215c46 Binary files /dev/null and b/tubelib/textures/tubelib_repairkit.png differ diff --git a/tubelib/textures/tubelib_yellow.png b/tubelib/textures/tubelib_yellow.png index e92f942..8ac9343 100644 Binary files a/tubelib/textures/tubelib_yellow.png and b/tubelib/textures/tubelib_yellow.png differ diff --git a/tubelib/tubes.lua b/tubelib/tubes.lua new file mode 100644 index 0000000..7c5c572 --- /dev/null +++ b/tubelib/tubes.lua @@ -0,0 +1,130 @@ +--[[ + + Tubes based on tubelib2 + ======================= + + Copyright (C) 2018 Joachim Stolberg + + LGPLv2.1+ + See LICENSE.txt for more information + + tubes.lua: Node registration and API functions to move items via tubes + +]]-- + +-- used for registered nodes +tubelib.KnownNodes = { + ["tubelib:tubeS"] = true, + ["tubelib:tubeA"] = true, +} + + +local Tube = tubelib2.Tube:new({ + -- North, East, South, West, Down, Up + dirs_to_check = {1,2,3,4,5,6}, + max_tube_length = 200, + show_infotext = false, + primary_node_names = {"tubelib:tubeS", "tubelib:tubeA"}, + after_place_tube = function(pos, param2, tube_type, num_tubes, tbl) + minetest.swap_node(pos, {name = "tubelib:tube"..tube_type, param2 = param2}) + end, +}) + +tubelib.Tube = Tube + +minetest.register_node("tubelib:tubeS", { + description = "Tubelib Tube", + tiles = { -- Top, base, right, left, front, back + "tubelib_tube.png^[transformR90", + "tubelib_tube.png^[transformR90", + "tubelib_tube.png", + "tubelib_tube.png", + "tubelib_hole.png", + "tubelib_hole.png", + }, + + after_place_node = function(pos, placer, itemstack, pointed_thing) + if not Tube:after_place_tube(pos, placer, pointed_thing) then + minetest.remove_node(pos) + return true + end + return false + end, + + after_dig_node = function(pos, oldnode, oldmetadata, digger) + Tube:after_dig_tube(pos, oldnode, oldmetadata) + end, + + paramtype2 = "facedir", + drawtype = "nodebox", + node_box = { + type = "fixed", + fixed = { + {-2/8, -2/8, -4/8, 2/8, 2/8, 4/8}, + }, + }, + selection_box = { + type = "fixed", + fixed = { -1/4, -1/4, -1/2, 1/4, 1/4, 1/2 }, + }, + collision_box = { + type = "fixed", + fixed = { -1/4, -1/4, -1/2, 1/4, 1/4, 1/2 }, + }, + on_rotate = screwdriver.disallow, + paramtype = "light", + sunlight_propagates = true, + is_ground_content = false, + groups = {choppy=2, cracky=3, stone=1}, + sounds = default.node_sound_wood_defaults(), +}) + +minetest.register_node("tubelib:tubeA", { + description = "Tubelib Tube", + tiles = { -- Top, base, right, left, front, back + "tubelib_knee2.png", + "tubelib_hole2.png^[transformR180", + "tubelib_knee.png^[transformR270", + "tubelib_knee.png", + "tubelib_knee2.png", + "tubelib_hole2.png", + }, + + after_dig_node = function(pos, oldnode, oldmetadata, digger) + Tube:after_dig_tube(pos, oldnode, oldmetadata) + end, + + paramtype2 = "facedir", + drawtype = "nodebox", + node_box = { + type = "fixed", + fixed = { + {-2/8, -4/8, -2/8, 2/8, 2/8, 2/8}, + {-2/8, -2/8, -4/8, 2/8, 2/8, -2/8}, + }, + }, + selection_box = { + type = "fixed", + fixed = { -1/4, -1/2, -1/2, 1/4, 1/4, 1/4 }, + }, + collision_box = { + type = "fixed", + fixed = { -1/4, -1/2, -1/2, 1/4, 1/4, 1/4 }, + }, + on_rotate = screwdriver.disallow, + paramtype = "light", + sunlight_propagates = true, + is_ground_content = false, + groups = {choppy=2, cracky=3, stone=1, not_in_creative_inventory=1}, + sounds = default.node_sound_wood_defaults(), + drop = "tubelib:tubeS", +}) + +minetest.register_craft({ + output = "tubelib:tubeS 4", + recipe = { + {"default:steel_ingot", "", "group:wood"}, + {"", "group:wood", ""}, + {"group:wood", "", "default:tin_ingot"}, + }, +}) diff --git a/tubelib/tubes1.lua b/tubelib/tubes1.lua deleted file mode 100644 index a77703e..0000000 --- a/tubelib/tubes1.lua +++ /dev/null @@ -1,294 +0,0 @@ ---[[ - - Tube Library - ============ - - Copyright (C) 2017-2018 Joachim Stolberg - - LGPLv2.1+ - See LICENSE.txt for more information - - History: - see init.lua - - tubes1.lua: Functions to place and remove tubes - -]]-- - - --- debugging -local P = minetest.pos_to_string - -local MAX_TUBE_LENGTH = 100 - --- Conversion from tube number/param2 (number*10 + param2) to tube hole dirs (view from the inside) -local TubeDirs = { - [10] = {1,3}, - [11] = {2,4}, - [12] = {1,3}, - [13] = {2,4}, - [20] = {5,6}, - [21] = {5,6}, - [22] = {5,6}, - [23] = {5,6}, - [30] = {3,4}, - [31] = {1,4}, - [32] = {1,2}, - [33] = {2,3}, - [40] = {3,5}, - [41] = {4,5}, - [42] = {1,5}, - [43] = {2,5}, - [50] = {3,6}, - [51] = {4,6}, - [52] = {1,6}, - [53] = {2,6}, -} - --- Conversion from tube dirs (dir1 * 10 + dir2) to tube number/param2 -local TubeNodeAttr = {} - -for k,v in pairs(TubeDirs) do - local key = v[1] * 10 + v[2] - local number = math.floor(k / 10) - local param2 = k % 10 - TubeNodeAttr[key] = {number = number, param2 = param2} -end - - --- Convertion of 'dir' (view from the outside to inside and vs) -local Turn180Deg = {3,4,1,2,6,5} -local Turn90Deg = {2,3,4,5,6,1} - -local Dir2Offset = { - {x=0, y=0, z=1}, - {x=1, y=0, z=0}, - {x=0, y=0, z=-1}, - {x=-1, y=0, z=0}, - {x=0, y=-1, z=0}, - {x=0, y=1, z=0} -} - -tubelib.TubeNames = { - ["tubelib:tube1"] = true, - ["tubelib:tube2"] = true, - ["tubelib:tube3"] = true, - ["tubelib:tube4"] = true, - ["tubelib:tube5"] = true, -} - --- used for registered nodes -tubelib.KnownNodes = { - ["tubelib:tube1"] = true, - ["tubelib:tube2"] = true, - ["tubelib:tube3"] = true, - ["tubelib:tube4"] = true, - ["tubelib:tube5"] = true, -} - --- use Voxel Manipulator to read the node -function tubelib.read_node_with_vm(pos) - local vm = VoxelManip() - local MinEdge, MaxEdge = vm:read_from_map(pos, pos) - local data = vm:get_data() - local param2_data = vm:get_param2_data() - local area = VoxelArea:new({MinEdge = MinEdge, MaxEdge = MaxEdge}) - return { - name = minetest.get_name_from_content_id(data[area:index(pos.x, pos.y, pos.z)]), - param2 = param2_data[area:index(pos.x, pos.y, pos.z)] - } -end - -local function get_tube_number_and_param2(dir1, dir2) - if dir1 == dir2 then - dir2 = Turn180Deg[dir1] - end - if dir1 > dir2 then - dir1, dir2 = dir2, dir1 - end - local item = TubeNodeAttr[dir1*10 + dir2] - return item.number, item.param2 -end - --- convert 6D-dir to position -local function get_tube_pos(pos, dir) - return vector.add(pos, Dir2Offset[dir]) -end - --- Tube open sides -local function get_tube_dirs(pos, node) - if node == nil then - node = minetest.get_node_or_nil(pos) or tubelib.read_node_with_vm(pos) - end - if tubelib.TubeNames[node.name] then - local ttype = (string.byte(node.name, -1) - 48) * 10 + node.param2 - return TubeDirs[ttype][1], TubeDirs[ttype][2] - end - return nil, nil -end - -function tubelib.get_next_tube(pos, dir) - pos = get_tube_pos(pos, dir) - local dir1, dir2 = get_tube_dirs(pos) - - if dir1 then - dir = Turn180Deg[dir] - if dir == dir1 then - return pos, dir2 - elseif dir == dir2 then - return pos, dir1 - end - end - return pos, nil -end - -local function is_known_node(pos, dir) - if dir then - pos = get_tube_pos(pos, dir) - local node = minetest.get_node_or_nil(pos) or tubelib.read_node_with_vm(pos) - if tubelib.KnownNodes[node.name] and not tubelib.TubeNames[node.name] then - return true - end - end - return false -end - - --- Walk to the other end of the tube line, starting at 'pos/dir'. --- Returns: cnt - number of tube nodes --- pos - the peer tube node --- dir - dir to the drop position, next after 'pos' -function tubelib.walk_to_peer(pos, dir) - local cnt = 0 - while cnt < MAX_TUBE_LENGTH do - local new_pos, new_dir = tubelib.get_next_tube(pos, dir) - if not new_dir then - break - end - cnt = cnt + 1 - pos, dir = new_pos, new_dir - end - return cnt, pos, dir -end - --- Delete meta data of the peer node -function tubelib.delete_meta_data(pos, node) - local dir1, dir2 = get_tube_dirs(pos, node) - local cnt1 = 0 - local dir, npos - if dir1 then - cnt1, npos, dir = tubelib.walk_to_peer(pos, dir1) - -- delete meta on peer tube - if cnt1 > 0 then - minetest.get_meta(npos):from_table(nil) - end - end - local cnt2 = 0 - if dir2 then - cnt2, npos, dir = tubelib.walk_to_peer(pos, dir2) - -- delete meta on peer tube - if cnt2 > 0 then - minetest.get_meta(npos):from_table(nil) - end - end - return cnt1 + cnt2 -end - -local function swap_node(pos, node_num, param2) - local node = minetest.get_node(pos) - node.name = "tubelib:tube"..node_num - node.param2 = param2 - minetest.swap_node(pos, node) -end - -local function is_connected(pos, dir) - if dir then - pos = get_tube_pos(pos, dir) - local dir1,dir2 = get_tube_dirs(pos) - -- return true if connected - dir = Turn180Deg[dir] - return dir == dir1 or dir == dir2 - end - return false -end - -local function is_tubelib_block(pos, dir) - if dir then - pos = get_tube_pos(pos, dir) - local dir1,dir2 = get_tube_dirs(pos) - -- return true if connected - dir = Turn180Deg[dir] - return dir == dir1 or dir == dir2 - end - return false -end -local function update_next_tube(dir, pos) - -- test if tube is connected with neighbor tubes - local dir1, dir2 = get_tube_dirs(pos) - local conn1 = is_connected(pos, dir1) or is_known_node(pos, dir1) - local conn2 = is_connected(pos, dir2) or is_known_node(pos, dir2) - -- already connected or no tube arround? - if (conn1 and conn2) or (not dir1 and not dir2) then - return - elseif not conn1 and not conn2 then - if dir1 ~= dir and dir2 ~= dir then - dir1 = Turn90Deg[dir1] - dir2 = Turn180Deg[dir1] - end - elseif conn1 then - dir2 = Turn180Deg[dir] - else - dir1 = Turn180Deg[dir] - end - local node_num, param2 = get_tube_number_and_param2(dir1, dir2) - swap_node(pos, node_num, param2) -end - --- update new placed tube -local function update_tube(pos, dir, force_dir) - local dir1 = nil - local dir2 = nil - -- use the predefined direction? - if force_dir then - dir1 = force_dir - end - -- search on all 6 pos for up to 2 tubes with open holes or - -- other tubelib compatible nodes - for ndir = 1,6 do - if not dir1 and is_connected(pos, ndir) then - dir1 = ndir - elseif not dir2 and is_connected(pos, ndir) and ndir ~= dir1 then - dir2 = ndir - end - end - if not force_dir and (not dir1 or not dir2) then - for ndir = 1,6 do - if not dir1 and is_known_node(pos, ndir) then - dir1 = ndir - elseif not dir2 and is_known_node(pos, ndir) and ndir ~= dir1 then - dir2 = ndir - end - end - end - dir1 = dir1 or dir - dir2 = dir2 or Turn180Deg[dir] - local node_num, param2 = get_tube_number_and_param2(dir1, dir2) - swap_node(pos, node_num, param2) -end - -function tubelib.update_tubes(pos, dir, force_dir, straight_ahead) - -- Update all tubes arround the currently placed tube - update_next_tube(1, {x=pos.x , y=pos.y , z=pos.z+1}) - update_next_tube(2, {x=pos.x+1, y=pos.y , z=pos.z }) - update_next_tube(3, {x=pos.x , y=pos.y , z=pos.z-1}) - update_next_tube(4, {x=pos.x-1, y=pos.y , z=pos.z }) - update_next_tube(5, {x=pos.x , y=pos.y-1, z=pos.z }) - update_next_tube(6, {x=pos.x , y=pos.y+1, z=pos.z }) - if not straight_ahead then - -- Update the placed tube - update_tube(pos, dir, force_dir) - end - return tubelib.delete_meta_data(pos, minetest.get_node(pos)) < MAX_TUBE_LENGTH -end - - diff --git a/tubelib/tubes2.lua b/tubelib/tubes2.lua deleted file mode 100644 index 9f9f56f..0000000 --- a/tubelib/tubes2.lua +++ /dev/null @@ -1,230 +0,0 @@ ---[[ - - Tube Library - ============ - - Copyright (C) 2017-2018 Joachim Stolberg - - LGPLv2.1+ - See LICENSE.txt for more information - - History: - see init.lua - - tubes2.lua: Node registration and API functions to move items via tubes - -]]-- - --- Convertion of contact side to facedir -local SideToFacedir = {B=0, R=1, F=2, L=3, D=4, U=5} - --- Calculate the facedir to the other node, based on both node positions -local function dir_to_facedir(my_pos, other_pos) - if my_pos.z ~= other_pos.z then return my_pos.z - other_pos.z + 1 end - if my_pos.x ~= other_pos.x then return my_pos.x - other_pos.x + 2 end - if my_pos.y > other_pos.y then return 5 else return 4 end -end - -local function remote_node(pos, dir) - local meta = minetest.get_meta(pos) - local cnt - - -- legacy tube? - if meta:get_string("dest_pos2") ~= "" then - meta:from_table(nil) - end - - -- data available - local dest_pos = meta:get_string("dest_pos") - if dest_pos ~= "" then - local npos = minetest.string_to_pos(dest_pos) - local facedir = meta:get_int("facedir") - return npos, facedir+1 - end - - -- determine data and store as meta - cnt, pos, dir = tubelib.walk_to_peer(pos, dir) - local pos1,_ = tubelib.get_next_tube(pos, dir) - meta:set_string("dest_pos", minetest.pos_to_string(pos1)) - meta:set_int("facedir", dir - 1) - - return pos1, dir -end - -local function is_known_node(pointed_thing) - if pointed_thing.type == "node" then - local node = minetest.get_node(pointed_thing.under) - if tubelib.KnownNodes[node.name] then - return pointed_thing.under - end - end - return nil -end - --- Determine neighbor position and own facedir to the node. --- based on own pos and contact side 'B' - 'U'. --- Function considers also tube connections. -function tubelib.get_neighbor_pos(pos, side) - local facedir = SideToFacedir[side] - local dir - if facedir < 4 then - local node = minetest.get_node(pos) - dir = ((facedir + node.param2) % 4) + 1 - end - local npos, ndir = tubelib.get_next_tube(pos, dir) - local node = minetest.get_node(npos) - if tubelib.TubeNames[node.name] then - if ndir then - npos, ndir = remote_node(npos, ndir) - end - return npos, (ndir or 1) -1 - end - return npos, facedir -end - - -------------------------------------------------------------------------------- --- Node registration -------------------------------------------------------------------------------- - -local DefNodeboxes = { - -- x1 y1 z1 x2 y2 z2 - { -1/4, -1/4, -1/4, 1/4, 1/4, 1/4 }, - { -1/4, -1/4, -1/4, 1/4, 1/4, 1/4 }, -} - -local DirCorrections = { - {3, 6}, {2, 5}, -- standard tubes - {3, 1}, {3, 2}, {3, 5}, -- knees from front to.. -} - -local SelectBoxes = { - { -1/4, -1/4, -1/2, 1/4, 1/4, 1/2 }, - { -1/4, -1/2, -1/4, 1/4, 1/2, 1/4 }, - { -1/2, -1/4, -1/2, 1/4, 1/4, 1/4 }, - { -1/4, -1/2, -1/2, 1/4, 1/4, 1/4 }, - { -1/4, -1/4, -1/2, 1/4, 1/2, 1/4 }, -} - -local TilesData = { - -- up, down, right, left, back, front - { - "tubelib_tube.png^[transformR90", - "tubelib_tube.png^[transformR90", - "tubelib_tube.png", - "tubelib_tube.png", - "tubelib_hole.png", - "tubelib_hole.png", - }, - { - "tubelib_hole.png", - "tubelib_hole.png", - "tubelib_tube.png^[transformR90", - "tubelib_tube.png^[transformR90", - "tubelib_tube.png^[transformR90", - "tubelib_tube.png^[transformR90", - }, - { - "tubelib_knee.png^[transformR270", - "tubelib_knee.png^[transformR180", - "tubelib_knee2.png^[transformR270", - "tubelib_hole2.png^[transformR90", - "tubelib_knee2.png^[transformR90", - "tubelib_hole2.png^[transformR270", - }, - { - "tubelib_knee2.png", - "tubelib_hole2.png^[transformR180", - "tubelib_knee.png^[transformR270", - "tubelib_knee.png", - "tubelib_knee2.png", - "tubelib_hole2.png", - }, - { - "tubelib_hole2.png", - "tubelib_knee2.png^[transformR180", - "tubelib_knee.png^[transformR180", - "tubelib_knee.png^[transformR90", - "tubelib_knee2.png^[transformR180", - "tubelib_hole2.png^[transformR180", - }, -} - - -for idx,pos in ipairs(DirCorrections) do - local node_box_data = table.copy(DefNodeboxes) - node_box_data[1][pos[1]] = node_box_data[1][pos[1]] * 2 - node_box_data[2][pos[2]] = node_box_data[2][pos[2]] * 2 - - local tiles_data = TilesData[idx] - local hidden - - if idx == 1 then - hidden = 0 - else - hidden = 1 - end - minetest.register_node("tubelib:tube"..idx, { - description = "Tubelib Tube", - tiles = tiles_data, - drawtype = "nodebox", - node_box = { - type = "fixed", - fixed = node_box_data, - }, - selection_box = { - type = "fixed", - fixed = SelectBoxes[idx], - }, - collision_box = { - type = "fixed", - fixed = SelectBoxes[idx], - }, - - after_place_node = function(pos, placer, itemstack, pointed_thing) - local dir1 = nil - local dir2 = nil - local pitch = placer:get_look_pitch() - local known_pos = is_known_node(pointed_thing) - local straight_ahead = placer:get_player_control().sneak and not known_pos - if known_pos and placer:get_player_control().sneak then -- placer pointed to a known node (chest) - dir2 = dir_to_facedir(pos, known_pos) + 1 - end - if pitch > 1 then -- up? - dir1 = 6 - elseif pitch < -1 then -- down? - dir1 = 5 - else - dir1 = minetest.dir_to_facedir(placer:get_look_dir()) + 1 - end - if not tubelib.update_tubes(pos, dir1, dir2, straight_ahead) then - tubelib.delete_meta_data(pos, minetest.get_node(pos)) - minetest.remove_node(pos) - return itemstack - end - end, - - after_dig_node = function(pos, oldnode, oldmetadata, digger) - tubelib.delete_meta_data(pos, oldnode) - end, - - on_rotate = screwdriver.disallow, - paramtype2 = "facedir", - paramtype = "light", - sunlight_propagates = true, - is_ground_content = false, - groups = {choppy=2, cracky=3, stone=1, not_in_creative_inventory=hidden}, - drop = "tubelib:tube1", - sounds = default.node_sound_wood_defaults(), - }) -end - - -minetest.register_craft({ - output = "tubelib:tube1 4", - recipe = { - {"default:steel_ingot", "", "group:wood"}, - {"", "group:wood", ""}, - {"group:wood", "", "default:tin_ingot"}, - }, -}) diff --git a/tubelib_addons1/autocrafter.lua b/tubelib_addons1/autocrafter.lua index fa631ac..9401211 100644 --- a/tubelib_addons1/autocrafter.lua +++ b/tubelib_addons1/autocrafter.lua @@ -116,7 +116,7 @@ local function stop_crafter(pos) local node = minetest.get_node(pos) local meta = minetest.get_meta(pos) local number = meta:get_string("number") or "" - meta:set_int("running", 0) + meta:set_int("running", tubelib.STATE_STOPPED) meta:set_string("formspec",formspec(tubelib.STOPPED)) meta:set_string("infotext", "Tubelib Autocrafter "..number..": stopped") node.name = "tubelib_addons1:autocrafter" @@ -129,7 +129,7 @@ local function goto_sleep(pos) local node = minetest.get_node(pos) local meta = minetest.get_meta(pos) local number = meta:get_string("number") or "" - meta:set_int("running", -1) + meta:set_int("running", tubelib.STATE_STANDBY) meta:set_string("formspec",formspec(tubelib.STANDBY)) meta:set_string("infotext", "Tubelib Autocrafter "..number..": standby") node.name = "tubelib_addons1:autocrafter" @@ -149,7 +149,7 @@ local function run_autocrafter(pos, elapsed) -- only use crafts that have an actual result if output_item:is_empty() then - if running <= 0 then + if running <= tubelib.STATE_STOPPED then return goto_sleep(pos) end meta:set_int("running", running) @@ -157,7 +157,7 @@ local function run_autocrafter(pos, elapsed) end if not autocraft(inventory, craft) then - if running <= 0 then + if running <= tubelib.STATE_STOPPED then return goto_sleep(pos) end meta:set_int("running", running) @@ -166,7 +166,7 @@ local function run_autocrafter(pos, elapsed) meta:set_int("item_counter", meta:get_int("item_counter") + output_item:get_count()) - if running <= 0 then + if running <= tubelib.STATE_STOPPED then return start_crafter(pos) else running = SLEEP_CNT_START_VAL @@ -351,17 +351,17 @@ local function on_receive_fields(pos, formname, fields, sender) local meta = minetest.get_meta(pos) local running = meta:get_int("running") if fields.button ~= nil then - if running > 0 then + if running > tubelib.STATE_STOPPED then update_meta(meta, tubelib.STOPPED) stop_crafter(pos) - meta:set_int("running", 0) + meta:set_int("running", tubelib.STATE_STOPPED) else if update_meta(meta, tubelib.RUNNING) then - meta:set_int("running", 1) + meta:set_int("running", tubelib.STATE_RUNNING) start_crafter(pos) else stop_crafter(pos) - meta:set_int("running", 0) + meta:set_int("running", tubelib.STATE_STOPPED) end end end @@ -486,4 +486,11 @@ tubelib.register_node("tubelib_addons1:autocrafter", {"tubelib_addons1:autocraft return "unsupported" end end, + on_server_restart = function(pos) + local meta = minetest.get_meta(pos) + if meta:get_int("running") ~= tubelib.STATE_STOPPED then + meta:set_int("running", tubelib.STATE_STANDBY) + minetest.get_node_timer(pos):start(craft_time*SLEEP_CNT_START_VAL) + end + end, }) diff --git a/tubelib_addons1/fermenter.lua b/tubelib_addons1/fermenter.lua index ff9f085..e77d427 100644 --- a/tubelib_addons1/fermenter.lua +++ b/tubelib_addons1/fermenter.lua @@ -353,4 +353,11 @@ tubelib.register_node("tubelib_addons1:fermenter", {}, { return "unsupported" end end, + on_node_load = function(pos) + local meta = minetest.get_meta(pos) + if meta:get_int("running") ~= STOP_STATE then + meta:set_int("running", STANDBY_STATE) + minetest.get_node_timer(pos):start(CYCLE_TIME * TICKS_TO_SLEEP) + end + end, }) diff --git a/tubelib_addons1/funnel.lua b/tubelib_addons1/funnel.lua index 965cd20..2c6a123 100644 --- a/tubelib_addons1/funnel.lua +++ b/tubelib_addons1/funnel.lua @@ -154,6 +154,10 @@ tubelib.register_node("tubelib_addons1:funnel", {}, { return "unsupported" end end, + on_node_load = function(pos) + minetest.get_node_timer(pos):start(1) + end, + }) diff --git a/tubelib_addons1/grinder.lua b/tubelib_addons1/grinder.lua index 2a19916..7ae6f8a 100644 --- a/tubelib_addons1/grinder.lua +++ b/tubelib_addons1/grinder.lua @@ -14,16 +14,31 @@ ]]-- -local TICKS_TO_SLEEP = 10 +-- for lazy programmers +local S = function(pos) if pos then return minetest.pos_to_string(pos) end end +local P = minetest.string_to_pos +local M = minetest.get_meta + +local STANDBY_TICKS = 4 +local COUNTDOWN_TICKS = 4 local CYCLE_TIME = 2 -local STOP_STATE = 0 -local STANDBY_STATE = -1 -local FAULT_STATE = -3 + -- Grinder recipes local Recipes = {} -local function formspec(state) +local State = tubelib.NodeStates:new({ + node_name_passive = "tubelib_addons1:grinder", + node_name_active = "tubelib_addons1:grinder_active", + node_name_defect = "tubelib_addons1:grinder_defect", + infotext_name = "Tubelib Grinder", + cycle_time = CYCLE_TIME, + standby_ticks = STANDBY_TICKS, + has_item_meter = true, + aging_factor = 10, +}) + +local function formspec(pos, meta) return "size[8,8]".. default.gui_bg.. default.gui_bg_img.. @@ -31,7 +46,7 @@ local function formspec(state) "list[context;src;0,0;3,3;]".. "item_image[0,0;1,1;default:cobble]".. "image[3.5,1;1,1;tubelib_gui_arrow.png]".. - "image_button[3.5,2;1,1;".. tubelib.state_button(state) ..";button;]".. + "image_button[3.5,2;1,1;".. State:get_state_button_image(meta) ..";state_button;]".. "list[context;dst;5,0;3,3;]".. "item_image[5,0;1,1;default:gravel]".. "list[current_player;main;0,4;8,4;]".. @@ -41,23 +56,21 @@ local function formspec(state) "listring[current_player;main]" end +State:register_formspec_func(formspec) + local function allow_metadata_inventory_put(pos, listname, index, stack, player) if minetest.is_protected(pos, player:get_player_name()) then return 0 end - local meta = minetest.get_meta(pos) - local inv = meta:get_inventory() - if listname == "src" then - return stack:get_count() - elseif listname == "dst" then - return 0 + local inv = M(pos):get_inventory() + if listname == "src" and State:get_state(M(pos)) == tubelib.STANDBY then + State:start(pos, M(pos)) end - return 0 + return stack:get_count() end local function allow_metadata_inventory_move(pos, from_list, from_index, to_list, to_index, count, player) - local meta = minetest.get_meta(pos) - local inv = meta:get_inventory() + local inv = M(pos):get_inventory() local stack = inv:get_stack(from_list, from_index) return allow_metadata_inventory_put(pos, to_list, to_index, stack, player) end @@ -69,7 +82,7 @@ local function allow_metadata_inventory_take(pos, listname, index, stack, player return stack:get_count() end -local function grinding(inv) +local function grinding(pos, meta, inv) for _,stack in ipairs(inv:get_list("src")) do if not stack:is_empty() then local name = stack:get_name() @@ -78,104 +91,31 @@ local function grinding(inv) if inv:room_for_item("dst", output) then inv:add_item("dst", output) inv:remove_item("src", ItemStack(name)) - return true + State:keep_running(pos, meta, COUNTDOWN_TICKS) + else + State:blocked(pos, meta) end + else + State:fault(pos, meta) end + return end end - return false -end - - -local function start_the_machine(pos) - local meta = minetest.get_meta(pos) - local node = minetest.get_node(pos) - local number = meta:get_string("number") - meta:set_int("running", TICKS_TO_SLEEP) - meta:set_string("infotext", "Tubelib Grinder "..number..": running") - meta:set_string("formspec", formspec(tubelib.RUNNING)) - node.name = "tubelib_addons1:grinder_active" - minetest.swap_node(pos, node) - minetest.get_node_timer(pos):start(CYCLE_TIME) - return false -end - -local function stop_the_machine(pos) - local meta = minetest.get_meta(pos) - local node = minetest.get_node(pos) - local number = meta:get_string("number") - meta:set_int("running", STOP_STATE) - meta:set_string("infotext", "Tubelib Grinder "..number..": stopped") - meta:set_string("formspec", formspec(tubelib.STOPPED)) - node.name = "tubelib_addons1:grinder" - minetest.swap_node(pos, node) - minetest.get_node_timer(pos):stop() - return false -end - -local function goto_sleep(pos) - local meta = minetest.get_meta(pos) - local node = minetest.get_node(pos) - local number = meta:get_string("number") - meta:set_int("running", STANDBY_STATE) - meta:set_string("infotext", "Tubelib Grinder "..number..": standby") - meta:set_string("formspec", formspec(tubelib.STANDBY)) - node.name = "tubelib_addons1:grinder" - minetest.swap_node(pos, node) - minetest.get_node_timer(pos):start(CYCLE_TIME * TICKS_TO_SLEEP) - return false -end - -local function goto_fault(pos) - local meta = minetest.get_meta(pos) - local node = minetest.get_node(pos) - local number = meta:get_string("number") - meta:set_int("running", FAULT_STATE) - meta:set_string("infotext", "Tubelib Grinder "..number..": fault") - meta:set_string("formspec", formspec(tubelib.FAULT)) - node.name = "tubelib_addons1:grinder" - minetest.swap_node(pos, node) - minetest.get_node_timer(pos):stop() - return false + State:idle(pos, meta) end local function keep_running(pos, elapsed) - local meta = minetest.get_meta(pos) - local running = meta:get_int("running") - 1 - --print("running", running) + local meta = M(pos) local inv = meta:get_inventory() - local busy = grinding(inv) - - if busy == true then - if running <= STOP_STATE then - return start_the_machine(pos) - else - running = TICKS_TO_SLEEP - end - elseif not inv:is_empty("src") then - return goto_fault(pos) - else - if running <= STOP_STATE then - return goto_sleep(pos) - end - end - meta:set_int("running", running) - return true + grinding(pos, meta, inv) + return State:is_active(meta) 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 running = meta:get_int("running") or 1 - if fields.button ~= nil then - if running > STOP_STATE or running == FAULT_STATE then - stop_the_machine(pos) - else - start_the_machine(pos) - end - end + State:state_button_event(pos, fields) end minetest.register_node("tubelib_addons1:grinder", { @@ -192,17 +132,15 @@ minetest.register_node("tubelib_addons1:grinder", { after_place_node = function(pos, placer) local number = tubelib.add_node(pos, "tubelib_addons1:grinder") - local meta = minetest.get_meta(pos) + State:node_init(pos, number) + local meta = M(pos) local inv = meta:get_inventory() inv:set_size('src', 9) inv:set_size('dst', 9) - meta:set_string("number", number) - meta:set_string("infotext", "Tubelib Grinder "..number..": stopped") - meta:set_string("formspec", formspec(tubelib.STOPPED)) end, on_dig = function(pos, node, puncher, pointed_thing) - local meta = minetest.get_meta(pos) + local meta = M(pos) local inv = meta:get_inventory() if inv:is_empty("dst") and inv:is_empty("src") then minetest.node_dig(pos, node, puncher, pointed_thing) @@ -210,6 +148,10 @@ minetest.register_node("tubelib_addons1:grinder", { end end, + after_dig_node = function(pos, oldnode, oldmetadata, digger) + State:after_dig_node(pos, oldnode, oldmetadata, digger) + end, + on_rotate = screwdriver.disallow, on_timer = keep_running, on_receive_fields = on_receive_fields, @@ -217,6 +159,7 @@ minetest.register_node("tubelib_addons1:grinder", { allow_metadata_inventory_move = allow_metadata_inventory_move, allow_metadata_inventory_take = allow_metadata_inventory_take, + drop = "", paramtype = "light", sunlight_propagates = true, paramtype2 = "facedir", @@ -263,6 +206,49 @@ minetest.register_node("tubelib_addons1:grinder_active", { sounds = default.node_sound_wood_defaults(), }) +minetest.register_node("tubelib_addons1:grinder_defect", { + description = "Tubelib Grinder", + tiles = { + -- up, down, right, left, back, front + 'tubelib_addons1_grinder.png', + 'tubelib_front.png^tubelib_defect.png', + 'tubelib_front.png^tubelib_defect.png', + 'tubelib_front.png^tubelib_defect.png', + "tubelib_front.png^tubelib_defect.png", + "tubelib_front.png^tubelib_defect.png", + }, + + after_place_node = function(pos, placer) + local number = tubelib.add_node(pos, "tubelib_addons1:grinder") + State:node_init(pos, number) + local meta = M(pos) + local inv = meta:get_inventory() + inv:set_size('src', 9) + inv:set_size('dst', 9) + State:defect(pos, meta) + end, + + on_dig = function(pos, node, puncher, pointed_thing) + local meta = M(pos) + local inv = meta:get_inventory() + if inv:is_empty("dst") and inv:is_empty("src") then + minetest.node_dig(pos, node, puncher, pointed_thing) + tubelib.remove_node(pos) + end + end, + + allow_metadata_inventory_put = allow_metadata_inventory_put, + allow_metadata_inventory_move = allow_metadata_inventory_move, + allow_metadata_inventory_take = allow_metadata_inventory_take, + + paramtype = "light", + sunlight_propagates = true, + paramtype2 = "facedir", + groups = {choppy=2, cracky=2, crumbly=2, not_in_creative_inventory=1}, + is_ground_content = false, + sounds = default.node_sound_wood_defaults(), +}) + minetest.register_craft({ output = "tubelib_addons1:grinder", recipe = { @@ -273,32 +259,33 @@ minetest.register_craft({ }) -tubelib.register_node("tubelib_addons1:grinder", {"tubelib_addons1:grinder_active"}, { +tubelib.register_node("tubelib_addons1:grinder", + {"tubelib_addons1:grinder_active", "tubelib_addons1:grinder_defect"}, { on_pull_item = function(pos, side) - local meta = minetest.get_meta(pos) - return tubelib.get_item(meta, "dst") + return tubelib.get_item(M(pos), "dst") end, on_push_item = function(pos, side, item) - local meta = minetest.get_meta(pos) - return tubelib.put_item(meta, "src", item) + return tubelib.put_item(M(pos), "src", item) end, on_unpull_item = function(pos, side, item) - local meta = minetest.get_meta(pos) - return tubelib.put_item(meta, "dst", item) + return tubelib.put_item(M(pos), "dst", item) end, on_recv_message = function(pos, topic, payload) - if topic == "on" then - start_the_machine(pos) - elseif topic == "off" then - stop_the_machine(pos) - elseif topic == "state" then - local meta = minetest.get_meta(pos) - local running = meta:get_int("running") - return tubelib.statestring(running) + local resp = State:on_receive_message(pos, topic, payload) + if resp then + return resp else return "unsupported" end end, + on_node_load = function(pos) + print("on_node_load") + return State:on_node_load(pos) + end, + on_node_repair = function(pos) + print("on_node_repair") + return State:on_node_repair(pos) + end, }) diff --git a/tubelib_addons1/harvester.lua b/tubelib_addons1/harvester.lua index dfef16e..9931da8 100644 --- a/tubelib_addons1/harvester.lua +++ b/tubelib_addons1/harvester.lua @@ -449,6 +449,15 @@ tubelib.register_node("tubelib_addons1:harvester_base", {}, { return "unsupported" end end, + on_node_load = function(pos) + local meta = minetest.get_meta(pos) + local this = minetest.deserialize(meta:get_string("this")) + if this and this.running ~= tubelib.STATE_STOPPED then + this.running = tubelib.STATE_STANDBY + meta:set_string("this", minetest.serialize(this)) + minetest.get_node_timer(pos):start(CYCLE_TIME * TICKS_TO_SLEEP) + end + end, }) diff --git a/tubelib_addons1/liquidsampler.lua b/tubelib_addons1/liquidsampler.lua index 01a769f..8e550df 100644 --- a/tubelib_addons1/liquidsampler.lua +++ b/tubelib_addons1/liquidsampler.lua @@ -304,5 +304,12 @@ tubelib.register_node("tubelib_addons1:liquidsampler", {"tubelib_addons1:liquids return "not supported" end end, + on_node_load = function(pos) + local meta = minetest.get_meta(pos) + if meta:get_int("running") ~= tubelib.STATE_STOPPED then + meta:set_int("running", tubelib.STATE_STANDBY) + minetest.get_node_timer(pos):start(20) + end + end, }) --------------------------------------------------------------- tubelib diff --git a/tubelib_addons1/pusher_fast.lua b/tubelib_addons1/pusher_fast.lua index ebf00a4..83bdc6f 100644 --- a/tubelib_addons1/pusher_fast.lua +++ b/tubelib_addons1/pusher_fast.lua @@ -13,7 +13,7 @@ Fast pusher for push/pull operation of StackItems from chests or other inventory/server nodes to tubes or other inventory/server nodes. - The Pusher supports the following messages: + The Pusher is based on the class NodeStates and supports the following messages: - topic = "on", payload = nil - topic = "off", payload = nil - topic = "state", payload = nil, @@ -29,85 +29,50 @@ -- | |/ -- +--------+ -local RUNNING_STATE = 10 +-- for lazy programmers +local S = function(pos) if pos then return minetest.pos_to_string(pos) end end +local P = minetest.string_to_pos +local M = minetest.get_meta -local function switch_on(pos, node) - local meta = minetest.get_meta(pos) - local number = meta:get_string("number") - meta:set_int("running", RUNNING_STATE) - meta:set_string("infotext", "Fast Pusher "..number..": running") - node.name = "tubelib_addons1:pusher_fast_active" - minetest.swap_node(pos, node) - minetest.get_node_timer(pos):start(1) - return false -end +local STANDBY_TICKS = 5 +local COUNTDOWN_TICKS = 5 +local CYCLE_TIME = 1 -local function switch_off(pos, node) - local meta = minetest.get_meta(pos) - local number = meta:get_string("number") - meta:set_int("running", tubelib.STATE_STOPPED) - meta:set_string("infotext", "Fast Pusher "..number..": stopped") - node.name = "tubelib_addons1:pusher_fast" - minetest.swap_node(pos, node) - minetest.get_node_timer(pos):stop() - return false -end +local State = tubelib.NodeStates:new({ + node_name_passive = "tubelib_addons1:pusher", + node_name_active = "tubelib_addons1:pusher_active", + node_name_defect = "tubelib_addons1:pusher_defect", + infotext_name = "Fast Pusher", + cycle_time = CYCLE_TIME, + standby_ticks = STANDBY_TICKS, + has_item_meter = true, + aging_factor = 10, +}) -local function goto_standby(pos, node) - local meta = minetest.get_meta(pos) - local number = meta:get_string("number") - meta:set_int("running", tubelib.STATE_STANDBY) - meta:set_string("infotext", "Fast Pusher "..number..": standby") - node.name = "tubelib_addons1:pusher_fast" - minetest.swap_node(pos, node) - minetest.get_node_timer(pos):start(20) - return false -end - -local function goto_blocked(pos, node) - local meta = minetest.get_meta(pos) - local number = meta:get_string("number") - meta:set_int("running", tubelib.STATE_BLOCKED) - meta:set_string("infotext", "Fast Pusher "..number..": blocked") - node.name = "tubelib_addons1:pusher_fast" - minetest.swap_node(pos, node) - minetest.get_node_timer(pos):start(20) - return false -end - -local function keep_running(pos, elapsed) - local meta = minetest.get_meta(pos) - local number = meta:get_string("number") - local running = meta:get_int("running") - 1 +local function pushing(pos, meta) local player_name = meta:get_string("player_name") local items = tubelib.pull_items(pos, "L", player_name) -- <<=== tubelib if items ~= nil then if tubelib.push_items(pos, "R", items, player_name) == false then -- <<=== tubelib -- place item back tubelib.unpull_items(pos, "L", items, player_name) -- <<=== tubelib - local node = minetest.get_node(pos) - return goto_blocked(pos, node) - end - meta:set_int("item_counter", meta:get_int("item_counter") + 1) - if running <= 0 then - local node = minetest.get_node(pos) - return switch_on(pos, node) - else - -- reload running state - running = RUNNING_STATE - end - else - if running <= 0 then - local node = minetest.get_node(pos) - return goto_standby(pos, node) + State:blocked(pos, meta) + return end + State:keep_running(pos, meta, COUNTDOWN_TICKS) + return end - meta:set_int("running", running) - return true + State:idle(pos, meta) end +local function keep_running(pos, elapsed) + local meta = M(pos) + pushing(pos, meta) + return State:is_active(meta) +end + minetest.register_node("tubelib_addons1:pusher_fast", { - description = "Tubelib Fast Pusher", + description = "Fast Pusher", tiles = { -- up, down, right, left, back, front 'tubelib_addons1_pusher.png', @@ -121,25 +86,25 @@ minetest.register_node("tubelib_addons1:pusher_fast", { after_place_node = function(pos, placer) local meta = minetest.get_meta(pos) meta:set_string("player_name", placer:get_player_name()) - local number = tubelib.add_node(pos, "tubelib_addons1:pusher_fast") - meta:set_string("number", number) - meta:set_string("infotext", "Pusher "..number..": stopped") - meta:set_int("item_counter", 0) + local number = tubelib.add_node(pos, "tubelib_addons1:pusher_fast") -- <<=== tubelib + State:node_init(pos, number) end, on_rightclick = function(pos, node, clicker) if not minetest.is_protected(pos, clicker:get_player_name()) then - switch_on(pos, node) + State:start(pos, M(pos)) end end, - after_dig_node = function(pos) - tubelib.remove_node(pos) + after_dig_node = function(pos, oldnode, oldmetadata, digger) + tubelib.remove_node(pos) -- <<=== tubelib + State:after_dig_node(pos, oldnode, oldmetadata, digger) end, on_timer = keep_running, on_rotate = screwdriver.disallow, + drop = "", paramtype = "light", sunlight_propagates = true, paramtype2 = "facedir", @@ -150,7 +115,7 @@ minetest.register_node("tubelib_addons1:pusher_fast", { minetest.register_node("tubelib_addons1:pusher_fast_active", { - description = "Tubelib Fast Pusher", + description = "Fast Pusher", tiles = { -- up, down, right, left, back, front { @@ -199,7 +164,7 @@ minetest.register_node("tubelib_addons1:pusher_fast_active", { on_rightclick = function(pos, node, clicker) if not minetest.is_protected(pos, clicker:get_player_name()) then - switch_off(pos, node) + State:stop(pos, M(pos)) end end, @@ -214,6 +179,42 @@ minetest.register_node("tubelib_addons1:pusher_fast_active", { sounds = default.node_sound_wood_defaults(), }) +minetest.register_node("tubelib_addons1:pusher_fast_defect", { + description = "Fast Pusher", + tiles = { + -- up, down, right, left, back, front + 'tubelib_addons1_pusher.png', + 'tubelib_addons1_pusher.png', + 'tubelib_outp.png^tubelib_defect.png', + 'tubelib_inp.png^tubelib_defect.png', + "tubelib_addons1_pusher.png^[transformR180]^tubelib_defect.png", + "tubelib_addons1_pusher.png^tubelib_defect.png", + }, + + after_place_node = function(pos, placer) + local meta = minetest.get_meta(pos) + meta:set_string("player_name", placer:get_player_name()) + local number = tubelib.add_node(pos, "tubelib_addons1:pusher") -- <<=== tubelib + State:node_init(pos, number) + State:defect(pos, meta) + end, + + after_dig_node = function(pos) + tubelib.remove_node(pos) -- <<=== tubelib + end, + + on_timer = keep_running, + on_rotate = screwdriver.disallow, + + paramtype = "light", + sunlight_propagates = true, + paramtype2 = "facedir", + groups = {choppy=2, cracky=2, crumbly=2, not_in_creative_inventory=1}, + is_ground_content = false, + sounds = default.node_sound_wood_defaults(), +}) + + minetest.register_craft({ output = "tubelib_addons1:pusher_fast", recipe = { @@ -224,34 +225,26 @@ minetest.register_craft({ }) --------------------------------------------------------------- tubelib -tubelib.register_node("tubelib_addons1:pusher_fast", {"tubelib_addons1:pusher_fast_active"}, { +tubelib.register_node("tubelib_addons1:pusher_fast", + {"tubelib_addons1:pusher_fast_active", "tubelib_addons1:pusher_fast_defect"}, { on_pull_item = nil, -- pusher has no inventory on_push_item = nil, -- pusher has no inventory on_unpull_item = nil, -- pusher has no inventory is_pusher = true, -- is a pulling/pushing node on_recv_message = function(pos, topic, payload) - local node = minetest.get_node(pos) - if topic == "on" then - return switch_on(pos, node) - elseif topic == "off" then - return switch_off(pos, node) - elseif topic == "state" then - if node.name == "ignore" then -- unloaded pusher? - return "blocked" - end - local meta = minetest.get_meta(pos) - local running = meta:get_int("running") or tubelib.STATE_STOPPED - return tubelib.statestring(running) - elseif topic == "counter" then - local meta = minetest.get_meta(pos) - return meta:get_int("item_counter") - elseif topic == "clear_counter" then - local meta = minetest.get_meta(pos) - return meta:set_int("item_counter", 0) + local resp = State:on_receive_message(pos, topic, payload) + if resp then + return resp else - return "not supported" + return "unsupported" end end, + on_node_load = function(pos) + State:on_node_load(pos) + end, + on_node_repair = function(pos) + return State:on_node_repair(pos) + end, }) --------------------------------------------------------------- tubelib diff --git a/tubelib_addons1/quarry.lua b/tubelib_addons1/quarry.lua index 9b2c227..4198779 100644 --- a/tubelib_addons1/quarry.lua +++ b/tubelib_addons1/quarry.lua @@ -427,5 +427,12 @@ tubelib.register_node("tubelib_addons1:quarry", {"tubelib_addons1:quarry_active" return "unsupported" end end, + on_node_load = function(pos) + local meta = minetest.get_meta(pos) + if meta:get_int("running") ~= STOP_STATE then + meta:set_int("running", TICKS_TO_SLEEP) + minetest.get_node_timer(pos):start(CYCLE_TIME) + end + end, }) diff --git a/tubelib_addons1/reformer.lua b/tubelib_addons1/reformer.lua index db842aa..bb9f05f 100644 --- a/tubelib_addons1/reformer.lua +++ b/tubelib_addons1/reformer.lua @@ -314,4 +314,11 @@ tubelib.register_node("tubelib_addons1:reformer", {}, { return "unsupported" end end, + on_node_load = function(pos) + local meta = minetest.get_meta(pos) + if meta:get_int("running") ~= STOP_STATE then + meta:set_int("running", STANDBY_STATE) + minetest.get_node_timer(pos):start(CYCLE_TIME * TICKS_TO_SLEEP) + end + end, }) diff --git a/tubelib_addons1/textures/tubelib_addons1_grinder_active.png b/tubelib_addons1/textures/tubelib_addons1_grinder_active.png index 1707d23..11f8bd3 100644 Binary files a/tubelib_addons1/textures/tubelib_addons1_grinder_active.png and b/tubelib_addons1/textures/tubelib_addons1_grinder_active.png differ diff --git a/tubelib_addons2/accesscontrol.lua b/tubelib_addons2/accesscontrol.lua index 9790c7b..f0568b8 100644 --- a/tubelib_addons2/accesscontrol.lua +++ b/tubelib_addons2/accesscontrol.lua @@ -94,6 +94,7 @@ minetest.register_node("tubelib_addons2:accesscontrol", { if tubelib.check_numbers(fields.numbers) then meta:set_string("numbers", fields.numbers) meta:set_string("code", fields.code) + meta:mark_as_private("code") meta:set_string("infotext", "Tubelib Access Lock, Enter access code") meta:set_string("formspec", formspec2("")) end diff --git a/tubelib_addons2/repeater.lua b/tubelib_addons2/repeater.lua index 07d5873..bbe0d87 100644 --- a/tubelib_addons2/repeater.lua +++ b/tubelib_addons2/repeater.lua @@ -111,4 +111,7 @@ tubelib.register_node("tubelib_addons2:repeater", {}, { return tubelib.send_message(numbers, owner, nil, topic, payload) end end, + on_node_load = function(pos) + minetest.get_node_timer(pos):start(1) + end, }) diff --git a/tubelib_addons2/sequencer.lua b/tubelib_addons2/sequencer.lua index 046bdb2..70464d0 100644 --- a/tubelib_addons2/sequencer.lua +++ b/tubelib_addons2/sequencer.lua @@ -261,4 +261,11 @@ tubelib.register_node("tubelib_addons2:sequencer", {}, { meta:set_int("endless", 0) end end, + on_node_load = function(pos) + local meta = minetest.get_meta(pos) + if meta:get_int("running") ~= STOP_STATE then + meta:set_int("running", RUNNING_STATE) + minetest.get_node_timer(pos):start(1) + end + end, }) \ No newline at end of file diff --git a/tubelib_addons2/timer.lua b/tubelib_addons2/timer.lua index 2465a76..f4e89f2 100644 --- a/tubelib_addons2/timer.lua +++ b/tubelib_addons2/timer.lua @@ -186,34 +186,14 @@ minetest.register_craft({ }, }) -minetest.register_lbm({ - label = "[Tubelib] Timer update", - name = "tubelib_addons2:update", - nodenames = {"tubelib_addons2:timer"}, - run_at_every_load = true, - action = function(pos, node) +tubelib.register_node("tubelib_addons2:timer", {}, { + on_node_load = function(pos) local meta = minetest.get_meta(pos) + minetest.get_node_timer(pos):start(CYCLE_TIME) -- check rules for just loaded areas local done = {false,false,false,false,false,false} meta:set_string("done", minetest.serialize(done)) check_rules(pos,0) - - local events = minetest.deserialize(meta:get_string("events")) - local numbers = minetest.deserialize(meta:get_string("numbers")) - local actions = {} - for _,a in ipairs(minetest.deserialize(meta:get_string("actions"))) do - if a == "start" then - actions[#actions+1] = "on" - elseif a == "stop" then - actions[#actions+1] = "off" - else - actions[#actions+1] = a - end - end - meta:set_string("actions", minetest.serialize(actions)) - meta:set_string("formspec", formspec(events, numbers, actions)) - end + end, }) - - diff --git a/tubelib_addons3/distributor.lua b/tubelib_addons3/distributor.lua index 9711fc6..e7a6475 100644 --- a/tubelib_addons3/distributor.lua +++ b/tubelib_addons3/distributor.lua @@ -482,4 +482,11 @@ tubelib.register_node("tubelib_addons3:distributor", {"tubelib_addons3:distribut return "unsupported" end end, + on_node_load = function(pos) + local meta = minetest.get_meta(pos) + if meta:get_int("running") ~= STOP_STATE then + meta:set_int("running", STANDBY_STATE) + minetest.get_node_timer(pos):start(CYCLE_TIME * TICKS_TO_SLEEP) + end + end, }) diff --git a/tubelib_addons3/pusher.lua b/tubelib_addons3/pusher.lua index 762dcea..23040f8 100644 --- a/tubelib_addons3/pusher.lua +++ b/tubelib_addons3/pusher.lua @@ -14,83 +14,48 @@ ]]-- -local RUNNING_STATE = 10 +-- for lazy programmers +local S = function(pos) if pos then return minetest.pos_to_string(pos) end end +local P = minetest.string_to_pos +local M = minetest.get_meta -local function switch_on(pos, node) - local meta = minetest.get_meta(pos) - local number = meta:get_string("number") - meta:set_int("running", RUNNING_STATE) - meta:set_string("infotext", "HighPerf Pusher "..number..": running") - node.name = "tubelib_addons3:pusher_active" - minetest.swap_node(pos, node) - minetest.get_node_timer(pos):start(2) - return false -end +local STANDBY_TICKS = 5 +local COUNTDOWN_TICKS = 5 +local CYCLE_TIME = 2 -local function switch_off(pos, node) - local meta = minetest.get_meta(pos) - local number = meta:get_string("number") - meta:set_int("running", tubelib.STATE_STOPPED) - meta:set_string("infotext", "HighPerf Pusher "..number..": stopped") - node.name = "tubelib_addons3:pusher" - minetest.swap_node(pos, node) - minetest.get_node_timer(pos):stop() - return false -end +local State = tubelib.NodeStates:new({ + node_name_passive = "tubelib_addons3:pusher", + node_name_active = "tubelib_addons3:pusher_active", + node_name_defect = "tubelib_addons3:pusher_defect", + infotext_name = "HighPerf Pusher", + cycle_time = CYCLE_TIME, + standby_ticks = STANDBY_TICKS, + has_item_meter = true, + aging_factor = 10, +}) -local function goto_standby(pos, node) - local meta = minetest.get_meta(pos) - local number = meta:get_string("number") - meta:set_int("running", tubelib.STATE_STANDBY) - meta:set_string("infotext", "HighPerf Pusher "..number..": standby") - node.name = "tubelib_addons3:pusher" - minetest.swap_node(pos, node) - minetest.get_node_timer(pos):start(20) - return false -end - -local function goto_blocked(pos, node) - local meta = minetest.get_meta(pos) - local number = meta:get_string("number") - meta:set_int("running", tubelib.STATE_BLOCKED) - meta:set_string("infotext", "HighPerf Pusher "..number..": blocked") - node.name = "tubelib_addons3:pusher" - minetest.swap_node(pos, node) - minetest.get_node_timer(pos):start(20) - return false -end - -local function keep_running(pos, elapsed) - local meta = minetest.get_meta(pos) - local number = meta:get_string("number") - local running = meta:get_int("running") - 1 +local function pushing(pos, meta) local player_name = meta:get_string("player_name") local items = tubelib.pull_stack(pos, "L", player_name) if items ~= nil then if tubelib.push_items(pos, "R", items, player_name) == false then -- place item back tubelib.unpull_items(pos, "L", items, player_name) - local node = minetest.get_node(pos) - return goto_blocked(pos, node) - end - meta:set_int("item_counter", meta:get_int("item_counter") + 1) - if running <= 0 then - local node = minetest.get_node(pos) - return switch_on(pos, node) - else - -- reload running state - running = RUNNING_STATE - end - else - if running <= 0 then - local node = minetest.get_node(pos) - return goto_standby(pos, node) + State:blocked(pos, meta) + return end + State:keep_running(pos, meta, COUNTDOWN_TICKS) + return end - meta:set_int("running", running) - return true + State:idle(pos, meta) end +local function keep_running(pos, elapsed) + local meta = M(pos) + pushing(pos, meta) + return State:is_active(meta) +end + minetest.register_node("tubelib_addons3:pusher", { description = "HighPerf Pusher", tiles = { @@ -107,24 +72,24 @@ minetest.register_node("tubelib_addons3:pusher", { local meta = minetest.get_meta(pos) meta:set_string("player_name", placer:get_player_name()) local number = tubelib.add_node(pos, "tubelib_addons3:pusher") - meta:set_string("number", number) - meta:set_string("infotext", "HighPerf Pusher "..number..": stopped") - meta:set_int("item_counter", 0) + State:node_init(pos, number) end, on_rightclick = function(pos, node, clicker) if not minetest.is_protected(pos, clicker:get_player_name()) then - switch_on(pos, node) + State:start(pos, M(pos)) end end, - after_dig_node = function(pos) + after_dig_node = function(pos, oldnode, oldmetadata, digger) tubelib.remove_node(pos) + State:after_dig_node(pos, oldnode, oldmetadata, digger) end, on_timer = keep_running, on_rotate = screwdriver.disallow, + drop = "", paramtype = "light", sunlight_propagates = true, paramtype2 = "facedir", @@ -184,7 +149,7 @@ minetest.register_node("tubelib_addons3:pusher_active", { on_rightclick = function(pos, node, clicker) if not minetest.is_protected(pos, clicker:get_player_name()) then - switch_off(pos, node) + State:stop(pos, M(pos)) end end, @@ -199,6 +164,42 @@ minetest.register_node("tubelib_addons3:pusher_active", { sounds = default.node_sound_wood_defaults(), }) +minetest.register_node("tubelib_addons3:pusher_defect", { + description = "HighPerf Pusher", + tiles = { + -- up, down, right, left, back, front + 'tubelib_pusher1.png^tubelib_addons3_node_frame4.png', + 'tubelib_pusher1.png^tubelib_addons3_node_frame4.png', + 'tubelib_outp.png^tubelib_addons3_node_frame4.png^tubelib_defect.png', + 'tubelib_inp.png^tubelib_addons3_node_frame4.png^tubelib_defect.png', + "tubelib_pusher1.png^[transformR180]^tubelib_addons3_node_frame4.png^[transformR180]^tubelib_defect.png", + "tubelib_pusher1.png^tubelib_addons3_node_frame4.png^tubelib_defect.png", + }, + + after_place_node = function(pos, placer) + local meta = minetest.get_meta(pos) + meta:set_string("player_name", placer:get_player_name()) + local number = tubelib.add_node(pos, "tubelib_addons3:pusher") + State:node_init(pos, number) + State:defect(pos, meta) + end, + + after_dig_node = function(pos) + tubelib.remove_node(pos) + end, + + on_timer = keep_running, + on_rotate = screwdriver.disallow, + + paramtype = "light", + sunlight_propagates = true, + paramtype2 = "facedir", + groups = {choppy=2, cracky=2, crumbly=2, not_in_creative_inventory=1}, + is_ground_content = false, + sounds = default.node_sound_wood_defaults(), +}) + + minetest.register_craft({ output = "tubelib_addons3:pusher", recipe = { @@ -208,30 +209,22 @@ minetest.register_craft({ }, }) -tubelib.register_node("tubelib_addons3:pusher", {"tubelib_addons3:pusher_active"}, { +tubelib.register_node("tubelib_addons3:pusher", + {"tubelib_addons3:pusher_active", "tubelib_addons3:pusher_defect"}, { is_pusher = true, -- is a pulling/pushing node on_recv_message = function(pos, topic, payload) - local node = minetest.get_node(pos) - if topic == "on" then - return switch_on(pos, node) - elseif topic == "off" then - return switch_off(pos, node) - elseif topic == "state" then - if node.name == "ignore" then -- unloaded pusher? - return "blocked" - end - local meta = minetest.get_meta(pos) - local running = meta:get_int("running") or tubelib.STATE_STOPPED - return tubelib.statestring(running) - elseif topic == "counter" then - local meta = minetest.get_meta(pos) - return meta:get_int("item_counter") - elseif topic == "clear_counter" then - local meta = minetest.get_meta(pos) - return meta:set_int("item_counter", 0) + local resp = State:on_receive_message(pos, topic, payload) + if resp then + return resp else - return "not supported" + return "unsupported" end end, + on_node_load = function(pos) + State:on_node_load(pos) + end, + on_node_repair = function(pos) + return State:on_node_repair(pos) + end, }) diff --git a/tubelib_addons3/pushing_chest.lua b/tubelib_addons3/pushing_chest.lua index 18ee8d2..85b1561 100644 --- a/tubelib_addons3/pushing_chest.lua +++ b/tubelib_addons3/pushing_chest.lua @@ -232,4 +232,7 @@ tubelib.register_node("tubelib_addons3:pushing_chest", {}, { on_recv_message = function(pos, topic, payload) return "unsupported" end, + on_node_load = function(pos) + minetest.get_node_timer(pos):start(2) + end, }) diff --git a/tubelib_addons3/teleporter.lua b/tubelib_addons3/teleporter.lua index e34a4f1..9cf5894 100644 --- a/tubelib_addons3/teleporter.lua +++ b/tubelib_addons3/teleporter.lua @@ -14,38 +14,12 @@ ]]-- -local PairingList = {} +local Tube = tubelib.Tube -local sForm = "size[7.5,3]".. +local sFormspec = "size[7.5,3]".. "field[0.5,1;7,1;channel;Enter channel string;]" .. "button_exit[2,2;3,1;exit;Save]" -local function pairing(pos, channel) - if PairingList[channel] and not vector.equals(pos, PairingList[channel]) then - -- store peer position on both nodes - local meta1 = minetest.get_meta(pos) - local peer = minetest.pos_to_string(PairingList[channel]) - meta1:set_string("peer", peer) - meta1:set_string("infotext", "Tubelib Teleporter, connected "..peer) - meta1:set_string("channel", nil) - meta1:set_string("formspec", nil) - - local meta2 = minetest.get_meta(PairingList[channel]) - local peer = minetest.pos_to_string(pos) - meta2:set_string("peer", peer) - meta2:set_string("infotext", "Tubelib Teleporter, connected "..peer) - meta2:set_string("channel", nil) - meta2:set_string("formspec", nil) - - PairingList[channel] = nil - return true - else - PairingList[channel] = pos - minetest.get_meta(pos):set_string("channel", channel) - return false - end -end - minetest.register_node("tubelib_addons3:teleporter", { description = "Tubelib Teleporter", tiles = { @@ -59,46 +33,23 @@ minetest.register_node("tubelib_addons3:teleporter", { }, after_place_node = function(pos, placer) - local meta = minetest.get_meta(pos) tubelib.add_node(pos, "tubelib_addons3:teleporter") - meta:set_string("formspec", sForm) - meta:set_string("infotext", "Tubelib Teleporter, unconfigured") + -- determine the tube side + local tube_dir = ((minetest.dir_to_facedir(placer:get_look_dir()) + 1) % 4) + 1 + Tube:prepare_pairing(pos, tube_dir, sFormspec) + Tube:after_place_node(pos, {tube_dir}) end, on_receive_fields = function(pos, formname, fields, player) - local meta = minetest.get_meta(pos) if fields.channel ~= nil then - if not pairing(pos, fields.channel) then - meta:set_string("formspec", "size[7.5,3]".. - "field[0.5,1;7,1;channel;Enter channel string;"..fields.channel.."]" .. - "button_exit[2,2;3,1;exit;Save]") - else - local peer_pos = minetest.string_to_pos(meta:get_string("peer")) - minetest.log("action", player:get_player_name().. - " pairs Tubelib Teleporter nodes at ".. - minetest.pos_to_string(pos).. - " and at "..minetest.pos_to_string(peer_pos)) - end + Tube:pairing(pos, fields.channel) end end, - on_destruct = function(pos) - -- unpair peer node - local meta = minetest.get_meta(pos) - local peer = meta:get_string("peer") - if peer ~= "" then - local peer_pos = minetest.string_to_pos(peer) - local peer_meta = minetest.get_meta(peer_pos) - peer_meta:set_string("channel", nil) - peer_meta:set_string("peer", nil) - peer_meta:set_string("formspec", sForm) - peer_meta:set_string("infotext", "Tubelib Teleporter, unconfigured") - else - local channel = meta:get_string("channel") - if channel then - PairingList[channel] = nil - end - end + after_dig_node = function(pos, oldnode, oldmetadata, digger) + Tube:stop_pairing(pos, oldmetadata, sFormspec) + local tube_dir = tonumber(oldmetadata.fields.tube_dir or 0) + Tube:after_dig_node(pos, {tube_dir}) end, on_rotate = screwdriver.disallow, @@ -120,22 +71,4 @@ minetest.register_craft({ }, }) --- recursion detection -local LastPeerPos = nil - -tubelib.register_node("tubelib_addons3:teleporter", {}, { - on_push_item = function(pos, side, item) - -- push on peer side - local meta = minetest.get_meta(pos) - local peer = meta:get_string("peer") - if peer ~= "" and peer ~= LastPeerPos then - LastPeerPos = peer - local res = tubelib.push_items(minetest.string_to_pos(peer), "R", item, nil) - LastPeerPos = nil - return res - end - return false - end, - is_pusher = true, -}) - +Tube:add_secondary_node_names({"tubelib_addons3:teleporter"}) \ No newline at end of file