Collider system added

This commit is contained in:
Joachim Stolberg 2021-12-11 20:15:55 +01:00
parent 0e3a4d4bc7
commit dee6c47555
38 changed files with 2527 additions and 176 deletions

View File

@ -60,6 +60,10 @@ local SpecialItems = {
["protector:chest"] = "default:chest", ["protector:chest"] = "default:chest",
["techage:ta4_rotor_blade"] = "", ["techage:ta4_rotor_blade"] = "",
["techage:ta4_carbon_fiber"] = "", ["techage:ta4_carbon_fiber"] = "",
["techage:ta4_round_ceramic"] = "",
["techage:ta4_furnace_ceramic"] = "",
["techage:ta5_aichip"] = "",
["techage:ta4_leds"] = "",
} }
local function formspec(self, pos, nvm) local function formspec(self, pos, nvm)

View File

@ -124,3 +124,118 @@ function techage.assemble.remove(pos, AssemblyPlan, player_name)
remove(pos, node.param2, AssemblyPlan, #AssemblyPlan) remove(pos, node.param2, AssemblyPlan, #AssemblyPlan)
nvm.assemble_build = false nvm.assemble_build = false
end end
--------------------------------------------------------------------------------
-- Assembly functions based on nodes from node inventory
--------------------------------------------------------------------------------
local function play_sound(pos, sound)
minetest.sound_play(sound, {
pos = pos,
gain = 1,
max_hear_distance = 10,
})
end
local function build_inv(pos, inv, param2, AssemblyPlan, player_name, idx)
local item = AssemblyPlan[idx]
if item ~= nil then
local y, path, fd_offs, node_name = item[1], item[2], item[3], item[4]
local pos1 = dest_pos(pos, param2, path, y)
if not minetest.is_protected(pos1, player_name) then
local node = minetest.get_node(pos1)
if techage.is_air_like(node.name) then
local stack = inv:remove_item("src", ItemStack(node_name))
if stack:get_count() == 1 then
minetest.add_node(pos1, {name=node_name, param2=(param2 + fd_offs) % 4})
play_sound(pos, "default_place_node_hard")
local ndef = minetest.registered_nodes[node_name]
if ndef and ndef.after_place_node then
local placer = minetest.get_player_by_name(player_name)
ndef.after_place_node(pos1, placer, ItemStack(node_name))
end
end
end
end
minetest.after(0.5, build_inv, pos, inv, param2, AssemblyPlan, player_name, idx + 1)
else
local nvm = techage.get_nvm(pos)
nvm.assemble_locked = false
end
end
local function remove_inv(pos, inv, param2, AssemblyPlan, player_name, idx)
local item = AssemblyPlan[idx]
if item ~= nil then
local y, path, fd_offs, node_name = item[1], item[2], item[3], item[4]
local pos1 = dest_pos(pos, param2, path, y)
if not minetest.is_protected(pos1, player_name) then
local stack = ItemStack(node_name)
if inv:room_for_item("src", stack) then
local node = minetest.get_node(pos1)
if node.name == node_name then
minetest.remove_node(pos1)
inv:add_item("src", stack)
play_sound(pos, "default_dig_cracky")
local ndef = minetest.registered_nodes[node_name]
if ndef and ndef.after_dig_node then
local digger = minetest.get_player_by_name(player_name)
ndef.after_dig_node(pos1, pos, ItemStack(node_name), {}, digger)
end
end
end
end
minetest.after(0.5, remove_inv, pos, inv, param2, AssemblyPlan, player_name, idx - 1)
else
local nvm = techage.get_nvm(pos)
nvm.assemble_locked = false
end
end
function techage.assemble.build_inv(pos, inv, AssemblyPlan, player_name)
-- check protection
if minetest.is_protected(pos, player_name) then
return
end
local nvm = techage.get_nvm(pos)
if nvm.assemble_locked then
return
end
local node = minetest.get_node(pos)
nvm.assemble_locked = true
build_inv(pos, inv, node.param2, AssemblyPlan, player_name, 1)
end
function techage.assemble.remove_inv(pos, inv, AssemblyPlan, player_name)
-- check protection
if minetest.is_protected(pos, player_name) then
return
end
local nvm = techage.get_nvm(pos)
if nvm.assemble_locked then
return
end
local node = minetest.get_node(pos)
nvm.assemble_locked = true
remove_inv(pos, inv, node.param2, AssemblyPlan, player_name, #AssemblyPlan)
end
function techage.assemble.count_items(AssemblyPlan)
local t = {}
for _, item in ipairs(AssemblyPlan) do
local node_name = item[4]
local ndef = minetest.registered_nodes[node_name]
local name = ndef.description
if not t[name] then
t[name] = 1
else
t[name] = t[name] + 1
end
end
return t
end
-- Determine the destination position based on the given route
-- param2, and a route table like : {0,3}
-- 0 = forward, 1 = right, 2 = backward, 3 = left
-- techage.assemble.get_pos(pos, param2, route, y_offs)
techage.assemble.get_pos = dest_pos

View File

@ -81,15 +81,23 @@ end
function flylib.to_path(s, max_dist) function flylib.to_path(s, max_dist)
local tPath local tPath
local dist = 0
for _, line in ipairs(strsplit(s)) do for _, line in ipairs(strsplit(s)) do
line = trim(line) line = trim(line)
line = string.split(line, "--", true, 1)[1] or "" line = string.split(line, "--", true, 1)[1] or ""
if line ~= "" then if line ~= "" then
local v = flylib.to_vector(line) local v = flylib.to_vector(line)
if v and (not max_dist or flylib.distance(v) <= max_dist) then if v then
--dist = dist + flylib.distance(v)
--if not max_dist or dist <= max_dist then
tPath = tPath or {} tPath = tPath or {}
tPath[#tPath + 1] = v tPath[#tPath + 1] = v
--else
-- return tPath, S("Error: Max. length of the flight route exceeded !!")
--end
else
return tPath, S("Error: Invalid path !!")
end end
end end
end end
@ -614,10 +622,13 @@ end
function flylib.move_to_other_pos(pos, move2to1) function flylib.move_to_other_pos(pos, move2to1)
local meta = M(pos) local meta = M(pos)
local nvm = techage.get_nvm(pos) local nvm = techage.get_nvm(pos)
local lpath = flylib.to_path(meta:get_string("path")) or {} local lpath, err = flylib.to_path(meta:get_string("path")) or {}
local max_speed = meta:contains("max_speed") and meta:get_int("max_speed") or MAX_SPEED local max_speed = meta:contains("max_speed") and meta:get_int("max_speed") or MAX_SPEED
local height = meta:contains("height") and meta:get_float("height") or 1 local height = meta:contains("height") and meta:get_float("height") or 1
local handover local handover
if err then return false end
height = techage.in_range(height, 0, 1) height = techage.in_range(height, 0, 1)
max_speed = techage.in_range(max_speed, MIN_SPEED, MAX_SPEED) max_speed = techage.in_range(max_speed, MIN_SPEED, MAX_SPEED)
nvm.lpos1 = nvm.lpos1 or {} nvm.lpos1 = nvm.lpos1 or {}

View File

@ -42,7 +42,7 @@ local function get_positions(pos, mem, dir)
return true -- no new values return true -- no new values
end end
-- return both both laser entities the pos and length -- return for both laser entities the pos and length
local function get_laser_length_and_pos(pos1, pos2, dir) local function get_laser_length_and_pos(pos1, pos2, dir)
local dist = vector.distance(pos1, pos2) local dist = vector.distance(pos1, pos2)
@ -133,5 +133,14 @@ function techage.renew_laser(pos, force)
return res return res
end end
function techage.add_laser(pos, pos1, pos2)
local dir = vector.direction(pos1, pos2)
local param2 = minetest.dir_to_facedir(dir)
local size, pos3, pos4 = get_laser_length_and_pos(pos1, pos2, dir)
if size then
add_laser(pos, pos3, pos4, size, param2)
end
end
-- techage.del_laser(pos) -- techage.del_laser(pos)
techage.del_laser = del_laser techage.del_laser = del_laser

View File

@ -456,6 +456,42 @@ function techage.wrench_tooltip(x, y)
"tooltip["..x..","..y..";0.5,0.5;"..tooltip..";#0C3D32;#FFFFFF]" "tooltip["..x..","..y..";0.5,0.5;"..tooltip..";#0C3D32;#FFFFFF]"
end end
-------------------------------------------------------------------------------
-- Terminal history buffer
-------------------------------------------------------------------------------
local BUFFER_DEPTH = 10
function techage.historybuffer_add(pos, s)
local mem = techage.get_mem(pos)
mem.hisbuf = mem.hisbuf or {}
if #s > 2 then
table.insert(mem.hisbuf, s)
if #mem.hisbuf > BUFFER_DEPTH then
table.remove(mem.hisbuf, 1)
end
mem.hisbuf_idx = #mem.hisbuf + 1
end
end
function techage.historybuffer_priv(pos)
local mem = techage.get_mem(pos)
mem.hisbuf = mem.hisbuf or {}
mem.hisbuf_idx = mem.hisbuf_idx or 1
mem.hisbuf_idx = math.max(1, mem.hisbuf_idx - 1)
return mem.hisbuf[mem.hisbuf_idx]
end
function techage.historybuffer_next(pos)
local mem = techage.get_mem(pos)
mem.hisbuf = mem.hisbuf or {}
mem.hisbuf_idx = mem.hisbuf_idx or 1
mem.hisbuf_idx = math.min(#mem.hisbuf, mem.hisbuf_idx + 1)
return mem.hisbuf[mem.hisbuf_idx]
end
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
-- Player TA5 Experience Points -- Player TA5 Experience Points
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
@ -468,12 +504,30 @@ function techage.get_expoints(player)
end end
end end
function techage.add_expoint(player) -- Can only be used from one collider
function techage.add_expoint(player, number)
if player and player.get_meta then if player and player.get_meta then
local meta = player:get_meta() local meta = player:get_meta()
if meta then if meta then
if not meta:contains("techage_collider_number") then
meta:set_string("techage_collider_number", number)
end
if meta:get_string("techage_collider_number") == number then
meta:set_int("techage_ex_points", meta:get_int("techage_ex_points") + 1) meta:set_int("techage_ex_points", meta:get_int("techage_ex_points") + 1)
return true return true
else
minetest.chat_send_player(player:get_player_name(), "[techage] More than one collider is not allowed!")
return false
end
end
end
end
function techage.on_remove_collider(player)
if player and player.get_meta then
local meta = player:get_meta()
if meta then
meta:set_string("techage_collider_number", "")
end end
end end
end end

103
basis/oggfiles.lua Normal file
View File

@ -0,0 +1,103 @@
techage.OggFileList = {
"autobahn_motor", -- ./mods/autobahn/sounds
"signs_bot_ping", -- ./mods/signs_bot/sounds
"signs_bot_go_away", -- ./mods/signs_bot/sounds
"signs_bot_step", -- ./mods/signs_bot/sounds
"signs_bot_pong", -- ./mods/signs_bot/sounds
"signs_bot_error", -- ./mods/signs_bot/sounds
"normal2", -- ./mods/hyperloop/sounds
"up2", -- ./mods/hyperloop/sounds
"down2", -- ./mods/hyperloop/sounds
"ele_norm", -- ./mods/hyperloop/sounds
"door", -- ./mods/hyperloop/sounds
"hyperloop_crowbar", -- ./mods/hyperloop/sounds
"ele_door", -- ./mods/hyperloop/sounds
"techage_watermill", -- ./mods/techage/sounds
"techage_button", -- ./mods/techage/sounds
"techage_steamengine", -- ./mods/techage/sounds
"techage_generator", -- ./mods/techage/sounds
"techage_gasflare", -- ./mods/techage/sounds
"techage_explore", -- ./mods/techage/sounds
"techage_mill", -- ./mods/techage/sounds
"techage_reactor", -- ./mods/techage/sounds
"techage_valve", -- ./mods/techage/sounds
"techage_oildrill", -- ./mods/techage/sounds
"techage_turbine", -- ./mods/techage/sounds
"techage_booster", -- ./mods/techage/sounds
"techage_quarry", -- ./mods/techage/sounds
"techage_reboiler", -- ./mods/techage/sounds
"jetpack_loop", -- ./mods/jetpack/sounds
"paperflip1", -- ./mods/unified_inventory/sounds
"teleport", -- ./mods/unified_inventory/sounds
"electricity", -- ./mods/unified_inventory/sounds
"owl", -- ./mods/unified_inventory/sounds
"click", -- ./mods/unified_inventory/sounds
"birds", -- ./mods/unified_inventory/sounds
"paperflip2", -- ./mods/unified_inventory/sounds
"dingdong", -- ./mods/unified_inventory/sounds
"trash", -- ./mods/unified_inventory/sounds
"trash_all", -- ./mods/unified_inventory/sounds
"ta4_jetpack", -- ./mods/ta4_jetpack/sounds
"ta4_jetpack_alarm", -- ./mods/ta4_jetpack/sounds
"ta4_jetpack_on", -- ./mods/ta4_jetpack/sounds
"player_damage", -- ./games/minetest_game/mods/player_api/sounds
"env_sounds_water", -- ./games/minetest_game/mods/env_sounds/sounds
"env_sounds_lava", -- ./games/minetest_game/mods/env_sounds/sounds
"doors_door_close", -- ./games/minetest_game/mods/doors/sounds
"doors_steel_door_close", -- ./games/minetest_game/mods/doors/sounds
"doors_door_open", -- ./games/minetest_game/mods/doors/sounds
"doors_fencegate_close", -- ./games/minetest_game/mods/doors/sounds
"doors_glass_door_close", -- ./games/minetest_game/mods/doors/sounds
"doors_fencegate_open", -- ./games/minetest_game/mods/doors/sounds
"doors_glass_door_open", -- ./games/minetest_game/mods/doors/sounds
"doors_steel_door_open", -- ./games/minetest_game/mods/doors/sounds
"fire_flint_and_steel", -- ./games/minetest_game/mods/fire/sounds
"fire_large", -- ./games/minetest_game/mods/fire/sounds
"fire_fire", -- ./games/minetest_game/mods/fire/sounds
"fire_extinguish_flame", -- ./games/minetest_game/mods/fire/sounds
"fire_small", -- ./games/minetest_game/mods/fire/sounds
"tnt_ignite", -- ./games/minetest_game/mods/tnt/sounds
"tnt_gunpowder_burning", -- ./games/minetest_game/mods/tnt/sounds
"tnt_explode", -- ./games/minetest_game/mods/tnt/sounds
"carts_cart_new", -- ./games/minetest_game/mods/carts/sounds
"carts_cart_moving", -- ./games/minetest_game/mods/carts/sounds
"xpanes_steel_bar_door_open", -- ./games/minetest_game/mods/xpanes/sounds
"xpanes_steel_bar_door_close", -- ./games/minetest_game/mods/xpanes/sounds
"default_break_glass", -- ./games/minetest_game/mods/default/sounds
"default_dig_dig_immediate", -- ./games/minetest_game/mods/default/sounds
"default_dig_cracky", -- ./games/minetest_game/mods/default/sounds
"default_dig_choppy", -- ./games/minetest_game/mods/default/sounds
"default_water_footstep", -- ./games/minetest_game/mods/default/sounds
"player_damage", -- ./games/minetest_game/mods/default/sounds
"default_gravel_footstep", -- ./games/minetest_game/mods/default/sounds
"default_dig_metal", -- ./games/minetest_game/mods/default/sounds
"default_gravel_dug", -- ./games/minetest_game/mods/default/sounds
"default_hard_footstep", -- ./games/minetest_game/mods/default/sounds
"default_sand_footstep", -- ./games/minetest_game/mods/default/sounds
"default_grass_footstep", -- ./games/minetest_game/mods/default/sounds
"default_chest_close", -- ./games/minetest_game/mods/default/sounds
"default_cool_lava", -- ./games/minetest_game/mods/default/sounds
"default_place_node_hard", -- ./games/minetest_game/mods/default/sounds
"default_ice_dug", -- ./games/minetest_game/mods/default/sounds
"default_dig_crumbly", -- ./games/minetest_game/mods/default/sounds
"default_tool_breaks", -- ./games/minetest_game/mods/default/sounds
"default_ice_footstep", -- ./games/minetest_game/mods/default/sounds
"default_dig_cracky", -- ./games/minetest_game/mods/default/sounds
"default_chest_open", -- ./games/minetest_game/mods/default/sounds
"default_gravel_dig", -- ./games/minetest_game/mods/default/sounds
"default_dig_oddly_breakable_by_hand", -- ./games/minetest_game/mods/default/sounds
"default_dug_metal", -- ./games/minetest_game/mods/default/sounds
"default_dirt_footstep", -- ./games/minetest_game/mods/default/sounds
"default_dig_choppy", -- ./games/minetest_game/mods/default/sounds
"default_glass_footstep", -- ./games/minetest_game/mods/default/sounds
"default_snow_footstep", -- ./games/minetest_game/mods/default/sounds
"default_place_node", -- ./games/minetest_game/mods/default/sounds
"default_dig_snappy", -- ./games/minetest_game/mods/default/sounds
"default_dug_node", -- ./games/minetest_game/mods/default/sounds
"default_metal_footstep", -- ./games/minetest_game/mods/default/sounds
"default_ice_dig", -- ./games/minetest_game/mods/default/sounds
"default_place_node_metal", -- ./games/minetest_game/mods/default/sounds
"default_wood_footstep", -- ./games/minetest_game/mods/default/sounds
"default_furnace_active", -- ./games/minetest_game/mods/default/sounds
"default_item_smoke", -- ./games/minetest_game/mods/default/sounds
}

91
collider/cooler.lua Normal file
View File

@ -0,0 +1,91 @@
--[[
TechAge
=======
Copyright (C) 2019-2021 Joachim Stolberg
AGPL v3
See LICENSE.txt for more information
TA4 Cooler as part of the Collider
]]--
-- for lazy programmers
local M = minetest.get_meta
local S = techage.S
local Pipe = techage.LiquidPipe
minetest.register_node("techage:ta4_collider_cooler", {
description = S("TA4 Collider Cooler"),
tiles = {
-- up, down, right, left, back, front
{
image = "techage_appl_cooler4.png^techage_frame4_ta4_top.png",
backface_culling = false,
animation = {
type = "vertical_frames",
aspect_w = 32,
aspect_h = 32,
length = 0.4,
},
},
{
image = "techage_appl_cooler4.png^techage_frame4_ta4_top.png",
backface_culling = false,
animation = {
type = "vertical_frames",
aspect_w = 32,
aspect_h = 32,
length = 0.4,
},
},
"techage_filling_ta4.png^techage_frame_ta4.png^techage_appl_hole_pipe.png",
"techage_filling_ta4.png^techage_frame_ta4.png^techage_appl_hole_pipe.png",
"techage_filling_ta4.png^techage_frame_ta4.png^techage_cooler.png",
"techage_filling_ta4.png^techage_frame_ta4.png^techage_cooler.png",
},
drawtype = "nodebox",
paramtype2 = "facedir",
groups = {cracky = 1},
on_rotate = screwdriver.disallow,
is_ground_content = false,
sounds = default.node_sound_metal_defaults(),
networks = {
pipe2 = {},
},
after_place_node = function(pos, placer, itemstack)
Pipe:after_place_node(pos)
end,
after_dig_node = function(pos, oldnode)
Pipe:after_dig_node(pos)
techage.del_mem(pos)
end,
})
Pipe:add_secondary_node_names({"techage:ta4_collider_cooler"})
Pipe:set_valid_sides("techage:ta4_collider_cooler", {"R", "L"})
techage.register_node({"techage:ta4_collider_cooler"}, {
on_transfer = function(pos, in_dir, topic, payload)
if topic == "cooler" then
return true
else
return false
end
end,
})
minetest.register_craft({
output = "techage:ta4_collider_cooler",
recipe = {
{'', 'dye:blue', ''},
{'', 'techage:cooler', ''},
{'', 'techage:aluminum', ''},
},
})

379
collider/detector.lua Normal file
View File

@ -0,0 +1,379 @@
--[[
TechAge
=======
Copyright (C) 2019-2021 Joachim Stolberg
AGPL v3
See LICENSE.txt for more information
TA4 Detector as part of the Collider
]]--
-- for lazy programmers
local M = minetest.get_meta
local S = techage.S
local S2P = minetest.string_to_pos
local P2S = minetest.pos_to_string
local getpos = techage.assemble.get_pos
local CYCLE_TIME = 2
local TNO_MAGNETS = 22
local PROBABILITY = 90 -- every 30 min.
local function tube_damage_check(pos, node, meta, nvm)
local resp = techage.tube_inlet_command(pos, "check")
if resp then
return true
end
return false, "Tube defect"
end
local Schedule = {[0] =
-- Route: 0 = forward, 1 = right, 2 = backward, 3 = left
-- Gas left/right
{name = "techage:ta4_collider_pipe_inlet", yoffs = 1, route = {3,3,3,2}, check = techage.gas_inlet_check},
{name = "techage:ta4_collider_pipe_inlet", yoffs = 1, route = {1,1,1,2}, check = techage.gas_inlet_check},
-- Power left/right
{name = "techage:ta4_collider_cable_inlet", yoffs = 2, route = {3,3,3}, check = techage.power_inlet_check},
{name = "techage:ta4_collider_cable_inlet", yoffs = 2, route = {1,1,1}, check = techage.power_inlet_check},
-- Tube left/right
--{name = "techage:ta4_collider_tube_inlet", yoffs = 1, route = {3,3,3}, check = techage.tube_inlet_check, no_vacuum=true},
--{name = "techage:ta4_collider_tube_inlet", yoffs = 1, route = {1,1,1}, check = techage.tube_inlet_check, no_vacuum=true},
-- Cooler
{name = "techage:ta4_collider_pipe_inlet", yoffs = 0, route = {0}, check = techage.cooler_check},
{name = "techage:ta4_collider_pipe_inlet", yoffs = 2, route = {0}, check = techage.cooler_check},
-- Air outlet
{name = "techage:ta4_collider_pipe_outlet", yoffs = 2, route = {}, check = techage.air_outlet_check},
}
local TIME_SLOTS = #Schedule + 2
local function play_sound(pos)
minetest.sound_play("techage_hum", {
pos = pos,
gain = 0.5,
max_hear_distance = 10,
})
end
local function terminal_message(pos, msg)
local term_num = M(pos):contains("term_num") and M(pos):get_string("term_num")
local own_num = M(pos):get_string("node_number")
if term_num and own_num then
techage.send_single(own_num, term_num, "text", msg)
end
end
local function experience_points(pos)
if math.random(PROBABILITY) == 1 then
local owner = M(pos):get_string("owner")
local own_num = M(pos):get_string("node_number")
local player = minetest.get_player_by_name(owner)
if player then
if techage.add_expoint(player, own_num) then
terminal_message(pos, "Experience point reached!")
end
end
end
end
local function check_state(pos)
-- Cyclically check all connections
local param2 = minetest.get_node(pos).param2
local nvm = techage.get_nvm(pos)
nvm.ticks = (nvm.ticks or 0) + 1
local idx = nvm.ticks % TIME_SLOTS
local item = Schedule[idx]
if idx == 1 then
nvm.result = true
end
if item then
local pos2 = getpos(pos, param2, item.route, item.yoffs)
local nvm2 = techage.get_nvm(pos2)
local meta2 = M(pos2)
local node2 = minetest.get_node(pos2)
if item.name == node2.name then
local res, err = item.check(pos2, node2, meta2, nvm2)
--print("check_state", idx, res, err)
if not res then
nvm.result = false
nvm.runnning = false
terminal_message(pos, (err or "unknown") .. "!!!")
return nvm.result
end
else
nvm.result = false
nvm.runnning = false
terminal_message(pos, "Detector defect!!!")
end
elseif idx == #Schedule + 1 then
return nvm.result
end
end
local function add_laser(pos)
local param2 = minetest.get_node(pos).param2
local pos1 = getpos(pos, param2, {3,3}, 1)
local pos2 = getpos(pos, param2, {1,1,1}, 1)
techage.del_laser(pos)
techage.add_laser(pos, pos1, pos2)
end
local function create_task(pos, task)
local mem = techage.get_mem(pos)
if not mem.co then
mem.co = coroutine.create(task)
end
local _, err = coroutine.resume(mem.co, pos)
if err then
mem.co = nil
--print(err)
return
end
minetest.after(0.4, create_task, pos)
end
-- Call on_cyclic_check of all magents so that the magnets don't need a FLB.
local function magnet_on_cyclic_check(pos, nvm)
local ndef = minetest.registered_nodes["techage:ta4_magnet"]
for idx,pos2 in ipairs(nvm.magnet_positions or {}) do
local res = ndef.on_cyclic_check(pos2)
if res == -2 then
terminal_message(pos, "Magnet #" .. idx .. " defect!!!")
return false
elseif res == -1 then
terminal_message(pos, "Vacuum defect!!!")
techage.air_outlet_reset({x=pos.x, y=pos.y + 2, z=pos.z})
return false
end
end
return true
end
minetest.register_node("techage:ta4_detector_core", {
description = S("TA4 Collider Detector Core"),
tiles = {
-- up, down, right, left, back, front
"default_steel_block.png",
"default_steel_block.png",
"default_steel_block.png^techage_collider_detector_core.png",
"default_steel_block.png^techage_collider_detector_core.png",
"default_steel_block.png^techage_collider_detector_core.png",
"default_steel_block.png^techage_collider_detector_core.png",
},
drawtype = "nodebox",
paramtype2 = "facedir",
groups = {cracky = 1},
is_ground_content = false,
sounds = default.node_sound_metal_defaults(),
after_place_node = function(pos, placer, itemstack)
local nvm = techage.get_nvm(pos)
local meta = M(pos)
local own_num = techage.add_node(pos, "techage:ta4_detector_core")
meta:set_string("node_number", own_num)
meta:set_string("owner", placer:get_player_name())
M({x=pos.x, y=pos.y - 1, z=pos.z}):set_string("infotext", S("TA4 Collider Detector " .. own_num))
minetest.get_node_timer(pos):start(CYCLE_TIME)
end,
on_timer = function(pos, elapsed)
local nvm = techage.get_nvm(pos)
if not magnet_on_cyclic_check(pos, nvm) then
techage.del_laser(pos)
if nvm.running then
terminal_message(pos, "Detector stopped.")
nvm.running = false
end
nvm.magnet_positions = nil
elseif nvm.running then
local res = check_state(pos)
if res == true then
experience_points(pos)
add_laser(pos)
if nvm.ticks <= TIME_SLOTS then -- only once
terminal_message(pos, "Detector running.")
end
elseif res == false then
techage.del_laser(pos)
nvm.running = false
nvm.magnet_positions = nil
terminal_message(pos, "Detector stopped.")
end
if nvm.running then
play_sound(pos)
end
end
return true
end,
after_dig_node = function(pos, oldnode, oldmetadata, digger)
techage.on_remove_collider(digger)
techage.remove_node(pos, oldnode, oldmetadata)
techage.del_mem(pos)
end,
})
local function check_expr(own_num, term_num, text, expr)
techage.send_single(own_num, term_num, "text", text .. "..." .. (expr and "ok" or "error!!!"))
return expr
end
local function start_task(pos)
local term_num = M(pos):contains("term_num") and M(pos):get_string("term_num")
local param2 = minetest.get_node(pos).param2
local pos2 = getpos(pos, param2, {3,3,3}, 1)
local own_num = M(pos):get_string("node_number")
local nvm = techage.get_nvm(pos)
nvm.magnet_positions = {}
if term_num and param2 and pos2 then
techage.send_single(own_num, term_num, "text", "#### Start ####")
coroutine.yield()
local resp = techage.tube_inlet_command(pos2, "enumerate", 1)
if not check_expr(own_num, term_num, "- Check number of magnets", resp == TNO_MAGNETS) then
return
end
coroutine.yield()
techage.send_single(own_num, term_num, "text", "- Check position of magnets...")
resp = techage.tube_inlet_command(pos2, "distance")
if resp ~= true then
techage.send_single(own_num, term_num, "append", "#" .. resp .. " defect!!!")
return
end
techage.send_single(own_num, term_num, "append", "ok")
coroutine.yield()
techage.send_single(own_num, term_num, "text", "- Start magnets...")
for num = 1, TNO_MAGNETS do
local resp = techage.tube_inlet_command(pos2, "pos", num)
if not resp or type(resp) ~= "table" then
techage.send_single(own_num, term_num, "append", "#" .. num .. " defect!!!")
nvm.magnet_positions = nil
return
else
nvm.magnet_positions[#nvm.magnet_positions + 1] = resp
end
coroutine.yield()
end
techage.send_single(own_num, term_num, "append", "ok")
coroutine.yield()
techage.send_single(own_num, term_num, "text", "- Check magnets...")
-- The check will be performed by the timer, so wait 5 sec.
for i = 1,14 do
coroutine.yield()
end
if nvm.magnet_positions then
techage.send_single(own_num, term_num, "append", "ok")
else
return
end
coroutine.yield()
techage.send_single(own_num, term_num, "text", "- Check detector...")
for _,item in ipairs(Schedule)do
local pos2 = getpos(pos, param2, item.route, item.yoffs)
local nvm2 = techage.get_nvm(pos2)
local meta2 = M(pos2)
local node2 = minetest.get_node(pos2)
if item.name == node2.name then
local res, err = item.check(pos2, node2, meta2, nvm2)
if not res then
techage.send_single(own_num, term_num, "append", err .. "!!!")
nvm.magnet_positions = nil
return
end
else
techage.send_single(own_num, term_num, "append", "defect!!!")
nvm.magnet_positions = nil
return
end
coroutine.yield()
end
techage.send_single(own_num, term_num, "append", "ok")
coroutine.yield()
techage.send_single(own_num, term_num, "text", "Ready.")
nvm.ticks = 0
nvm.running = true
end
end
local function test_magnet(pos, payload)
local term_num = M(pos):contains("term_num") and M(pos):get_string("term_num")
local param2 = minetest.get_node(pos).param2
local pos2 = getpos(pos, param2, {3,3,3}, 1)
local own_num = M(pos):get_string("node_number")
local magnet_num = tonumber(payload)
local res, err = techage.tube_inlet_command(pos2, "test", magnet_num)
if res then
techage.send_single(own_num, term_num, "text", "magnet #" .. magnet_num .. ": ok")
else
techage.send_single(own_num, term_num, "text", "magnet #" .. magnet_num .. ": " .. err .. "!!!")
end
end
techage.register_node({"techage:ta4_detector_core"}, {
on_recv_message = function(pos, src, topic, payload)
local nvm = techage.get_nvm(pos)
if topic == "connect" then
M(pos):set_string("term_num", src)
return true
elseif topic == "start" then
create_task(pos, start_task)
return true
elseif topic == "stop" then
nvm.running = false
techage.del_laser(pos)
return "Detector stopped."
elseif topic == "status" then
if nvm.running == true then
return "running"
elseif nvm.result == false then
return "fault"
else
return "stopped"
end
elseif topic == "test"then
if payload and tonumber(payload) then
test_magnet(pos, payload)
return true
else
return "Invalid magnet number"
end
elseif topic == "points" then
local owner = M(pos):get_string("owner")
local player = minetest.get_player_by_name(owner)
if player then
local points = techage.get_expoints(player)
return "Ex. Points = " .. points
end
else
return "unsupported"
end
end,
on_node_load = function(pos)
minetest.get_node_timer(pos):start(CYCLE_TIME)
end,
})
minetest.register_craft({
output = "techage:ta4_detector_core",
recipe = {
{'techage:aluminum', 'basic_materials:heating_element', 'default:steel_ingot'},
{'default:diamond', 'techage:ta4_wlanchip', 'techage:electric_cableS'},
{'default:steel_ingot', '', 'techage:aluminum'},
},
})

364
collider/inlets.lua Normal file
View File

@ -0,0 +1,364 @@
--[[
TechAge
=======
Copyright (C) 2019-2021 Joachim Stolberg
AGPL v3
See LICENSE.txt for more information
TA4 Tube/Pipe Inlets as part of the Collider
]]--
-- for lazy programmers
local M = minetest.get_meta
local S = techage.S
local PWR_NEEDED = 15
local CYCLE_TIME = 2
local GAS_CAPA = 20
local AIR_CAPA = 1000
local VTube = techage.VTube
local Pipe = techage.LiquidPipe
local Cable = techage.ElectricCable
local power = networks.power
local liquid = networks.liquid
--------------------------------------------------------------------------------
-- Tube Inlet
--------------------------------------------------------------------------------
minetest.register_node("techage:ta4_collider_tube_inlet", {
description = S("TA4 Collider Tube Inlet"),
tiles = {
-- up, down, right, left, back, front
"default_steel_block.png",
"default_steel_block.png",
"default_steel_block.png",
"default_steel_block.png",
"default_steel_block.png",
"default_steel_block.png^techage_collider_tube_open.png",
},
drawtype = "nodebox",
node_box = {
type = "fixed",
fixed = {
{-4/8, -4/8, -4/8, -1/8, 4/8, 4/8},
{ 1/8, -4/8, -4/8, 4/8, 4/8, 4/8},
{-4/8, 1/8, -4/8, 4/8, 4/8, 4/8},
{-4/8, -4/8, -4/8, 4/8, -1/8, 4/8},
},
},
selection_box = {
type = "fixed",
fixed = {-4/8, -4/8, -4/8, 4/8, 4/8, 4/8},
},
paramtype2 = "facedir",
groups = {cracky = 1},
on_rotate = screwdriver.disallow,
is_ground_content = false,
sounds = default.node_sound_metal_defaults(),
after_place_node = function(pos, placer, itemstack)
VTube:after_place_node(pos)
end,
after_dig_node = function(pos, oldnode)
VTube:after_dig_node(pos)
techage.del_mem(pos)
end,
})
VTube:add_secondary_node_names({"techage:ta4_collider_tube_inlet"})
VTube:set_valid_sides("techage:ta4_collider_tube_inlet", {"F"})
-- Called from the detector via tube ring
techage.register_node({"techage:ta4_collider_tube_inlet"}, {
on_transfer = function(pos, in_dir, topic, payload)
if topic == "distance" then
return pos
elseif topic == "enumerate" and payload then
return payload - 1
elseif topic == "check" then
local nvm = techage.get_nvm(pos)
nvm.check_received = true
return true
end
end,
})
-- Used by the detector to check the tube connection
function techage.tube_inlet_command(pos, command, payload)
if command == "distance" then
local pos2 = techage.transfer(pos, "F", command, payload, VTube, {"techage:ta4_magnet"})
if type(pos2) == "table" then
local dist = math.abs(pos.x - pos2.x) + math.abs(pos.z - pos2.z)
if pos.y == pos2.y and dist == VTube.max_tube_length + 1 then
return true
end
return 0
else
return pos2
end
end
return techage.transfer(pos, "F", command, payload, VTube, {"techage:ta4_magnet"})
end
minetest.register_craft({
output = "techage:ta4_collider_tube_inlet",
recipe = {
{'', '', ''},
{'techage:ta4_vtubeS', 'default:steelblock', ''},
{'', '', ''},
},
})
--------------------------------------------------------------------------------
-- Pipe Inlet (gas)
--------------------------------------------------------------------------------
minetest.register_node("techage:ta4_collider_pipe_inlet", {
description = S("TA4 Collider Pipe Inlet"),
tiles = {
-- up, down, right, left, back, front
"default_steel_block.png",
"default_steel_block.png",
"default_steel_block.png",
"default_steel_block.png",
"default_steel_block.png",
"default_steel_block.png^techage_appl_hole_pipe.png",
},
drawtype = "nodebox",
paramtype2 = "facedir",
groups = {cracky = 1},
on_rotate = screwdriver.disallow,
is_ground_content = false,
sounds = default.node_sound_metal_defaults(),
networks = {
pipe2 = {},
},
after_place_node = function(pos, placer, itemstack)
local nvm = techage.get_nvm(pos)
Pipe:after_place_node(pos)
nvm.liquid = {}
end,
after_dig_node = function(pos, oldnode)
Pipe:after_dig_node(pos)
techage.del_mem(pos)
end,
})
liquid.register_nodes({"techage:ta4_collider_pipe_inlet"}, Pipe, "tank", {"F"}, {
capa = GAS_CAPA,
peek = function(pos, indir)
local nvm = techage.get_nvm(pos)
return liquid.srv_peek(nvm)
end,
put = function(pos, indir, name, amount)
local nvm = techage.get_nvm(pos)
return liquid.srv_put(nvm, name, amount, GAS_CAPA)
end,
take = function(pos, indir, name, amount)
local nvm = techage.get_nvm(pos)
return liquid.srv_take(nvm, name, amount)
end,
untake = function(pos, indir, name, amount)
local nvm = techage.get_nvm(pos)
liquid.srv_put(nvm, name, amount, GAS_CAPA)
end,
})
techage.register_node({"techage:ta4_collider_pipe_inlet"}, {
on_transfer = function(pos, in_dir, topic, payload)
-- called from heatexchanger
if topic == "detector" then
local nvm = techage.get_nvm(pos)
nvm.detector_received = true
return true
end
end,
})
-- Used by the detector to check for gas pressure
function techage.gas_inlet_check(pos, node, meta, nvm)
nvm.liquid = nvm.liquid or {}
if nvm.liquid.amount == GAS_CAPA and nvm.liquid.name == "techage:hydrogen" then
return true
end
return false, "no gas"
end
-- Used by the detector to check for cooler connection
function techage.cooler_check(pos, node, meta, nvm)
if nvm.detector_received then
nvm.detector_received = nil
return true
end
return false, "Cooler defect"
end
minetest.register_craft({
output = "techage:ta4_collider_pipe_inlet",
recipe = {
{'', '', ''},
{'techage:ta3_pipeS', 'default:steelblock', ''},
{'', '', ''},
},
})
--------------------------------------------------------------------------------
-- Pipe Outlet (air)
--------------------------------------------------------------------------------
local function init_air(nvm)
nvm.liquid = {
amount = AIR_CAPA,
name = "air",
}
return nvm.liquid
end
minetest.register_node("techage:ta4_collider_pipe_outlet", {
description = S("TA4 Collider Pipe Outlet"),
tiles = {
-- up, down, right, left, back, front
"default_steel_block.png^techage_appl_hole_pipe.png",
"default_steel_block.png",
"default_steel_block.png",
"default_steel_block.png",
"default_steel_block.png",
"default_steel_block.png",
},
drawtype = "nodebox",
paramtype2 = "facedir",
groups = {cracky = 1},
on_rotate = screwdriver.disallow,
is_ground_content = false,
sounds = default.node_sound_metal_defaults(),
networks = {
pipe2 = {},
},
after_place_node = function(pos, placer, itemstack)
local nvm = techage.get_nvm(pos)
init_air(nvm)
Pipe:after_place_node(pos)
end,
after_dig_node = function(pos, oldnode)
Pipe:after_dig_node(pos)
techage.del_mem(pos)
end,
})
liquid.register_nodes({"techage:ta4_collider_pipe_outlet"}, Pipe, "tank", {"U"}, {
capa = AIR_CAPA,
peek = function(pos, indir)
local nvm = techage.get_nvm(pos)
return liquid.srv_peek(nvm)
end,
put = function(pos, indir, name, amount)
local nvm = techage.get_nvm(pos)
return liquid.srv_put(nvm, name, amount, AIR_CAPA)
end,
take = function(pos, indir, name, amount)
local nvm = techage.get_nvm(pos)
return liquid.srv_take(nvm, name, amount)
end,
untake = function(pos, indir, name, amount)
local nvm = techage.get_nvm(pos)
liquid.srv_put(nvm, name, amount, AIR_CAPA)
end,
})
-- Used by the detector to check the vacuum
function techage.air_outlet_check(pos, node, meta, nvm)
nvm.liquid = nvm.liquid or {}
if nvm.liquid.amount == 0 then
return true
end
return false, "no vacuum"
end
function techage.air_outlet_reset(pos)
local nvm = techage.get_nvm(pos)
init_air(nvm)
end
minetest.register_craft({
output = "techage:ta4_collider_pipe_outlet",
recipe = {
{'', 'techage:ta3_pipeS', ''},
{'', 'default:steelblock', ''},
{'', '', ''},
},
})
--------------------------------------------------------------------------------
-- Cable Inlet (power)
--------------------------------------------------------------------------------
minetest.register_node("techage:ta4_collider_cable_inlet", {
description = S("TA4 Collider Cable Inlet"),
tiles = {
-- up, down, right, left, back, front
"default_steel_block.png",
"default_steel_block.png",
"default_steel_block.png",
"default_steel_block.png",
"default_steel_block.png",
"default_steel_block.png^techage_appl_hole_electric.png",
},
drawtype = "nodebox",
paramtype2 = "facedir",
groups = {cracky = 1},
on_rotate = screwdriver.disallow,
is_ground_content = false,
sounds = default.node_sound_metal_defaults(),
networks = {
pipe2 = {},
},
after_place_node = function(pos, placer, itemstack)
Cable:after_place_node(pos)
minetest.get_node_timer(pos):start(CYCLE_TIME)
end,
on_timer = function(pos, elapsed)
local nvm = techage.get_nvm(pos)
nvm.consumed = power.consume_power(pos, Cable, nil, PWR_NEEDED)
return true
end,
after_dig_node = function(pos, oldnode)
Cable:after_dig_node(pos)
techage.del_mem(pos)
end,
})
-- Used by the detector to check for power
function techage.power_inlet_check(pos, node, meta, nvm)
if nvm.consumed == PWR_NEEDED then
return true
end
return false, "no power"
end
power.register_nodes({"techage:ta4_collider_cable_inlet"}, Cable, "con", {"F"})
techage.register_node({"techage:ta4_collider_cable_inlet"}, {
on_node_load = function(pos)
minetest.get_node_timer(pos):start(CYCLE_TIME)
end,
})
minetest.register_craft({
output = "techage:ta4_collider_cable_inlet",
recipe = {
{'', '', ''},
{'techage:electric_cableS', 'default:steelblock', ''},
{'', '', ''},
},
})

271
collider/magnet.lua Normal file
View File

@ -0,0 +1,271 @@
--[[
TechAge
=======
Copyright (C) 2019-2021 Joachim Stolberg
AGPL v3
See LICENSE.txt for more information
TA4 Magnet as part of the Collider
]]--
-- for lazy programmers
local M = minetest.get_meta
local S = techage.S
local S2P = minetest.string_to_pos
local P2S = minetest.pos_to_string
local PWR_NEEDED = 5
local CYCLE_TIME = 2
local CAPACITY = 10
local Cable = techage.ElectricCable
local Pipe = techage.LiquidPipe
local VTube = techage.VTube
local power = networks.power
local liquid = networks.liquid
minetest.register_node("techage:ta4_detector_magnet", {
description = S("TA4 Collider Detector Magnet"),
tiles = {
-- up, down, right, left, back, front
"techage_collider_magnet.png^techage_collider_magnet_appl.png",
"techage_collider_magnet.png^techage_collider_magnet_appl.png",
"techage_collider_magnet.png",
"techage_collider_magnet.png",
"techage_collider_magnet.png^techage_collider_magnet_appl.png",
"techage_collider_magnet.png^techage_collider_magnet_appl.png",
},
drawtype = "nodebox",
paramtype2 = "facedir",
groups = {cracky = 1},
is_ground_content = false,
sounds = default.node_sound_metal_defaults(),
})
minetest.register_node("techage:ta4_magnet", {
description = S("TA4 Collider Magnet"),
inventory_image = minetest.inventorycube(
"techage_collider_magnet.png^techage_appl_hole_electric.png",
"techage_collider_magnet.png^techage_appl_hole_pipe.png",
"techage_collider_magnet.png^techage_collider_magnet_tube.png"),
tiles = {
-- up, down, right, left, back, front
"techage_collider_magnet.png^techage_appl_hole_electric.png",
"techage_collider_magnet.png",
"techage_collider_magnet.png^techage_collider_magnet_tube.png",
"techage_collider_magnet.png^techage_collider_magnet_tube.png",
"techage_collider_magnet.png^techage_collider_magnet_appl.png^techage_appl_hole_pipe.png^techage_collider_magnet_sign.png",
"techage_collider_magnet.png^techage_collider_magnet_appl.png^techage_appl_hole_pipe.png^techage_collider_magnet_sign.png",
},
drawtype = "nodebox",
use_texture_alpha = techage.CLIP,
node_box = {
type = "fixed",
fixed = {
{-11/16, -11/16, -11/16, 11/16, 11/16, -2/16},
{-11/16, -11/16, 2/16, 11/16, 11/16, 11/16},
{-11/16, 2/16, -11/16, 11/16, 11/16, 11/16},
{-11/16, -11/16, -11/16, 11/16, -2/16, 11/16},
},
},
selection_box = {
type = "fixed",
fixed = {-4/8, -4/8, -4/8, 4/8, 4/8, 4/8},
},
collision_box = {
type = "fixed",
fixed = {-11/16, -11/16, -11/16, 11/16, 11/16, 11/16},
},
wield_scale = {x = 0.8, y = 0.8, z = 0.8},
paramtype2 = "facedir",
groups = {cracky = 1},
on_rotate = screwdriver.disallow,
is_ground_content = false,
sounds = default.node_sound_metal_defaults(),
after_place_node = function(pos, placer, itemstack)
if pos.y > techage.collider_min_depth then
minetest.remove_node(pos)
minetest.add_item(pos, ItemStack("techage:ta4_magnet"))
return
end
local nvm = techage.get_nvm(pos)
nvm.liquid = {}
Pipe:after_place_node(pos)
Cable:after_place_node(pos)
VTube:after_place_node(pos)
M(pos):set_string("infotext", S("TA4 Collider Magnet") .. " #0")
end,
-- To be called by the detector
on_cyclic_check = function(pos)
local nvm = techage.get_nvm(pos)
nvm.liquid = nvm.liquid or {}
nvm.consumed = power.consume_power(pos, Cable, 6, PWR_NEEDED)
if nvm.tube_damage then
nvm.tube_damage = nil
return -1
elseif nvm.liquid.amount == CAPACITY and
nvm.liquid.name == "techage:hydrogen" and
nvm.consumed == PWR_NEEDED then
return 0
end
return -2
end,
tubelib2_on_update2 = function(pos, outdir, tlib2, node)
if tlib2.tube_type == "vtube" then
local nvm = techage.get_nvm(pos)
nvm.tube_damage = true
elseif tlib2.tube_type == "pipe2" then
local nvm = techage.get_nvm(pos)
nvm.liquid = nvm.liquid or {}
nvm.liquid.amount = 0
end
end,
after_dig_node = function(pos, oldnode)
Pipe:after_dig_node(pos)
Cable:after_dig_node(pos)
VTube:after_dig_node(pos)
techage.del_mem(pos)
end,
})
power.register_nodes({"techage:ta4_magnet"}, Cable, "con", {"U"})
liquid.register_nodes({"techage:ta4_magnet"}, Pipe, "tank", {"F", "B"}, {
capa = CAPACITY,
peek = function(pos, indir)
local nvm = techage.get_nvm(pos)
return liquid.srv_peek(nvm)
end,
put = function(pos, indir, name, amount)
local nvm = techage.get_nvm(pos)
return liquid.srv_put(nvm, name, amount, CAPACITY)
end,
take = function(pos, indir, name, amount)
local nvm = techage.get_nvm(pos)
return liquid.srv_take(nvm, name, amount)
end,
untake = function(pos, indir, name, amount)
local nvm = techage.get_nvm(pos)
liquid.srv_put(nvm, name, amount, CAPACITY)
end,
})
VTube:add_secondary_node_names({"techage:ta4_magnet"})
VTube:set_valid_sides("techage:ta4_magnet", {"R", "L"})
local function send_to_next(pos, in_dir, topic, payload)
return techage.transfer(pos, in_dir, topic, payload, VTube,
{"techage:ta4_magnet", "techage:ta4_collider_tube_inlet"})
end
--[[
Commands
--------
distance : Check distance between all magnets.
Returns pos of next magnet or the number of the defect magnet.
enumerate : Give each magnet a unique number (1...n)
pos : Read the position
test : Test all magnet attributs.
Returns true or false, err
]]--
techage.register_node({"techage:ta4_magnet"}, {
on_transfer = function(pos, in_dir, topic, payload)
local nvm = techage.get_nvm(pos)
if topic == "distance" then
local pos2 = send_to_next(pos, in_dir, topic, payload)
if type(pos2) == "table" then
local dist = math.abs(pos.x - pos2.x) + math.abs(pos.z - pos2.z)
if pos.y == pos2.y and dist == VTube.max_tube_length + 1 then
return pos
end
return nvm.number or 0
else
return pos2
end
elseif topic == "enumerate" and payload then
payload = tonumber(payload) or 1
nvm.number = payload
M(pos):set_string("infotext", S("TA4 Collider Magnet") .. " #" .. payload)
return send_to_next(pos, in_dir, topic, payload + 1)
elseif topic == "pos" then
if payload and tonumber(payload) == nvm.number then
return pos
else
return send_to_next(pos, in_dir, topic, payload)
end
elseif topic == "test" then
if payload and tonumber(payload) == nvm.number then
if not nvm.liquid or nvm.liquid.amount < CAPACITY then
return false, "no gas"
elseif nvm.liquid.name ~= "techage:hydrogen" then
return false, "wrong gas"
elseif nvm.consumed ~= PWR_NEEDED then
return false, "no power"
elseif nvm.tube_damage then
nvm.tube_damage = nil
return false, "no vacuum"
end
return true
else
return send_to_next(pos, in_dir, topic, payload)
end
end
end,
})
minetest.register_node("techage:ta4_magnet_base", {
description = S("TA4 Collider Magnet Base"),
tiles = {
-- up, down, right, left, back, front
"default_steel_block.png",
},
drawtype = "nodebox",
node_box = {
type = "fixed",
fixed = {
{-6/16, -8/16, -6/16, 6/16, 5/16, 6/16},
},
},
paramtype2 = "facedir",
groups = {cracky = 1},
is_ground_content = false,
paramtype = "light",
use_texture_alpha = techage.CLIP,
sounds = default.node_sound_metal_defaults(),
})
minetest.register_craft({
output = "techage:ta4_detector_magnet 2",
recipe = {
{'default:steel_ingot', '', 'techage:aluminum'},
{'dye:red', 'basic_materials:gold_wire', 'dye:brown'},
{'techage:aluminum', '', 'default:steel_ingot'},
},
})
minetest.register_craft({
output = "techage:ta4_magnet",
recipe = {
{'techage:ta3_pipeS', '', 'techage:electric_cableS'},
{'techage:ta4_round_ceramic', 'techage:ta4_detector_magnet', 'techage:ta4_round_ceramic'},
{'', '', ''},
},
})
minetest.register_craft({
output = "techage:ta4_magnet_base 4",
recipe = {
{'techage:aluminum', 'default:steel_ingot', ''},
{'techage:aluminum', 'default:steel_ingot', ''},
{'techage:aluminum', 'default:steel_ingot', ''},
},
})

208
collider/terminal.lua Normal file
View File

@ -0,0 +1,208 @@
--[[
Techage
=======
Copyright (C) 2020-2021 Joachim Stolberg
AGPL v3
See LICENSE.txt for more information
TA4 Terminal
]]--
local M = minetest.get_meta
local S = techage.S
local STR_LEN = 80
local HELP = [[#### TA4 Terminal ####
Send commands to the connected machine
and output text messages from the
machine.
Commands can have up to 80 characters.
Local commands:
- clear = clear screen
- help = this message
- pub = switch to public use
- priv = switch to private use
- connect <num> = connect the machine
All other commands are machine dependent.
]]
local function get_string(meta, num, default)
local s = meta:get_string("bttn_text"..num)
if not s or s == "" then
return default
end
return s
end
local function formspec2(mem)
mem.command = mem.command or ""
mem.output = mem.output or ""
local output = minetest.formspec_escape(mem.output)
output = output:gsub("\n", ",")
local command = minetest.formspec_escape(mem.command)
local bttn_text1 = get_string(meta, 1, "User1")
local bttn_text2 = get_string(meta, 2, "User2")
local bttn_text3 = get_string(meta, 3, "User3")
local bttn_text4 = get_string(meta, 4, "User4")
local bttn_text5 = get_string(meta, 5, "User5")
local bttn_text6 = get_string(meta, 6, "User6")
local bttn_text7 = get_string(meta, 7, "User7")
local bttn_text8 = get_string(meta, 8, "User8")
local bttn_text9 = get_string(meta, 9, "User9")
return "size[10,8]"..
"style_type[table,field;font=mono]"..
"button[0,0;3.3,1;bttn1;"..bttn_text1.."]button[3.3,0;3.3,1;bttn2;"..bttn_text2.."]button[6.6,0;3.3,1;bttn3;"..bttn_text3.."]"..
"button[0,0.8;3.3,1;bttn4;"..bttn_text4.."]button[3.3,0.8;3.3,1;bttn5;"..bttn_text5.."]button[6.6,0.8;3.3,1;bttn6;"..bttn_text6.."]"..
"button[0,1.6;3.3,1;bttn7;"..bttn_text7.."]button[3.3,1.6;3.3,1;bttn8;"..bttn_text8.."]button[6.6,1.6;3.3,1;bttn9;"..bttn_text9.."]"..
"table[0,2.5;9.8,4.7;output;"..output..";200]"..
"field[0.4,7.7;7.6,1;cmnd;;"..mem.command.."]" ..
"field_close_on_enter[cmnd;false]"..
"button[7.9,7.4;2,1;enter;"..S("Enter").."]"
end
local function output(pos, text)
local mem = techage.get_mem(pos)
mem.output = mem.output .. "\n" .. (text or "")
mem.output = mem.output:sub(-500,-1)
M(pos):set_string("formspec", formspec2(mem))
end
local function command(pos, mem, player)
local meta = minetest.get_meta(pos)
local owner = meta:get_string("owner")
if mem.command == "clear" then
mem.output = ""
mem.command = ""
meta:set_string("formspec", formspec2(mem))
elseif mem.command == "" then
output(pos, ">")
mem.command = ""
meta:set_string("formspec", formspec2(mem))
elseif mem.command == "help" then
local meta = minetest.get_meta(pos)
mem.output = HELP
mem.command = ""
meta:set_string("formspec", formspec2(mem))
elseif mem.command == "pub" and owner == player then
meta:set_int("public", 1)
output(pos, "> "..mem.command)
mem.command = ""
output(pos, "Switched to public use!")
elseif mem.command == "priv" and owner == player then
meta:set_int("public", 0)
output(pos, "> "..mem.command)
mem.command = ""
output(pos, "Switched to private use!")
elseif meta:get_int("public") == 1 or owner == player then
if mem.command == "clear" then
mem.output =
mem.command = ""
meta:set_string("formspec", formspec2(mem))
end
end
end
minetest.register_node("techage:ta4_terminal", {
description = "TA4 Collider Terminal",
tiles = {
-- up, down, right, left, back, front
'techage_terminal1_top.png',
'techage_terminal1_bottom.png',
'techage_terminal1_side.png',
'techage_terminal1_side.png',
'techage_terminal1_bottom.png',
"techage_terminal1_front.png",
},
drawtype = "nodebox",
node_box = {
type = "fixed",
fixed = {
{-12/32, -16/32, -8/32, 12/32, -14/32, 12/32},
{-12/32, -14/32, 12/32, 12/32, 6/32, 14/32},
},
},
selection_box = {
type = "fixed",
fixed = {
{-12/32, -16/32, -8/32, 12/32, -14/32, 12/32},
{-12/32, -14/32, 12/32, 12/32, 6/32, 14/32},
},
},
after_place_node = function(pos, placer)
local number = techage.add_node(pos, minetest.get_node(pos).name)
local meta = minetest.get_meta(pos)
meta:set_string("formspec", formspec1())
meta:set_string("owner", placer:get_player_name())
meta:set_string("infotext", S("TA4 Collider Terminal") .. ": " .. S("not connected")
end,
on_receive_fields = function(pos, formname, fields, player)
local meta = minetest.get_meta(pos)
local mem = techage.get_mem(pos)
if fields.number and fields.number ~= "" then
local owner = meta:get_string("owner")
if techage.check_numbers(fields.number, owner) then
local own_number = meta:get_string("own_number")
if techage.send_single(own_number, fields.number, "connect") == true then
meta:set_string("number", fields.number)
meta:set_string("infotext", S("TA4 Collider Terminal") .. ": " .. S("connected with") .. " " .. fields.number)
meta:set_string("formspec", formspec2(mem))
end
end
elseif (fields.enter or fields.key_enter_field) and fields.cmnd then
mem.command = string.sub(fields.cmnd, 1, STR_LEN)
command(pos, mem, player:get_player_name())
elseif fields.key_up then
mem.command = pdp13.historybuffer_priv(pos)
meta:set_string("formspec", formspec2(mem))
elseif fields.key_down then
mem.command = pdp13.historybuffer_next(pos)
meta:set_string("formspec", formspec2(mem))
end
end,
after_dig_node = function(pos, oldnode, oldmetadata)
techage.remove_node(pos, oldnode, oldmetadata)
end,
paramtype = "light",
use_texture_alpha = techage.CLIP,
sunlight_propagates = true,
paramtype2 = "facedir",
groups = {choppy=2, cracky=2, crumbly=2},
is_ground_content = false,
sounds = default.node_sound_metal_defaults(),
})
minetest.register_craft({
output = "techage:ta4_terminal",
recipe = {
{"", "techage:ta4_display", ""},
{"dye:black", "techage:ta4_wlanchip", "default:copper_ingot"},
{"", "techage:aluminum", ""},
},
})
techage.register_node({"techage:ta4_terminal"}, {
on_recv_message = function(pos, src, topic, payload)
if topic == "term" then
output(pos, payload)
return true
elseif topic == "clear" then
local mem = techage.get_mem(pos)
mem.output = ""
mem.command = ""
M(pos):set_string("formspec", formspec2(mem))
return true
end
end,
})

130
collider/vacuumtube.lua Normal file
View File

@ -0,0 +1,130 @@
--[[
TechAge
=======
Copyright (C) 2019-2021 Joachim Stolberg
AGPL v3
See LICENSE.txt for more information
TA4 Vacuum Tube as part of the Collider
]]--
-- for lazy programmers
local M = minetest.get_meta
local S = techage.S
local VTube = tubelib2.Tube:new({
dirs_to_check = {1,2,3,4},
max_tube_length = 5,
tube_type = "vtube",
show_infotext = false,
primary_node_names = {"techage:ta4_vtubeS", "techage:ta4_vtubeA"},
secondary_node_names = {"techage:ta4_magnet"},
after_place_tube = function(pos, param2, tube_type, num_tubes)
minetest.swap_node(pos, {name = "techage:ta4_vtube"..tube_type, param2 = param2})
end,
})
techage.VTube = VTube
minetest.register_node("techage:ta4_vtubeS", {
description = S("TA4 Vacuum Tube"),
drawtype = "nodebox",
tiles = {
-- up, down, right, left, back, front
"techage_collider_tube.png^[transformR90",
"techage_collider_tube.png^[transformR90",
"techage_collider_tube.png",
"techage_collider_tube.png",
'techage_collider_tube_open.png',
'techage_collider_tube_open.png',
},
node_box = {
type = "fixed",
fixed = {
{-8/16, -8/16, -8/16, -6/16, 8/16, 8/16},
{ 6/16, -8/16, -8/16, 8/16, 8/16, 8/16},
{-8/16, 6/16, -8/16, 8/16, 8/16, 8/16},
{-8/16, -8/16, -8/16, 8/16, -6/16, 8/16},
},
},
selection_box = {
type = "fixed",
fixed = {-8/16, -8/16, -8/16, 8/16, 8/16, 8/16},
},
after_place_node = function(pos, placer, itemstack, pointed_thing)
if not VTube: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)
VTube:after_dig_tube(pos, oldnode, oldmetadata)
end,
paramtype2 = "facedir", -- important!
on_rotate = screwdriver.disallow, -- important!
paramtype = "light",
use_texture_alpha = techage.CLIP,
sunlight_propagates = true,
is_ground_content = false,
groups = {cracky = 2},
sounds = default.node_sound_metal_defaults(),
})
minetest.register_node("techage:ta4_vtubeA", {
description = S("TA4 Vacuum Tube"),
drawtype = "nodebox",
tiles = {
-- up, down, right, left, back, front
"techage_collider_tube.png^[transformR90",
'techage_collider_tube.png^techage_collider_tube_open.png',
"techage_collider_tube.png",
"techage_collider_tube.png",
"techage_collider_tube.png^[transformR90",
'techage_collider_tube.png^techage_collider_tube_open.png',
},
node_box = {
type = "fixed",
fixed = {
{-8/16, -8/16, -8/16, -6/16, 8/16, 8/16},
{ 6/16, -8/16, -8/16, 8/16, 8/16, 8/16},
{-8/16, 6/16, -8/16, 8/16, 8/16, 8/16},
{-8/16, -8/16, 6/16, 8/16, 8/16, 8/16},
{-8/16, -8/16, -8/16, 8/16, -6/16, -6/16},
},
},
selection_box = {
type = "fixed",
fixed = {-8/16, -8/16, -8/16, 8/16, 8/16, 8/16},
},
after_dig_node = function(pos, oldnode, oldmetadata, digger)
VTube:after_dig_tube(pos, oldnode, oldmetadata)
end,
paramtype2 = "facedir", -- important!
on_rotate = screwdriver.disallow, -- important!
paramtype = "light",
use_texture_alpha = techage.CLIP,
sunlight_propagates = true,
is_ground_content = false,
groups = {cracky = 1, not_in_creative_inventory=1},
drop = "techage:ta4_vtubeS",
sounds = default.node_sound_metal_defaults(),
})
minetest.register_craft({
output = "techage:ta4_vtubeS 4",
recipe = {
{'', 'default:steel_ingot', ''},
{'techage:aluminum', 'dye:blue', 'techage:aluminum'},
{'', 'default:steel_ingot', ''},
},
})

205
collider/worker.lua Normal file
View File

@ -0,0 +1,205 @@
--[[
TechAge
=======
Copyright (C) 2019-2021 Joachim Stolberg
AGPL v3
See LICENSE.txt for more information
TA4 Detector Worlker as part of the Collider
]]--
-- for lazy programmers
local M = minetest.get_meta
local S = techage.S
local AssemblyPlan = {
-- y-offs, path, facedir-offs, name
-- 0 = forward, 1 = right, 2 = backward, 3 = left
-- level 1
-- left/right
{ 1, {3,3,3,2}, 0, "default:steelblock"},
{ 1, {3,3,3}, 0, "default:steelblock"},
{ 1, {3,3,3,0}, 0, "default:steelblock"},
{ 1, {1,1,1,2}, 0, "default:steelblock"},
{ 1, {1,1,1}, 0, "default:steelblock"},
{ 1, {1,1,1,0}, 0, "default:steelblock"},
-- front
{ 1, {3,3,2}, 0, "default:steelblock"},
{ 1, {3,2}, 0, "default:steelblock"},
{ 1, {2}, 0, "default:steelblock"},
{ 1, {1,2}, 0, "default:steelblock"},
{ 1, {1,1,2}, 0, "default:steelblock"},
-- back
{ 1, {3,3,0}, 0, "default:steelblock"},
{ 1, {3,0}, 0, "default:steelblock"},
{ 1, {0}, 2, "techage:ta4_collider_pipe_inlet"},
{ 1, {1,0}, 0, "default:steelblock"},
{ 1, {1,1,0}, 0, "default:steelblock"},
-- middle
{ 1, {3,3}, 0, "techage:ta4_detector_magnet"},
{ 1, {3}, 0, "techage:ta4_detector_magnet"},
{ 1, {}, 0, "techage:ta4_detector_core"},
{ 1, {1}, 0, "techage:ta4_detector_magnet"},
{ 1, {1,1}, 0, "techage:ta4_detector_magnet"},
-- level 2
-- left/right
{ 2, {3,3,3,2}, 1, "techage:ta4_collider_pipe_inlet"},
{ 2, {3,3,3}, 1, "techage:ta4_collider_tube_inlet"},
{ 2, {3,3,3,0}, 0, "default:steelblock"},
{ 2, {1,1,1,2}, 3, "techage:ta4_collider_pipe_inlet"},
{ 2, {1,1,1}, 3, "techage:ta4_collider_tube_inlet"},
{ 2, {1,1,1,0}, 0, "default:steelblock"},
-- front
{ 2, {3,3,2}, 0, "techage:ta4_detector_magnet"},
{ 2, {3,2}, 0, "techage:ta4_detector_magnet"},
{ 2, {2}, 0, "default:obsidian_glass"},
{ 2, {1,2}, 0, "techage:ta4_detector_magnet"},
{ 2, {1,1,2}, 0, "techage:ta4_detector_magnet"},
-- back
{ 2, {3,3,0}, 0, "techage:ta4_detector_magnet"},
{ 2, {3,0}, 0, "techage:ta4_detector_magnet"},
{ 2, {0}, 0, "default:steelblock"},
{ 2, {1,0}, 0, "techage:ta4_detector_magnet"},
{ 2, {1,1,0}, 0, "techage:ta4_detector_magnet"},
-- level 3
-- left/right
{ 3, {3,3,3,2}, 0, "default:steelblock"},
{ 3, {3,3,3}, 1, "techage:ta4_collider_cable_inlet"},
{ 3, {3,3,3,0}, 0, "default:steelblock"},
{ 3, {1,1,1,2}, 0, "default:steelblock"},
{ 3, {1,1,1}, 3, "techage:ta4_collider_cable_inlet"},
{ 3, {1,1,1,0}, 0, "default:steelblock"},
-- front
{ 3, {3,3,2}, 0, "default:steelblock"},
{ 3, {3,2}, 0, "default:steelblock"},
{ 3, {2}, 0, "default:steelblock"},
{ 3, {1,2}, 0, "default:steelblock"},
{ 3, {1,1,2}, 0, "default:steelblock"},
-- back
{ 3, {3,3,0}, 0, "default:steelblock"},
{ 3, {3,0}, 0, "default:steelblock"},
{ 3, {0}, 2, "techage:ta4_collider_pipe_inlet"},
{ 3, {1,0}, 0, "default:steelblock"},
{ 3, {1,1,0}, 0, "default:steelblock"},
-- middle
{ 3, {3,3}, 0, "techage:ta4_detector_magnet"},
{ 3, {3}, 0, "techage:ta4_detector_magnet"},
{ 3, {}, 0, "techage:ta4_collider_pipe_outlet"},
{ 3, {1}, 0, "techage:ta4_detector_magnet"},
{ 3, {1,1}, 0, "techage:ta4_detector_magnet"},
}
local t = {}
for name, cnt in pairs(techage.assemble.count_items(AssemblyPlan)) do
t[#t + 1] = " - " .. cnt .. " " .. name
end
local LABEL = table.concat(t, "\n")
local function build(pos, player_name)
minetest.chat_send_player(player_name, S("[TA4] Detector is being built!"))
local inv = M(pos):get_inventory()
techage.assemble.build_inv(pos, inv, AssemblyPlan, player_name)
end
local function remove(pos, player_name)
minetest.chat_send_player(player_name, S("[TA4] Detector is being removed!"))
local inv = M(pos):get_inventory()
techage.assemble.remove_inv(pos, inv, AssemblyPlan, player_name)
end
local function formspec()
return "size[8,8.2]"..
"list[context;src;5,0;3,3;]"..
"label[0.2,-0.2;" .. S("Item list") .. ":\n" .. LABEL .. "]" ..
"button_exit[0,3.5;4,1;build;" .. S("Build detector") .. "]" ..
"button_exit[4,3.5;4,1;remove;" .. S("Remove detector") .. "]" ..
"list[current_player;main;0,4.5;8,4;]"..
"listring[context;src]"..
"listring[current_player;main]"
end
minetest.register_node("techage:ta4_collider_detector_worker", {
description = S("TA4 Collider Detector Worker"),
tiles = {
-- up, down, right, left, back, front
"default_steel_block.png^techage_collider_detector_appl.png^techage_collider_detector_banner.png",
"default_steel_block.png^techage_collider_detector_banner.png",
"default_steel_block.png^techage_collider_detector_banner.png",
"default_steel_block.png^techage_collider_detector_banner.png",
"default_steel_block.png^techage_collider_detector_banner.png",
"default_steel_block.png^techage_collider_detector_appl.png^techage_collider_detector_banner.png",
},
drawtype = "nodebox",
paramtype2 = "facedir",
groups = {cracky = 1},
on_rotate = screwdriver.disallow,
is_ground_content = false,
sounds = default.node_sound_metal_defaults(),
after_place_node = function(pos, placer, itemstack)
if pos.y > (techage.collider_min_depth - 2) then
minetest.remove_node(pos)
minetest.add_item(pos, ItemStack("techage:ta4_collider_detector_worker"))
return
end
local inv = M(pos):get_inventory()
inv:set_size("src", 9)
M(pos):set_string("formspec", formspec())
end,
on_receive_fields = function(pos, formname, fields, player)
if minetest.is_protected(pos, player:get_player_name()) then
return
end
local nvm = techage.get_nvm(pos)
if fields.build then
if not nvm.assemble_locked then
build(pos, player:get_player_name())
end
elseif fields.remove then
if not nvm.assemble_locked then
remove(pos, player:get_player_name())
end
end
end,
after_dig_node = function(pos, oldnode)
techage.del_mem(pos)
end,
can_dig = function(pos, player)
if minetest.is_protected(pos, player:get_player_name()) then
return false
end
local nvm = techage.get_nvm(pos)
if nvm.assemble_locked or nvm.assemble_build then
minetest.after(30, function(pos)
local nvm = techage.get_nvm(pos)
nvm.assemble_locked = false
end, pos)
return false
end
local inv = M(pos):get_inventory()
return inv:is_empty("src")
end,
})
minetest.register_craft({
output = "techage:ta4_collider_detector_worker",
recipe = {
{'techage:aluminum', 'default:chest', 'default:steel_ingot'},
{'', 'basic_materials:gear_steel', ''},
{'default:steel_ingot', 'default:mese_crystal', 'techage:aluminum'},
},
})

View File

@ -25,12 +25,12 @@ local power = networks.power
local function turbine_cmnd(pos, topic, payload) local function turbine_cmnd(pos, topic, payload)
return techage.transfer(pos, "R", topic, payload, Pipe, return techage.transfer(pos, "R", topic, payload, Pipe,
{"techage:ta4_turbine", "techage:ta4_turbine_on"}) {"techage:ta4_turbine", "techage:ta4_turbine_on", "techage:ta4_collider_cooler"})
end end
local function inlet_cmnd(pos, topic, payload) local function inlet_cmnd(pos, topic, payload)
return techage.transfer(pos, "L", topic, payload, Pipe, return techage.transfer(pos, "L", topic, payload, Pipe,
{"techage:ta4_pipe_inlet"}) {"techage:ta4_pipe_inlet", "techage:ta4_collider_pipe_inlet"})
end end
minetest.register_node("techage:heatexchanger1", { minetest.register_node("techage:heatexchanger1", {
@ -83,7 +83,7 @@ techage.register_node({"techage:heatexchanger1"}, {
on_transfer = function(pos, indir, topic, payload) on_transfer = function(pos, indir, topic, payload)
local nvm = techage.get_nvm(pos) local nvm = techage.get_nvm(pos)
-- used by heatexchanger2 -- used by heatexchanger2
if topic == "diameter" or topic == "volume" or topic == "window" then if topic == "diameter" or topic == "volume" or topic == "window" or topic == "detector" then
return inlet_cmnd(pos, topic, payload) return inlet_cmnd(pos, topic, payload)
else else
return turbine_cmnd(pos, topic, payload) return turbine_cmnd(pos, topic, payload)

View File

@ -9,6 +9,7 @@
See LICENSE.txt for more information See LICENSE.txt for more information
TA4 Heat Exchanger2 (middle part) TA4 Heat Exchanger2 (middle part)
(alternatively used as cooler for the TA4 collider)
]]-- ]]--
@ -31,6 +32,7 @@ local PWR_CAPA = {
[9] = GRVL_CAPA * 7 * 7 * 7, -- 286 kuh [9] = GRVL_CAPA * 7 * 7 * 7, -- 286 kuh
} }
local DOWN = 5 local DOWN = 5
local PWR_NEEDED = 5
local function heatexchanger1_cmnd(pos, topic, payload) local function heatexchanger1_cmnd(pos, topic, payload)
return techage.transfer({x = pos.x, y = pos.y - 1, z = pos.z}, return techage.transfer({x = pos.x, y = pos.y - 1, z = pos.z},
@ -75,7 +77,25 @@ local function stop_sound(pos)
end end
end end
local function cooler_formspec(self, pos, nvm)
return "size[4,2]"..
"box[0,-0.1;3.8,0.5;#c6e8ff]" ..
"label[0.2,-0.1;" .. minetest.colorize( "#000000", S("TA4 Heat Exchanger")) .. "]" ..
"image_button[1.5,1;1,1;".. self:get_state_button_image(nvm) ..";state_button;]"..
"tooltip[1.5,1;1,1;"..self:get_state_tooltip(nvm).."]"
end
local function can_start(pos, nvm) local function can_start(pos, nvm)
-- Used as cooler for the collider?
if heatexchanger1_cmnd(pos, "detector") then
if power.power_available(pos, Cable, DOWN) then
nvm.used_as_cooler = true
return true
else
return S("No power")
end
end
-- Used as heat exchanger
local netID = networks.determine_netID(pos, Cable, DOWN) local netID = networks.determine_netID(pos, Cable, DOWN)
if heatexchanger1_cmnd(pos, "netID") ~= netID then if heatexchanger1_cmnd(pos, "netID") ~= netID then
return S("Power network connection error") return S("Power network connection error")
@ -97,21 +117,32 @@ local function can_start(pos, nvm)
end end
local function start_node(pos, nvm) local function start_node(pos, nvm)
if nvm.used_as_cooler then
play_sound(pos)
else
nvm.win_pos = heatexchanger1_cmnd(pos, "window") nvm.win_pos = heatexchanger1_cmnd(pos, "window")
power.start_storage_calc(pos, Cable, DOWN) power.start_storage_calc(pos, Cable, DOWN)
play_sound(pos) play_sound(pos)
heatexchanger1_cmnd(pos, "start") heatexchanger1_cmnd(pos, "start")
end end
end
local function stop_node(pos, nvm) local function stop_node(pos, nvm)
if nvm.used_as_cooler then
stop_sound(pos)
else
power.start_storage_calc(pos, Cable, DOWN) power.start_storage_calc(pos, Cable, DOWN)
stop_sound(pos) stop_sound(pos)
heatexchanger1_cmnd(pos, "stop") heatexchanger1_cmnd(pos, "stop")
end end
end
local function formspec(self, pos, nvm) local function formspec(self, pos, nvm)
local data local data
if nvm.used_as_cooler then
return cooler_formspec(self, pos, nvm)
end
if techage.is_running(nvm) then if techage.is_running(nvm) then
data = power.get_network_data(pos, Cable, DOWN) data = power.get_network_data(pos, Cable, DOWN)
end end
@ -135,11 +166,9 @@ local function check_TES_integrity(pos, nvm)
end end
if (nvm.ticks % 30) == 0 then -- every minute if (nvm.ticks % 30) == 0 then -- every minute
return heatexchanger1_cmnd(pos, "volume") return heatexchanger1_cmnd(pos, "volume")
end elseif (nvm.ticks % 30) == 10 then -- every minute
if (nvm.ticks % 30) == 10 then -- every minute return heatexchanger1_cmnd(pos, "diameter") ~= nil or S("inlet/pipe error")
return heatexchanger3_cmnd(pos, "diameter") ~= nil or S("inlet/pipe error") elseif (nvm.ticks % 30) == 20 then -- every minute
end
if (nvm.ticks % 30) == 20 then -- every minute
return heatexchanger3_cmnd(pos, "diameter") ~= nil or S("inlet/pipe error") return heatexchanger3_cmnd(pos, "diameter") ~= nil or S("inlet/pipe error")
end end
local netID = networks.determine_netID(pos, Cable, DOWN) local netID = networks.determine_netID(pos, Cable, DOWN)
@ -166,8 +195,38 @@ local State = techage.NodeStates:new({
formspec_func = formspec, formspec_func = formspec,
}) })
local function cooler_timer(pos, nvm)
local err = false
if power.consume_power(pos, Cable, DOWN, PWR_NEEDED) ~= PWR_NEEDED then
State:fault(pos, nvm, "No power")
stop_sound(pos)
return true
end
-- Cyclically check pipe connections
nvm.ticks = (nvm.ticks or 0) + 1
if (nvm.ticks % 5) == 0 then -- every 10 s
err = heatexchanger1_cmnd(pos, "detector") ~= true
elseif (nvm.ticks % 5) == 1 then -- every 10 s
err = heatexchanger3_cmnd(pos, "detector") ~= true
elseif (nvm.ticks % 5) == 2 then -- every 10 s
err = heatexchanger1_cmnd(pos, "cooler") ~= true
elseif (nvm.ticks % 5) == 3 then -- every 10 s
err = heatexchanger3_cmnd(pos, "cooler") ~= true
end
if err then
State:fault(pos, nvm, "Pipe connection error")
stop_sound(pos)
end
return true
end
local function node_timer(pos, elapsed) local function node_timer(pos, elapsed)
local nvm = techage.get_nvm(pos) local nvm = techage.get_nvm(pos)
if nvm.used_as_cooler then
cooler_timer(pos, nvm)
return true
end
local res = check_TES_integrity(pos, nvm) local res = check_TES_integrity(pos, nvm)
if res ~= true then if res ~= true then
State:fault(pos, nvm, res) State:fault(pos, nvm, res)

View File

@ -42,9 +42,14 @@ local function after_dig_node(pos, oldnode)
Pipe:after_dig_node(pos) Pipe:after_dig_node(pos)
end end
local function cooler_cmnd(pos, topic, payload)
return techage.transfer(pos, "R", topic, payload, Pipe,
{"techage:ta4_collider_cooler"})
end
local function inlet_cmnd(pos, topic, payload) local function inlet_cmnd(pos, topic, payload)
return techage.transfer(pos, "L", topic, payload, Pipe, return techage.transfer(pos, "L", topic, payload, Pipe,
{"techage:ta4_pipe_inlet"}) {"techage:ta4_pipe_inlet", "techage:ta4_collider_pipe_inlet"})
end end
minetest.register_node("techage:heatexchanger3", { minetest.register_node("techage:heatexchanger3", {
@ -77,7 +82,11 @@ Pipe:add_secondary_node_names({"techage:heatexchanger3"})
-- command interface, used by heatexchanger2 -- command interface, used by heatexchanger2
techage.register_node({"techage:heatexchanger3"}, { techage.register_node({"techage:heatexchanger3"}, {
on_transfer = function(pos, indir, topic, payload) on_transfer = function(pos, indir, topic, payload)
if topic == "cooler" then
return cooler_cmnd(pos, topic, payload)
else
return inlet_cmnd(pos, topic, payload) return inlet_cmnd(pos, topic, payload)
end
end, end,
}) })

View File

@ -55,6 +55,7 @@ techage.max_num_forceload_blocks = tonumber(minetest.settings:get("techage_max_n
techage.basalt_stone_enabled = minetest.settings:get_bool("techage_basalt_stone_enabled") ~= false techage.basalt_stone_enabled = minetest.settings:get_bool("techage_basalt_stone_enabled") ~= false
techage.ore_rarity = tonumber(minetest.settings:get("techage_ore_rarity")) or 1 techage.ore_rarity = tonumber(minetest.settings:get("techage_ore_rarity")) or 1
techage.modified_recipes_enabled = minetest.settings:get_bool("techage_modified_recipes_enabled") ~= false techage.modified_recipes_enabled = minetest.settings:get_bool("techage_modified_recipes_enabled") ~= false
techage.collider_min_depth = tonumber(minetest.settings:get("techage_collider_min_depth")) or -30
-- allow to load marshal and sqlite3 -- allow to load marshal and sqlite3
techage.IE = minetest.request_insecure_environment() techage.IE = minetest.request_insecure_environment()
@ -98,6 +99,7 @@ dofile(MP.."/basis/windturbine_lib.lua")
dofile(MP.."/basis/laser_lib.lua") dofile(MP.."/basis/laser_lib.lua")
dofile(MP.."/basis/legacy.lua") dofile(MP.."/basis/legacy.lua")
dofile(MP.."/basis/hyperloop.lua") dofile(MP.."/basis/hyperloop.lua")
dofile(MP.."/basis/oggfiles.lua")
-- Main doc -- Main doc
dofile(MP.."/doc/manual_DE.lua") dofile(MP.."/doc/manual_DE.lua")
@ -294,6 +296,7 @@ dofile(MP.."/move_controller/doorcontroller2.lua") -- new
dofile(MP.."/move_controller/movecontroller.lua") dofile(MP.."/move_controller/movecontroller.lua")
dofile(MP.."/move_controller/turncontroller.lua") dofile(MP.."/move_controller/turncontroller.lua")
dofile(MP.."/move_controller/flycontroller.lua") dofile(MP.."/move_controller/flycontroller.lua")
dofile(MP.."/move_controller/soundblock.lua")
-- Test -- Test
@ -377,6 +380,14 @@ dofile(MP.."/items/moreblocks.lua")
dofile(MP.."/carts/tank_cart.lua") dofile(MP.."/carts/tank_cart.lua")
dofile(MP.."/carts/chest_cart.lua") dofile(MP.."/carts/chest_cart.lua")
-- Collider
dofile(MP.."/collider/vacuumtube.lua")
dofile(MP.."/collider/magnet.lua")
dofile(MP.."/collider/inlets.lua")
dofile(MP.."/collider/cooler.lua")
dofile(MP.."/collider/detector.lua")
dofile(MP.."/collider/worker.lua")
-- Prevent other mods from using IE -- Prevent other mods from using IE
techage.IE = nil techage.IE = nil

View File

@ -53,3 +53,17 @@ techage.furnace.register_recipe({
}, },
time = 16, time = 16,
}) })
minetest.register_craftitem("techage:ta4_round_ceramic", {
description = S("TA4 Round Ceramic"),
inventory_image = "techage_round_ceramic.png",
})
techage.furnace.register_recipe({
output = "techage:ta4_round_ceramic 2",
recipe = {
"techage:ta4_ceramic_material", "techage:ta4_ceramic_material",
"techage:ta4_ceramic_material", "techage:ta4_ceramic_material",
},
time = 16,
})

View File

@ -56,6 +56,11 @@ local function pumping(pos, nvm, state, capa)
if taken > 0 then if taken > 0 then
local leftover = liquid.put(pos, Pipe, outdir, name, taken, mem.dbg_cycles > 0) local leftover = liquid.put(pos, Pipe, outdir, name, taken, mem.dbg_cycles > 0)
if leftover and leftover > 0 then if leftover and leftover > 0 then
-- air needs no tank
if name == "air" then
state:keep_running(pos, nvm, COUNTDOWN_TICKS)
return 0
end
liquid.untake(pos, Pipe, Flip[outdir], name, leftover) liquid.untake(pos, Pipe, Flip[outdir], name, leftover)
if leftover == taken then if leftover == taken then
state:blocked(pos, nvm) state:blocked(pos, nvm)

View File

@ -3,7 +3,7 @@
Terminal Terminal
======== ========
Copyright (C) 2018-2020 Joachim Stolberg Copyright (C) 2018-2021 Joachim Stolberg
AGPL v3 AGPL v3
See LICENSE.txt for more information See LICENSE.txt for more information
@ -15,22 +15,36 @@
local M = minetest.get_meta local M = minetest.get_meta
local S = techage.S local S = techage.S
local HELP_TA3 = "Syntax:\n".. local HELP_TA3 = [[ #### TA3 Terminal ####
" cmd <num> <cmnd>\n".. Send commands to machines and output the results.
"\n".. Local commands:
"like: cmd 181 on\n".. - Clear screen with 'clear'
"or: cmd 4573 state\n".. - Output this message with 'help'
"\n".. - Switch to public use of buttons with 'pub'
"Local commands:\n".. - Switch to private use of buttons with 'priv'
"- clear = clear screen\n".. - Program a user button with
"- help = this message\n".. 'set <button-num> <button-text> <command>'
"- pub = switch to public use of buttons\n".. Example: 'set 1 ON cmd 1234 on'
"- priv = switch to private use of buttons\n".. - send a command with 'cmd <num> <cmnd>'
"To program a user button with a command:\n".. Example: 'cmd 1234 on']]
" set <button-num> <button-text> <command>\n"..
"e.g.: set 1 ON cmd 123 on"
local CMNDS_TA3 = S("Syntax error, try help") local HELP_TA4 = [[ #### TA4 Terminal ####
Send commands to machines and output the results.
Local commands:
- Clear screen with 'clear'
- Output this message with 'help'
- Switch to public use of buttons with 'pub'
- Switch to private use of buttons with 'priv'
- Program a user button with
'set <button-num> <button-text> <command>'
Example: 'set 1 ON cmd 1234 on'
- send a command with 'cmd <num> <cmnd>'
Example: 'cmd 1234 on'
- Connect to a machine with 'connect <num>'
If connected, compact commands like 'status'
are possible.]]
local SYNTAX_ERR = S("Syntax error, try help")
local function get_string(meta, num, default) local function get_string(meta, num, default)
local s = meta:get_string("bttn_text"..num) local s = meta:get_string("bttn_text"..num)
@ -54,24 +68,28 @@ local function formspec2(meta)
local bttn_text7 = get_string(meta, 7, "User7") local bttn_text7 = get_string(meta, 7, "User7")
local bttn_text8 = get_string(meta, 8, "User8") local bttn_text8 = get_string(meta, 8, "User8")
local bttn_text9 = get_string(meta, 9, "User9") local bttn_text9 = get_string(meta, 9, "User9")
return "size[10,8]".. return "size[10,8.5]"..
default.gui_bg.. --"style_type[table,field;font=mono]"..
default.gui_bg_img.. "button[0,-0.2;3.3,1;bttn1;"..bttn_text1.."]button[3.3,-0.2;3.3,1;bttn2;"..bttn_text2.."]button[6.6,-0.2;3.3,1;bttn3;"..bttn_text3.."]"..
default.gui_slots.. "button[0,0.6;3.3,1;bttn4;"..bttn_text4.."]button[3.3,0.6;3.3,1;bttn5;"..bttn_text5.."]button[6.6,0.6;3.3,1;bttn6;"..bttn_text6.."]"..
"style_type[table,field;font=mono]".. "button[0,1.4;3.3,1;bttn7;"..bttn_text7.."]button[3.3,1.4;3.3,1;bttn8;"..bttn_text8.."]button[6.6,1.4;3.3,1;bttn9;"..bttn_text9.."]"..
"button[0,0;3.3,1;bttn1;"..bttn_text1.."]button[3.3,0;3.3,1;bttn2;"..bttn_text2.."]button[6.6,0;3.3,1;bttn3;"..bttn_text3.."]".. "table[0,2.3;9.8,5.6;output;"..output..";200]"..
"button[0,0.8;3.3,1;bttn4;"..bttn_text4.."]button[3.3,0.8;3.3,1;bttn5;"..bttn_text5.."]button[6.6,0.8;3.3,1;bttn6;"..bttn_text6.."]".. "field[0.4,8.2;7.6,1;cmnd;;"..command.."]" ..
"button[0,1.6;3.3,1;bttn7;"..bttn_text7.."]button[3.3,1.6;3.3,1;bttn8;"..bttn_text8.."]button[6.6,1.6;3.3,1;bttn9;"..bttn_text9.."]"..
"table[0,2.5;9.8,4.7;output;"..output..";200]"..
"field[0.4,7.7;7.6,1;cmnd;;"..command.."]" ..
"field_close_on_enter[cmnd;false]".. "field_close_on_enter[cmnd;false]"..
"button[7.9,7.4;2,1;ok;"..S("Enter").."]" "button[7.9,7.9;2,1;ok;"..S("Enter").."]"
end end
local function output(pos, text) local function output(pos, text)
local meta = minetest.get_meta(pos) local meta = minetest.get_meta(pos)
text = meta:get_string("output") .. "\n" .. (text or "") text = meta:get_string("output") .. "\n" .. (text or "")
text = text:sub(-500,-1) text = text:sub(-1000,-1)
meta:set_string("output", text)
meta:set_string("formspec", formspec2(meta))
end
local function append(pos, text)
local meta = minetest.get_meta(pos)
text = meta:get_string("output") .. (text or "")
meta:set_string("output", text) meta:set_string("output", text)
meta:set_string("formspec", formspec2(meta)) meta:set_string("formspec", formspec2(meta))
end end
@ -84,61 +102,7 @@ local function get_line_text(pos, num)
return line:gsub("^[%s$]*(.-)%s*$", "%1") return line:gsub("^[%s$]*(.-)%s*$", "%1")
end end
local function server_debug(pos, command, player)
local function command(pos, command, player)
local meta = minetest.get_meta(pos)
local owner = meta:get_string("owner") or ""
if command then
command = command:sub(1,80)
command = string.trim(command)
if command == "clear" then
meta:set_string("output", "")
meta:set_string("formspec", formspec2(meta))
elseif command == "help" then
local meta = minetest.get_meta(pos)
meta:set_string("output", HELP_TA3)
meta:set_string("formspec", formspec2(meta))
elseif command == "pub" then
meta:set_int("public", 1)
output(pos, player..":$ "..command)
output(pos, S("Switched to public use!"))
elseif command == "priv" then
meta:set_int("public", 0)
output(pos, player..":$ "..command)
output(pos, S("Switched to private use!"))
else
output(pos, "$ "..command)
local own_num = meta:get_string("node_number")
local num, cmnd, payload = command:match('^cmd%s+([0-9]+)%s+(%w+)%s*(.*)$')
if num and cmnd then
if techage.not_protected(num, owner, owner) then
local resp = techage.send_single(own_num, num, cmnd, payload)
if type(resp) == "string" then
output(pos, resp)
else
output(pos, dump(resp))
end
end
return
end
num, cmnd = command:match('^turn%s+([0-9]+)%s+([onf]+)$')
if num and (cmnd == "on" or cmnd == "off") then
if techage.not_protected(num, owner, owner) then
local resp = techage.send_single(own_num, num, cmnd)
output(pos, dump(resp))
end
return
end
local bttn_num, label, cmnd = command:match('^set%s+([1-9])%s+([%w_]+)%s+(.+)$')
if bttn_num and label and cmnd then
meta:set_string("bttn_text"..bttn_num, label)
meta:set_string("bttn_cmnd"..bttn_num, cmnd)
meta:set_string("formspec", formspec2(meta))
return
end
local cmnd, payload = command:match('^pipe%s+([%w_]+)%s*(.*)$') local cmnd, payload = command:match('^pipe%s+([%w_]+)%s*(.*)$')
if cmnd then if cmnd then
if not minetest.check_player_privs(player, "server") then if not minetest.check_player_privs(player, "server") then
@ -153,10 +117,10 @@ local function command(pos, command, player)
techage.LiquidPipe, -- network techage.LiquidPipe, -- network
nil) -- valid nodes nil) -- valid nodes
output(pos, dump(resp)) output(pos, dump(resp))
return return true
end end
local cmnd, payload = command:match('^axle%s+([%w_]+)%s*(.*)$') cmnd, payload = command:match('^axle%s+([%w_]+)%s*(.*)$')
if cmnd then if cmnd then
if not minetest.check_player_privs(player, "server") then if not minetest.check_player_privs(player, "server") then
output(pos, "server privs missing") output(pos, "server privs missing")
@ -170,12 +134,126 @@ local function command(pos, command, player)
techage.TA1Axle, -- network techage.TA1Axle, -- network
nil) -- valid nodes nil) -- valid nodes
output(pos, dump(resp)) output(pos, dump(resp))
return true
end
cmnd, payload = command:match('^vtube%s+([%w_]+)%s*(.*)$')
if cmnd then
if not minetest.check_player_privs(player, "server") then
output(pos, "server privs missing")
return
end
local resp = techage.transfer(
pos,
"B", -- outdir
cmnd, -- topic
payload, -- payload
techage.VTube, -- network
nil) -- valid nodes
output(pos, dump(resp))
return true
end
end
local function command(pos, command, player, is_ta4)
local meta = minetest.get_meta(pos)
local owner = meta:get_string("owner") or ""
command = command:sub(1,80)
command = string.trim(command)
local cmnd, data = command:match('^(%w+)%s*(.*)$')
if cmnd == "clear" then
meta:set_string("output", "")
meta:set_string("formspec", formspec2(meta))
elseif cmnd == "" then
output(pos, "$")
elseif cmnd == "help" then
if is_ta4 then
output(pos, HELP_TA4)
else
output(pos, HELP_TA3)
end
elseif cmnd == "pub" then
meta:set_int("public", 1)
output(pos, "$ "..command)
output(pos, "Switched to public buttons!")
elseif cmnd == "priv" then
meta:set_int("public", 0)
output(pos, "$ "..command)
output(pos, "Switched to private buttons!")
elseif cmnd == "connect" and data then
output(pos, "$ "..command)
if techage.not_protected(data, owner, owner) then
local own_num = meta:get_string("node_number")
local resp = techage.send_single(own_num, data, cmnd)
if resp then
meta:set_string("connected_to", data)
output(pos, "Connected.")
else
meta:set_string("connected_to", "")
output(pos, "Not connected!")
end
else
output(pos, "Protection error!")
end
else
output(pos, "$ "..command)
local own_num = meta:get_string("node_number")
local connected_to = meta:contains("connected_to") and meta:get_string("connected_to")
local bttn_num, label, num, cmnd, payload
num, cmnd, payload = command:match('^cmd%s+([0-9]+)%s+(%w+)%s*(.*)$')
if num and cmnd then
if techage.not_protected(num, owner, owner) then
local resp = techage.send_single(own_num, num, cmnd, payload)
if type(resp) == "string" then
output(pos, resp)
else
output(pos, dump(resp))
end
end
return return
end end
if command ~= "" then num, cmnd = command:match('^turn%s+([0-9]+)%s+([onf]+)$')
output(pos, CMNDS_TA3) if num and (cmnd == "on" or cmnd == "off") then
if techage.not_protected(num, owner, owner) then
local resp = techage.send_single(own_num, num, cmnd)
output(pos, dump(resp))
end end
return
end
bttn_num, label, cmnd = command:match('^set%s+([1-9])%s+([%w_]+)%s+(.+)$')
if bttn_num and label and cmnd then
meta:set_string("bttn_text"..bttn_num, label)
meta:set_string("bttn_cmnd"..bttn_num, cmnd)
meta:set_string("formspec", formspec2(meta))
return
end
if server_debug(pos, command, player) then
return
end
if connected_to then
local cmnd, payload = command:match('^(%w+)%s*(.*)$')
if cmnd then
local resp = techage.send_single(own_num, connected_to, cmnd, payload)
if resp ~= true then
if type(resp) == "string" then
output(pos, resp)
else
output(pos, dump(resp))
end
end
return
end
end
if command ~= "" then
output(pos, SYNTAX_ERR)
end end
end end
end end
@ -186,9 +264,9 @@ local function send_cmnd(pos, meta, num)
command(pos, cmnd, owner) command(pos, cmnd, owner)
end end
local function register_terminal(num, tiles, node_box, selection_box) local function register_terminal(name, description, tiles, node_box, selection_box)
minetest.register_node("techage:terminal"..num, { minetest.register_node("techage:"..name, {
description = S("TA3 Terminal"), description = description,
tiles = tiles, tiles = tiles,
drawtype = "nodebox", drawtype = "nodebox",
node_box = node_box, node_box = node_box,
@ -201,7 +279,7 @@ local function register_terminal(num, tiles, node_box, selection_box)
meta:set_string("command", S("commands like: help")) meta:set_string("command", S("commands like: help"))
meta:set_string("formspec", formspec2(meta)) meta:set_string("formspec", formspec2(meta))
meta:set_string("owner", placer:get_player_name()) meta:set_string("owner", placer:get_player_name())
meta:set_string("infotext", S("TA3 Terminal") .. " " .. number) meta:set_string("infotext", description .. " " .. number)
end, end,
on_receive_fields = function(pos, formname, fields, player) on_receive_fields = function(pos, formname, fields, player)
@ -216,11 +294,21 @@ local function register_terminal(num, tiles, node_box, selection_box)
meta:set_string("command", s) meta:set_string("command", s)
meta:set_string("formspec", formspec2(meta)) meta:set_string("formspec", formspec2(meta))
return return
elseif (fields.key_enter == "true" or fields.ok) and fields.cmnd ~= "" then elseif (fields.ok or fields.key_enter_field) and fields.cmnd then
command(pos, fields.cmnd, player:get_player_name()) local is_ta4 = string.find(description, "TA4")
command(pos, fields.cmnd, player:get_player_name(), is_ta4)
techage.historybuffer_add(pos, fields.cmnd)
meta:set_string("command", "") meta:set_string("command", "")
meta:set_string("formspec", formspec2(meta)) meta:set_string("formspec", formspec2(meta))
return return
elseif fields.key_up then
meta:set_string("command", techage.historybuffer_priv(pos))
meta:set_string("formspec", formspec2(meta))
return
elseif fields.key_down then
meta:set_string("command", techage.historybuffer_next(pos))
meta:set_string("formspec", formspec2(meta))
return
end end
end end
if public or not protected then if public or not protected then
@ -251,7 +339,7 @@ local function register_terminal(num, tiles, node_box, selection_box)
}) })
end end
register_terminal("2", { register_terminal("terminal2", S("TA3 Terminal"), {
-- up, down, right, left, back, front -- up, down, right, left, back, front
'techage_terminal2_top.png', 'techage_terminal2_top.png',
'techage_terminal2_side.png', 'techage_terminal2_side.png',
@ -277,7 +365,33 @@ register_terminal("2", {
fixed = { fixed = {
{-12/32, -16/32, -4/32, 12/32, 6/32, 16/32}, {-12/32, -16/32, -4/32, 12/32, 6/32, 16/32},
}, },
}) }
)
register_terminal("terminal3", S("TA4 Terminal"), {
-- up, down, right, left, back, front
'techage_terminal1_top.png',
'techage_terminal1_bottom.png',
'techage_terminal1_side.png',
'techage_terminal1_side.png',
'techage_terminal1_bottom.png',
"techage_terminal1_front.png",
},
{
type = "fixed",
fixed = {
{-12/32, -16/32, -8/32, 12/32, -14/32, 12/32},
{-12/32, -14/32, 12/32, 12/32, 6/32, 14/32},
},
},
{
type = "fixed",
fixed = {
{-12/32, -16/32, -8/32, 12/32, -14/32, 12/32},
{-12/32, -14/32, 12/32, 12/32, 6/32, 14/32},
},
}
)
minetest.register_craft({ minetest.register_craft({
output = "techage:terminal2", output = "techage:terminal2",
@ -288,6 +402,15 @@ minetest.register_craft({
}, },
}) })
minetest.register_craft({
output = "techage:terminal3",
recipe = {
{"techage:basalt_glass_thin", "", ""},
{"techage:ta4_leds", "", ""},
{"techage:aluminum", "techage:ta4_wlanchip", "techage:ta4_ramchip"},
},
})
techage.register_node({"techage:terminal2"}, { techage.register_node({"techage:terminal2"}, {
on_recv_message = function(pos, src, topic, payload) on_recv_message = function(pos, src, topic, payload)
output(pos, "src="..src..", cmd="..dump(topic)..", data="..dump(payload)) output(pos, "src="..src..", cmd="..dump(topic)..", data="..dump(payload))
@ -302,3 +425,16 @@ techage.register_node({"techage:terminal2"}, {
end end
end, end,
}) })
techage.register_node({"techage:terminal3"}, {
on_recv_message = function(pos, src, topic, payload)
if topic == "text" then
output(pos, payload)
elseif topic == "append" then
append(pos, payload)
else
output(pos, "src="..src..", cmd="..dump(topic)..", data="..dump(payload))
end
return true
end,
})

View File

@ -47,18 +47,20 @@ local WRENCH_MENU = {
local function formspec(nvm, meta) local function formspec(nvm, meta)
local status = meta:get_string("status") local status = meta:get_string("status")
local path = meta:contains("path") and meta:get_string("path") or "0,3,0" local path = meta:contains("path") and meta:get_string("path") or "0,3,0"
return "size[8,7]" .. return "size[8,6.7]" ..
"style_type[textarea;font=mono;textcolor=#FFFFFF;border=true]" .. "style_type[textarea;font=mono;textcolor=#FFFFFF;border=true]" ..
"box[0,-0.1;7.2,0.5;#c6e8ff]" .. "box[0,-0.1;7.2,0.5;#c6e8ff]" ..
"label[0.2,-0.1;" .. minetest.colorize( "#000000", S("TA5 Fly Controller")) .. "]" .. "label[0.2,-0.1;" .. minetest.colorize( "#000000", S("TA5 Fly Controller")) .. "]" ..
techage.wrench_image(7.4, -0.05) .. techage.wrench_image(7.4, -0.05) ..
"button[0.1,0.7;3.8,1;record;" .. S("Record") .. "]" .. "button[0.1,0.7;3.8,1;record;" .. S("Record") .. "]" ..
"button[4.1,0.7;3.8,1;done;" .. S("Done") .. "]" .. "button[4.1,0.7;3.8,1;done;" .. S("Done") .. "]" ..
"textarea[0.4,2.1;3.8,3.8;path;" .. S("Move path (A to B)") .. ";"..path.."]" .. "textarea[0.4,2.1;3.8,4.4;path;" .. S("Move path (A to B)") .. ";"..path.."]" ..
"button[4.1,3.2;3.8,1;store;" .. S("Store") .. "]" .. "button[4.1,1.8;3.8,1;store;" .. S("Store") .. "]" ..
"button[0.1,5.5;3.8,1;moveAB;" .. S("Move A-B") .. "]" .. "button[4.1,2.6;3.8,1;test;" .. S("Test") .. "]" ..
"button[4.1,5.5;3.8,1;moveBA;" .. S("Move B-A") .. "]" .. "button[4.1,3.4;3.8,1;moveAB;" .. S("Move A-B") .. "]" ..
"label[0.3,6.5;" .. status .. "]" "button[4.1,4.2;3.8,1;moveBA;" .. S("Move B-A") .. "]" ..
"button[4.1,5.0;3.8,1;move;" .. S("Move") .. "]" ..
"label[0.3,6.3;" .. status .. "]"
end end
@ -110,17 +112,46 @@ minetest.register_node("techage:ta5_flycontroller", {
mark.stop(name) mark.stop(name)
meta:set_string("formspec", formspec(nvm, meta)) meta:set_string("formspec", formspec(nvm, meta))
elseif fields.store then elseif fields.store then
if fly.to_path(fields.path, MAX_DIST) then local _, err = fly.to_path(fields.path, MAX_DIST)
if not err then
meta:set_string("path", fields.path) meta:set_string("path", fields.path)
meta:set_string("status", S("Stored")) meta:set_string("status", S("Stored"))
else else
meta:set_string("status", S("Error: Invalid path !!")) meta:set_string("status", err)
end end
meta:set_string("formspec", formspec(nvm, meta)) meta:set_string("formspec", formspec(nvm, meta))
local name = player:get_player_name() local name = player:get_player_name()
mark.stop(name) mark.stop(name)
nvm.moveBA = false nvm.moveBA = false
nvm.running = true nvm.running = true
elseif fields.test then
local path, err = fly.to_path(fields.path, MAX_DIST)
if err then
meta:set_string("status", err)
elseif path and nvm.lpos1 then
local pos = table.copy(nvm.lpos1[1])
if pos then
for _, offs in ipairs(path) do
local pos2 = vector.add(pos, offs)
local s = string.format("[TA4 Fly Controller] %s + %s = %s", P2S(pos), P2S(offs), P2S(pos2))
minetest.chat_send_player(player:get_player_name(), s)
pos = pos2
end
meta:set_string("status", S("See chat output"))
else
minetest.chat_send_player(player:get_player_name(), S("[TA4 Fly Controller] Recording is missing!"))
meta:set_string("status", S("Error: Recording is missing !!"))
end
else
if nvm.lpos1 then
minetest.chat_send_player(player:get_player_name(), S("[TA4 Fly Controller] Invalid path!"))
meta:set_string("status", S("Error: Invalid path !!"))
else
minetest.chat_send_player(player:get_player_name(), S("[TA4 Fly Controller] Recording is missing!"))
meta:set_string("status", S("Error: Recording is missing !!"))
end
end
meta:set_string("formspec", formspec(nvm, meta))
elseif fields.moveAB then elseif fields.moveAB then
meta:set_string("status", "") meta:set_string("status", "")
if fly.move_to_other_pos(pos, false) then if fly.move_to_other_pos(pos, false) then
@ -139,6 +170,16 @@ minetest.register_node("techage:ta5_flycontroller", {
mark.stop(name) mark.stop(name)
end end
meta:set_string("formspec", formspec(nvm, meta)) meta:set_string("formspec", formspec(nvm, meta))
elseif fields.move then
meta:set_string("status", "")
nvm.moveBA = nvm.moveBA == false
if fly.move_to_other_pos(pos, nvm.moveBA == false) then
nvm.running = true
meta:set_string("formspec", formspec(nvm, meta))
local name = player:get_player_name()
mark.stop(name)
end
meta:set_string("formspec", formspec(nvm, meta))
end end
end, end,

View File

@ -0,0 +1,128 @@
--[[
TechAge
=======
Copyright (C) 2021 Joachim Stolberg
AGPL v3
See LICENSE.txt for more information
Sound Block
]]--
-- for lazy programmers
local M = minetest.get_meta
local S = techage.S
local t = {}
for idx, ogg in ipairs(techage.OggFileList) do
t[idx] = idx .. "," .. ogg
end
local OGG_FILES = table.concat(t, ",")
local logic = techage.logic
local GAIN = {0.05 ,0.1, 0.2, 0.5, 1.0}
local function play_sound(pos, ogg, gain)
minetest.sound_play(ogg, {
pos = pos,
gain = GAIN[gain or 1] or 1,
max_hear_distance = 15})
end
local function formspec(meta)
local idx = meta:contains("idx") and meta:get_int("idx") or 1
local gain = meta:contains("gain") and meta:get_int("gain") or 1
return "size[8,8]"..
"tablecolumns[text,width=5;text]"..
"table[0,0;8,6;oggfiles;" .. OGG_FILES .. ";" .. idx .. "]" ..
"dropdown[0,6.5;5.5,1.4;gain;1,2,3,4,5;" .. gain .. "]" ..
"button[2.5,7.2;3,1;play;" .. S("Play") .. "]"
end
minetest.register_node("techage:ta3_soundblock", {
description = S("TA3 Sound Block"),
tiles = {
-- up, down, right, left, back, front
"techage_filling_ta3.png^techage_frame_ta3_top.png",
"techage_filling_ta3.png^techage_frame_ta3_top.png",
"techage_filling_ta3.png^techage_frame_ta3.png^techage_appl_sound.png",
},
after_place_node = function(pos, placer)
local meta = M(pos)
logic.after_place_node(pos, placer, "techage:ta3_soundblock", S("TA3 Sound Block"))
logic.infotext(meta, S("TA3 Sound Block"))
meta:set_string("formspec", formspec(meta))
end,
on_receive_fields = function(pos, formname, fields, player)
if minetest.is_protected(pos, player:get_player_name()) then
return
end
if fields.oggfiles then
local mem = techage.get_mem(pos)
local t = minetest.explode_table_event(fields.oggfiles)
mem.idx = t.row
end
if fields.gain then
M(pos):set_int("gain", tonumber(fields.gain) or 1)
end
if fields.play then
local mem = techage.get_mem(pos)
M(pos):set_int("idx", mem.idx or 1)
local ogg = techage.OggFileList[mem.idx or 1] or techage.OggFileList[1]
play_sound(pos, ogg, M(pos):get_int("gain"))
end
end,
paramtype2 = "facedir",
groups = {choppy=2, cracky=2, crumbly=2},
is_ground_content = false,
sounds = default.node_sound_wood_defaults(),
})
local INFO = [[Commands: 'on', 'sound', 'gain']]
techage.register_node({"techage:ta3_soundblock"}, {
on_recv_message = function(pos, src, topic, payload)
if topic == "info" then
return INFO
elseif topic == "on" then
local mem = techage.get_mem(pos)
if not mem.blocking_time or (mem.blocking_time < minetest.get_gametime()) then
local idx = M(pos):get_int("idx")
local ogg = techage.OggFileList[idx or 1] or techage.OggFileList[1]
local gain = M(pos):get_float("gain")
play_sound(pos, ogg, gain)
mem.blocking_time = minetest.get_gametime() + 2
return true
end
elseif topic == "sound" then
M(pos):get_int("idx", tonumber(payload or 1) or 1)
elseif topic == "gain" then
M(pos):get_int("gain", tonumber(payload or 1) or 1)
else
return "unsupported"
end
end,
on_node_load = function(pos)
local meta = M(pos)
meta:set_string("formspec", formspec(meta))
end
})
minetest.register_craft({
output = "techage:ta3_soundblock",
recipe = {
{"", "group:wood",""},
{"techage:vacuum_tube", "basic_materials:gold_wire", "techage:usmium_nuggets"},
{"", "group:wood", ""},
},
})

View File

@ -30,3 +30,7 @@ techage_use_sqlite (use sqlite database) bool false
# To reduce the server CPU load, the number of sent techage commands # To reduce the server CPU load, the number of sent techage commands
# per player and minute can be limited. # per player and minute can be limited.
techage_command_limit (Max. number of commands sent per minute) int 1200 techage_command_limit (Max. number of commands sent per minute) int 1200
# Colliders are huge systems and should not be built on the surface.
# 'techage_collider_min_depth specifies' the min. depth (Y) to build a TA4 Collider
techage_collider_min_depth (Min. depth to build a TA4 Collider) int -30

BIN
sounds/techage_hum.ogg Normal file

Binary file not shown.

Binary file not shown.

View File

@ -271,7 +271,7 @@ minetest.register_entity("techage:ta1_watermill_entity", {
stop_wheel(pos, self) stop_wheel(pos, self)
end end
trigger_consumer(pos, self.facedir) trigger_consumer(pos, self.facedir)
minetest.sound_play("techage_watermill", {gain = 0.3, pos = pos, minetest.sound_play("techage_watermill", {gain = 0.5, pos = pos,
max_hear_distance = 10}, true) max_hear_distance = 10}, true)
end end
end, end,

Binary file not shown.

After

Width:  |  Height:  |  Size: 146 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 135 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 124 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 490 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 168 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 153 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 138 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 123 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 585 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 223 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 289 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 435 B