interact directly with machine blocks when marks displayed hold sneak and punch a block to abort interactive setup allow removing keypad password add place sounds for mover in normal, dig and transport modes somewhat rework player punch in space code maintenance
117 lines
3.6 KiB
Lua
117 lines
3.6 KiB
Lua
-- (c) 2015-2016 rnd
|
|
-- Copyright (C) 2022-2024 мтест
|
|
-- See README.md for license details
|
|
|
|
local F, S = basic_machines.F, basic_machines.S
|
|
local mover_bonemeal_table = basic_machines.get_mover("bonemeal_table")
|
|
local mover_chests = basic_machines.get_mover("chests")
|
|
local check_palette_index = basic_machines.check_palette_index
|
|
local node_to_stack = basic_machines.node_to_stack
|
|
local vplayer = {}
|
|
|
|
minetest.register_on_leaveplayer(function(player)
|
|
vplayer[player:get_player_name()] = nil
|
|
end)
|
|
|
|
local function create_virtual_player(name)
|
|
return {is_player = function() return true end,
|
|
get_player_name = function() return name end,
|
|
get_player_control = function() return {} end}
|
|
end
|
|
|
|
local function drop(_, meta, owner, prefer, pos1, node1, node1_name, source_chest, pos2, mreverse)
|
|
prefer = prefer or meta:get_string("prefer")
|
|
source_chest = source_chest or mover_chests[node1_name]
|
|
local bonemeal, node1_param2
|
|
|
|
-- checks
|
|
if prefer ~= "" then -- filter check
|
|
if source_chest then
|
|
if mreverse == 1 then
|
|
bonemeal = mover_bonemeal_table[prefer]
|
|
end
|
|
elseif prefer == node1_name then -- only take preferred node
|
|
local valid
|
|
valid, node1_param2 = check_palette_index(meta, node1) -- only take preferred node with palette_index
|
|
if not valid then
|
|
return
|
|
end
|
|
else
|
|
return
|
|
end
|
|
elseif source_chest then -- prefer == "", doesn't know what to take out of chest
|
|
return
|
|
end
|
|
|
|
-- drop items
|
|
if source_chest then -- take items from chest (filter needed)
|
|
if bonemeal then -- use bonemeal
|
|
local stack = ItemStack(prefer)
|
|
|
|
local inv = minetest.get_meta(pos1):get_inventory()
|
|
if inv:contains_item("main", stack) then
|
|
inv:remove_item("main", stack)
|
|
else
|
|
return
|
|
end
|
|
|
|
local on_use = (minetest.registered_items[prefer] or {}).on_use
|
|
if on_use then
|
|
vplayer[owner] = vplayer[owner] or create_virtual_player(owner)
|
|
local itemstack = on_use(ItemStack(prefer .. " 2"),
|
|
vplayer[owner], {type = "node", under = pos2,
|
|
above = {x = pos2.x, y = pos2.y + 1, z = pos2.z}})
|
|
bonemeal = itemstack and itemstack:get_count() == 1 or
|
|
basic_machines.creative(owner)
|
|
if not bonemeal then -- bonemeal not used, drop it
|
|
minetest.add_item(pos2, stack)
|
|
end
|
|
else
|
|
return
|
|
end
|
|
elseif minetest.get_node(pos2).name == "air" then -- drop items
|
|
local stack, removed_items = ItemStack(prefer)
|
|
|
|
local inv = minetest.get_meta(pos1):get_inventory()
|
|
if inv:contains_item("main", stack) then
|
|
if (stack:to_table() or {}).metadata == "" then
|
|
removed_items = inv:remove_item("main", stack)
|
|
else
|
|
inv:remove_item("main", stack)
|
|
end
|
|
elseif prefer == node1_name and inv:is_empty("main") then -- remove chest only if empty
|
|
minetest.remove_node(pos1)
|
|
else
|
|
return
|
|
end
|
|
|
|
minetest.add_item(pos2, removed_items or stack)
|
|
else -- nothing to do
|
|
return
|
|
end
|
|
elseif minetest.get_node(pos2).name == "air" then -- drop node
|
|
minetest.remove_node(pos1)
|
|
|
|
if prefer ~= "" then
|
|
minetest.add_item(pos2, node_to_stack(node1, nil, node1_param2))
|
|
else -- without filter
|
|
local paramtype2 = (minetest.registered_nodes[node1.name] or {}).paramtype2
|
|
minetest.add_item(pos2, node_to_stack(node1, paramtype2))
|
|
end
|
|
else -- nothing to do
|
|
return
|
|
end
|
|
|
|
-- play sound
|
|
local activation_count = meta:get_int("activation_count")
|
|
-- if activation_count < 16 then
|
|
-- minetest.sound_play("basic_machines_transport", {pos = pos2, gain = 1, max_hear_distance = 8}, true)
|
|
-- end
|
|
|
|
return activation_count
|
|
end
|
|
|
|
basic_machines.add_mover_mode("drop",
|
|
F(S("This will take block/item out of chest (you need to set filter) and will drop it")),
|
|
F(S("drop")), drop
|
|
) |