1
0
mirror of https://github.com/mt-mods/pipeworks.git synced 2025-06-29 14:50:41 +02:00

Fake player and wielder improvements (#126)

This commit is contained in:
OgelGames
2024-05-27 00:31:04 +10:00
committed by GitHub
parent 1225e4168b
commit 223c90e684
7 changed files with 262 additions and 752 deletions

View File

@ -1,247 +1,201 @@
local S = minetest.get_translator("pipeworks")
local assumed_eye_pos = vector.new(0, 1.5, 0)
local has_digilines = minetest.get_modpath("digilines")
local function delay(x)
return (function() return x end)
end
local function set_wielder_formspec(data, meta)
local size = "10.2,"..(7+data.wield_inv_height)
local list_background = ""
local function set_wielder_formspec(def, meta)
local width, height = def.wield_inv.width, def.wield_inv.height
local offset = 5.22 - width * 0.625
local size = "10.2,"..(6.5 + height * 1.25 + (has_digilines and 1.25 or 0))
local list_bg = ""
if minetest.get_modpath("i3") or minetest.get_modpath("mcl_formspec") then
list_background = "style_type[box;colors=#666]"
for i=0, data.wield_inv_height-1 do
for j=0, data.wield_inv_width-1 do
list_background = list_background .. "box[".. ((10-data.wield_inv_width)*0.5)+(i*1.25) ..",".. 1+(j*1.25) ..";1,1;]"
list_bg = "style_type[box;colors=#666]"
for i=0, height-1 do
for j=0, width-1 do
list_bg = list_bg.."box["..offset+(i*1.25)..","..1.25+(j*1.25)..";1,1;]"
end
end
end
meta:set_string("formspec",
"formspec_version[2]" ..
"size["..size.."]"..
pipeworks.fs_helpers.get_prepends(size)..
"item_image[0.5,0.5;1,1;"..data.name_base.."_off]"..
"label[1.5,1;"..minetest.formspec_escape(data.description).."]"..
list_background ..
"list[context;"..minetest.formspec_escape(data.wield_inv_name)..";"..((10-data.wield_inv_width)*0.5)..",1;"..data.wield_inv_width..","..data.wield_inv_height..";]"..
pipeworks.fs_helpers.get_inv((2+data.wield_inv_height)) ..
"listring[context;"..minetest.formspec_escape(data.wield_inv_name).."]" ..
"listring[current_player;main]"
)
meta:set_string("infotext", data.description)
end
local can_tool_dig_node = function(nodename, toolcaps, toolname)
--pipeworks.logger("can_tool_dig_node() STUB nodename="..tostring(nodename).." toolname="..tostring(toolname).." toolcaps: "..dump(toolcaps))
-- brief documentation of minetest.get_dig_params() as it's not yet documented in lua_api.txt:
-- takes two arguments, a node's block groups and a tool's capabilities,
-- both as they appear in their respective definitions.
-- returns a table with the following fields:
-- diggable: boolean, can this tool dig this node at all
-- time: float, time needed to dig with this tool
-- wear: int, number of wear points to inflict on the item
local nodedef = minetest.registered_nodes[nodename]
-- don't explode due to nil def in event of unknown node!
if (nodedef == nil) then return false end
local nodegroups = nodedef.groups
local diggable = minetest.get_dig_params(nodegroups, toolcaps).diggable
if not diggable then
-- a pickaxe can't actually dig leaves based on it's groups alone,
-- but a player holding one can - the game seems to fall back to the hand.
-- fall back to checking the hand's properties if the tool isn't the correct one.
local hand_caps = minetest.registered_items[""].tool_capabilities
diggable = minetest.get_dig_params(nodegroups, hand_caps).diggable
local inv_offset = 1.5 + height * 1.25
local fs = "formspec_version[2]size["..size.."]"..
pipeworks.fs_helpers.get_prepends(size)..list_bg..
"item_image[0.5,0.3;1,1;"..def.name.."_off]"..
"label[1.75,0.8;"..minetest.formspec_escape(def.description).."]"..
"list[context;"..def.wield_inv.name..";"..offset..",1.25;"..width..","..height..";]"
if has_digilines then
fs = fs.."field[1.5,"..inv_offset..";5,0.8;channel;"..S("Channel")..";${channel}]"..
"button_exit[6.5,"..inv_offset..";2,0.8;save;"..S("Save").."]"..
pipeworks.fs_helpers.get_inv(inv_offset + 1.25).."listring[]"
else
fs = fs..pipeworks.fs_helpers.get_inv(inv_offset).."listring[]"
end
return diggable
meta:set_string("formspec", fs)
meta:set_string("infotext", def.description)
end
local function wielder_on(data, wielder_pos, wielder_node)
data.fixup_node(wielder_pos, wielder_node)
if wielder_node.name ~= data.name_base.."_off" then return end
wielder_node.name = data.name_base.."_on"
minetest.swap_node(wielder_pos, wielder_node)
minetest.check_for_falling(wielder_pos)
local wielder_meta = minetest.get_meta(wielder_pos)
local inv = wielder_meta:get_inventory()
local wield_inv_name = data.wield_inv_name
local wieldindex
for i, stack in ipairs(inv:get_list(wield_inv_name)) do
if not stack:is_empty() then
wieldindex = i
break
local function wielder_action(def, pos, node, index)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
local list = inv:get_list(def.wield_inv.name)
local wield_index
if index then
if list[index] and (def.wield_hand or not list[index]:is_empty()) then
wield_index = index
end
else
for i, stack in ipairs(list) do
if not stack:is_empty() then
wield_index = i
break
end
end
end
if not wieldindex then
if not data.ghost_inv_name then return end
wield_inv_name = data.ghost_inv_name
inv:set_stack(wield_inv_name, 1, ItemStack(data.ghost_tool))
wieldindex = 1
if not wield_index and not def.wield_hand then
return
end
local dir = minetest.facedir_to_dir(wielder_node.param2)
-- under/above is currently intentionally left switched
-- even though this causes some problems with deployers and e.g. seeds
-- as there are some issues related to nodebreakers otherwise breaking 2 nodes afar.
-- solidity would have to be checked as well,
-- but would open a whole can of worms related to difference in nodebreaker/deployer behavior
-- and the problems of wielders acting on themselves if below is solid
local under_pos = vector.subtract(wielder_pos, dir)
local above_pos = vector.subtract(under_pos, dir)
local pitch
local yaw
if dir.z < 0 then
yaw = 0
pitch = 0
elseif dir.z > 0 then
yaw = math.pi
pitch = 0
elseif dir.x < 0 then
yaw = 3*math.pi/2
pitch = 0
elseif dir.x > 0 then
yaw = math.pi/2
pitch = 0
elseif dir.y > 0 then
yaw = 0
pitch = -math.pi/2
else
yaw = 0
pitch = math.pi/2
end
local virtplayer = pipeworks.create_fake_player({
name = data.masquerade_as_owner and wielder_meta:get_string("owner")
or ":pipeworks:" .. minetest.pos_to_string(wielder_pos),
formspec = wielder_meta:get_string("formspec"),
look_dir = vector.multiply(dir, -1),
look_pitch = pitch,
look_yaw = yaw,
sneak = data.sneak,
position = vector.subtract(wielder_pos, assumed_eye_pos),
local dir = minetest.facedir_to_dir(node.param2)
local fakeplayer = fakelib.create_player({
name = meta:get_string("owner"),
direction = vector.multiply(dir, -1),
position = pos,
inventory = inv,
wield_index = wieldindex,
wield_list = wield_inv_name
wield_index = wield_index or 1,
wield_list = def.wield_inv.name,
})
local pointed_thing = { type="node", under=under_pos, above=above_pos }
data.act(virtplayer, pointed_thing)
if data.eject_drops then
-- Under and above positions are intentionally switched.
local pointed = {
type = "node",
under = vector.subtract(pos, dir),
above = vector.subtract(pos, vector.multiply(dir, 2)),
}
def.action(fakeplayer, pointed)
if def.eject_drops then
for i, stack in ipairs(inv:get_list("main")) do
if not stack:is_empty() then
pipeworks.tube_inject_item(wielder_pos, wielder_pos, dir, stack)
pipeworks.tube_inject_item(pos, pos, dir, stack)
inv:set_stack("main", i, ItemStack(""))
end
end
end
end
local function wielder_off(data, pos, node)
if node.name == data.name_base.."_on" then
node.name = data.name_base.."_off"
local function wielder_on(def, pos, node)
if node.name ~= def.name.."_off" then
return
end
node.name = def.name.."_on"
minetest.swap_node(pos, node)
wielder_action(def, pos, node)
end
local function wielder_off(def, pos, node)
if node.name == def.name.."_on" then
node.name = def.name.."_off"
minetest.swap_node(pos, node)
minetest.check_for_falling(pos)
end
end
local function register_wielder(data)
data.fixup_node = data.fixup_node or function (pos, node) end
data.fixup_oldmetadata = data.fixup_oldmetadata or function (m) return m end
for _, state in ipairs({ "off", "on" }) do
local groups = { snappy=2, choppy=2, oddly_breakable_by_hand=2, mesecon=2, tubedevice=1, tubedevice_receiver=1, axey=1, handy=1, pickaxey=1 }
if state == "on" then groups.not_in_creative_inventory = 1 end
local tile_images = {}
for _, face in ipairs({ "top", "bottom", "side2", "side1", "back", "front" }) do
table.insert(tile_images, data.texture_base.."_"..face..(data.texture_stateful[face] and "_"..state or "")..".png")
local function wielder_digiline_action(def, pos, channel, msg)
local meta = minetest.get_meta(pos)
local set_channel = meta:get_string("channel")
if channel ~= set_channel then
return
end
if type(msg) ~= "table" then
if type(msg) == "string" then
if msg:sub(1, 8) == "activate" then
msg = {command = "activate", slot = tonumber(msg:sub(9))}
end
else
return
end
minetest.register_node(data.name_base.."_"..state, {
description = data.description,
tiles = tile_images,
end
if msg.command == "activate" then
local node = minetest.get_node(pos)
local index = type(msg.slot) == "number" and msg.slot or nil
wielder_action(def, pos, node, index)
end
end
function pipeworks.register_wielder(def)
for _,state in ipairs({"off", "on"}) do
local groups = {
snappy = 2, choppy = 2, oddly_breakable_by_hand = 2,
mesecon = 2, tubedevice = 1, tubedevice_receiver = 1,
axey = 1, handy = 1, pickaxey = 1,
not_in_creative_inventory = state == "on" and 1 or nil
}
minetest.register_node(def.name.."_"..state, {
description = def.description,
tiles = def.tiles[state],
paramtype2 = "facedir",
groups = groups,
is_ground_content = false,
_mcl_hardness = 0.6,
_sound_def = {
key = "node_sound_stone_defaults",
},
drop = def.name.."_off",
mesecons = {
effector = {
rules = pipeworks.rules_all,
action_on = function (pos, node)
wielder_on(data, pos, node)
action_on = function(pos, node)
wielder_on(def, pos, node)
end,
action_off = function (pos, node)
wielder_off(data, pos, node)
action_off = function(pos, node)
wielder_off(def, pos, node)
end,
},
},
digilines = {
receptor = {},
effector = {
action = function(pos, _, channel, msg)
wielder_digiline_action(def, pos, channel, msg)
end,
},
},
tube = {
can_insert = function(pos, node, stack, tubedir)
if not data.tube_permit_anteroposterior_insert then
local nodedir = minetest.facedir_to_dir(node.param2)
if vector.equals(tubedir, nodedir) or vector.equals(tubedir, vector.multiply(nodedir, -1)) then
can_insert = function(pos, node, stack, direction)
if def.eject_drops then
-- Prevent ejected items from being inserted
local dir = vector.multiply(minetest.facedir_to_dir(node.param2), -1)
if vector.equals(direction, dir) then
return false
end
end
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
return inv:room_for_item(data.wield_inv_name, stack)
local inv = minetest.get_meta(pos):get_inventory()
return inv:room_for_item(def.wield_inv.name, stack)
end,
insert_object = function(pos, node, stack, tubedir)
if not data.tube_permit_anteroposterior_insert then
local nodedir = minetest.facedir_to_dir(node.param2)
if vector.equals(tubedir, nodedir) or vector.equals(tubedir, vector.multiply(nodedir, -1)) then
return stack
end
end
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
return inv:add_item(data.wield_inv_name, stack)
insert_object = function(pos, node, stack)
local inv = minetest.get_meta(pos):get_inventory()
return inv:add_item(def.wield_inv.name, stack)
end,
input_inventory = data.wield_inv_name,
connect_sides = data.tube_connect_sides,
can_remove = function(pos, node, stack, tubedir)
input_inventory = "main",
connect_sides = def.connect_sides,
can_remove = function(pos, node, stack)
return stack:get_count()
end,
},
is_ground_content = false,
paramtype2 = "facedir",
tubelike = 1,
groups = groups,
_mcl_hardness=0.6,
_sound_def = {
key = "node_sound_stone_defaults",
},
drop = data.name_base.."_off",
on_construct = function(pos)
local meta = minetest.get_meta(pos)
set_wielder_formspec(data, meta)
local inv = meta:get_inventory()
inv:set_size(data.wield_inv_name, data.wield_inv_width*data.wield_inv_height)
if data.ghost_inv_name then
inv:set_size(data.ghost_inv_name, 1)
end
if data.eject_drops then
inv:set_size("main", 100)
inv:set_size(def.wield_inv.name, def.wield_inv.width * def.wield_inv.height)
if def.eject_drops then
inv:set_size("main", 32)
end
set_wielder_formspec(def, meta)
end,
after_place_node = function (pos, placer)
after_place_node = function(pos, placer)
pipeworks.scan_for_tube_objects(pos)
local placer_pos = placer:get_pos()
if placer_pos and placer:is_player() then placer_pos = vector.add(placer_pos, assumed_eye_pos) end
if placer_pos then
local dir = vector.subtract(pos, placer_pos)
local node = minetest.get_node(pos)
node.param2 = minetest.dir_to_facedir(dir, true)
minetest.set_node(pos, node)
if not placer then
return
end
local node = minetest.get_node(pos)
node.param2 = minetest.dir_to_facedir(placer:get_look_dir(), true)
minetest.set_node(pos, node)
minetest.get_meta(pos):set_string("owner", placer:get_player_name())
end,
can_dig = (data.can_dig_nonempty_wield_inv and delay(true) or function(pos, player)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
return inv:is_empty(data.wield_inv_name)
end),
after_dig_node = function(pos, oldnode, oldmetadata, digger)
-- The legacy-node fixup is done here in a
-- different form from the standard fixup,
-- rather than relying on a standard fixup
-- in an on_dig callback, because some
-- non-standard diggers (such as technic's
-- mining drill) don't respect on_dig.
oldmetadata = data.fixup_oldmetadata(oldmetadata)
for _, stack in ipairs(oldmetadata.inventory[data.wield_inv_name] or {}) do
for _,stack in ipairs(oldmetadata.inventory.main or {}) do
if not stack:is_empty() then
minetest.add_item(pos, stack)
end
@ -249,7 +203,6 @@ local function register_wielder(data)
pipeworks.scan_for_tube_objects(pos)
end,
on_rotate = pipeworks.on_rotate,
on_punch = data.fixup_node,
allow_metadata_inventory_put = function(pos, listname, index, stack, player)
if not pipeworks.may_configure(pos, player) then return 0 end
return stack:get_count()
@ -261,212 +214,141 @@ local function register_wielder(data)
allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player)
if not pipeworks.may_configure(pos, player) then return 0 end
return count
end
end,
on_receive_fields = function(pos, _, fields, sender)
if not fields.channel or not pipeworks.may_configure(pos, sender) then
return
end
minetest.get_meta(pos):set_string("channel", fields.channel)
end,
})
end
table.insert(pipeworks.ui_cat_tube_list, def.name.."_off")
end
local function get_tiles(name, stateful)
local tiles = {on = {}, off = {}}
for _,state in ipairs({"off", "on"}) do
for _,side in ipairs({"top", "bottom", "side2", "side1", "back", "front"}) do
local suffix = stateful[side] and "_"..state or ""
table.insert(tiles[state], "pipeworks_"..name.."_"..side..suffix..".png")
end
end
return tiles
end
if pipeworks.enable_node_breaker then
local data
-- see after end of data table for other use of these variables
local name_base = "pipeworks:nodebreaker"
local wield_inv_name = "pick"
data = {
name_base = name_base,
pipeworks.register_wielder({
name = "pipeworks:nodebreaker",
description = S("Node Breaker"),
texture_base = "pipeworks_nodebreaker",
texture_stateful = { top = true, bottom = true, side2 = true, side1 = true, front = true },
tube_connect_sides = { top=1, bottom=1, left=1, right=1, back=1 },
tube_permit_anteroposterior_insert = false,
wield_inv_name = wield_inv_name,
wield_inv_width = 1,
wield_inv_height = 1,
can_dig_nonempty_wield_inv = true,
ghost_inv_name = "ghost_pick",
ghost_tool = ":", -- hand by default
fixup_node = function (pos, node)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
-- Node breakers predating the visible pick slot
-- may have been partially updated. This code
-- fully updates them. Some have been observed
-- to have no pick slot at all; first add one.
if inv:get_size("pick") ~= 1 then
inv:set_size("pick", 1)
end
-- Originally, they had a ghost pick in a "pick"
-- inventory, no other inventory, and no form.
-- The partial update of early with-form node
-- breaker code gives them "ghost_pick" and "main"
-- inventories, but leaves the old ghost pick in
-- the "pick" inventory, and doesn't add a form.
-- First perform that partial update.
if inv:get_size("ghost_pick") ~= 1 then
inv:set_size("ghost_pick", 1)
inv:set_size("main", 100)
end
-- If the node breaker predates the visible pick
-- slot, which we can detect by it not having a
-- form, then the pick slot needs to be cleared
-- of the old ghost pick.
if (meta:get_string("formspec") or "") == "" then
inv:set_stack("pick", 1, ItemStack(""))
end
-- Finally, unconditionally set the formspec
-- and infotext. This not only makes the
-- pick slot visible for node breakers where
-- it wasn't before; it also updates the form
-- for node breakers that had an older version
-- of the form, and sets infotext where it was
-- missing for early with-form node breakers.
set_wielder_formspec(data, meta)
end,
fixup_oldmetadata = function (oldmetadata)
-- Node breakers predating the visible pick slot,
-- with node form, kept their ghost pick in an
-- inventory named "pick", the same name as the
-- later visible pick slot. The pick must be
-- removed to avoid spilling it.
if not oldmetadata.fields.formspec then
return { inventory = { pick = {} }, fields = oldmetadata.fields }
tiles = get_tiles("nodebreaker", {top = 1, bottom = 1, side2 = 1, side1 = 1, front = 1}),
connect_sides = {top = 1, bottom = 1, left = 1, right = 1, back = 1},
wield_inv = {name = "pick", width = 1, height = 1},
wield_hand = true,
eject_drops = true,
action = function(fakeplayer, pointed)
local stack = fakeplayer:get_wielded_item()
local old_stack = ItemStack(stack)
local item_def = minetest.registered_items[stack:get_name()]
if item_def.on_use then
fakeplayer:set_wielded_item(item_def.on_use(stack, fakeplayer, pointed) or stack)
else
return oldmetadata
end
end,
masquerade_as_owner = true,
sneak = false,
act = function(virtplayer, pointed_thing)
if minetest.is_protected(vector.add(virtplayer:get_pos(), assumed_eye_pos), virtplayer:get_player_name()) then
return
end
--local dname = "nodebreaker.act() "
local wieldstack = virtplayer:get_wielded_item()
local oldwieldstack = ItemStack(wieldstack)
local on_use = (minetest.registered_items[wieldstack:get_name()] or {}).on_use
if on_use then
--pipeworks.logger(dname.."invoking on_use "..tostring(on_use))
wieldstack = on_use(wieldstack, virtplayer, pointed_thing) or wieldstack
virtplayer:set_wielded_item(wieldstack)
else
local under_node = minetest.get_node(pointed_thing.under)
local def = minetest.registered_nodes[under_node.name]
if not def then
-- do not dig an unknown node
local node = minetest.get_node(pointed.under)
local node_def = minetest.registered_nodes[node.name]
if not node_def or not node_def.on_dig then
return
end
-- check that the current tool is capable of destroying the
-- target node.
-- if we can't, don't dig, and leave the wield stack unchanged.
-- note that wieldstack:get_tool_capabilities() returns hand
-- properties if the item has none of it's own.
if can_tool_dig_node(under_node.name,
wieldstack:get_tool_capabilities(),
wieldstack:get_name()) then
def.on_dig(pointed_thing.under, under_node, virtplayer)
local sound = def.sounds and def.sounds.dug
if sound then
minetest.sound_play(sound.name,
{pos=pointed_thing.under, gain=sound.gain})
-- Check if the tool can dig the node
local tool = stack:get_tool_capabilities()
if not minetest.get_dig_params(node_def.groups, tool).diggable then
-- Try using hand if tool can't dig the node
local hand = ItemStack():get_tool_capabilities()
if not minetest.get_dig_params(node_def.groups, hand).diggable then
return
end
wieldstack = virtplayer:get_wielded_item()
--~ else
--pipeworks.logger(dname.."couldn't dig node!")
end
-- This must only check for false, because `on_dig` returning nil is the same as returning true.
if node_def.on_dig(pointed.under, node, fakeplayer) == false then
return
end
local sound = node_def.sounds and node_def.sounds.dug
if sound then
minetest.sound_play(sound, {pos = pointed.under}, true)
end
stack = fakeplayer:get_wielded_item()
end
local wieldname = wieldstack:get_name()
if wieldname == oldwieldstack:get_name() then
-- don't mechanically wear out tool
if wieldstack:get_count() == oldwieldstack:get_count() and
wieldstack:get_metadata() == oldwieldstack:get_metadata() and
((minetest.registered_items[wieldstack:get_name()] or {}).wear_represents or "mechanical_wear") == "mechanical_wear" then
virtplayer:set_wielded_item(oldwieldstack)
if stack:get_name() == old_stack:get_name() then
-- Don't mechanically wear out tool
if stack:get_wear() ~= old_stack:get_wear() and stack:get_count() == old_stack:get_count()
and (item_def.wear_represents == nil or item_def.wear_represents == "mechanical_wear") then
print("replaced")
fakeplayer:set_wielded_item(old_stack)
end
elseif wieldname ~= "" then
-- tool got replaced by something else:
-- treat it as a drop
virtplayer:get_inventory():add_item("main", wieldstack)
virtplayer:set_wielded_item(ItemStack(""))
elseif not stack:is_empty() then
-- Tool got replaced by something else, treat it as a drop.
fakeplayer:get_inventory():add_item("main", stack)
fakeplayer:set_wielded_item("")
end
end,
eject_drops = true,
}
register_wielder(data)
pipeworks.ui_cat_tube_list[#pipeworks.ui_cat_tube_list+1] = "pipeworks:nodebreaker_off"
-- aliases for when someone had technic installed, but then uninstalled it but not pipeworks
})
minetest.register_alias("technic:nodebreaker_off", "pipeworks:nodebreaker_off")
minetest.register_alias("technic:nodebreaker_on", "pipeworks:nodebreaker_on")
minetest.register_alias("technic:node_breaker_off", "pipeworks:nodebreaker_off")
minetest.register_alias("technic:node_breaker_on", "pipeworks:nodebreaker_on")
-- turn legacy auto-tree-taps into node breakers
dofile(pipeworks.modpath.."/legacy.lua")
-- register LBM for transition to cheaper node breakers
local lbm_id = "pipeworks:refund_node_breaker_pick"
minetest.register_lbm({
name = lbm_id,
label = "Give back mese pick for pre-transition node breakers",
run_at_every_load = false,
nodenames = { name_base.."_on", name_base.."_off" },
action = function(pos, node)
pipeworks.logger(lbm_id.." entry, nodename="..node.name)
local invref = minetest.get_meta(pos):get_inventory()
invref:add_item(wield_inv_name, ItemStack("default:pick_mese"))
end
})
minetest.register_alias("auto_tree_tap:off", "pipeworks:nodebreaker_off")
minetest.register_alias("auto_tree_tap:on", "pipeworks:nodebreaker_on")
end
if pipeworks.enable_deployer then
register_wielder({
name_base = "pipeworks:deployer",
pipeworks.register_wielder({
name = "pipeworks:deployer",
description = S("Deployer"),
texture_base = "pipeworks_deployer",
texture_stateful = { front = true },
tube_connect_sides = { back=1 },
tube_permit_anteroposterior_insert = true,
wield_inv_name = "main",
wield_inv_width = 3,
wield_inv_height = 3,
can_dig_nonempty_wield_inv = false,
masquerade_as_owner = true,
sneak = false,
act = function(virtplayer, pointed_thing)
if minetest.is_protected(vector.add(virtplayer:get_pos(), assumed_eye_pos), virtplayer:get_player_name()) then
return
tiles = get_tiles("deployer", {front = 1}),
connect_sides = {back = 1},
wield_inv = {name = "main", width = 3, height = 3},
action = function(fakeplayer, pointed)
local stack = fakeplayer:get_wielded_item()
local def = minetest.registered_items[stack:get_name()]
if def and def.on_place then
local new_stack, placed_pos = def.on_place(stack, fakeplayer, pointed)
fakeplayer:set_wielded_item(new_stack or stack)
-- minetest.item_place_node doesn't play sound to the placer
local sound = placed_pos and def.sounds and def.sounds.place
local name = fakeplayer:get_player_name()
if sound and name ~= "" then
minetest.sound_play(sound, {pos = placed_pos, to_player = name}, true)
end
end
local wieldstack = virtplayer:get_wielded_item()
virtplayer:set_wielded_item((minetest.registered_items[wieldstack:get_name()] or {on_place=minetest.item_place}).on_place(wieldstack, virtplayer, pointed_thing) or wieldstack)
end,
eject_drops = false,
})
pipeworks.ui_cat_tube_list[#pipeworks.ui_cat_tube_list+1] = "pipeworks:deployer_off"
-- aliases for when someone had technic installed, but then uninstalled it but not pipeworks
minetest.register_alias("technic:deployer_off", "pipeworks:deployer_off")
minetest.register_alias("technic:deployer_on", "pipeworks:deployer_on")
end
if pipeworks.enable_dispenser then
register_wielder({
name_base = "pipeworks:dispenser",
-- Override minetest.item_drop to negate its hardcoded offset
-- when the dropper is a fake player.
local item_drop = minetest.item_drop
-- luacheck: ignore 122
function minetest.item_drop(stack, dropper, pos)
if dropper and dropper.is_fake_player then
pos = vector.new(pos.x, pos.y - 1.2, pos.z)
end
return item_drop(stack, dropper, pos)
end
pipeworks.register_wielder({
name = "pipeworks:dispenser",
description = S("Dispenser"),
texture_base = "pipeworks_dispenser",
texture_stateful = { front = true },
tube_connect_sides = { back=1 },
tube_permit_anteroposterior_insert = true,
wield_inv_name = "main",
wield_inv_width = 3,
wield_inv_height = 3,
can_dig_nonempty_wield_inv = false,
masquerade_as_owner = false,
sneak = true,
act = function(virtplayer, pointed_thing)
local wieldstack = virtplayer:get_wielded_item()
virtplayer:set_wielded_item((minetest.registered_items[wieldstack:get_name()] or
{on_drop=minetest.item_drop}).on_drop(wieldstack, virtplayer, virtplayer:get_pos()) or
wieldstack)
tiles = get_tiles("dispenser", {front = 1}),
connect_sides = {back = 1},
wield_inv = {name = "main", width = 3, height = 3},
action = function(fakeplayer)
local stack = fakeplayer:get_wielded_item()
local def = minetest.registered_items[stack:get_name()]
if def and def.on_drop then
local pos = fakeplayer:get_pos()
fakeplayer:set_wielded_item(def.on_drop(stack, fakeplayer, pos) or stack)
end
end,
eject_drops = false,
})
pipeworks.ui_cat_tube_list[#pipeworks.ui_cat_tube_list+1] = "pipeworks:dispenser_off"
end