Skip to content

Commit

Permalink
Merge pull request #117 from S-S-X/containertool-upgrade-handling
Browse files Browse the repository at this point in the history
Containertool upgrade handling
  • Loading branch information
S-S-X authored Dec 4, 2021
2 parents 65eb904 + c51a9c1 commit 01e9c31
Show file tree
Hide file tree
Showing 9 changed files with 341 additions and 21 deletions.
2 changes: 2 additions & 0 deletions .luacheckrc
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,6 @@ read_globals = {
"signs_lib",
"display_api",
"digtron",
"drawers",
"jumpdrive",
}
4 changes: 3 additions & 1 deletion containertool/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,12 @@ w = ability to write

* technic chests (r/w)
* technic self contained injector (r/w)
* technic machines with inventory (r/w)
* technic machines with inventory (r/w + clone upgrades)
* default wooden chests (r/w)
* more_chests:shared (r/w)
* digilines:chest (r/w)
* drawers (clone upgrades)
* jumpdrive engines (clone upgrades)

## Minetest protection checks (default settings)

Expand Down
22 changes: 22 additions & 0 deletions containertool/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,24 @@ local tool = metatool:register_tool('containertool', {
},
})

-- Blacklist some nodes
local tubedevice_blacklist = {
"^technic:.*_battery_box",
"^technic:.*tool_workshop",
"^pipeworks:dispenser",
"^pipeworks:nodebreaker",
"^pipeworks:deployer",
"^digtron:",
"^jumpdrive:",
"^vacuum:",
}

local function is_blacklisted(name)
for _,value in ipairs(tubedevice_blacklist) do
if name:find(value) then return true end
end
end

local function has_digiline(name)
local nodedef = minetest.registered_nodes[name]
return nodedef and nodedef.digiline and nodedef.digiline.receptor
Expand Down Expand Up @@ -63,6 +81,7 @@ end
tool:ns({
description = description,
is_tubedevice = is_tubedevice,
is_blacklisted = is_blacklisted,
has_digiline = has_digiline,
get_digiline_channel = get_digiline_channel,
get_common_attributes = function(meta, node, pos, player)
Expand Down Expand Up @@ -116,6 +135,9 @@ tool:load_node_definition(dofile(modpath .. '/nodes/technic_chests.lua'))
tool:load_node_definition(dofile(modpath .. '/nodes/technic_injector.lua'))
tool:load_node_definition(dofile(modpath .. '/nodes/more_chests_shared.lua'))
tool:load_node_definition(dofile(modpath .. '/nodes/digilines_chest.lua'))
tool:load_node_definition(dofile(modpath .. '/nodes/technic_machines.lua'))
tool:load_node_definition(dofile(modpath .. '/nodes/drawers.lua'))
tool:load_node_definition(dofile(modpath .. '/nodes/jumpdrive.lua'))

-- Register after everything else, default behavior for nodes that seems to be compatible
minetest.register_on_mods_loaded(function()
Expand Down
2 changes: 1 addition & 1 deletion containertool/mod.conf
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name=containertool
description=Provides metatool:containertool to copy/paste container settings
depends=metatool
optional_depends=default,technic_chests,more_chests,digilines
optional_depends=default,technic_chests,more_chests,digilines,technic,drawers
22 changes: 3 additions & 19 deletions containertool/nodes/common_defaults.lua
Original file line number Diff line number Diff line change
Expand Up @@ -6,35 +6,19 @@ local ns = metatool.ns('containertool')

-- Node feature checker
local is_tubedevice = ns.is_tubedevice
local is_blacklisted = ns.is_blacklisted
-- Base metadata reader
local get_common_attributes = ns.get_common_attributes
-- Special metadata setters
local set_key_lock_secret = ns.set_key_lock_secret
local set_digiline_meta = ns.set_digiline_meta
local set_splitstacks = ns.set_splitstacks

-- Blacklist some nodes
local tubedevice_blacklist = {
"^technic:.*_battery_box",
"^technic:.*tool_workshop",
"^pipeworks:dispenser",
"^pipeworks:nodebreaker",
"^pipeworks:deployer",
"^digtron:",
"^jumpdrive:",
"^vacuum:",
}
local function blacklisted(name)
for _,value in ipairs(tubedevice_blacklist) do
if name:find(value) then return true end
end
end

-- Collect nodes and on_receive_fields callback functions
local nodes = {}
local on_receive_fields = {}
for nodename, nodedef in pairs(minetest.registered_nodes) do print(nodename)
if is_tubedevice(nodename) and not blacklisted(nodename) then
for nodename, nodedef in pairs(minetest.registered_nodes) do
if is_tubedevice(nodename) and not is_blacklisted(nodename) then
-- Match found, add to registration list
table.insert(nodes, nodename)
if nodedef.on_receive_fields then
Expand Down
101 changes: 101 additions & 0 deletions containertool/nodes/drawers.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
--
-- Register drawers for Container tool
--

if not minetest.get_modpath('drawers') then
return
end

local ns = metatool.ns('containertool')

-- Helper functions
local get_description = ns.description

local properties = {
on_construct = drawers.drawer_on_construct,
on_destruct = drawers.drawer_on_destruct,
on_dig = drawers.drawer_on_dig,
allow_metadata_inventory_put = drawers.drawer_allow_metadata_inventory_put,
-- not typo, take and put are same function in drawers API:
allow_metadata_inventory_take = drawers.drawer_allow_metadata_inventory_put,
on_metadata_inventory_put = drawers.add_drawer_upgrade,
on_metadata_inventory_take = drawers.remove_drawer_upgrade,
}

local function is_drawer(nodedef)
for key, value in pairs(properties) do
if nodedef[key] ~= value then
return false
end
end
return true
end

-- Collect nodes
local nodes = {}
for nodename, nodedef in pairs(minetest.registered_nodes) do
if is_drawer(nodedef) then
table.insert(nodes, nodename)
end
end

local definition = {
name = 'drawer',
nodes = nodes,
group = 'drawer',
protection_bypass_read = "interact",
}

function definition:copy(node, pos, player)
local meta = minetest.get_meta(pos)

local inv = meta:get_inventory()
local invlist = inv:get_list("upgrades")
local upgrades = {}
for index, stack in pairs(invlist) do
if not stack:is_empty() then
upgrades[index] = ("%s %d"):format(stack:get_name(), stack:get_count())
end
end

return {
description = get_description(meta, node, pos),
owner = meta:get("owner"),
inv = {
upgrades = upgrades,
}
}
end

function definition:paste(node, pos, player, data)
if type(data.inv) ~= "table" or type(data.inv.upgrades) ~= "table" then
return
end

-- Handle possible machine upgrades and player inventory
local meta = minetest.get_meta(pos)
local require_update = false

local playerinv = player:get_inventory()
local inv = meta:get_inventory()
for index, itemstring in pairs(data.inv.upgrades) do
if inv:get_stack("upgrades", index):is_empty() then
-- Target slot is empty, try to place upgrade item
local datastack = ItemStack(itemstring)
local itemcount = drawers.drawer_allow_metadata_inventory_put(pos, "upgrades", index, datastack, player)
-- Usually if there's space for item itemcount should be same as datastack count
if itemcount and itemcount > 0 and itemcount <= datastack:get_count() then
datastack:set_count(itemcount)
local playerstack = playerinv:remove_item("main", datastack)
inv:set_stack("upgrades", index, playerstack)
require_update = true
end
end
end

if require_update then
drawers.update_drawer_upgrades(pos)
end
end

return definition
78 changes: 78 additions & 0 deletions containertool/nodes/jumpdrive.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
--
-- Register jumpdrive engines for Container tool
--

if not minetest.get_modpath('jumpdrive') then
return
end

local definition = {
name = "jumpdrive_engine",
nodes = {
"jumpdrive:engine",
"jumpdrive:area_engine",
},
group = "jumpdrive_engine",
protection_bypass_read = "interact",
}

local ns = metatool.ns('containertool')

-- Base metadata reader and metadata setters
local get_common_attributes = ns.get_common_attributes
local set_digiline_meta = ns.set_digiline_meta

function definition:copy(node, pos, player)
local meta = minetest.get_meta(pos)

-- Read common data like owner, splitstacks, channel etc.
local data = get_common_attributes(meta, node, pos, player)

-- Get installed upgrades
data.inv = { upgrade = {} }
local inv = meta:get_inventory()
local invlist = inv:get_list("upgrade")
local upgrades = data.inv.upgrade

for index, stack in pairs(invlist) do
if not stack:is_empty() then
upgrades[index] = ("%s %d"):format(stack:get_name(), stack:get_count())
end
end

return data
end

function definition:paste(node, pos, player, data)
local meta = minetest.get_meta(pos)

-- Set common metadata values
set_digiline_meta(meta, {channel = data.channel}, node)

if type(data.inv) == "table" and type(data.inv.upgrade) == "table" then

-- Handle machine upgrades and player inventory
local require_update = false

local playerinv = player:get_inventory()
local inv = meta:get_inventory()
for index, itemstring in pairs(data.inv.upgrades) do
if inv:get_stack("upgrade", index):is_empty() then
-- Target slot is empty, try to place upgrade item
local datastack = ItemStack(itemstring)
if datastack:get_count() > 0 then
local playerstack = playerinv:remove_item("main", datastack)
inv:set_stack("upgrade", index, playerstack)
require_update = true
end
end
end

if require_update then
jumpdrive.upgrade.calculate(pos)
end
end

end

return definition
Loading

0 comments on commit 01e9c31

Please sign in to comment.