basic_machines-cd2025/mover_common.lua
waxtatect a263c4ccb9 set meta once only
fix recycler again
2023-03-02 14:44:42 +01:00

205 lines
8.8 KiB
Lua

local F, S = basic_machines.F, basic_machines.S
local math_abs = math.abs
local mover_chests = basic_machines.get_mover("chests")
local mover_modes
local mover_plants_table = basic_machines.get_mover("plants_table")
local vector_add = vector.add
basic_machines.get_distance = function(pos1, pos2)
return (math_abs(pos2.x - pos1.x) + math_abs(pos2.y - pos1.y) + math_abs(pos2.z - pos1.z))
end
if basic_machines.settings.mover_no_large_stacks then
basic_machines.check_mover_target = function(mode, pos, meta)
if mode == "normal" then
local pos2 = vector_add(pos, {x = meta:get_int("x2"), y = meta:get_int("y2"), z = meta:get_int("z2")})
if mover_chests[minetest.get_node(pos2).name] then return true end
elseif mode == "drop" or mode == "inventory" then -- any target
return true
end
return false
end
basic_machines.clamp_item_count = function(item)
local itemstring = type(item) == "string"
local stack = itemstring and ItemStack(item) or item
local stack_max = stack:get_stack_max()
if stack:get_count() > stack_max then stack:set_count(stack_max) end
return itemstring and stack:to_string() or stack
end
end
-- anal retentive change in minetest 5.0.0 to minetest 5.1.0 (#7011) changing unknown node warning into crash
-- forcing many checks with all possible combinations + adding many new crashes combinations
basic_machines.check_mover_filter = function(mode, pos, meta, filter) -- mover input validation, is it correct node
filter = filter or meta:get_string("prefer")
if filter == "" then return true end -- allow clearing filter
if mode == "object" or mode == "inventory" or mode == "drop" then
return true
elseif mode == "dig" and meta:get_int("reverse") == 1 and mover_plants_table[filter] then -- allow farming
return true
elseif minetest.registered_nodes[filter] then -- normal, dig and transport mode
return true
elseif mode == "normal" then -- allow chest transfer
local pos2 = vector_add(pos, {x = meta:get_int("x2"), y = meta:get_int("y2"), z = meta:get_int("z2")})
if mover_chests[minetest.get_node(pos2).name] then return true end
end
return false
end
basic_machines.find_and_connect_battery = function(pos, meta)
for i = 0, 2 do
local positions = minetest.find_nodes_in_area( -- find battery
vector.subtract(pos, 1), vector_add(pos, 1), "basic_machines:battery_" .. i)
if #positions > 0 then
local fpos = positions[1] -- pick first battery found
meta:set_int("batx", fpos.x); meta:set_int("baty", fpos.y); meta:set_int("batz", fpos.z)
return fpos
end
end
end
local mover_modelist_translated
basic_machines.get_mover_form = function(pos)
local meta = minetest.get_meta(pos)
local seltab = meta:get_int("seltab")
if seltab ~= 2 then -- MODE
if mover_modes == nil then
mover_modes = basic_machines.get_mover("modes")
mover_modelist_translated = table.concat(mover_modes._tr_table, ",")
end
local mode = mover_modes[meta:get_string("mode")]
local list_name = "nodemeta:" .. pos.x .. ',' .. pos.y .. ',' .. pos.z
return ("formspec_version[4]size[10.25,10.8]style_type[list;spacing=0.25,0.15]tabheader[0,0;tabs;" ..
F(S("Mode of operation")) .. "," .. F(S("Where to move")) .. ";" .. seltab .. ";true;true]" ..
"label[0.25,0.3;" .. minetest.colorize("lawngreen", F(S("Mode selection"))) ..
"]dropdown[0.25,0.5;3.5,0.8;mode;" .. mover_modelist_translated .. ";" .. (mode and mode.id or 1) ..
"]button[4,0.5;1,0.8;help;" .. F(S("help")) .. "]button_exit[6.5,0.5;1,0.8;OK;" .. F(S("OK")) ..
"]textarea[0.25,1.6;9.75,2;description;;" .. (mode and mode.desc or F(S("description"))) ..
"]field[0.25,4.2;3.5,0.8;prefer;" .. F(S("Filter")) .. ";" .. F(meta:get_string("prefer")) ..
"]image[4,4.1;1,1;[combine:1x1^[noalpha^[colorize:#141318]" ..
"list[" .. list_name .. ";filter;4,4.1;1,1]" ..
"]label[6.5,3.9;" .. F(S("Upgrade")) .. "]list[" .. list_name .. ";upgrade;6.5,4.1;1,1]" ..
basic_machines.get_form_player_inventory(0.25, 5.85, 8, 4, 0.25) ..
"listring[" .. list_name .. ";upgrade]" ..
"listring[current_player;main]" ..
"listring[" .. list_name .. ";filter]" ..
"listring[current_player;main]")
else -- POSITIONS
local mode_string = meta:get_string("mode")
local pos1 = {x = meta:get_int("x0"), y = meta:get_int("y0"), z = meta:get_int("z0")}
local pos11 = {x = meta:get_int("x1"), y = meta:get_int("y1"), z = meta:get_int("z1")}
local pos2 = {x = meta:get_int("x2"), y = meta:get_int("y2"), z = meta:get_int("z2")}
local inventory_list1, inventory_list2, btns_ns
if mode_string == "inventory" then
local meta1 = minetest.get_meta(vector_add(pos, pos1)) -- source1 meta
local meta2 = minetest.get_meta(vector_add(pos, pos2)) -- target meta
local inv1m, inv2m = meta:get_string("inv1"), meta:get_string("inv2")
local inv1, inv2 = 1, 1
local list1, inv_list1 = meta1:get_inventory():get_lists(), ""
-- stupid dropdown requires item index but returns string on receive so we have to find index.. grrr
-- one other solution: invert the table: key <-> value
local j = 1
for k, _ in pairs(list1) do
inv_list1 = inv_list1 .. F(S(k)) .. ","
if k == inv1m then inv1 = j end; j = j + 1
end
local list2, inv_list2 = meta2:get_inventory():get_lists(), ""; j = 1
for k, _ in pairs(list2) do
inv_list2 = inv_list2 .. F(S(k)) .. ","
if k == inv2m then inv2 = j; end; j = j + 1
end
inventory_list1 = "label[5.5,0.7;" .. F(S("Source inventory")) .. "]dropdown[5.5,0.9;2.25,0.8;inv1;" ..
inv_list1:gsub(",$", "") .. ";" .. inv1 .. "]"
inventory_list2 = "label[5.5,3.85;" .. F(S("Target inventory")) .. "]dropdown[5.5,4.05;2.25,0.8;inv2;" ..
inv_list2:gsub(",$", "") .. ";" .. inv2 .. "]"
else
inventory_list1, inventory_list2 = "", ""
end
if mode_string == "object" then
btns_ns = ""
else
btns_ns = "button_exit[0.25,6.8;1,0.8;now;" .. F(S("Now")) ..
"]button_exit[1.5,6.8;1,0.8;show;" .. F(S("Show")) .. "]"
end
return ("formspec_version[4]size[8,7.8]tabheader[0,0;tabs;" ..
F(S("Mode of operation")) .. "," .. F(S("Where to move")) .. ";" .. seltab .. ";true;true]" ..
"label[0.25,0.3;" .. minetest.colorize("lawngreen", F(S("Input area - mover will dig here"))) ..
"]field[0.25,0.9;1,0.8;x0;" .. F(S("Source1")) .. ";" .. pos1.x .. "]field[1.5,0.9;1,0.8;y0;;" .. pos1.y ..
"]field[2.75,0.9;1,0.8;z0;;" .. pos1.z .. "]image[4,0.8;1,1;machines_pos1.png]" .. inventory_list1 ..
"field[0.25,2.15;1,0.8;x1;" .. F(S("Source2")) .. ";" .. pos11.x .. "]field[1.5,2.15;1,0.8;y1;;" .. pos11.y ..
"]field[2.75,2.15;1,0.8;z1;;" .. pos11.z .. "]image[4,2.05;1,1;machines_pos11.png]" ..
"label[0.25,3.45;" .. minetest.colorize("red", F(S("Target position - mover will move to here"))) ..
"]field[0.25,4.05;1,0.8;x2;" .. F(S("Target")) .. ";" .. pos2.x .. "]field[1.5,4.05;1,0.8;y2;;" .. pos2.y ..
"]field[2.75,4.05;1,0.8;z2;;" .. pos2.z .. "]image[4,3.95;1,1;machines_pos2.png]" .. inventory_list2 ..
"label[0.25,5.3;" .. F(S("Reverse source and target (0/1/2/3)")) ..
"]field[0.25,5.55;1,0.8;reverse;;" .. meta:get_int("reverse") .. "]" .. btns_ns ..
"button[5.5,6.8;1,0.8;help;" .. F(S("help")) .. "]button_exit[6.75,6.8;1,0.8;OK;" .. F(S("OK")) .. "]")
end
end
local predefined_id = {["normal"] = 1, ["dig"] = 2, ["drop"] = 3, ["object"] = 4, ["inventory"] = 5, ["transport"] = 6}
basic_machines.add_mover_mode = function(name, description, tr_name, func) -- just add a mode
local modes = basic_machines.get_mover("modes")
if modes.name then return end
local count = modes._count + 1
local id = predefined_id[name] or count
local tr_table = modes._tr_table; tr_table[id] = tr_name
basic_machines.set_mover("modes", {
_count = count,
_tr_table = tr_table,
[name] = {id = id, desc = description, task = func}
})
end
basic_machines.get_palette_index = function(inventory)
local palette_index
if inventory:get_count() > 0 then
palette_index = tonumber(inventory:get_meta():get("palette_index"))
end
return palette_index
end
local get_palette_index = basic_machines.get_palette_index
basic_machines.check_palette_index = function(meta, node, node_def)
local inv_stack = meta:get_inventory():get_stack("filter", 1)
local def = node_def or inv_stack:get_definition()
local inv_palette_index = get_palette_index(inv_stack)
local palette_index = minetest.strip_param2_color(node.param2, def and def.paramtype2)
if inv_palette_index ~= palette_index then
return false
end
return true, palette_index
end
basic_machines.itemstring_to_stack = function(itemstring, palette_index)
local stack = ItemStack(itemstring)
if palette_index then
stack:get_meta():set_int("palette_index", palette_index)
end
return stack
end
basic_machines.node_to_stack = function(node, paramtype2, param2)
local stack = ItemStack(node.name)
if paramtype2 then
param2 = minetest.strip_param2_color(node.param2, paramtype2)
end
if param2 then
stack:get_meta():set_int("palette_index", param2)
end
return stack
end