219 lines
7.1 KiB
Lua
219 lines
7.1 KiB
Lua
local F, S = basic_machines.F, basic_machines.S
|
|
local mover_chests = basic_machines.get_mover("chests")
|
|
local mover_hardness = basic_machines.get_mover("hardness")
|
|
local mover_plants_table = basic_machines.get_mover("plants_table")
|
|
local machines_operations = basic_machines.properties.machines_operations
|
|
local mover_upgrade_max = basic_machines.properties.mover_upgrade_max
|
|
local check_palette_index = basic_machines.check_palette_index
|
|
local get_distance = basic_machines.get_distance
|
|
local mover_add_removed_items = basic_machines.settings.mover_add_removed_items
|
|
local node_to_stack = basic_machines.node_to_stack
|
|
local math_min = math.min
|
|
|
|
local function normal(pos, meta, owner, prefer, pos1, node1, node1_name, source_chest, pos2, mreverse, upgradetype, upgrade, fuel_cost)
|
|
prefer = prefer or meta:get_string("prefer")
|
|
source_chest = source_chest or mover_chests[node1_name]
|
|
local third_upgradetype = upgradetype == 3
|
|
local node2_name, target_chest, node_def, node1_param2, new_fuel_cost, last_pos2
|
|
|
|
-- checks
|
|
if prefer ~= "" then -- filter check
|
|
if source_chest then -- set preferred node
|
|
if not third_upgradetype then
|
|
node2_name = minetest.get_node(pos2).name
|
|
target_chest = mover_chests[node2_name]
|
|
end
|
|
if target_chest then -- allow chest transfer
|
|
node1.name = prefer
|
|
else -- set preferred node
|
|
node_def = minetest.registered_nodes[prefer]
|
|
if node_def then
|
|
node1.name = prefer
|
|
else -- (see basic_machines.check_mover_filter)
|
|
minetest.chat_send_player(owner, S("MOVER: Filter defined with unknown node (@1) at @2, @3, @4.",
|
|
prefer, pos.x, pos.y, pos.z)); return
|
|
end
|
|
end
|
|
elseif prefer == node1_name or third_upgradetype then -- only take preferred node
|
|
node_def = minetest.registered_nodes[prefer]
|
|
if node_def then
|
|
if not third_upgradetype then
|
|
local valid
|
|
valid, node1_param2 = check_palette_index(meta, node1, node_def) -- only take preferred node with palette_index
|
|
if not valid then
|
|
return
|
|
end
|
|
end
|
|
else -- (see basic_machines.check_mover_filter)
|
|
minetest.chat_send_player(owner, S("MOVER: Filter defined with unknown node (@1) at @2, @3, @4.",
|
|
prefer, pos.x, pos.y, pos.z)); return
|
|
end
|
|
else
|
|
return
|
|
end
|
|
elseif source_chest then -- prefer == "", doesn't know what to take out of chest
|
|
return
|
|
end
|
|
|
|
-- normal move
|
|
if source_chest then -- take items from chest (filter needed)
|
|
if target_chest then -- put items in chest
|
|
local stack = ItemStack(prefer); local removed_items
|
|
|
|
local inv1 = minetest.get_meta(pos1):get_inventory()
|
|
if inv1:contains_item("main", stack) then
|
|
removed_items = inv1:remove_item("main", stack)
|
|
local palette_index = removed_items:get_meta():get_int("palette_index")
|
|
if palette_index == 0 and not mover_add_removed_items then
|
|
removed_items = nil
|
|
end
|
|
else
|
|
return
|
|
end
|
|
|
|
local inv2 = minetest.get_meta(pos2):get_inventory()
|
|
inv2:add_item("main", removed_items or stack)
|
|
|
|
new_fuel_cost = fuel_cost * 0.1 -- chest to chest transport has lower cost, * 0.1
|
|
else
|
|
local air_found, node2_count
|
|
|
|
if node2_name == "air" then
|
|
air_found = true
|
|
else
|
|
node2_count = 0
|
|
for i = #pos2, 1, -1 do
|
|
if minetest.get_node(pos2[i]).name == "air" then
|
|
if not last_pos2 then last_pos2 = pos2[i] end
|
|
node2_count = node2_count + 1
|
|
else
|
|
pos2[i] = {}
|
|
end
|
|
end
|
|
if node2_count > 0 then
|
|
air_found = true
|
|
end
|
|
end
|
|
|
|
if air_found then -- take node out of chest and place it
|
|
local inv = minetest.get_meta(pos1):get_inventory()
|
|
local stack = ItemStack(prefer)
|
|
if third_upgradetype then stack:set_count(node2_count) end
|
|
if inv:contains_item("main", stack) then
|
|
local removed_items = inv:remove_item("main", stack)
|
|
local palette_index = removed_items:get_meta():get_int("palette_index")
|
|
if palette_index ~= 0 then
|
|
node1.param2 = palette_index
|
|
elseif mover_plants_table[prefer] then
|
|
node1.param2 = 1
|
|
elseif mreverse ~= 1 or node_def.paramtype2 ~= "facedir" then
|
|
node1.param2 = 0
|
|
end
|
|
else
|
|
return
|
|
end
|
|
|
|
if third_upgradetype then
|
|
if fuel_cost > 0 then
|
|
local length_pos2 = #pos2
|
|
if node2_count < length_pos2 then
|
|
new_fuel_cost = fuel_cost * (1 - node2_count / length_pos2)
|
|
end
|
|
end
|
|
|
|
minetest.bulk_set_node(pos2, node1)
|
|
else
|
|
minetest.set_node(pos2, node1)
|
|
end
|
|
else -- nothing to do
|
|
return
|
|
end
|
|
end
|
|
else
|
|
node2_name = minetest.get_node(pos2).name
|
|
|
|
if mover_chests[node2_name] then -- target_chest, put items in chest
|
|
if third_upgradetype then
|
|
local length_pos1, node1_count = #pos1, 0
|
|
local first_pos1; new_fuel_cost = 0
|
|
|
|
local inv = minetest.get_meta(pos2):get_inventory()
|
|
for i = 1, length_pos1 do
|
|
local node1i_name = node1_name[i]
|
|
if node1i_name then
|
|
if mover_chests[node1i_name] then
|
|
pos1[i] = {}
|
|
else
|
|
local items
|
|
|
|
if prefer == "" then
|
|
local node1i = node1[i]
|
|
local paramtype2 = (minetest.registered_nodes[node1i.name] or {}).paramtype2
|
|
items = inv:add_item("main", node_to_stack(node1i, paramtype2))
|
|
elseif prefer == node1i_name then
|
|
local node1i = node1[i]
|
|
local valid, node1i_param2 = check_palette_index(meta, node1i, node_def)
|
|
if valid then
|
|
items = inv:add_item("main", node_to_stack(node1i, nil, node1i_param2))
|
|
else
|
|
pos1[i] = {}
|
|
end
|
|
end
|
|
|
|
if items then
|
|
if fuel_cost > 0 then
|
|
if not first_pos1 then first_pos1 = pos1[i] end
|
|
new_fuel_cost = new_fuel_cost + (mover_hardness[node1i_name] or 1)
|
|
end
|
|
node1_count = node1_count + 1
|
|
else
|
|
pos1[i] = {}
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
if node1_count == 0 then
|
|
return
|
|
elseif new_fuel_cost > 0 then
|
|
if node1_count < length_pos1 then
|
|
new_fuel_cost = new_fuel_cost * get_distance(first_pos1, pos2) / machines_operations
|
|
new_fuel_cost = new_fuel_cost / math_min(mover_upgrade_max + 1, upgrade) -- upgrade decreases fuel cost
|
|
else
|
|
new_fuel_cost = nil
|
|
end
|
|
end
|
|
|
|
minetest.bulk_set_node(pos1, {name = "air"})
|
|
else
|
|
minetest.set_node(pos1, {name = "air"})
|
|
|
|
local inv = minetest.get_meta(pos2):get_inventory()
|
|
if prefer ~= "" then
|
|
inv:add_item("main", node_to_stack(node1, nil, node1_param2))
|
|
else -- without filter
|
|
local paramtype2 = (minetest.registered_nodes[node1.name] or {}).paramtype2
|
|
inv:add_item("main", node_to_stack(node1, paramtype2))
|
|
end
|
|
end
|
|
elseif node2_name == "air" and not third_upgradetype then -- move node from pos1 to pos2
|
|
minetest.set_node(pos1, {name = "air"})
|
|
minetest.set_node(pos2, node1)
|
|
else -- nothing to do
|
|
return
|
|
end
|
|
end
|
|
|
|
-- play sound
|
|
local activation_count = meta:get_int("activation_count")
|
|
if activation_count < 16 then
|
|
minetest.sound_play("basic_machines_transporter", {pos = last_pos2 or pos2, gain = 1, max_hear_distance = 8}, true)
|
|
end
|
|
|
|
return activation_count, new_fuel_cost
|
|
end
|
|
|
|
basic_machines.add_mover_mode("normal",
|
|
F(S("This will move blocks as they are - without change\nUpgrade with movers to process additional blocks")),
|
|
F(S("normal")), normal
|
|
) |