Add ta5 teleport tubes

This commit is contained in:
Joachim Stolberg 2022-01-02 21:00:46 +01:00
parent 9b02954efd
commit 577a4e8bd3
8 changed files with 390 additions and 10 deletions

View File

@ -3,14 +3,14 @@
TechAge
=======
Copyright (C) 2019-2020 Joachim Stolberg
Copyright (C) 2019-2022 Joachim Stolberg
AGPL v3
See LICENSE.txt for more information
Consumer node basis functionality.
It handles:
- up to 3 stages of nodes (TA2/TA3/TA4)
- up to 4 stages of nodes (TA2/TA3/TA4/TA5)
- power consumption
- node state handling
- registration of passive and active nodes
@ -119,7 +119,7 @@ function techage.register_consumer(base_name, inv_name, tiles, tNode, validState
if not node_name_prefix then
node_name_prefix = "techage:ta"
end
for stage = 2,4 do
for stage = 2,5 do
local name_pas = node_name_prefix..stage.."_"..base_name.."_pas"
local name_act = node_name_prefix..stage.."_"..base_name.."_act"
local name_inv = "TA"..stage.." "..inv_name
@ -299,5 +299,5 @@ function techage.register_consumer(base_name, inv_name, tiles, tNode, validState
end
end
end
return names[1], names[2], names[3]
return names[1], names[2], names[3], names[4]
end

View File

@ -91,14 +91,14 @@ local function update_node_data(pos, state, conn_name, remote_name, rmt_pos)
meta:set_string("status", "server")
meta:set_string("conn_name", conn_name)
meta:set_string("remote_name", "")
meta:set_string("conn_status", S("connected with") .. " " .. P2S(rmt_pos))
meta:set_string("conn_status", S("connected to") .. " " .. P2S(rmt_pos))
nvm.rmt_pos = rmt_pos
elseif state == "client_connected" then
Stations:update(pos, {conn_name="nil", single="nil"})
meta:set_string("status", "client")
meta:set_string("conn_name", "")
meta:set_string("remote_name", remote_name)
meta:set_string("conn_status", S("connected with") .. " " .. P2S(rmt_pos))
meta:set_string("conn_status", S("connected to") .. " " .. P2S(rmt_pos))
nvm.rmt_pos = rmt_pos
elseif state == "server_not_connected" then
Stations:update(pos, {conn_name=conn_name, single=true})
@ -212,7 +212,7 @@ function techage.hyperloop.after_dig_node(pos, oldnode, oldmetadata, digger)
end
function techage.hyperloop.after_formspec(pos, fields)
if HYPERLOOP and fields.save then
if HYPERLOOP and fields.save or fields.key_enter_field then
local meta = M(pos)
local conn_name = meta:get_string("conn_name")
local remote_name = meta:get_string("remote_name")

View File

@ -174,6 +174,7 @@ function NodeStates:new(attr)
cycle_time = attr.cycle_time, -- for running state
standby_ticks = attr.standby_ticks, -- for standby state
-- optional
countdown_ticks = attr.countdown_ticks or 1,
node_name_passive = attr.node_name_passive,
node_name_active = attr.node_name_active,
infotext_name = attr.infotext_name,
@ -254,7 +255,7 @@ function NodeStates:start(pos, nvm)
if self.start_node then
self.start_node(pos, nvm, state)
end
nvm.techage_countdown = 1
nvm.techage_countdown = self.countdown_ticks
if self.node_name_active then
swap_node(pos, self.node_name_active)
end

View File

@ -288,9 +288,9 @@ function techage.menu.generate_formspec(pos, ndef, form_def, player_name)
end
function techage.menu.eval_input(pos, form_def, fields, player_name)
if fields.save then
if fields.save or fields.key_enter_field then
local meta = minetest.get_meta(pos)
evaluate_data(pos, meta, form_def, fields, player_name)
end
return fields.refresh or fields.save
return fields.refresh or fields.save or fields.key_enter_field
end

149
basis/teleport.lua Normal file
View File

@ -0,0 +1,149 @@
--[[
TechAge
=======
Copyright (C) 2019-2022 Joachim Stolberg
AGPL v3
See LICENSE.txt for more information
For tupe/pipe blocks with teleport support
]]--
-- for lazy programmers
local S2P = minetest.string_to_pos
local P2S = minetest.pos_to_string
local NDEF = function(pos) return minetest.registered_nodes[techage.get_node_lvm(pos).name] or {} end
local M = minetest.get_meta
local S = techage.S
local menu = techage.menu
techage.teleport = {}
local PairingList = {} -- {owner = {node_type = {channel = pos}}}
local function get_pairing_table1(meta)
local owner = meta:get_string("owner")
local node_type = meta:get_string("tele_node_type")
PairingList[owner] = PairingList[owner] or {}
PairingList[owner][node_type] = PairingList[owner][node_type] or {}
return PairingList[owner][node_type]
end
local function get_pairing_table2(oldmetadata)
local owner = oldmetadata.fields.owner
local node_type = oldmetadata.fields.tele_node_type
PairingList[owner] = PairingList[owner] or {}
PairingList[owner][node_type] = PairingList[owner][node_type] or {}
return PairingList[owner][node_type]
end
local function get_free_server_list(pos)
local tbl = {""}
for name, pos in pairs(get_pairing_table1(M(pos))) do
table.insert(tbl, name)
end
return table.concat(tbl, ",")
end
local TELE_MENU = {
{
type = "label",
label = S("Enter a block name or select an existing one"),
tooltip = "",
name = "l1",
},
{
type = "ascii",
name = "conn_name",
label = S("Block name"),
tooltip = S("Connection name for this block"),
default = "",
},
{
type = "dropdown",
choices = "",
on_dropdown = get_free_server_list,
name = "remote_name",
label = S("Remote name"),
tooltip = S("Connection name of the remote block"),
},
}
function techage.teleport.formspec(pos)
local ndef = NDEF(pos)
return menu.generate_formspec(pos, ndef, TELE_MENU)
end
local function store_connection(pos, peer_pos)
local meta = M(pos)
local status = S("connected to") .. " " .. P2S(peer_pos)
meta:set_string("tele_status", status)
meta:set_string("tele_peer_pos", P2S(peer_pos))
meta:set_string("formspec", "")
end
function techage.teleport.prepare_pairing(pos, node_type, status)
local meta = M(pos)
if node_type then
meta:set_string("tele_node_type", node_type)
end
status = status or S("not connected")
meta:set_string("tele_status", status)
meta:set_string("tele_peer_pos", "")
meta:set_string("formspec", techage.teleport.formspec(pos))
end
function techage.teleport.stop_pairing(pos, oldmetadata)
-- disconnect peer node
if oldmetadata and oldmetadata.fields then
if oldmetadata.fields.tele_peer_pos then
local peer_pos = S2P(oldmetadata.fields.tele_peer_pos)
local meta = M(peer_pos)
if meta:get_string("conn_name") ~= "" then -- Server
local tbl = get_pairing_table1(meta)
tbl[meta:get_string("conn_name")] = peer_pos
techage.teleport.prepare_pairing(peer_pos, nil, S("server not connected"))
else
techage.teleport.prepare_pairing(peer_pos)
end
elseif oldmetadata.fields.conn_name then
local tbl = get_pairing_table2(oldmetadata)
tbl[oldmetadata.fields.conn_name] = nil
end
end
end
function techage.teleport.is_connected(pos)
return M(pos):get_string("tele_peer_pos") ~= ""
end
function techage.teleport.get_remote_pos(pos)
local s = M(pos):get_string("tele_peer_pos")
if s ~= "" then
return S2P(s)
end
end
function techage.teleport.after_formspec(pos, fields)
if techage.menu.eval_input(pos, TELE_MENU, fields) then
if not techage.teleport.is_connected(pos) then
local meta = M(pos)
if fields.remote_name ~= "" then -- Client
local tbl = get_pairing_table1(meta)
local peer_pos = tbl[fields.remote_name]
if peer_pos then
tbl[fields.remote_name] = nil
store_connection(pos, peer_pos)
store_connection(peer_pos, pos)
end
elseif fields.conn_name ~= "" then -- Server
local tbl = get_pairing_table1(meta)
tbl[fields.conn_name] = pos
techage.teleport.prepare_pairing(pos, nil, S("server not connected"))
end
end
end
end

View File

@ -103,6 +103,7 @@ dofile(MP.."/basis/oggfiles.lua")
dofile(MP.."/basis/submenu.lua")
dofile(MP.."/basis/shared_inv.lua")
dofile(MP.."/basis/shared_tank.lua")
dofile(MP.."/basis/teleport.lua")
-- Main doc
dofile(MP.."/doc/manual_DE.lua")
@ -393,6 +394,8 @@ dofile(MP.."/collider/cooler.lua")
dofile(MP.."/collider/detector.lua")
dofile(MP.."/collider/worker.lua")
dofile(MP.."/teleport/teleport_tube.lua")
-- Prevent other mods from using IE
techage.IE = nil

227
teleport/teleport_tube.lua Normal file
View File

@ -0,0 +1,227 @@
--[[
TechAge
=======
Copyright (C) 2017-2022 Joachim Stolberg
AGPL v3
See LICENSE.txt for more information
TA5 teleport nodes
]]--
-- for lazy programmers
local P2S = function(pos) if pos then return minetest.pos_to_string(pos) end end
local S2P = minetest.string_to_pos
local M = minetest.get_meta
local S = techage.S
local Tube = techage.Tube
local teleport = techage.teleport
local Cable = techage.ElectricCable
--local Cable = techage.Axle
local power = networks.power
local STANDBY_TICKS = 4
local COUNTDOWN_TICKS = 4
local CYCLE_TIME = 2
local PWR_NEEDED = 12
local EX_POINTS = 60
local DESCRIPTION = S("TA5 Teleport Tube")
-- 2 Blöcke on/off
-- Strom von 7 Seiten
-- Pipe/Tube nur von einer Seite
-- TA5 Design
-- Consumer block mit on/off
-- Inventory mit 4 stacks
-- wrench menü?
-- normales Menü wenn connected
local WRENCH_MENU = {
{
type = "dropdown",
choices = "1,2,4,6,8,12,16",
name = "ontime",
label = S("On Time") .. " [s]",
tooltip = S("The time between the 'on' and 'off' commands."),
default = "1",
},
{
type = "dropdown",
choices = "2,4,6,8,12,16,20",
name = "blockingtime",
label = S("Blocking Time") .. " [s]",
tooltip = S("The time after the 'off' command\nuntil the next 'on' command is accepted."),
default = "8",
},
{
type = "items",
name = "config",
label = S("Configured Items"),
tooltip = S("Items which generate an 'on' command.\nIf empty, all passed items generate an 'on' command."),
size = 4,
}
}
local function formspec(self, pos, nvm)
local title = DESCRIPTION .. " " .. M(pos):get_string("tele_status")
return "size[8,2]"..
"box[0,-0.1;7.8,0.5;#c6e8ff]" ..
"label[0.5,-0.1;" .. minetest.colorize( "#000000", title) .. "]" ..
"image_button[3.5,1;1,1;" .. self:get_state_button_image(nvm) .. ";state_button;]" ..
"tooltip[3.5,1;1,1;" .. self:get_state_tooltip(nvm) .. "]"
end
local function can_start(pos, nvm, state)
return teleport.is_connected(pos)
end
local State = techage.NodeStates:new({
node_name_passive = "techage:ta5_tele_tube",
infotext_name = DESCRIPTION,
cycle_time = CYCLE_TIME,
standby_ticks = STANDBY_TICKS,
countdown_ticks = COUNTDOWN_TICKS,
formspec_func = formspec,
can_start = can_start,
})
local function consume_power(pos, nvm)
if techage.needs_power(nvm) then
local taken = power.consume_power(pos, Cable, nil, PWR_NEEDED)
if techage.is_running(nvm) then
if taken < PWR_NEEDED then
State:nopower(pos, nvm)
else
return true -- keep running
end
elseif taken == PWR_NEEDED then
State:start(pos, nvm)
end
end
end
minetest.register_node("techage:ta5_tele_tube", {
description = DESCRIPTION,
tiles = {
-- up, down, right, left, back, front
"techage_filling_ta4.png^techage_frame_ta5_top.png",
"techage_filling_ta4.png^techage_frame_ta5_top.png",
"techage_filling_ta4.png^techage_frame_ta5.png^techage_appl_wifi.png",
"techage_filling_ta4.png^techage_frame_ta5.png^techage_appl_hole_tube.png",
"techage_filling_ta4.png^techage_frame_ta5.png^techage_appl_wifi.png",
"techage_filling_ta4.png^techage_frame_ta5.png^techage_appl_wifi.png",
},
after_place_node = function(pos, placer)
local meta = M(pos)
local nvm = techage.get_nvm(pos)
local node = minetest.get_node(pos)
local tube_dir = techage.side_to_outdir("L", node.param2)
local number = techage.add_node(pos, "techage:ta5_tele_tube")
nvm.running = false
State:node_init(pos, nvm, number)
meta:set_int("tube_dir", tube_dir)
meta:set_string("owner", placer:get_player_name())
Tube:after_place_node(pos, {tube_dir})
Cable:after_place_node(pos)
teleport.prepare_pairing(pos, "ta5_tele_tube")
end,
on_receive_fields = function(pos, formname, fields, player)
if minetest.is_protected(pos, player:get_player_name()) then
return
end
if teleport.is_connected(pos) then
local nvm = techage.get_nvm(pos)
State:state_button_event(pos, nvm, fields)
M(pos):set_string("formspec", formspec(State, pos, nvm))
else
if techage.get_expoints(player) >= EX_POINTS then
teleport.after_formspec(pos, fields)
end
end
end,
on_rightclick = function(pos, clicker, listname)
if teleport.is_connected(pos) then
local nvm = techage.get_nvm(pos)
M(pos):set_string("formspec", formspec(State, pos, nvm))
else
M(pos):set_string("formspec", teleport.formspec(pos))
end
end,
on_timer = function(pos, elapsed)
local nvm = techage.get_nvm(pos)
consume_power(pos, nvm)
-- the state has to be triggered by on_push_item
State:idle(pos, nvm)
return State:is_active(nvm)
end,
after_dig_node = function(pos, oldnode, oldmetadata, digger)
techage.remove_node(pos, oldnode, oldmetadata)
teleport.stop_pairing(pos, oldmetadata)
Tube:after_dig_node(pos)
Cable:after_dig_node(pos)
techage.del_mem(pos)
end,
paramtype2 = "facedir", -- important!
on_rotate = screwdriver.disallow, -- important!
is_ground_content = false,
groups = {choppy=2, cracky=2, crumbly=2},
sounds = default.node_sound_wood_defaults(),
})
minetest.register_craft({
output = "techage:ta5_tele_tube",
recipe = {
{"", "dye:red", ""},
{"techage:ta4_tubeS", "techage:ta5_aichip", ""},
{"", "group:wood", ""},
},
})
techage.register_node({"techage:ta5_tele_tube"}, {
on_push_item = function(pos, in_dir, stack)
local nvm = techage.get_nvm(pos)
if techage.is_operational(nvm) then
local rmt_pos = teleport.get_remote_pos(pos)
local rmt_nvm = techage.get_nvm(rmt_pos)
if techage.is_operational(rmt_nvm) then
local tube_dir = M(rmt_pos):get_int("tube_dir")
if techage.push_items(rmt_pos, tube_dir, stack) then
State:keep_running(pos, nvm, COUNTDOWN_TICKS)
State:keep_running(rmt_pos, rmt_nvm, COUNTDOWN_TICKS)
return true
end
else
State:blocked(pos, nvm, S("Remote node error"))
end
end
return false
end,
is_pusher = true, -- is a pulling/pushing node
on_recv_message = function(pos, src, topic, payload)
if topic == "count" then
local nvm = techage.get_nvm(pos)
return nvm.counter or 0
elseif topic == "reset" then
local nvm = techage.get_nvm(pos)
nvm.counter = 0
return true
else
return "unsupported"
end
end,
})
power.register_nodes({"techage:ta5_tele_tube"}, Cable, "con", {"B", "R", "F", "D", "U"})
Tube:set_valid_sides("techage:ta5_tele_tube", {"L"})

Binary file not shown.

After

Width:  |  Height:  |  Size: 163 B