forked from mtcontrib/pipeworks
Refactor node breaker
Merge node breaker into the generic wielder mechanism. Center the wield inventory in all wielders' formspecs. Implement full auto-upgrade of legacy node breakers, occurring upon use or punching of the node breaker. Make node breaker respect on_dig hooks.
This commit is contained in:
parent
46d44eebcf
commit
7cf5e3cfb9
5
init.lua
5
init.lua
@ -122,11 +122,6 @@ if pipeworks.enable_pipe_devices then dofile(pipeworks.modpath.."/devices.lua")
|
||||
if pipeworks.enable_redefines then dofile(pipeworks.modpath.."/compat.lua") end
|
||||
if pipeworks.enable_autocrafter then dofile(pipeworks.modpath.."/autocrafter.lua") end
|
||||
|
||||
if pipeworks.enable_node_breaker then
|
||||
dofile(pipeworks.modpath.."/node_breaker.lua")
|
||||
dofile(pipeworks.modpath.."/legacy.lua")
|
||||
end
|
||||
|
||||
minetest.register_alias("pipeworks:pipe", "pipeworks:pipe_110000_empty")
|
||||
|
||||
print("Pipeworks loaded!")
|
||||
|
@ -14,6 +14,7 @@ if not minetest.get_modpath("auto_tree_tap") and
|
||||
inv:set_size("ghost_pick", 1)
|
||||
inv:set_size("main", 100)
|
||||
minetest.set_node(pos, {name = "pipeworks:nodebreaker_off", param2 = fdir})
|
||||
minetest.registered_nodes["pipeworks:nodebreaker_off"].on_punch(pos, node)
|
||||
inv:set_stack("pick", 1, ItemStack("technic:treetap"))
|
||||
end
|
||||
})
|
||||
|
413
node_breaker.lua
413
node_breaker.lua
@ -1,413 +0,0 @@
|
||||
|
||||
--register 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") --old name
|
||||
minetest.register_alias("technic:node_breaker_on", "pipeworks:nodebreaker_on") --old name
|
||||
|
||||
minetest.register_craft({
|
||||
output = 'pipeworks:nodebreaker_off 1',
|
||||
recipe = {
|
||||
{'group:wood', 'default:pick_mese','group:wood'},
|
||||
{'default:stone', 'mesecons:piston','default:stone'},
|
||||
{'default:stone', 'mesecons:mesecon','default:stone'},
|
||||
}
|
||||
})
|
||||
|
||||
local function swap_node(pos, name)
|
||||
local node = minetest.get_node(pos)
|
||||
if node.name == name then
|
||||
return
|
||||
end
|
||||
node.name = name
|
||||
minetest.swap_node(pos, node)
|
||||
end
|
||||
|
||||
--define the functions from https://github.com/minetest/minetest/pull/834 while waiting for the devs to notice it
|
||||
local function dir_to_facedir(dir, is6d)
|
||||
--account for y if requested
|
||||
if is6d and math.abs(dir.y) > math.abs(dir.x) and math.abs(dir.y) > math.abs(dir.z) then
|
||||
|
||||
--from above
|
||||
if dir.y < 0 then
|
||||
if math.abs(dir.x) > math.abs(dir.z) then
|
||||
if dir.x < 0 then
|
||||
return 19
|
||||
else
|
||||
return 13
|
||||
end
|
||||
else
|
||||
if dir.z < 0 then
|
||||
return 10
|
||||
else
|
||||
return 4
|
||||
end
|
||||
end
|
||||
|
||||
--from below
|
||||
else
|
||||
if math.abs(dir.x) > math.abs(dir.z) then
|
||||
if dir.x < 0 then
|
||||
return 15
|
||||
else
|
||||
return 17
|
||||
end
|
||||
else
|
||||
if dir.z < 0 then
|
||||
return 6
|
||||
else
|
||||
return 8
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--otherwise, place horizontally
|
||||
elseif math.abs(dir.x) > math.abs(dir.z) then
|
||||
if dir.x < 0 then
|
||||
return 3
|
||||
else
|
||||
return 1
|
||||
end
|
||||
else
|
||||
if dir.z < 0 then
|
||||
return 2
|
||||
else
|
||||
return 0
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function delay(x)
|
||||
return (function() return x end)
|
||||
end
|
||||
|
||||
local function break_node (pos, facedir)
|
||||
--locate the outgoing velocity, front, and back of the node via facedir_to_dir
|
||||
if type(facedir) ~= "number" or facedir < 0 or facedir > 23 then return end
|
||||
|
||||
local vel = minetest.facedir_to_dir(facedir)
|
||||
local front = {x=pos.x - vel.x, y=pos.y - vel.y, z=pos.z - vel.z}
|
||||
|
||||
local node = minetest.get_node(front)
|
||||
--if node.name == "air" or node.name == "ignore" then
|
||||
-- return nil
|
||||
--elseif minetest.registered_nodes[node.name] and minetest.registered_nodes[node.name].liquidtype ~= "none" then
|
||||
-- return nil
|
||||
--end
|
||||
local meta = minetest.get_meta(pos)
|
||||
local inv = meta:get_inventory()
|
||||
|
||||
if inv:get_size("ghost_pick") ~= 1 then -- Legacy code
|
||||
inv:set_size("ghost_pick", 1)
|
||||
inv:set_size("main", 100)
|
||||
end
|
||||
|
||||
local pick_inv = "pick"
|
||||
local pick = inv:get_stack("pick", 1)
|
||||
if pick:is_empty() then
|
||||
pick = ItemStack("default:pick_mese")
|
||||
inv:set_stack("ghost_pick", 1, pick)
|
||||
pick_inv = "ghost_pick"
|
||||
end
|
||||
local pitch
|
||||
local yaw
|
||||
if vel.z < 0 then
|
||||
yaw = 0
|
||||
pitch = 0
|
||||
elseif vel.z > 0 then
|
||||
yaw = math.pi
|
||||
pitch = 0
|
||||
elseif vel.x < 0 then
|
||||
yaw = 3*math.pi/2
|
||||
pitch = 0
|
||||
elseif vel.x > 0 then
|
||||
yaw = math.pi/2
|
||||
pitch = 0
|
||||
elseif vel.y > 0 then
|
||||
yaw = 0
|
||||
pitch = -math.pi/2
|
||||
else
|
||||
yaw = 0
|
||||
pitch = math.pi/2
|
||||
end
|
||||
local digger = {
|
||||
get_inventory_formspec = delay(""),
|
||||
get_look_dir = delay({x = -vel.x, y = -vel.y, z = -vel.z}),
|
||||
get_look_pitch = delay(pitch),
|
||||
get_look_yaw = delay(yaw),
|
||||
get_player_control = delay({jump=false, right=false, left=false, LMB=false, RMB=false, sneak=false, aux1=false, down=false, up=false}),
|
||||
get_player_control_bits = delay(0),
|
||||
get_player_name = delay(meta:get_string("owner")),
|
||||
is_player = delay(true),
|
||||
is_fake_player = true,
|
||||
set_inventory_formspec = delay(),
|
||||
getpos = delay({x = pos.x, y = pos.y - 1.5, z = pos.z}), -- Player height
|
||||
get_hp = delay(20),
|
||||
get_inventory = delay(inv),
|
||||
get_wielded_item = delay(pick),
|
||||
get_wield_index = delay(1),
|
||||
get_wield_list = delay(pick_inv),
|
||||
moveto = delay(),
|
||||
punch = delay(),
|
||||
remove = delay(),
|
||||
right_click = delay(),
|
||||
setpos = delay(),
|
||||
set_hp = delay(),
|
||||
set_properties = delay(),
|
||||
set_wielded_item = function(self, stack)
|
||||
if stack:get_name() == pick:get_name() then
|
||||
inv:set_stack(pick_inv, 1, stack)
|
||||
else
|
||||
inv:add_item("main", stack)
|
||||
inv:set_stack(pick_inv, 1, ItemStack(""))
|
||||
end
|
||||
end,
|
||||
set_animation = delay(),
|
||||
set_attach = delay(),
|
||||
set_detach = delay(),
|
||||
set_bone_position = delay(),
|
||||
}
|
||||
|
||||
local pickdef = minetest.registered_items[pick:get_name()]
|
||||
local pickcopy = ItemStack(pick)
|
||||
if pick_inv == "pick" and pickdef and pickdef.on_use then
|
||||
local pos_under, pos_above = {x = pos.x - vel.x, y = pos.y - vel.y, z = pos.z - vel.z}, {x = pos.x - 2*vel.x, y = pos.y - 2*vel.y, z = pos.z - 2*vel.z}
|
||||
local pointed_thing = {type="node", under=pos_under, above=pos_above}
|
||||
inv:set_stack(pick_inv, 1, pickdef.on_use(pick, digger, pointed_thing) or pick)
|
||||
else
|
||||
minetest.node_dig(front, node, digger)
|
||||
end
|
||||
|
||||
|
||||
local newpick = inv:get_stack(pick_inv, 1)
|
||||
if newpick:get_name() == pickcopy:get_name() and newpick:get_count() == pickcopy:get_count() and newpick:get_metadata() == pickcopy:get_metadata() and pickdef and (not pickdef.wear_represents or pickdef.wear_represents == "mechanical_wear") then
|
||||
inv:set_stack(pick_inv, 1, pickcopy) -- Do not wear pick out
|
||||
end
|
||||
|
||||
for i = 1, 100 do
|
||||
local dropped_item = inv:get_stack("main", i)
|
||||
if not dropped_item:is_empty() then
|
||||
local item1 = pipeworks.tube_item({x=pos.x, y=pos.y, z=pos.z}, dropped_item)
|
||||
item1:get_luaentity().start_pos = {x=pos.x, y=pos.y, z=pos.z}
|
||||
item1:setvelocity(vel)
|
||||
item1:setacceleration({x=0, y=0, z=0})
|
||||
inv:set_stack("main", i, ItemStack(""))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local node_breaker_on = function(pos, node)
|
||||
if node.name == "pipeworks:nodebreaker_off" then
|
||||
swap_node(pos, "pipeworks:nodebreaker_on")
|
||||
break_node(pos, node.param2)
|
||||
nodeupdate(pos)
|
||||
end
|
||||
end
|
||||
|
||||
local node_breaker_off = function(pos, node)
|
||||
if node.name == "pipeworks:nodebreaker_on" then
|
||||
swap_node(pos, "pipeworks:nodebreaker_off")
|
||||
nodeupdate(pos)
|
||||
end
|
||||
end
|
||||
|
||||
minetest.register_node("pipeworks:nodebreaker_off", {
|
||||
description = "Node Breaker",
|
||||
tile_images = {"pipeworks_nodebreaker_top_off.png","pipeworks_nodebreaker_bottom_off.png","pipeworks_nodebreaker_side2_off.png","pipeworks_nodebreaker_side1_off.png",
|
||||
"pipeworks_nodebreaker_back.png","pipeworks_nodebreaker_front_off.png"},
|
||||
is_ground_content = true,
|
||||
paramtype2 = "facedir",
|
||||
groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2, mesecon = 2,tubedevice=1, tubedevice_receiver=1},
|
||||
mesecons= {effector={rules=pipeworks.rules_all,action_on=node_breaker_on, action_off=node_breaker_off}},
|
||||
sounds = default.node_sound_stone_defaults(),
|
||||
tube = {connect_sides = {left = 1, right = 1, back = 1, top = 1, bottom = 1},
|
||||
input_inventory = "pick",
|
||||
insert_object = function(pos, node, stack, direction)
|
||||
local vel = minetest.facedir_to_dir(node.param2)
|
||||
if math.abs(vel.x) == math.abs(direction.x) and math.abs(vel.y) == math.abs(direction.y) and math.abs(vel.z) == math.abs(direction.z) then
|
||||
return stack
|
||||
end
|
||||
local meta = minetest.get_meta(pos)
|
||||
local inv = meta:get_inventory()
|
||||
return inv:add_item("pick", stack)
|
||||
end,
|
||||
can_insert = function(pos, node, stack, direction)
|
||||
local vel = minetest.facedir_to_dir(node.param2)
|
||||
if math.abs(vel.x) == math.abs(direction.x) and math.abs(vel.y) == math.abs(direction.y) and math.abs(vel.z) == math.abs(direction.z) then
|
||||
return false
|
||||
end
|
||||
local meta = minetest.get_meta(pos)
|
||||
local inv = meta:get_inventory()
|
||||
return inv:room_for_item("pick", stack)
|
||||
end,
|
||||
can_remove = function(pos, node, stack, dir)
|
||||
return stack:get_count()
|
||||
end},
|
||||
on_construct = function(pos)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local inv = meta:get_inventory()
|
||||
inv:set_size("pick", 1)
|
||||
inv:set_size("ghost_pick", 1)
|
||||
inv:set_size("main", 100)
|
||||
--inv:set_stack("pick", 1, ItemStack("default:pick_mese"))
|
||||
meta:set_string("formspec",
|
||||
"invsize[8,6;]"..
|
||||
"label[0,0;Node breaker]"..
|
||||
"list[current_name;pick;3.5,0;1,1;]"..
|
||||
"list[current_player;main;0,2;8,4;]")
|
||||
meta:set_string("infotext", "Node Breaker")
|
||||
end,
|
||||
after_place_node = function (pos, placer)
|
||||
pipeworks.scan_for_tube_objects(pos, placer)
|
||||
local placer_pos = placer:getpos()
|
||||
|
||||
--correct for the player's height
|
||||
if placer:is_player() then placer_pos.y = placer_pos.y + 1.5 end
|
||||
|
||||
--correct for 6d facedir
|
||||
if placer_pos then
|
||||
local dir = {
|
||||
x = pos.x - placer_pos.x,
|
||||
y = pos.y - placer_pos.y,
|
||||
z = pos.z - placer_pos.z
|
||||
}
|
||||
local node = minetest.get_node(pos)
|
||||
node.param2 = dir_to_facedir(dir, true)
|
||||
minetest.set_node(pos, node)
|
||||
minetest.log("action", "real (6d) facedir: " .. node.param2)
|
||||
end
|
||||
|
||||
minetest.get_meta(pos):set_string("owner", placer:get_player_name())
|
||||
end,
|
||||
after_dig_node = function(pos, oldnode, oldmetadata, digger)
|
||||
if oldmetadata.inventory.pick and oldmetadata.fields.formspec then
|
||||
local stack = oldmetadata.inventory.pick[1]
|
||||
if not stack:is_empty() then
|
||||
minetest.add_item(pos, stack)
|
||||
end
|
||||
end
|
||||
pipeworks.scan_for_tube_objects(pos, oldnode, oldmetadata, digger)
|
||||
end,
|
||||
allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player)
|
||||
local meta = minetest.get_meta(pos)
|
||||
if player:get_player_name() ~= meta:get_string("owner") and meta:get_string("owner") ~= "" then
|
||||
return 0
|
||||
end
|
||||
return count
|
||||
end,
|
||||
allow_metadata_inventory_put = function(pos, listname, index, stack, player)
|
||||
local meta = minetest.get_meta(pos)
|
||||
if player:get_player_name() ~= meta:get_string("owner") and meta:get_string("owner") ~= "" then
|
||||
return 0
|
||||
end
|
||||
return stack:get_count()
|
||||
end,
|
||||
allow_metadata_inventory_take = function(pos, listname, index, stack, player)
|
||||
local meta = minetest.get_meta(pos)
|
||||
if player:get_player_name() ~= meta:get_string("owner") and meta:get_string("owner") ~= "" then
|
||||
return 0
|
||||
end
|
||||
return stack:get_count()
|
||||
end
|
||||
})
|
||||
|
||||
minetest.register_node("pipeworks:nodebreaker_on", {
|
||||
description = "Node Breaker",
|
||||
tile_images = {"pipeworks_nodebreaker_top_on.png","pipeworks_nodebreaker_bottom_on.png","pipeworks_nodebreaker_side2_on.png","pipeworks_nodebreaker_side1_on.png",
|
||||
"pipeworks_nodebreaker_back.png","pipeworks_nodebreaker_front_on.png"},
|
||||
mesecons= {effector={rules=pipeworks.rules_all,action_on=node_breaker_on, action_off=node_breaker_off}},
|
||||
is_ground_content = true,
|
||||
paramtype2 = "facedir",
|
||||
groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2, mesecon = 2,tubedevice=1,not_in_creative_inventory=1, tubedevice_receiver=1},
|
||||
sounds = default.node_sound_stone_defaults(),
|
||||
drop = "pipeworks:nodebreaker_off",
|
||||
tube = {connect_sides = {left = 1, right = 1, back = 1, top = 1, bottom = 1},
|
||||
input_inventory = "pick",
|
||||
insert_object = function(pos, node, stack, direction)
|
||||
local vel = minetest.facedir_to_dir(node.param2)
|
||||
if math.abs(vel.x) == math.abs(direction.x) and math.abs(vel.y) == math.abs(direction.y) and math.abs(vel.z) == math.abs(direction.z) then
|
||||
return stack
|
||||
end
|
||||
local meta = minetest.get_meta(pos)
|
||||
local inv = meta:get_inventory()
|
||||
return inv:add_item("pick", stack)
|
||||
end,
|
||||
can_insert = function(pos, node, stack, direction)
|
||||
local vel = minetest.facedir_to_dir(node.param2)
|
||||
if math.abs(vel.x) == math.abs(direction.x) and math.abs(vel.y) == math.abs(direction.y) and math.abs(vel.z) == math.abs(direction.z) then
|
||||
return false
|
||||
end
|
||||
local meta = minetest.get_meta(pos)
|
||||
local inv = meta:get_inventory()
|
||||
return inv:room_for_item("pick", stack)
|
||||
end,
|
||||
can_remove = function(pos, node, stack, dir)
|
||||
return stack:get_count()
|
||||
end},
|
||||
on_construct = function(pos)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local inv = meta:get_inventory()
|
||||
inv:set_size("pick", 1)
|
||||
inv:set_size("ghost_pick", 1)
|
||||
inv:set_size("main", 100)
|
||||
meta:set_string("formspec",
|
||||
"invsize[8,6;]"..
|
||||
"label[0,0;Node breaker]"..
|
||||
"list[current_name;pick;3.5,0;1,1;]"..
|
||||
"list[current_player;main;0,2;8,4;]")
|
||||
--inv:set_stack("pick", 1, ItemStack("default:pick_mese"))
|
||||
meta:set_string("infotext", "Node Breaker")
|
||||
end,
|
||||
after_place_node = function (pos, placer)
|
||||
pipeworks.scan_for_tube_objects(pos, placer)
|
||||
local placer_pos = placer:getpos()
|
||||
|
||||
--correct for the player's height
|
||||
if placer:is_player() then placer_pos.y = placer_pos.y + 1.5 end
|
||||
|
||||
--correct for 6d facedir
|
||||
if placer_pos then
|
||||
local dir = {
|
||||
x = pos.x - placer_pos.x,
|
||||
y = pos.y - placer_pos.y,
|
||||
z = pos.z - placer_pos.z
|
||||
}
|
||||
local node = minetest.get_node(pos)
|
||||
node.param2 = dir_to_facedir(dir, true)
|
||||
minetest.set_node(pos, node)
|
||||
minetest.log("action", "real (6d) facedir: " .. node.param2)
|
||||
end
|
||||
|
||||
minetest.get_meta(pos):set_string("owner", placer:get_player_name())
|
||||
end,
|
||||
after_dig_node = function(pos, oldnode, oldmetadata, digger)
|
||||
if oldmetadata.inventory.pick and oldmetadata.fields.formspec then
|
||||
local stack = oldmetadata.inventory.pick[1]
|
||||
if not stack:is_empty() then
|
||||
minetest.add_item(pos, stack)
|
||||
end
|
||||
end
|
||||
pipeworks.scan_for_tube_objects(pos, oldnode, oldmetadata, digger)
|
||||
end,
|
||||
allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player)
|
||||
local meta = minetest.get_meta(pos)
|
||||
if player:get_player_name() ~= meta:get_string("owner") and meta:get_string("owner") ~= "" then
|
||||
return 0
|
||||
end
|
||||
return count
|
||||
end,
|
||||
allow_metadata_inventory_put = function(pos, listname, index, stack, player)
|
||||
local meta = minetest.get_meta(pos)
|
||||
if player:get_player_name() ~= meta:get_string("owner") and meta:get_string("owner") ~= "" then
|
||||
return 0
|
||||
end
|
||||
return stack:get_count()
|
||||
end,
|
||||
allow_metadata_inventory_take = function(pos, listname, index, stack, player)
|
||||
local meta = minetest.get_meta(pos)
|
||||
if player:get_player_name() ~= meta:get_string("owner") and meta:get_string("owner") ~= "" then
|
||||
return 0
|
||||
end
|
||||
return stack:get_count()
|
||||
end
|
||||
})
|
248
wielder.lua
248
wielder.lua
@ -1,26 +1,47 @@
|
||||
local assumed_eye_pos = vector.new(0, 1.5, 0)
|
||||
|
||||
local function vector_copy(v)
|
||||
return { x = v.x, y = v.y, z = v.z }
|
||||
end
|
||||
|
||||
local function delay(x)
|
||||
return (function() return x end)
|
||||
end
|
||||
|
||||
local function set_wielder_formspec(data, meta)
|
||||
meta:set_string("formspec",
|
||||
"invsize[8,"..(6+data.wield_inv_height)..";]"..
|
||||
"item_image[0,0;1,1;"..data.name_base.."_off]"..
|
||||
"label[1,0;"..minetest.formspec_escape(data.description).."]"..
|
||||
"list[current_name;"..minetest.formspec_escape(data.wield_inv_name)..";"..((8-data.wield_inv_width)*0.5)..",1;"..data.wield_inv_width..","..data.wield_inv_height..";]"..
|
||||
"list[current_player;main;0,"..(2+data.wield_inv_height)..";8,4;]")
|
||||
meta:set_string("infotext", data.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)
|
||||
nodeupdate(wielder_pos)
|
||||
local wielder_meta = minetest.get_meta(wielder_pos)
|
||||
local inv = wielder_meta:get_inventory()
|
||||
local invlist = inv:get_list("main")
|
||||
local wield_inv_name = data.wield_inv_name
|
||||
local wieldindex, wieldstack
|
||||
for i, stack in ipairs(invlist) do
|
||||
for i, stack in ipairs(inv:get_list(wield_inv_name)) do
|
||||
if not stack:is_empty() then
|
||||
wieldindex = i
|
||||
wieldstack = stack
|
||||
break
|
||||
end
|
||||
end
|
||||
if not wieldindex then return 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
|
||||
wieldstack = inv:get_stack(wield_inv_name, 1)
|
||||
end
|
||||
local dir = minetest.facedir_to_dir(wielder_node.param2)
|
||||
local under_pos = vector.subtract(wielder_pos, dir)
|
||||
local above_pos = vector.subtract(under_pos, dir)
|
||||
@ -61,7 +82,7 @@ local function wielder_on(data, wielder_pos, wielder_node)
|
||||
get_inventory = delay(inv),
|
||||
get_wielded_item = delay(wieldstack),
|
||||
get_wield_index = delay(wieldindex),
|
||||
get_wield_list = delay("main"),
|
||||
get_wield_list = delay(wield_inv_name),
|
||||
moveto = delay(),
|
||||
punch = delay(),
|
||||
remove = delay(),
|
||||
@ -69,14 +90,25 @@ local function wielder_on(data, wielder_pos, wielder_node)
|
||||
setpos = delay(),
|
||||
set_hp = delay(),
|
||||
set_properties = delay(),
|
||||
set_wielded_item = function(self, item) inv:set_stack("main", wieldindex, item) end,
|
||||
set_wielded_item = function(self, item) inv:set_stack(wield_inv_name, wieldindex, item) end,
|
||||
set_animation = delay(),
|
||||
set_attach = delay(),
|
||||
set_detach = delay(),
|
||||
set_bone_position = delay(),
|
||||
}
|
||||
local pointed_thing = { type="node", under=under_pos, above=above_pos }
|
||||
virtplayer:set_wielded_item(data.on_act(virtplayer, pointed_thing) or wieldstack)
|
||||
data.act(virtplayer, pointed_thing)
|
||||
if data.eject_drops then
|
||||
for i, stack in ipairs(inv:get_list("main")) do
|
||||
if not stack:is_empty() then
|
||||
local tubeitem = pipeworks.tube_item(vector_copy(wielder_pos), stack)
|
||||
tubeitem:get_luaentity().start_pos = vector_copy(wielder_pos)
|
||||
tubeitem:setvelocity(vector_copy(dir))
|
||||
tubeitem:setacceleration(vector.new(0,0,0))
|
||||
inv:set_stack("main", i, ItemStack(""))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function wielder_off(data, pos, node)
|
||||
@ -88,6 +120,8 @@ local function wielder_off(data, pos, node)
|
||||
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 }
|
||||
if state == "on" then groups.not_in_creative_inventory = 1 end
|
||||
@ -110,19 +144,31 @@ local function register_wielder(data)
|
||||
},
|
||||
},
|
||||
tube = {
|
||||
insert_object = function(pos,node,stack,direction)
|
||||
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
|
||||
return false
|
||||
end
|
||||
end
|
||||
local meta = minetest.get_meta(pos)
|
||||
local inv = meta:get_inventory()
|
||||
return inv:add_item("main",stack)
|
||||
return inv:room_for_item(data.wield_inv_name, stack)
|
||||
end,
|
||||
can_insert = function(pos,node,stack,direction)
|
||||
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:room_for_item("main",stack)
|
||||
return inv:add_item(data.wield_inv_name, stack)
|
||||
end,
|
||||
input_inventory = "main",
|
||||
connect_sides = {back=1},
|
||||
can_remove = function(pos, node, stack, dir)
|
||||
input_inventory = data.wield_inv_name,
|
||||
connect_sides = data.tube_connect_sides,
|
||||
can_remove = function(pos, node, stack, tubedir)
|
||||
return stack:get_count()
|
||||
end,
|
||||
},
|
||||
@ -134,23 +180,18 @@ local function register_wielder(data)
|
||||
drop = data.name_base.."_off",
|
||||
on_construct = function(pos)
|
||||
local meta = minetest.get_meta(pos)
|
||||
meta:set_string("formspec",
|
||||
"invsize[8,9;]"..
|
||||
"item_image[0,0;1,1;"..data.name_base.."_off]"..
|
||||
"label[1,0;"..minetest.formspec_escape(data.description).."]"..
|
||||
"list[current_name;main;4,1;3,3;]"..
|
||||
"list[current_player;main;0,5;8,4;]")
|
||||
meta:set_string("infotext", data.description)
|
||||
set_wielder_formspec(data, meta)
|
||||
local inv = meta:get_inventory()
|
||||
inv:set_size("main", 3*3)
|
||||
end,
|
||||
can_dig = function(pos,player)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local inv = meta:get_inventory()
|
||||
return inv:is_empty("main")
|
||||
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)
|
||||
end
|
||||
end,
|
||||
after_place_node = function (pos, placer)
|
||||
pipeworks.scan_for_tube_objects(pos, placer)
|
||||
pipeworks.scan_for_tube_objects(pos)
|
||||
local placer_pos = placer:getpos()
|
||||
if placer_pos and placer:is_player() then placer_pos = vector.add(placer_pos, assumed_eye_pos) end
|
||||
if placer_pos then
|
||||
@ -162,7 +203,27 @@ local function register_wielder(data)
|
||||
end
|
||||
minetest.get_meta(pos):set_string("owner", placer:get_player_name())
|
||||
end,
|
||||
after_dig_node = pipeworks.scan_for_tube_objects,
|
||||
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
|
||||
if not stack:is_empty() then
|
||||
minetest.add_item(pos, stack)
|
||||
end
|
||||
end
|
||||
pipeworks.scan_for_tube_objects(pos)
|
||||
end,
|
||||
on_punch = data.fixup_node,
|
||||
allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player)
|
||||
local meta = minetest.get_meta(pos)
|
||||
if player:get_player_name() ~= meta:get_string("owner") and meta:get_string("owner") ~= "" then
|
||||
@ -188,18 +249,134 @@ local function register_wielder(data)
|
||||
end
|
||||
end
|
||||
|
||||
if pipeworks.enable_node_breaker then
|
||||
local data
|
||||
data = {
|
||||
name_base = "pipeworks:nodebreaker",
|
||||
description = "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 = "pick",
|
||||
wield_inv_width = 1,
|
||||
wield_inv_height = 1,
|
||||
can_dig_nonempty_wield_inv = true,
|
||||
ghost_inv_name = "ghost_pick",
|
||||
ghost_tool = "default:pick_mese",
|
||||
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. 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 }
|
||||
else
|
||||
return oldmetadata
|
||||
end
|
||||
end,
|
||||
masquerade_as_owner = true,
|
||||
sneak = false,
|
||||
act = function(virtplayer, pointed_thing)
|
||||
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
|
||||
virtplayer:set_wielded_item(on_use(wieldstack, virtplayer, pointed_thing) or wieldstack)
|
||||
else
|
||||
local under_node = minetest.get_node(pointed_thing.under)
|
||||
local on_dig = (minetest.registered_nodes[under_node.name] or {on_dig=minetest.node_dig}).on_dig
|
||||
on_dig(pointed_thing.under, under_node, virtplayer)
|
||||
end
|
||||
wieldstack = virtplayer:get_wielded_item()
|
||||
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)
|
||||
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(""))
|
||||
end
|
||||
end,
|
||||
eject_drops = true,
|
||||
}
|
||||
register_wielder(data)
|
||||
minetest.register_craft({
|
||||
output = "pipeworks:nodebreaker_off",
|
||||
recipe = {
|
||||
{ "group:wood", "default:pick_mese", "group:wood" },
|
||||
{ "default:stone", "mesecons:piston", "default:stone" },
|
||||
{ "default:stone", "mesecons:mesecon", "default:stone" },
|
||||
}
|
||||
})
|
||||
-- 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")
|
||||
end
|
||||
|
||||
if pipeworks.enable_deployer then
|
||||
register_wielder({
|
||||
name_base = "pipeworks:deployer",
|
||||
description = "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,
|
||||
on_act = function(virtplayer, pointed_thing)
|
||||
act = function(virtplayer, pointed_thing)
|
||||
local wieldstack = virtplayer:get_wielded_item()
|
||||
return (minetest.registered_items[wieldstack:get_name()] or {on_place=minetest.item_place}).on_place(wieldstack, virtplayer, pointed_thing)
|
||||
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,
|
||||
})
|
||||
minetest.register_craft({
|
||||
output = "pipeworks:deployer_off",
|
||||
@ -220,12 +397,19 @@ if pipeworks.enable_dispenser then
|
||||
description = "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,
|
||||
on_act = function(virtplayer, pointed_thing)
|
||||
act = function(virtplayer, pointed_thing)
|
||||
local wieldstack = virtplayer:get_wielded_item()
|
||||
return (minetest.registered_items[wieldstack:get_name()] or {on_drop=minetest.item_drop}).on_drop(wieldstack, virtplayer, virtplayer:getpos())
|
||||
virtplayer:set_wielded_item((minetest.registered_items[wieldstack:get_name()] or {on_drop=minetest.item_drop}).on_drop(wieldstack, virtplayer, virtplayer:getpos()) or wieldstack)
|
||||
end,
|
||||
eject_drops = false,
|
||||
})
|
||||
minetest.register_craft({
|
||||
output = "pipeworks:dispenser_off",
|
||||
|
Loading…
Reference in New Issue
Block a user