Add recipeblock and mba_detector, improve ta4 pump and ta4 autocrafter
This commit is contained in:
parent
a2d39706cf
commit
fea1a6981c
@ -189,6 +189,17 @@ local function normalize(item_list)
|
||||
return item_list
|
||||
end
|
||||
|
||||
local function get_input_from_recipeblock(pos, number, idx)
|
||||
local own_num = M(pos):get_string("node_number")
|
||||
local owner = M(pos):get_string("owner")
|
||||
if techage.check_numbers(number, owner) then
|
||||
local input = techage.send_single(own_num, number, "input", idx)
|
||||
if input and type(input) == "string" then
|
||||
return input
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function on_output_change(pos, inventory, stack)
|
||||
if not stack then
|
||||
inventory:set_list("output", {})
|
||||
@ -212,6 +223,47 @@ local function on_output_change(pos, inventory, stack)
|
||||
after_recipe_change(pos, inventory)
|
||||
end
|
||||
|
||||
local function determine_recipe_items(pos, input)
|
||||
if input and type(input) == "string" then
|
||||
-- Test if "<node-number>.<recipe-number>" input
|
||||
local num, idx = unpack(string.split(input, ".", false, 1))
|
||||
if num and idx then
|
||||
input = get_input_from_recipeblock(pos, num, idx)
|
||||
end
|
||||
|
||||
if input then
|
||||
-- "<item>,<item>,..." input
|
||||
local items = string.split(input, ",", true, 8)
|
||||
if items and type(items) == "table" and next(items) then
|
||||
return items
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function on_new_recipe(pos, input)
|
||||
local items = determine_recipe_items(pos, input)
|
||||
if items then
|
||||
input = {
|
||||
method = "normal",
|
||||
width = 3,
|
||||
items = items,
|
||||
}
|
||||
local output, _ = minetest.get_craft_result(input)
|
||||
if output.item:get_name() ~= "" then
|
||||
local inv = M(pos):get_inventory()
|
||||
for i = 1, 9 do
|
||||
inv:set_stack("recipe", i, input.items[i])
|
||||
end
|
||||
after_recipe_change(pos, inv)
|
||||
end
|
||||
else
|
||||
local inv = M(pos):get_inventory()
|
||||
inv:set_list("recipe", {})
|
||||
after_recipe_change(pos, inv)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local function allow_metadata_inventory_put(pos, listname, index, stack, player)
|
||||
if minetest.is_protected(pos, player:get_player_name()) then
|
||||
@ -346,6 +398,8 @@ tiles.act = {
|
||||
},
|
||||
}
|
||||
|
||||
local INFO = [[Commands: 'state', 'recipe']]
|
||||
|
||||
local tubing = {
|
||||
on_inv_request = function(pos, in_dir, access_type)
|
||||
if access_type == "push" then
|
||||
@ -378,7 +432,20 @@ local tubing = {
|
||||
end
|
||||
end,
|
||||
on_recv_message = function(pos, src, topic, payload)
|
||||
return CRD(pos).State:on_receive_message(pos, topic, payload)
|
||||
if topic == "recipe" and CRD(pos).stage == 4 then
|
||||
if payload and payload ~= "" then
|
||||
local inv = M(pos):get_inventory()
|
||||
on_new_recipe(pos, payload)
|
||||
return true
|
||||
else
|
||||
local inv = M(pos):get_inventory()
|
||||
return inv:get_stack("output", 1):get_name()
|
||||
end
|
||||
elseif topic == "info" and CRD(pos).stage == 4 then
|
||||
return INFO
|
||||
else
|
||||
return CRD(pos).State:on_receive_message(pos, topic, payload)
|
||||
end
|
||||
end,
|
||||
on_node_load = function(pos)
|
||||
CRD(pos).State:on_node_load(pos)
|
||||
@ -410,7 +477,7 @@ local node_name_ta2, node_name_ta3, node_name_ta4 =
|
||||
num_items = {0,1,2,4},
|
||||
power_consumption = {0,4,6,9},
|
||||
},
|
||||
{false, true, true, false}) -- TA2/TA3
|
||||
{false, true, true, true}) -- TA2/TA3/TA4
|
||||
|
||||
minetest.register_craft({
|
||||
output = node_name_ta2,
|
||||
@ -430,9 +497,18 @@ minetest.register_craft({
|
||||
},
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = node_name_ta4,
|
||||
recipe = {
|
||||
{"", "default:diamond", ""},
|
||||
{"", node_name_ta3, ""},
|
||||
{"", "techage:ta4_wlanchip", ""},
|
||||
},
|
||||
})
|
||||
|
||||
local Cable = techage.ElectricCable
|
||||
local power = networks.power
|
||||
|
||||
techage.register_node_for_v1_transition({"techage:ta3_autocrafter_pas"}, function(pos, node)
|
||||
techage.register_node_for_v1_transition({"techage:ta3_autocrafter_pas", "techage:ta4_autocrafter_pas"}, function(pos, node)
|
||||
power.update_network(pos, nil, Cable)
|
||||
end)
|
||||
end)
|
||||
|
244
basic_machines/recipeblock.lua
Normal file
244
basic_machines/recipeblock.lua
Normal file
@ -0,0 +1,244 @@
|
||||
--[[
|
||||
|
||||
TechAge
|
||||
=======
|
||||
|
||||
Copyright (C) 2019-2021 Joachim Stolberg
|
||||
|
||||
AGPL v3
|
||||
See LICENSE.txt for more information
|
||||
|
||||
TA4 Recipe Block for the TA4 Autocrafter
|
||||
]]--
|
||||
|
||||
-- for lazy programmers
|
||||
local P2S = function(pos) if pos then return minetest.pos_to_string(pos) end end
|
||||
local S2P = minetest.string_to_pos
|
||||
local M = minetest.get_meta
|
||||
local S = techage.S
|
||||
|
||||
local MAX_RECIPE = 10
|
||||
|
||||
local function recipes_formspec(x, y, idx)
|
||||
return "container[" .. x .. "," .. y .. "]" ..
|
||||
"background[0,0;8,3.2;techage_form_grey.png]" ..
|
||||
"list[context;input;0.1,0.1;3,3;]" ..
|
||||
"image[3,1.1;1,1;techage_form_arrow.png]" ..
|
||||
"list[context;output;3.9,1.1;1,1;]" ..
|
||||
"button[5.5,1.1;1,1;priv;<<]" ..
|
||||
"button[6.5,1.1;1,1;next;>>]" ..
|
||||
"label[5.5,0.5;"..S("Recipe") .. ": " .. idx .. "/" .. MAX_RECIPE .. "]" ..
|
||||
"container_end[]"
|
||||
end
|
||||
|
||||
local function formspec(pos, nvm)
|
||||
return "size[8,7.4]"..
|
||||
recipes_formspec(0, 0, nvm.recipe_idx or 1) ..
|
||||
"list[current_player;main;0,3.6;8,4;]" ..
|
||||
"listring[current_player;main]"..
|
||||
"listring[context;src]" ..
|
||||
"listring[current_player;main]"..
|
||||
"listring[context;dst]" ..
|
||||
"listring[current_player;main]"
|
||||
end
|
||||
|
||||
local function determine_new_input(pos, inv)
|
||||
local output = inv:get_stack("output", 1):get_name()
|
||||
if output and output ~= "" then
|
||||
local recipe = minetest.get_craft_recipe(output)
|
||||
if recipe.items and recipe.type == "normal" then
|
||||
for i = 1, 9 do
|
||||
local name = recipe.items[i]
|
||||
if name then
|
||||
if minetest.registered_items[name] then
|
||||
inv:set_stack("input", i, name)
|
||||
end
|
||||
end
|
||||
end
|
||||
inv:set_stack("output", 1, recipe.output)
|
||||
end
|
||||
else
|
||||
for i = 1, 9 do
|
||||
inv:set_stack("input", i, nil)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function determine_new_output(pos, inv)
|
||||
local items = {}
|
||||
for i = 1, 9 do
|
||||
items[i] = inv:get_stack("input", i):get_name()
|
||||
end
|
||||
local input = {
|
||||
method = "normal",
|
||||
width = 3,
|
||||
items = items,
|
||||
}
|
||||
local output, _ = minetest.get_craft_result(input)
|
||||
inv:set_stack("output", 1, output.item)
|
||||
end
|
||||
|
||||
local function get_recipe(inv)
|
||||
local items = {}
|
||||
local last_idx = 0
|
||||
for i = 1, 9 do
|
||||
local name = inv:get_stack("input", i):get_name()
|
||||
if name ~= "" then
|
||||
last_idx = i
|
||||
end
|
||||
items[i] = name
|
||||
end
|
||||
local input = table.concat(items, ",", 1, last_idx)
|
||||
local stack = inv:get_stack("output", 1)
|
||||
return {
|
||||
input = input,
|
||||
output = stack:get_name() .. " " .. stack:get_count()
|
||||
}
|
||||
end
|
||||
|
||||
local function after_recipe_change(pos, inv, listname)
|
||||
if listname == "input" then
|
||||
determine_new_output(pos, inv)
|
||||
else
|
||||
determine_new_input(pos, inv)
|
||||
end
|
||||
local nvm = techage.get_nvm(pos)
|
||||
nvm.recipes = nvm.recipes or {}
|
||||
nvm.recipes[nvm.recipe_idx or 1] = get_recipe(inv)
|
||||
end
|
||||
|
||||
local function update_inventor(pos, inv, idx)
|
||||
local nvm = techage.get_nvm(pos)
|
||||
nvm.recipes = nvm.recipes or {}
|
||||
local recipe = nvm.recipes[idx]
|
||||
if recipe then
|
||||
local items = string.split(recipe.input, ",", true)
|
||||
for i = 1, 9 do
|
||||
inv:set_stack("input", i, items[i] or "")
|
||||
end
|
||||
inv:set_stack("output", 1, recipe.output)
|
||||
else
|
||||
for i = 1, 9 do
|
||||
inv:set_stack("input", i, nil)
|
||||
end
|
||||
inv:set_stack("output", 1, nil)
|
||||
end
|
||||
end
|
||||
|
||||
local function allow_metadata_inventory_put(pos, listname, index, stack, player)
|
||||
if minetest.is_protected(pos, player:get_player_name()) then
|
||||
return 0
|
||||
end
|
||||
|
||||
local inv = M(pos):get_inventory()
|
||||
local list = inv:get_list(listname)
|
||||
stack:set_count(1)
|
||||
inv:set_stack(listname, index, stack)
|
||||
after_recipe_change(pos, inv, listname)
|
||||
return 0
|
||||
end
|
||||
|
||||
local function allow_metadata_inventory_take(pos, listname, index, stack, player)
|
||||
if minetest.is_protected(pos, player:get_player_name()) then
|
||||
return 0
|
||||
end
|
||||
|
||||
local inv = M(pos):get_inventory()
|
||||
inv:set_stack(listname, index, nil)
|
||||
after_recipe_change(pos, inv, listname)
|
||||
return 0
|
||||
end
|
||||
|
||||
local function allow_metadata_inventory_move(pos, from_list, from_index, to_list, to_index, count, player)
|
||||
if minetest.is_protected(pos, player:get_player_name()) then
|
||||
return 0
|
||||
end
|
||||
|
||||
local inv = M(pos):get_inventory()
|
||||
if from_list == to_list then
|
||||
minetest.after(0.1, after_recipe_change, pos, inv, from_list)
|
||||
return 1
|
||||
end
|
||||
return 0
|
||||
end
|
||||
|
||||
minetest.register_node("techage:ta4_recipeblock", {
|
||||
description = S("TA4 Recipe Block"),
|
||||
tiles = {
|
||||
-- up, down, right, left, back, front
|
||||
"techage_filling_ta4.png^techage_frame_ta4_top.png",
|
||||
"techage_filling_ta4.png^techage_frame_ta4_top.png",
|
||||
"techage_filling_ta4.png^techage_frame_ta4.png^techage_appl_recipeblock.png",
|
||||
},
|
||||
|
||||
on_construct = function(pos)
|
||||
local inv = M(pos):get_inventory()
|
||||
inv:set_size('input', 9)
|
||||
inv:set_size('output', 1)
|
||||
end,
|
||||
|
||||
after_place_node = function(pos, placer, itemstack)
|
||||
local nvm = techage.get_nvm(pos)
|
||||
local number = techage.add_node(pos, "techage:ta4_chest")
|
||||
M(pos):set_string("owner", placer:get_player_name())
|
||||
M(pos):set_string("node_number", number)
|
||||
M(pos):set_string("formspec", formspec(pos, nvm))
|
||||
M(pos):set_string("infotext", S("TA4 Recipe Block") .. " " .. number)
|
||||
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)
|
||||
nvm.recipe_idx = nvm.recipe_idx or 1
|
||||
if fields.next == ">>" then
|
||||
nvm.recipe_idx = techage.in_range(nvm.recipe_idx + 1, 1, MAX_RECIPE)
|
||||
elseif fields.priv == "<<" then
|
||||
nvm.recipe_idx = techage.in_range(nvm.recipe_idx - 1, 1, MAX_RECIPE)
|
||||
end
|
||||
local inv = M(pos):get_inventory()
|
||||
update_inventor(pos, inv, nvm.recipe_idx or 1)
|
||||
M(pos):set_string("formspec", formspec(pos, nvm))
|
||||
end,
|
||||
|
||||
after_dig_node = function(pos, oldnode, oldmetadata, digger)
|
||||
techage.remove_node(pos, oldnode, oldmetadata)
|
||||
techage.del_mem(pos)
|
||||
end,
|
||||
|
||||
allow_metadata_inventory_put = allow_metadata_inventory_put,
|
||||
allow_metadata_inventory_take = allow_metadata_inventory_take,
|
||||
allow_metadata_inventory_move = allow_metadata_inventory_move,
|
||||
|
||||
paramtype2 = "facedir",
|
||||
groups = {choppy=2, cracky=2, crumbly=2},
|
||||
is_ground_content = false,
|
||||
sounds = default.node_sound_wood_defaults(),
|
||||
})
|
||||
|
||||
techage.register_node({"techage:ta4_recipeblock"}, {
|
||||
on_recv_message = function(pos, src, topic, payload)
|
||||
local nvm = techage.get_nvm(pos)
|
||||
if topic == "input" and payload and payload ~= "" then
|
||||
nvm.recipes = nvm.recipes or {}
|
||||
local recipe = nvm.recipes[tonumber(payload) or 1]
|
||||
if recipe then
|
||||
return recipe.input
|
||||
end
|
||||
else
|
||||
return "unsupported"
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = "techage:ta4_recipeblock",
|
||||
recipe = {
|
||||
{"techage:ta4_carbon_fiber", "dye:blue", "techage:aluminum"},
|
||||
{"", "basic_materials:ic", ""},
|
||||
{"default:steel_ingot", "techage:ta4_wlanchip", "default:steel_ingot"},
|
||||
},
|
||||
})
|
||||
|
@ -547,7 +547,7 @@ end
|
||||
|
||||
minetest.register_chatcommand("ta_send", {
|
||||
description = minetest.formspec_escape(
|
||||
"Send a techage command to the block with the number given: /ta_send <number> <topic> [<data>]"),
|
||||
"Send a techage command to the block with the number given: /ta_send <number> <command> [<data>]"),
|
||||
func = function(name, param)
|
||||
local num, cmnd, payload = param:match('^([0-9]+)%s+(%w+)%s*(.*)$')
|
||||
|
||||
@ -563,6 +563,43 @@ minetest.register_chatcommand("ta_send", {
|
||||
return false, "Destination block is protected"
|
||||
end
|
||||
end
|
||||
return false, "Syntax: /ta_send <number> <topic> [<data>]"
|
||||
return false, "Syntax: /ta_send <number> <command> [<data>]"
|
||||
end
|
||||
})
|
||||
|
||||
minetest.register_chatcommand("expoints", {
|
||||
privs = {
|
||||
server = true
|
||||
},
|
||||
func = function(name, param)
|
||||
local player_name, points = param:match("^(%S+)%s*(%d*)$")
|
||||
if player_name then
|
||||
local player = minetest.get_player_by_name(player_name)
|
||||
if player then
|
||||
if points and points ~= "" then
|
||||
if techage.set_expoints(player, tonumber(points)) then
|
||||
return true, "The player "..player_name.." now has "..points.." experience points."
|
||||
end
|
||||
else
|
||||
points = techage.get_expoints(player)
|
||||
return true, "The player "..player_name.." has "..points.." experience points."
|
||||
end
|
||||
else
|
||||
return false, "Unknown player "..player_name
|
||||
end
|
||||
end
|
||||
return false, "Syntax error! Syntax: /expoints <name> [<points>]"
|
||||
end
|
||||
})
|
||||
|
||||
minetest.register_chatcommand("my_expoints", {
|
||||
func = function(name, param)
|
||||
local player = minetest.get_player_by_name(name)
|
||||
if player then
|
||||
local points = techage.get_expoints(player)
|
||||
if points then
|
||||
return true, "You have "..points.." experience points."
|
||||
end
|
||||
end
|
||||
end
|
||||
})
|
||||
|
@ -20,6 +20,36 @@ local S = techage.S
|
||||
|
||||
local flylib = {}
|
||||
|
||||
local function lvect_add_vec(lvect1, offs)
|
||||
if not lvect1 or not offs then return end
|
||||
|
||||
local lvect2 = {}
|
||||
for _, v in ipairs(lvect1) do
|
||||
lvect2[#lvect2 + 1] = vector.add(v, offs)
|
||||
end
|
||||
return lvect2
|
||||
end
|
||||
|
||||
local function lvect_add(lvect1, lvect2)
|
||||
if not lvect1 or not lvect2 then return end
|
||||
|
||||
local lvect3 = {}
|
||||
for i, v in ipairs(lvect1) do
|
||||
lvect3[#lvect3 + 1] = vector.add(v, lvect2[i])
|
||||
end
|
||||
return lvect3
|
||||
end
|
||||
|
||||
local function lvect_subtract(lvect1, lvect2)
|
||||
if not lvect1 or not lvect2 then return end
|
||||
|
||||
local lvect3 = {}
|
||||
for i, v in ipairs(lvect1) do
|
||||
lvect3[#lvect3 + 1] = vector.subtract(v, lvect2[i])
|
||||
end
|
||||
return lvect3
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
-- to_path function for the fly/move path
|
||||
-------------------------------------------------------------------------------
|
||||
@ -294,7 +324,10 @@ end
|
||||
local function determine_dir(pos1, pos2)
|
||||
local vdist = vector.subtract(pos2, pos1)
|
||||
local ndist = vector.length(vdist)
|
||||
return vector.divide(vdist, ndist)
|
||||
if ndist > 0 then
|
||||
return vector.divide(vdist, ndist)
|
||||
end
|
||||
return {x=0, y=0, z=0}
|
||||
end
|
||||
|
||||
local function move_entity(obj, dest_pos, dir, is_corner)
|
||||
@ -413,12 +446,14 @@ minetest.register_entity("techage:move_item", {
|
||||
|
||||
on_step = function(self, dtime, moveresult)
|
||||
local stop_obj = function(obj, self)
|
||||
local dest_pos = self.dest_pos
|
||||
obj:move_to(self.dest_pos, true)
|
||||
obj:set_acceleration({x=0, y=0, z=0})
|
||||
obj:set_velocity({x=0, y=0, z=0})
|
||||
self.dest_pos = nil
|
||||
self.old_dist = nil
|
||||
self.ttl = 2
|
||||
return dest_pos
|
||||
end
|
||||
|
||||
if self.dest_pos then
|
||||
@ -431,24 +466,21 @@ minetest.register_entity("techage:move_item", {
|
||||
-- Landing
|
||||
if self.lpath and self.lpath[self.path_idx] then
|
||||
if dist < 1 or dist > self.old_dist then
|
||||
local dest_pos = self.dest_pos
|
||||
stop_obj(obj, self)
|
||||
local dest_pos = stop_obj(obj, self)
|
||||
if not moveon_entity(obj, self, dest_pos) then
|
||||
minetest.after(0.5, entity_to_node, dest_pos, obj)
|
||||
end
|
||||
return
|
||||
end
|
||||
elseif self.handover and dist < 0.2 or dist > self.old_dist then
|
||||
local dest_pos = self.dest_pos
|
||||
stop_obj(obj, self)
|
||||
local dest_pos = stop_obj(obj, self)
|
||||
if not handover_to(obj, self, dest_pos) then
|
||||
minetest.after(0.5, entity_to_node, dest_pos, obj)
|
||||
end
|
||||
return
|
||||
else
|
||||
if dist < 0.05 or dist > self.old_dist then
|
||||
local dest_pos = self.dest_pos
|
||||
stop_obj(obj, self)
|
||||
local dest_pos = stop_obj(obj, self)
|
||||
minetest.after(0.5, entity_to_node, dest_pos, obj)
|
||||
return
|
||||
end
|
||||
@ -513,17 +545,7 @@ local function is_simple_node(pos)
|
||||
return true
|
||||
end
|
||||
|
||||
local function table_add(tbl, offs)
|
||||
if not tbl or not offs then return end
|
||||
|
||||
local tbl2 = {}
|
||||
for _, v in ipairs(tbl) do
|
||||
tbl2[#tbl2 + 1] = vector.add(v, offs)
|
||||
end
|
||||
return tbl2
|
||||
end
|
||||
|
||||
local function move_node(pos, pos1_idx, start_pos, lpath, max_speed, height, move2to1, handover)
|
||||
local function move_node(pos, pos1_idx, start_pos, lpath, max_speed, height, move2to1, handover, cpos)
|
||||
local pos2 = next_path_pos(start_pos, lpath, 1)
|
||||
--print("move_node", P2S(pos), P2S(start_pos), lpath, max_speed, height, move2to1, P2S(pos2))
|
||||
if pos2 then
|
||||
@ -547,7 +569,7 @@ local function move_node(pos, pos1_idx, start_pos, lpath, max_speed, height, mov
|
||||
self.base_pos = pos
|
||||
self.move2to1 = move2to1
|
||||
self.handover = handover
|
||||
print("move_node", P2S(start_pos), P2S(pos2), P2S(dir), P2S(pos))
|
||||
--print("move_node", P2S(start_pos), P2S(pos2), P2S(dir), P2S(pos))
|
||||
move_entity(obj, pos2, dir)
|
||||
end
|
||||
end
|
||||
@ -598,13 +620,14 @@ function flylib.move_to_other_pos(pos, move2to1)
|
||||
local handover
|
||||
height = techage.in_range(height, 0, 1)
|
||||
max_speed = techage.in_range(max_speed, MIN_SPEED, MAX_SPEED)
|
||||
nvm.lpos1 = nvm.lpos1 or {}
|
||||
|
||||
local offs = dest_offset(lpath)
|
||||
if move2to1 then
|
||||
lpath = reverse_path(lpath)
|
||||
end
|
||||
nvm.lpos1 = nvm.lpos1 or {}
|
||||
nvm.lpos2 = table_add(nvm.lpos1, offs)
|
||||
-- calc destination positions
|
||||
nvm.lpos2 = lvect_add_vec(nvm.lpos1, offs)
|
||||
|
||||
if move2to1 then
|
||||
handover = meta:contains("handoverA") and meta:get_string("handoverA")
|
||||
|
@ -84,31 +84,33 @@ end
|
||||
-------------------------------------------------------------------------------
|
||||
-- Rotate nodes around the center
|
||||
-------------------------------------------------------------------------------
|
||||
local function center(nodes)
|
||||
function techage.positions_center(lpos)
|
||||
local c = {x=0, y=0, z=0}
|
||||
for _,v in ipairs(nodes) do
|
||||
for _,v in ipairs(lpos) do
|
||||
c = vector.add(c, v)
|
||||
end
|
||||
c = vector.divide(c, #nodes)
|
||||
c = vector.divide(c, #lpos)
|
||||
c = vector.round(c)
|
||||
c.y = 0
|
||||
return c
|
||||
end
|
||||
|
||||
local function rotate_around_axis(v, c, rot)
|
||||
function techage.rotate_around_axis(v, c, turn)
|
||||
local dx, dz = v.x - c.x, v.z - c.z
|
||||
if rot == "l" then
|
||||
if turn == "l" then
|
||||
return {
|
||||
x = c.x - dz,
|
||||
y = v.y,
|
||||
z = c.z + dx,
|
||||
}
|
||||
elseif rot == "r" then
|
||||
elseif turn == "r" then
|
||||
return {
|
||||
x = c.x + dz,
|
||||
y = v.y,
|
||||
z = c.z - dx,
|
||||
}
|
||||
elseif turn == "" then
|
||||
return v
|
||||
else -- turn 180 degree
|
||||
return {
|
||||
x = c.x - dx,
|
||||
@ -119,13 +121,13 @@ local function rotate_around_axis(v, c, rot)
|
||||
end
|
||||
|
||||
-- Function returns a list ẃith the new node positions
|
||||
-- rot is one of "l", "r", "2l", "2r"
|
||||
-- turn is one of "l", "r", "2l", "2r"
|
||||
-- cpos is the center pos (optional)
|
||||
function techage.rotate_around_center(nodes1, rot, cpos)
|
||||
cpos = cpos or center(nodes1)
|
||||
function techage.rotate_around_center(nodes1, turn, cpos)
|
||||
cpos = cpos or techage.positions_center(nodes1)
|
||||
local nodes2 = {}
|
||||
for _,pos in ipairs(nodes1) do
|
||||
nodes2[#nodes2 + 1] = rotate_around_axis(pos, cpos, rot)
|
||||
nodes2[#nodes2 + 1] = techage.rotate_around_axis(pos, cpos, turn)
|
||||
end
|
||||
return nodes2
|
||||
end
|
||||
@ -471,6 +473,7 @@ function techage.add_expoint(player)
|
||||
local meta = player:get_meta()
|
||||
if meta then
|
||||
meta:set_int("techage_ex_points", meta:get_int("techage_ex_points") + 1)
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -480,6 +483,7 @@ function techage.set_expoints(player, ex_points)
|
||||
local meta = player:get_meta()
|
||||
if meta then
|
||||
meta:set_int("techage_ex_points", ex_points)
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -22,6 +22,19 @@ local range = techage.in_range
|
||||
|
||||
techage.recipes = {}
|
||||
|
||||
local GROUP_ITEMS = {
|
||||
stone = "default:cobble",
|
||||
wood = "default:wood",
|
||||
book = "default:book",
|
||||
sand = "default:sand",
|
||||
leaves = "default:leaves",
|
||||
stick = "default:stick",
|
||||
tree = "default:tree",
|
||||
vessel = "vessels:glass_bottle",
|
||||
wool = "wool:white",
|
||||
}
|
||||
|
||||
|
||||
local RECIPE = {
|
||||
output = {name = "", num = 0},
|
||||
waste = {name = "", num = 0},
|
||||
@ -137,3 +150,17 @@ function techage.recipes.get_recipe(name)
|
||||
return NormalizedRecipes[name]
|
||||
end
|
||||
|
||||
|
||||
function techage.recipes.get_default_group_item_name(item_name)
|
||||
if item_name and item_name:sub(1, 6) == "group:" then
|
||||
local default_name = GROUP_ITEMS[item_name:sub(7)]
|
||||
if default_name then
|
||||
return default_name
|
||||
end
|
||||
end
|
||||
return item_name
|
||||
end
|
||||
|
||||
function techage.recipes.add_group_item(group, default_item_name)
|
||||
GROUP_ITEMS[group] = default_item_name
|
||||
end
|
||||
|
@ -1729,7 +1729,7 @@ techage.manual_DE.aText = {
|
||||
"\n",
|
||||
"Siehe TA3 Pumpe.\n"..
|
||||
"\n"..
|
||||
"Die TA4 Pumpe pumpt 8 Einheiten Flüssigkeit alle zwei Sekunden.\n"..
|
||||
"Die TA4 Pumpe pumpt 8 Einheiten Flüssigkeit alle zwei Sekunden. Zusätzlich unterstützt die Pumpe das Kommando 'flowrate'. Damit kann die Gesamtdurchflussmenge durch die Pumpe abgefragt werden.\n"..
|
||||
"\n"..
|
||||
"\n"..
|
||||
"\n",
|
||||
|
@ -1725,7 +1725,7 @@ techage.manual_EN.aText = {
|
||||
"\n",
|
||||
"See TA3 pump.\n"..
|
||||
"\n"..
|
||||
"The TA4 pump pumps 8 units of liquid every two seconds.\n"..
|
||||
"The TA4 pump pumps 8 units of liquid every two seconds. The pump also supports the 'flowrate' command. This means that the total flow rate through the pump can be queried. \n"..
|
||||
"\n"..
|
||||
"\n"..
|
||||
"\n",
|
||||
|
6
init.lua
6
init.lua
@ -33,8 +33,8 @@ elseif minetest.global_exists("minecart") and minecart.version < 1.08 then
|
||||
elseif minetest.global_exists("lcdlib") and lcdlib.version < 1.01 then
|
||||
minetest.log("error", "[techage] Techage requires lcdlib version 1.01 or newer!")
|
||||
return
|
||||
elseif minetest.global_exists("safer_lua") and safer_lua.version < 1.0 then
|
||||
minetest.log("error", "[techage] Techage requires safer_lua version 1.0 or newer!")
|
||||
elseif minetest.global_exists("safer_lua") and safer_lua.version < 1.01 then
|
||||
minetest.log("error", "[techage] Techage requires safer_lua version 1.01 or newer!")
|
||||
return
|
||||
elseif minetest.global_exists("networks") and networks.version < 0.10 then
|
||||
minetest.log("error", "[techage] Techage requires networks version 0.10 or newer!")
|
||||
@ -187,6 +187,7 @@ dofile(MP.."/basic_machines/ta4_injector.lua")
|
||||
dofile(MP.."/basic_machines/itemsource.lua")
|
||||
dofile(MP.."/basic_machines/recycler.lua")
|
||||
dofile(MP.."/basic_machines/concentrator.lua")
|
||||
dofile(MP.."/basic_machines/recipeblock.lua")
|
||||
|
||||
-- Liquids II
|
||||
dofile(MP.."/liquids/tank.lua")
|
||||
@ -274,6 +275,7 @@ dofile(MP.."/logic/lua_logic.lua") -- old
|
||||
dofile(MP.."/logic/logic_block.lua") -- new
|
||||
dofile(MP.."/logic/node_detector.lua")
|
||||
dofile(MP.."/logic/player_detector.lua")
|
||||
dofile(MP.."/logic/mba_detector.lua")
|
||||
dofile(MP.."/logic/cart_detector.lua")
|
||||
dofile(MP.."/logic/collector.lua")
|
||||
dofile(MP.."/logic/button_2x.lua")
|
||||
|
@ -25,6 +25,13 @@ local COUNTDOWN_TICKS = 4
|
||||
local CYCLE_TIME = 2
|
||||
local CAPA = 4
|
||||
|
||||
local WRENCH_MENU = {{
|
||||
type = "output",
|
||||
name = "flowrate",
|
||||
label = S("Total flow rate"),
|
||||
tooltip = S("Total flow rate in liquid units"),
|
||||
}}
|
||||
|
||||
local State3 = techage.NodeStates:new({
|
||||
node_name_passive = "techage:t3_pump",
|
||||
node_name_active = "techage:t3_pump_on",
|
||||
@ -52,13 +59,15 @@ local function pumping(pos, nvm, state, capa)
|
||||
liquid.untake(pos, Pipe, Flip[outdir], name, leftover)
|
||||
if leftover == taken then
|
||||
state:blocked(pos, nvm)
|
||||
return
|
||||
return 0
|
||||
end
|
||||
return taken - leftover
|
||||
end
|
||||
state:keep_running(pos, nvm, COUNTDOWN_TICKS)
|
||||
return
|
||||
return taken
|
||||
end
|
||||
state:idle(pos, nvm)
|
||||
return 0
|
||||
end
|
||||
|
||||
local function after_place_node3(pos, placer)
|
||||
@ -85,7 +94,7 @@ end
|
||||
|
||||
local function node_timer4(pos, elapsed)
|
||||
local nvm = techage.get_nvm(pos)
|
||||
pumping(pos, nvm, State4, CAPA * 2)
|
||||
nvm.flowrate = (nvm.flowrate or 0) + pumping(pos, nvm, State4, CAPA * 2)
|
||||
return State4:is_active(nvm)
|
||||
end
|
||||
|
||||
@ -235,6 +244,7 @@ minetest.register_node("techage:t4_pump", {
|
||||
groups = {cracky=2},
|
||||
is_ground_content = false,
|
||||
sounds = default.node_sound_metal_defaults(),
|
||||
ta4_formspec = WRENCH_MENU,
|
||||
})
|
||||
|
||||
minetest.register_node("techage:t4_pump_on", {
|
||||
@ -261,7 +271,12 @@ techage.register_node({"techage:t3_pump", "techage:t3_pump_on"}, {
|
||||
|
||||
techage.register_node({"techage:t4_pump", "techage:t4_pump_on"}, {
|
||||
on_recv_message = function(pos, src, topic, payload)
|
||||
return State4:on_receive_message(pos, topic, payload)
|
||||
if topic == "flowrate" then
|
||||
local nvm = techage.get_nvm(pos)
|
||||
return nvm.flowrate or 0
|
||||
else
|
||||
return State4:on_receive_message(pos, topic, payload)
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
|
100
logic/mba_detector.lua
Normal file
100
logic/mba_detector.lua
Normal file
@ -0,0 +1,100 @@
|
||||
--[[
|
||||
|
||||
TechAge
|
||||
=======
|
||||
|
||||
Copyright (C) 2017-2020 Joachim Stolberg
|
||||
|
||||
AGPL v3
|
||||
See LICENSE.txt for more information
|
||||
|
||||
TA4 Mapblock Active Detector
|
||||
|
||||
]]--
|
||||
|
||||
-- for lazy programmers
|
||||
local M = minetest.get_meta
|
||||
local S = techage.S
|
||||
|
||||
local logic = techage.logic
|
||||
|
||||
minetest.register_node("techage:ta4_mbadetector", {
|
||||
description = "TA4 Mapblock Active Detector",
|
||||
inventory_image = 'techage_smartline_mba_detector_inv.png',
|
||||
tiles = {
|
||||
-- up, down, right, left, back, front
|
||||
"techage_smartline.png",
|
||||
"techage_smartline.png",
|
||||
"techage_smartline.png",
|
||||
"techage_smartline.png",
|
||||
"techage_smartline.png",
|
||||
"techage_smartline.png^techage_smartline_mba_detector.png",
|
||||
},
|
||||
|
||||
drawtype = "nodebox",
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{ -6/32, -6/32, 14/32, 6/32, 6/32, 16/32},
|
||||
},
|
||||
},
|
||||
|
||||
after_place_node = function(pos, placer)
|
||||
local meta = M(pos)
|
||||
logic.after_place_node(pos, placer, "techage:ta4_mbadetector", S("TA4 Mapblock Active Detector"))
|
||||
logic.infotext(meta, S("TA4 Mapblock Active Detector"))
|
||||
minetest.get_node_timer(pos):start(1)
|
||||
end,
|
||||
|
||||
on_timer = function(pos, elapsed)
|
||||
local mem = techage.get_mem(pos)
|
||||
mem.gametime = minetest.get_gametime()
|
||||
return true
|
||||
end,
|
||||
|
||||
after_dig_node = function(pos, oldnode, oldmetadata, digger)
|
||||
techage.remove_node(pos, oldnode, oldmetadata)
|
||||
techage.del_mem(pos)
|
||||
end,
|
||||
|
||||
paramtype = "light",
|
||||
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_mbadetector",
|
||||
recipe = {
|
||||
{"", "group:wood", "default:mese_crystal"},
|
||||
{"", "techage:vacuum_tube", "default:copper_ingot"},
|
||||
{"", "group:wood", ""},
|
||||
},
|
||||
})
|
||||
|
||||
techage.register_node({"techage:ta4_mbadetector"}, {
|
||||
on_recv_message = function(pos, src, topic, payload)
|
||||
if topic == "state" then
|
||||
if minetest.compare_block_status then
|
||||
if minetest.compare_block_status(pos, "active") then
|
||||
return "on"
|
||||
else
|
||||
return "off"
|
||||
end
|
||||
else
|
||||
local mem = techage.get_mem(pos)
|
||||
local res = mem.gametime and mem.gametime > (minetest.get_gametime() - 2)
|
||||
return res and "on" or "off"
|
||||
end
|
||||
else
|
||||
return "unsupported"
|
||||
end
|
||||
end,
|
||||
on_node_load = function(pos)
|
||||
minetest.get_node_timer(pos):start(1)
|
||||
end,
|
||||
}
|
||||
)
|
||||
|
@ -689,7 +689,7 @@ In einen TA4 Tank passen 2000 Einheiten oder 200 Fässer einer Flüssigkeit.
|
||||
|
||||
Siehe TA3 Pumpe.
|
||||
|
||||
Die TA4 Pumpe pumpt 8 Einheiten Flüssigkeit alle zwei Sekunden.
|
||||
Die TA4 Pumpe pumpt 8 Einheiten Flüssigkeit alle zwei Sekunden. Zusätzlich unterstützt die Pumpe das Kommando `flowrate`. Damit kann die Gesamtdurchflussmenge durch die Pumpe abgefragt werden.
|
||||
|
||||
[ta4_pump|image]
|
||||
|
||||
|
@ -681,7 +681,7 @@ A TA4 tank can hold 2000 units or 200 barrels of liquid.
|
||||
|
||||
See TA3 pump.
|
||||
|
||||
The TA4 pump pumps 8 units of liquid every two seconds.
|
||||
The TA4 pump pumps 8 units of liquid every two seconds. The pump also supports the `flowrate` command. This means that the total flow rate through the pump can be queried.
|
||||
|
||||
[ta4_pump|image]
|
||||
|
||||
|
@ -134,7 +134,8 @@ SaferLua directly supports the following standard functions:
|
||||
- string.rep
|
||||
- string.sub
|
||||
- string.upper
|
||||
- string.split
|
||||
- string.split (result is an Array)
|
||||
- string.split2 (result are multiple returns like the Lua function unpack)
|
||||
- string.trim
|
||||
|
||||
For own function definitions, the menu tab 'func' can be used. Here you write your functions like:
|
||||
@ -366,12 +367,14 @@ Please note, that this is not a technical distinction, only a logical.
|
||||
| "depth" | number | Read the current depth value of a quarry block (1..80) |
|
||||
| "load" | number | Read the load value in percent (0..100) of a tank, silo, accu, or battery block, or from the Signs Bot Box. Silo and tank return two values: The percentage value and the absolute value in units.<br /> Example: percent, absolute = $send_cmnd("223", "load") |
|
||||
| "delivered" | number | Read the current delivered power value of a generator block. A power consuming block (accu) provides a negative value |
|
||||
| "flowrate" | Total flow rate in liquid units | Only for TA4 Pumps |
|
||||
| "action" | player-name, action-string | Only for Sensor Chests |
|
||||
| "stacks" | Array with up to 4 Stores with the inventory content (see example) | Only for Sensor Chests |
|
||||
| "count" | number | Read the item counter of the TA4 Item Detector block |
|
||||
| "count" | number of items | Read the total amount of TA4 chest items. An optional number as `add_data` is used to address only one inventory slot (1..8, from left to right). |
|
||||
| "itemstring" | item string of the given slot | Specific command for the TA4 8x2000 Chest to read the item type (technical name) of one chest slot, specified via `add_data` (1..8).<br />Example: s = $send_cmnd("223", "itemstring", 1) |
|
||||
| "output" | recipe output string, <br />e.g.: "default:glass" | Only for the Industrial Furnace. If no recipe is active, the command returns "unknown" |
|
||||
| "input" | `<index>` | Read a recipe from the TA4 Recipe Block. `<index>` is the number of the recipe. The block return a list of recipe items. |
|
||||
|
||||
|
||||
|
||||
@ -385,18 +388,23 @@ Please note, that this is not a technical distinction, only a logical.
|
||||
| -------------------------------- | ------------ | ------------------------------------------------------------ |
|
||||
| "on", "off" | nil | turn a node on/off (machine, lamp,...) |
|
||||
| "red, "amber", "green", "off" | nil | set Signal Tower color |
|
||||
| "red, "amber", "green", "off" | lamp number (1..4) | Set the signal lamp color. Valid for "TA4 2x Signal Lamp" and "TA4 4x Signal Lamp" |
|
||||
| "port" | `<color>=on/off` | Enable/disable a Distributor filter slot..<br />Example: `yellow=on`<br />colors: "red", "green", "blue", "yellow" |
|
||||
| "text" | text string | Text to be used for the Sensor Chest menu |
|
||||
| "reset" | nil | Reset the item counter of the TA4 Item Detector block |
|
||||
| "pull" | item string | Start the TA4 pusher to pull/push items.<br /> Example: `default:dirt 8` |
|
||||
| "config" | item string | Configure the TA4 pusher.<br />Example: `wool:blue` |
|
||||
| "exchange" | inventory slot number | place/remove/exchange an block by means of the TA3 Door Controller II (techage:ta3_doorcontroller2) |
|
||||
|
||||
|
||||
|
||||
* `$display(num, row, text)` Send a text string to the display with number _num_. _row_ is the display row, a value from 1 to 5, or 0 to add the text string at the bottom (scroll screen mode). _text_ is the string to be displayed. If the first char of the string is a blank, the text will be horizontally centered.
|
||||
* `$clear_screen(num)` Clear the screen of the display with number _num_.
|
||||
* `$position(num)` Returns the position as string "'(x,y,z)" of the device with the given _num_.
|
||||
| "a2b" | nil | TA4 Move Controller command to move the block(s) from position A to B |
|
||||
| "b2a" | nil | TA4 Move Controller command to move the block(s) from position B to A |
|
||||
| "move" | nil | TA4 Move Controller command to move the block(s) to the opposite position |
|
||||
| "left" | nil | TA4 Turn Controller command to turn the block(s) to the left |
|
||||
| "right" | nil | TA4 Turn Controller command to turn the block(s) to the right |
|
||||
| "uturn" | nil | TA4 Turn Controller command to turn the block(s) 180 degrees |
|
||||
| "recipe" | `<item_name>,<item_name>,...` | Set the TA4 Autocrafter recipe. <br />Example for the torch recipe: `default:coal_lump,,,default:stick` <br />Hint: Empty fields may only be left out at the end of the item list! |
|
||||
| "recipe" | `<number>.<index>` | Set the TA4 Autocrafter recipe with a recipe from a TA4 Recipe Block.<br />`<number>` is the TA4 Recipe Block number<br />`<index>` is the number of the recipe in the TA4 Recipe Block |
|
||||
| "goto" | `<slot>` | Start command for the TA4 Sequencer. `<slot>` is the time slot like `[1]` where the execution starts. |
|
||||
| "stop" | nil | Stop command for the TA4 Sequencer. |
|
||||
|
||||
|
||||
### Server and Terminal Functions
|
||||
@ -414,25 +422,27 @@ In contrast the Controller can send text strings to the terminal.
|
||||
- `$get_term()` - Read a text command received from the Terminal
|
||||
- `$put_term(num, text)` - Send a text string to the Terminal. _num_ is the number of the Terminal.
|
||||
|
||||
|
||||
### Further Functions
|
||||
### Communication between Lua Controllers
|
||||
|
||||
Messages are used to transport data between Controllers. Messages can contain arbitrary data. Incoming messages are stored in order (up to 10) and can be read one after the other.
|
||||
|
||||
* `$get_msg([raw])` - Read a received message. The function returns the sender number and the message. (see example "Emails"). If the _raw_ parameter is not set or false, the message is guaranteed to be a string.
|
||||
* `$send_msg(num, msg)` - Send a message to another Controller. _num_ is the destination number. (see example "Emails")
|
||||
|
||||
* `$chat(text)` - Send yourself a chat message. _text_ is a text string.
|
||||
### Further Functions
|
||||
|
||||
* `$chat(text)` - Send yourself a chat message. _text_ is a text string.
|
||||
* `$door(pos, text)` - Open/Close a door at position "pos".
|
||||
Example: `$door("123,7,-1200", "close")`.
|
||||
Hint: Use the Techage Info Tool to determine the door position.
|
||||
|
||||
* `$item_description("default:apple")`
|
||||
Get the description (item name) for a specified itemstring, e. g. determined via the TA4 8x2000 Chest command `itemstring`:
|
||||
`str = $send_cmnd("223", "itemstring", 1)`
|
||||
`descr = $item_description(str)`
|
||||
|
||||
|
||||
* `$display(num, row, text)` Send a text string to the display with number _num_. _row_ is the display row, a value from 1 to 5, or 0 to add the text string at the bottom (scroll screen mode). _text_ is the string to be displayed. If the first char of the string is a blank, the text will be horizontally centered.
|
||||
* `$clear_screen(num)` Clear the screen of the display with number _num_.
|
||||
* `$position(num)` Returns the position as string "'(x,y,z)" of the device with the given _num_.
|
||||
|
||||
## Example Scripts
|
||||
|
||||
@ -662,7 +672,7 @@ loop() code:
|
||||
-- read from Terminal and send the message
|
||||
s = $get_term()
|
||||
if s then
|
||||
name,text = unpack(string.split(s, ":", false, 1))
|
||||
name,text = string.split2(s, ":", false, 1)
|
||||
num = $server_read(SERVER, name)
|
||||
if num then
|
||||
$send_msg(num, text)
|
||||
|
Binary file not shown.
@ -97,7 +97,6 @@ minetest.register_node("techage:ta4_turncontroller", {
|
||||
nvm.lpos = new_posses
|
||||
local name = player:get_player_name()
|
||||
mark.stop(name)
|
||||
print("new_posses", #new_posses)
|
||||
end
|
||||
meta:set_string("formspec", formspec(nvm, meta))
|
||||
elseif fields.right then
|
||||
@ -107,7 +106,6 @@ minetest.register_node("techage:ta4_turncontroller", {
|
||||
nvm.lpos = new_posses
|
||||
local name = player:get_player_name()
|
||||
mark.stop(name)
|
||||
print("new_posses", #new_posses)
|
||||
end
|
||||
meta:set_string("formspec", formspec(nvm, meta))
|
||||
end
|
||||
|
BIN
textures/techage_appl_recipeblock.png
Normal file
BIN
textures/techage_appl_recipeblock.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 144 B |
BIN
textures/techage_smartline_mba_detector.png
Normal file
BIN
textures/techage_smartline_mba_detector.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 408 B |
BIN
textures/techage_smartline_mba_detector_inv.png
Normal file
BIN
textures/techage_smartline_mba_detector_inv.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 669 B |
@ -109,6 +109,11 @@ local function read_state(itemstack, user, pointed_thing)
|
||||
consumption = dump(consumption)
|
||||
minetest.chat_send_player(user:get_player_name(), ndef.description.." "..number..": consumption = "..consumption.." kud ")
|
||||
end
|
||||
local flowrate = techage.send_single("0", number, "flowrate", nil)
|
||||
if flowrate and flowrate ~= "" and flowrate ~= "unsupported" then
|
||||
flowrate = dump(flowrate)
|
||||
minetest.chat_send_player(user:get_player_name(), ndef.description.." "..number..": flowrate = "..flowrate.." ")
|
||||
end
|
||||
local owner = M(pos):get_string("owner") or ""
|
||||
if owner ~= "" then
|
||||
minetest.chat_send_player(user:get_player_name(), S("Node owner")..": "..owner.." ")
|
||||
|
Loading…
Reference in New Issue
Block a user