-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* (#55) Container tool * (#55) Very basic configuration for technic chests * (#55) Color handling for technic chests * (#55) Container tool * (#55) Very basic configuration for technic chests * (#55) Color handling for technic chests * (#55) Cleaner handling for chests, default handler for split, keys, channel * (#55) Shared chest, digiline chest * Add simple tool behavior tests * Containertool recipe * Container tool tests * Add blacklisted nodes and tool behavior tests for common_defaults * Test owned unprotected read/write Co-authored-by: SX <sx@minetest>
- Loading branch information
Showing
19 changed files
with
977 additions
and
21 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
## Container tool basics | ||
|
||
Container tool is made available for copying container settings from one node to another. | ||
For example it can be used to copy settings from one container to another. | ||
|
||
#### Copy settings from compatible nodes | ||
|
||
Hold tool in your hand and point node that you want to copy settings from, hold special or sneak button and left click on node to copy settings. | ||
Chat will display confirmation message when settings is copied into tool memory. | ||
|
||
#### Apply copied settings to compatible nodes | ||
|
||
Hold tool containing desired settings in you hand and point node that you want apply settings to. | ||
Left click with tool to apply new settings, chat will display confirmation message when settings is applied to pointed node. | ||
|
||
## Nodes compatible with Container tool | ||
|
||
r = ability to read | ||
w = ability to write | ||
|
||
* technic chests (r/w) | ||
* technic self contained injector (r/w) | ||
* technic machines with inventory (r/w) | ||
* default wooden chests (r/w) | ||
* more_chests:shared (r/w) | ||
* digilines:chest (r/w) | ||
|
||
## Minetest protection checks (default settings) | ||
|
||
Protection checks are done automatically for all tool uses, node registration does not need any protection checks. | ||
Tool can be used to read settings from protected nodes but it cannot be used to write settings to protected nodes. | ||
|
||
## Configuration | ||
|
||
Container tool configuration keys with default values (where * is any containertool node): | ||
|
||
``` | ||
metatool:containertool:nodes:*:protection_bypass_read = interact | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
-- | ||
-- metatool:containertool is in game tool that allows cloning container configuration | ||
-- | ||
|
||
local tool = metatool:register_tool('containertool', { | ||
description = 'Container tool', | ||
name = 'Container tool', | ||
texture = 'containertool.png', | ||
recipe = { | ||
{ '', '', 'default:mese_crystal' }, | ||
{ '', 'default:chest', '' }, | ||
{ 'default:skeleton_key', '', '' } | ||
}, | ||
settings = { | ||
copy_key_lock_secret = true, | ||
copy_digiline_channel = false, | ||
}, | ||
}) | ||
|
||
local function has_digiline(name) | ||
local nodedef = minetest.registered_nodes[name] | ||
return nodedef and nodedef.digiline and nodedef.digiline.receptor | ||
end | ||
|
||
local function has_key_lock(name) | ||
local nodedef = minetest.registered_nodes[name] | ||
return nodedef and type(nodedef.on_skeleton_key_use) == "function" | ||
end | ||
|
||
local function is_tubedevice(name, pos) | ||
local nodedef = minetest.registered_nodes[name] | ||
if nodedef and nodedef.groups and nodedef.groups.tubedevice_receiver then | ||
if nodedef.tube and (not pos or nodedef.tube.input_inventory) then | ||
return true | ||
elseif pos then | ||
local formspec = minetest.get_meta(pos):get("formspec") | ||
return formspec and formspec:find("fs_helpers_cycling:%d+:splitstacks") | ||
end | ||
end | ||
end | ||
|
||
local function description(meta, node, pos) | ||
local nicename = meta:get("infotext") or minetest.registered_nodes[node.name].description or node.name | ||
return ("%s at %s"):format(nicename, minetest.pos_to_string(pos)) | ||
end | ||
|
||
local function get_digiline_channel(meta, node) | ||
if tool.settings.copy_digiline_channel and has_digiline(node.name) then | ||
return meta:get_string("channel") | ||
end | ||
end | ||
|
||
local function get_key_lock_secret(meta, player, owner) | ||
if tool.settings.copy_key_lock_secret and player:get_player_name() == owner then | ||
return meta:get("key_lock_secret") | ||
end | ||
end | ||
|
||
local function get_splitstacks(meta, node, pos) | ||
return is_tubedevice(node.name, pos) and meta:get_int("splitstacks") | ||
end | ||
|
||
tool:ns({ | ||
description = description, | ||
is_tubedevice = is_tubedevice, | ||
has_digiline = has_digiline, | ||
get_digiline_channel = get_digiline_channel, | ||
get_common_attributes = function(meta, node, pos, player) | ||
local owner = meta:get("owner") | ||
return { | ||
description = description(meta, node, pos), | ||
owner = owner, | ||
key_lock_secret = get_key_lock_secret(meta, player, owner), | ||
channel = get_digiline_channel(meta, node), | ||
splitstacks = get_splitstacks(meta, node), | ||
} | ||
end, | ||
set_digiline_meta = function(meta, data, node) | ||
if has_digiline(node.name) then | ||
for key, value in pairs(data) do | ||
if key ~= "channel" or tool.settings.copy_digiline_channel then | ||
if type(value) == "string" then | ||
meta:set_string(key, value) | ||
elseif type(value) == "number" then | ||
meta:set_int(key, value) | ||
end | ||
end | ||
end | ||
end | ||
end, | ||
set_key_lock_secret = function(meta, data, node) | ||
if tool.settings.copy_key_lock_secret and data.key_lock_secret and has_key_lock(node.name) then | ||
meta:set_string("key_lock_secret", data.key_lock_secret) | ||
end | ||
end, | ||
set_splitstacks = function(meta, data, node, pos) | ||
if type(data.splitstacks) == "number" and is_tubedevice(node.name, pos) then | ||
meta:set_int("splitstacks", data.splitstacks) | ||
end | ||
end, | ||
get_int = function(meta, key) | ||
local value = meta:get(key) | ||
return value and tonumber(value) | ||
end, | ||
set_int = function(meta, key, value) | ||
if value then meta:set_int(key, value) end | ||
end, | ||
set_string = function (meta, key, value) | ||
if value then meta:set_string(key, value) end | ||
end, | ||
}) | ||
|
||
-- nodes | ||
local modpath = minetest.get_modpath('containertool') | ||
tool:load_node_definition(dofile(modpath .. '/nodes/technic_chests.lua')) | ||
tool:load_node_definition(dofile(modpath .. '/nodes/more_chests_shared.lua')) | ||
tool:load_node_definition(dofile(modpath .. '/nodes/digilines_chest.lua')) | ||
|
||
-- Register after everything else, default behavior for nodes that seems to be compatible | ||
minetest.register_on_mods_loaded(function() | ||
tool:load_node_definition(dofile(modpath .. '/nodes/common_defaults.lua')) | ||
end) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
name=containertool | ||
description=Provides metatool:containertool to copy/paste container settings | ||
depends=metatool | ||
optional_depends=default,technic_chests,more_chests,digilines |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
-- | ||
-- Register rest of compatible nodes for Container tool | ||
-- | ||
|
||
local ns = metatool.ns('containertool') | ||
|
||
-- Node feature checker | ||
local is_tubedevice = ns.is_tubedevice | ||
-- 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 | ||
-- Match found, add to registration list | ||
table.insert(nodes, nodename) | ||
if nodedef.on_receive_fields then | ||
on_receive_fields[nodename] = nodedef.on_receive_fields | ||
end | ||
end | ||
end | ||
|
||
local definition = { | ||
name = 'common_container', | ||
nodes = nodes, | ||
group = 'container', | ||
protection_bypass_read = "interact", | ||
} | ||
|
||
function definition:before_write(pos, player) | ||
-- Stay safe and check both owner and protection for unknown nodes | ||
local meta = minetest.get_meta(pos) | ||
local owner = meta:get("owner") | ||
local owner_check = owner == nil or owner == player:get_player_name() | ||
if not owner_check then | ||
minetest.record_protection_violation(pos, player:get_player_name()) | ||
end | ||
return owner_check and metatool.before_write(self, pos, player) | ||
end | ||
|
||
function definition:copy(node, pos, player) | ||
-- Read common data like owner, splitstacks, channel etc. | ||
return get_common_attributes(minetest.get_meta(pos), node, pos, player) | ||
end | ||
|
||
function definition:paste(node, pos, player, data) | ||
local meta = minetest.get_meta(pos) | ||
set_key_lock_secret(meta, data, node) | ||
set_splitstacks(meta, data, node, pos) | ||
set_digiline_meta(meta, {channel = data.channel}, node) | ||
-- Yeah, sorry... everyone just keeps their internal stuff "protected" | ||
if on_receive_fields[node.name] then | ||
if not pcall(function()on_receive_fields[node.name](pos, "", {}, player)end) then | ||
pcall(function()on_receive_fields[node.name](pos, "", {quit=1}, player)end) | ||
end | ||
end | ||
end | ||
|
||
return definition |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
-- | ||
-- Register digilines chest for containertool | ||
-- | ||
|
||
local ns = metatool.ns('containertool') | ||
local description = ns.description | ||
local get_digiline_channel = ns.get_digiline_channel | ||
|
||
local definition = { | ||
name = 'digilines_chest', | ||
nodes = "digilines:chest", | ||
group = 'container', | ||
protection_bypass_read = "interact", | ||
} | ||
|
||
function definition:copy(node, pos, player) | ||
local meta = minetest.get_meta(pos) | ||
local channel = get_digiline_channel(meta, node) | ||
if channel then | ||
return { | ||
description = description(meta, node, pos), | ||
channel = channel, | ||
} | ||
end | ||
end | ||
|
||
function definition:paste(node, pos, player, data) | ||
if data.channel and metatool.settings("containertool", "copy_digiline_channel") then | ||
local nodedef = minetest.registered_nodes[node.name] | ||
nodedef.on_receive_fields(pos, "", {channel=data.channel}, player) | ||
end | ||
end | ||
|
||
return definition |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
-- | ||
-- Register shared chest for containertool | ||
-- | ||
|
||
local ns = metatool.ns('containertool') | ||
local description = ns.description | ||
|
||
local definition = { | ||
name = 'shared_chest', | ||
nodes = "more_chests:shared", | ||
group = 'container', | ||
protection_bypass_read = "interact", | ||
} | ||
|
||
function definition:copy(node, pos, player) | ||
local meta = minetest.get_meta(pos) | ||
return { | ||
description = description(meta, node, pos), | ||
shared_with = meta:get("shared"), | ||
} | ||
end | ||
|
||
function definition:paste(node, pos, player, data) | ||
local nodedef = minetest.registered_nodes[node.name] | ||
nodedef.on_receive_fields(pos, "", {shared=data.shared_with}, player) | ||
end | ||
|
||
return definition |
Oops, something went wrong.