Add force-blueprinting to the API

This commit is contained in:
luk3yx 2019-03-06 22:16:00 +13:00
parent 2c5eddaddf
commit 033bfaaa74
2 changed files with 25 additions and 15 deletions

15
API.md
View File

@ -53,12 +53,15 @@ The following API functions exist, where the `node` parameter is normally a
### Creating/applying blueprint strings/tables. ### Creating/applying blueprint strings/tables.
- `blueprints.get_blueprint(pos, raw = false)`: Returns a blueprint string - `blueprints.get_blueprint(pos, raw = false, force = false)`: Returns a
(or table if raw is true) for the object. If the node cannot be blueprinted, blueprint string (or table if raw is true) for the object. If the node
this will return `nil`. cannot be blueprinted, this will return `nil`. If `force` is `true`, the
- `blueprints.apply_blueprint(pos, blueprint, only_if_exists = false)`: Applies rules will be ignored and the entire node will be blueprinted.
the blueprint `blueprint` at `pos`, the blueprint specified may be a string - `blueprints.apply_blueprint(pos, blueprint, only_if_exists = false, force = false)`:
or table. Returns `true` on success or `nil` on faliure. Applies the blueprint `blueprint` at `pos`, the blueprint specified may be
a string or table. Returns `true` on success or `nil` on faliure. If `force`
is `true`, the rules will be ignored when applying the blueprint. This must
also have been `true` when `get_blueprint` was called.
### Other possibly useful function(s). ### Other possibly useful function(s).
- `blueprints.check_protection(pos, name)`: Checks the protection at `pos` for - `blueprints.check_protection(pos, name)`: Checks the protection at `pos` for

View File

@ -118,14 +118,19 @@ local function get_inv_lists(rules)
end end
-- Get a blueprint string for a node. -- Get a blueprint string for a node.
blueprints.get_blueprint = function(pos, raw) blueprints.get_blueprint = function(pos, raw, force)
-- Check aliases -- Check aliases
local node = minetest.get_node(pos) local node = minetest.get_node(pos)
node.name = blueprints.check_alias(node.name) node.name = blueprints.check_alias(node.name)
-- Get the rules list -- Get the rules list
local rules
local rules = blueprints.get_rules(node) local rules = blueprints.get_rules(node)
if not rules.allowed then return end if force then
rules.meta = true
elseif not rules.allowed then
return
end
-- Using a meta table allows ints/floats/etc to be copied nicely. -- Using a meta table allows ints/floats/etc to be copied nicely.
local blueprint = {name = node.name, pattern = rules.pattern} local blueprint = {name = node.name, pattern = rules.pattern}
@ -144,7 +149,8 @@ blueprints.get_blueprint = function(pos, raw)
end end
-- Get a nicer inv_lists -- Get a nicer inv_lists
local inv_lists = get_inv_lists(rules) local inv_lists
if not force then inv_lists = get_inv_lists(rules) end
-- Copy allowed inventories -- Copy allowed inventories
if metatable.inventory then if metatable.inventory then
@ -152,7 +158,7 @@ blueprints.get_blueprint = function(pos, raw)
for listname, list in pairs(metatable.inventory) do for listname, list in pairs(metatable.inventory) do
blueprint.inv[listname] = {} blueprint.inv[listname] = {}
for id, itemstack in ipairs(list) do for id, itemstack in ipairs(list) do
if inv_lists[listname] then if force or inv_lists[listname] then
blueprint.inv[listname][id] = itemstack:to_table() or '' blueprint.inv[listname][id] = itemstack:to_table() or ''
else else
blueprint.inv[listname][id] = '' blueprint.inv[listname][id] = ''
@ -174,7 +180,7 @@ blueprints.get_blueprint = function(pos, raw)
end end
-- Apply blueprints (and double-check the allowed fields) -- Apply blueprints (and double-check the allowed fields)
blueprints.apply_blueprint = function(pos, blueprint, only_if_exists) blueprints.apply_blueprint = function(pos, blueprint, only_if_exists, force)
-- Deserialize if required and get the rules -- Deserialize if required and get the rules
if type(blueprint) == 'string' then if type(blueprint) == 'string' then
blueprint = minetest.deserialize(blueprint) blueprint = minetest.deserialize(blueprint)
@ -196,7 +202,7 @@ blueprints.apply_blueprint = function(pos, blueprint, only_if_exists)
-- Get the rules -- Get the rules
local rules = blueprints.get_rules(blueprint) local rules = blueprints.get_rules(blueprint)
if not rules or not rules.allowed then return end if not rules or (not rules.allowed and not force) then return end
-- Set the node (and param2) -- Set the node (and param2)
local node = {name = blueprint.name} local node = {name = blueprint.name}
@ -208,7 +214,7 @@ blueprints.apply_blueprint = function(pos, blueprint, only_if_exists)
-- Copy across allowed metadata fields -- Copy across allowed metadata fields
if blueprint.meta and rules.meta then if blueprint.meta and rules.meta then
if rules.meta == true then if rules.meta == true or force then
metatable.fields = blueprint.meta metatable.fields = blueprint.meta
else else
for _, name in ipairs(rules.meta) do for _, name in ipairs(rules.meta) do
@ -219,12 +225,13 @@ blueprints.apply_blueprint = function(pos, blueprint, only_if_exists)
-- Copy allowed inventories -- Copy allowed inventories
if blueprint.inv then if blueprint.inv then
local inv_lists = get_inv_lists(rules) local inv_lists
if not force then inv_lists = get_inv_lists(rules) end
for name, inv in pairs(blueprint.inv) do for name, inv in pairs(blueprint.inv) do
metatable.inventory[name] = {} metatable.inventory[name] = {}
for id, item in ipairs(inv) do for id, item in ipairs(inv) do
if not inv_lists[name] then item = '' end if not force and not inv_lists[name] then item = '' end
metatable.inventory[name][id] = ItemStack(item) metatable.inventory[name][id] = ItemStack(item)
end end
end end