Initial commit
|
@ -0,0 +1,81 @@
|
|||
<center>
|
||||
<h1>Blueprints API</h1>
|
||||
<img src="blueprint-types.png" alt=" " />
|
||||
</center>
|
||||
|
||||
## Blueprint rules
|
||||
|
||||
Blueprint rules define how nodes can be blueprinted. They are just a table with
|
||||
the following parameters:
|
||||
|
||||
- `allowed`: Specifies whether the item is allowed to be blueprinted
|
||||
(`true`, `false` or `'default'`). If this is `'default'`, the item will be
|
||||
blueprinted if it is visible in the creative inventory (does not have the
|
||||
`not_in_creative_inventory` group).
|
||||
- `param2`: Allows the node's param2 to be saved in the blueprint. Defaults to
|
||||
`true`.
|
||||
- `meta`: Allows the node's metadata to be copied. Can either be `true` to
|
||||
allow everything to be copied, or a table with a list of metadata strings
|
||||
to copy.
|
||||
- `pvmeta`: A table containing a list of metadata strings to mark as private
|
||||
when restoring from the blueprint.
|
||||
- `inv_lists`: A table containing the inventory lists to be copied.
|
||||
- `item`: A custom blueprint item to give the player when blueprinting the
|
||||
object. Made with `blueprints.register_blueprint()`.
|
||||
|
||||
*All parameters are optional, and will default to the ones specified in
|
||||
`core.lua`.*
|
||||
|
||||
To modify these rules for your node, you can add a `_blueprints` field to your
|
||||
node's definition with a table containing any of the above parameters. Unknown
|
||||
rules will be silently ignored.
|
||||
|
||||
## Functions
|
||||
|
||||
The following API functions exist, where the `node` parameter is normally a
|
||||
`string`:
|
||||
|
||||
### Node rules and aliases
|
||||
|
||||
- `blueprints.get_rules(node)`: Gets a rules table for the node specified.
|
||||
You should not modify this table, as you may inadvertently modify the
|
||||
default rules. The `allowed` parameter will always be returned with either
|
||||
`true` or `false`, the value for `'default'` will be calculated when this
|
||||
is called.
|
||||
- `blueprints.register_alias(old_node, new_node)`: This will make blueprints
|
||||
treat `old_node` as the same as `new_node` internally. Blueprints made with
|
||||
`new_node` can be applied to `old_node`s, and the blueprint rules of
|
||||
`new_node` will be used for `old_node` as well.
|
||||
- `blueprints.check_alias(node)`: Checks for node aliases, will return `node`
|
||||
if no alias exists. Nodes registered with `mesecon.register_node` will be
|
||||
auto-aliased (`_on` to `_off`), however this can be overridden by adding
|
||||
a new alias. Aliases are not recursive.
|
||||
|
||||
### Creating/applying blueprint strings/tables.
|
||||
|
||||
- `blueprints.get_blueprint(pos, raw = false)`: Returns a blueprint string
|
||||
(or table if raw is true) for the object. If the node cannot be blueprinted,
|
||||
this will return `nil`.
|
||||
- `blueprints.apply_blueprint(pos, blueprint, only_if_exists = false)`: Applies
|
||||
the blueprint `blueprint` at `pos`, the blueprint specified may be a string
|
||||
or table. Returns `true` on success or `nil` on faliure.
|
||||
|
||||
### Other possibly useful function(s).
|
||||
- `blueprints.check_protection(pos, name)`: Checks the protection at `pos` for
|
||||
`name`, automatically recording a violation if one exists. Returns `true`
|
||||
and records a violation if `name` has no access to `pos`, otherwise returns
|
||||
`false`.
|
||||
|
||||
### Registering blueprints.
|
||||
- `blueprints.register_blueprint(name, def)`: Registers a non-blank blueprint.
|
||||
`def` is optional, and if left out, sensible defaults will be used. Any
|
||||
parameters valid with craftitems should work here, however `on_use`,
|
||||
`on_place`, `stack_max` and a few others may be overridden. If
|
||||
`inventory_image` is not specified, one will be generated based on the node
|
||||
name (for example `blueprints:test_blueprint` would become
|
||||
`blueprints_test_blueprint.png`) and are overlayed on top of the empty
|
||||
blueprint texture. If you want to use a custom blank blueprint, you can
|
||||
specify the `blank` parameter in the table.
|
||||
- `bluepritns.register_blank_blueprint(name, def)`: The same as
|
||||
`reigster_blueprint`, except for blank blueprints. `blank` should not be
|
||||
specified here, and a `def` containing `description` is mandatory.
|
|
@ -0,0 +1,21 @@
|
|||
# The MIT License (MIT)
|
||||
|
||||
*Copyright © 2018 by luk3yx*
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
|
@ -0,0 +1,72 @@
|
|||
<center>
|
||||
<h1>Minetest blueprints mod</h1>
|
||||
<img src="blueprint-types.png" alt=" " />
|
||||
</center>
|
||||
|
||||
A Minetest mod that allows items to be copied.
|
||||
|
||||
## What is/isn't it?
|
||||
|
||||
Blueprints is a way to copy complex node settings with two clicks. One blueprint
|
||||
can only store one node, if you want to bulk save/load/copy/move nodes, see
|
||||
[WorldEdit](https://github.com/Uberi/Minetest-WorldEdit).
|
||||
|
||||
## Items
|
||||
|
||||
Blueprints introduces two types of items: Blank blueprints, and... well...
|
||||
non-blank blueprints.
|
||||
|
||||
Blank blueprint crafting:
|
||||
|
||||
![1 paper surrounded by 8 basic_materials plastic strips](crafting.png)
|
||||
|
||||
Requires:
|
||||
- 8 `basic_materials` plastic strips
|
||||
- 1 paper sheet
|
||||
|
||||
To erase data off a blueprint, provided it isn't already blank, put it in the
|
||||
crafting grid.
|
||||
|
||||
## Usage instructions
|
||||
|
||||
Blueprints are relatively intuitive to use. To take a blueprint of something,
|
||||
simply left-click it while holding a blank blueprint. To apply the blueprint
|
||||
to other nodes, you can left-click the node. **Do not apply blueprints to chests
|
||||
or other nodes with items in, you will lose your items.** To place a new node
|
||||
down with the blueprint applied, just right-click while holding the blueprint.
|
||||
Note that with pipeworks and mesecons placing a node with a blueprint will not
|
||||
link up wires/pipes to the node.
|
||||
|
||||
## What can/can't be blueprinted?
|
||||
|
||||
By default, item metadata (such as node settings) is saved, however, of course,
|
||||
node inventories aren't. This can be overridden on a per-item basis (for more
|
||||
information, see the [API] page). Unless overridden by mods, nodes not in the
|
||||
creative inventory cannot be blueprinted.
|
||||
|
||||
Because of the way pipeworks teleportation tubes work, they cannot be
|
||||
blueprinted.
|
||||
|
||||
## Dependencies
|
||||
|
||||
Blueprints has no mandatory dependencies, however blueprints will be uncraftable
|
||||
without `basic_materials` and `default`.
|
||||
|
||||
The following dependencies are so blueprint rules can be added onto items for
|
||||
better compatibility:
|
||||
- `mesecons`
|
||||
- `mesecons_fpga`
|
||||
- `mesecons_microcontroller`
|
||||
- `mesecons_luacontroller`
|
||||
- `pipeworks`
|
||||
|
||||
## License
|
||||
|
||||
The whole mod, including textures, are licensed under the [MIT license].
|
||||
|
||||
## API
|
||||
|
||||
Mod developers can restrict what can/can't be blueprinted with the [API].
|
||||
|
||||
[API]: API.md
|
||||
[MIT license]: LICENSE.md
|
After Width: | Height: | Size: 1.1 KiB |
|
@ -0,0 +1,253 @@
|
|||
--
|
||||
-- Minetest blueprints mod: Core functions
|
||||
--
|
||||
|
||||
blueprints = {}
|
||||
|
||||
-- Default rules
|
||||
-- These may be overriden on a per-node basis using '_blueprints' in the node's
|
||||
-- definition.
|
||||
blueprints.default_rules = {
|
||||
-- allowed - Allows the node to be blueprint-ified. If this is 'default',
|
||||
-- it will only allow nodes that are in the creative inventory, and will
|
||||
-- be set to either true or false when blueprints.get_rules() is called.
|
||||
allowed = 'default',
|
||||
|
||||
-- param2 - Allows param2 to be saved in the blueprint.
|
||||
param2 = true,
|
||||
|
||||
-- meta - Specifies which meta strings to save. This can be 'true' to save
|
||||
-- everything.
|
||||
-- meta = {'formspec', 'infotext'},
|
||||
meta = true,
|
||||
|
||||
-- pvmeta - Specifies which meta strings to mark as private.
|
||||
pvmeta = {},
|
||||
|
||||
-- inv_lists - A list of inventory lists to be copied.
|
||||
inv_lists = {},
|
||||
|
||||
-- item - The blueprint item to use.
|
||||
item = 'blueprints:print'
|
||||
}
|
||||
|
||||
-- Aliases - Allow multiple nodes to be treated internally as one.
|
||||
local aliases = {}
|
||||
blueprints.register_alias = function(old_node, new_node)
|
||||
aliases[old_node] = new_node
|
||||
end
|
||||
|
||||
blueprints.check_alias = function(node)
|
||||
if aliases[node] then return aliases[node] end
|
||||
local def = minetest.registered_nodes[node]
|
||||
-- Mesecons integration
|
||||
if def and def.__mesecon_state and def.__mesecon_basename then
|
||||
node = def.__mesecon_basename .. '_off'
|
||||
end
|
||||
return node
|
||||
end
|
||||
|
||||
blueprints.check_reverse_alias = function(new_node, old_node)
|
||||
return blueprints.check_alias(old_node) == new_node
|
||||
end
|
||||
|
||||
-- Get a list of rules for a node.
|
||||
blueprints.get_rules = function(node)
|
||||
if node and type(node) ~= 'string' then node = node.name end
|
||||
|
||||
-- Check aliases
|
||||
node = blueprints.check_alias(node)
|
||||
|
||||
-- Unknown nodes cannot be blueprinted.
|
||||
local def = false
|
||||
if node and node ~= 'ignore' then
|
||||
def = minetest.registered_nodes[node]
|
||||
end
|
||||
if not def then
|
||||
return {
|
||||
allowed = false,
|
||||
param2 = false,
|
||||
meta = {},
|
||||
pvmeta = {},
|
||||
inv_lists = {},
|
||||
item = 'blueprints:blank'
|
||||
}
|
||||
end
|
||||
|
||||
-- Use the default rules
|
||||
local node_rules = def._blueprints
|
||||
if not node_rules then
|
||||
if def.groups and def.groups.not_in_creative_inventory then
|
||||
node_rules = {}
|
||||
else
|
||||
return blueprints.default_rules
|
||||
end
|
||||
end
|
||||
|
||||
-- Replace any omitted values with the defaults.
|
||||
local rules = {}
|
||||
for k, v in pairs(blueprints.default_rules) do
|
||||
if node_rules[k] ~= nil then
|
||||
rules[k] = node_rules[k]
|
||||
else
|
||||
rules[k] = v
|
||||
end
|
||||
end
|
||||
|
||||
-- Check for 'You hacker you!'
|
||||
if rules.allowed == 'default' then
|
||||
if def.groups and def.groups.not_in_creative_inventory then
|
||||
rules.allowed = false
|
||||
else
|
||||
rules.allowed = true
|
||||
end
|
||||
end
|
||||
|
||||
return rules
|
||||
end
|
||||
|
||||
-- Get a nicer inv_lists
|
||||
local function get_inv_lists(rules)
|
||||
local inv_lists = {}
|
||||
if rules.inv_lists then
|
||||
for _, list in ipairs(rules.inv_lists) do
|
||||
inv_lists[list] = true
|
||||
end
|
||||
end
|
||||
return inv_lists
|
||||
end
|
||||
|
||||
-- Get a blueprint string for a node.
|
||||
blueprints.get_blueprint = function(pos, raw)
|
||||
-- Check aliases
|
||||
local node = minetest.get_node(pos)
|
||||
node.name = blueprints.check_alias(node.name)
|
||||
|
||||
-- Get the rules list
|
||||
local rules = blueprints.get_rules(node)
|
||||
if not rules.allowed then return end
|
||||
|
||||
-- Using a meta table allows ints/floats/etc to be copied nicely.
|
||||
local blueprint = {name = node.name, pattern = rules.pattern}
|
||||
local metatable = minetest.get_meta(pos):to_table()
|
||||
|
||||
-- Copy across allowed metadata fields
|
||||
if (rules.meta == true or #rules.meta > 0) and metatable.fields then
|
||||
if rules.meta == true then
|
||||
blueprint.meta = metatable.fields
|
||||
else
|
||||
blueprint.meta = {}
|
||||
for _, name in ipairs(rules.meta) do
|
||||
blueprint.meta[name] = metatable.fields[name]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Get a nicer inv_lists
|
||||
local inv_lists = get_inv_lists(rules)
|
||||
|
||||
-- Copy allowed inventories
|
||||
if metatable.inventory then
|
||||
blueprint.inv = {}
|
||||
for listname, list in pairs(metatable.inventory) do
|
||||
blueprint.inv[listname] = {}
|
||||
for id, itemstack in ipairs(list) do
|
||||
if inv_lists[listname] then
|
||||
blueprint.inv[listname][id] = itemstack:to_table() or ''
|
||||
else
|
||||
blueprint.inv[listname][id] = ''
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Copy across param2
|
||||
if rules.param2 then
|
||||
blueprint.param2 = node.param2
|
||||
end
|
||||
|
||||
-- Return the blueprint
|
||||
if not raw then
|
||||
blueprint = minetest.serialize(blueprint)
|
||||
end
|
||||
return blueprint
|
||||
end
|
||||
|
||||
-- Apply blueprints (and double-check the allowed fields)
|
||||
blueprints.apply_blueprint = function(pos, blueprint, only_if_exists)
|
||||
-- Deserialize if required and get the rules
|
||||
if type(blueprint) == 'string' then
|
||||
blueprint = minetest.deserialize(blueprint)
|
||||
end
|
||||
if not blueprint then return end
|
||||
|
||||
-- Make sure the node exists
|
||||
if only_if_exists then
|
||||
local node = minetest.get_node(pos)
|
||||
if node.name ~= blueprint.name then
|
||||
-- "Un-alias" the blueprint.
|
||||
if blueprints.check_reverse_alias(blueprint.name, node.name) then
|
||||
blueprint.name = node.name
|
||||
else
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Get the rules
|
||||
local rules = blueprints.get_rules(blueprint)
|
||||
if not rules or not rules.allowed then return end
|
||||
|
||||
-- Set the node (and param2)
|
||||
local node = {name = blueprint.name}
|
||||
if rules.param2 and blueprint.param2 then
|
||||
node.param2 = blueprint.param2
|
||||
end
|
||||
minetest.set_node(pos, node)
|
||||
local metatable = {fields = {}, inventory = {}}
|
||||
|
||||
-- Copy across allowed metadata fields
|
||||
if blueprint.meta and rules.meta then
|
||||
if rules.meta == true then
|
||||
metatable.fields = blueprint.meta
|
||||
else
|
||||
for _, name in ipairs(rules.meta) do
|
||||
metatable.fields[name] = blueprint.meta[name]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Copy allowed inventories
|
||||
if blueprint.inv then
|
||||
local inv_lists = get_inv_lists(rules)
|
||||
|
||||
for name, inv in pairs(blueprint.inv) do
|
||||
metatable.inventory[name] = {}
|
||||
for id, item in ipairs(inv) do
|
||||
if not inv_lists[name] then item = '' end
|
||||
metatable.inventory[name][id] = ItemStack(item)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Update the node meta
|
||||
local meta = minetest.get_meta(pos)
|
||||
meta:from_table(metatable)
|
||||
meta:mark_as_private(rules.pvmeta)
|
||||
return true
|
||||
end
|
||||
|
||||
-- Protection check function
|
||||
blueprints.check_protection = function(pos, name)
|
||||
if type(name) ~= 'string' then
|
||||
name = name:get_player_name()
|
||||
end
|
||||
|
||||
if minetest.is_protected(pos, name) and
|
||||
not minetest.check_player_privs(name, {protection_bypass=true}) then
|
||||
minetest.record_protection_violation(pos, name)
|
||||
return true
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
After Width: | Height: | Size: 2.5 KiB |
|
@ -0,0 +1,7 @@
|
|||
basic_materials?
|
||||
default?
|
||||
pipeworks?
|
||||
mesecons?
|
||||
mesecons_fpga?
|
||||
mesecons_microcontroller?
|
||||
mesecons_luacontroller?
|
|
@ -0,0 +1,44 @@
|
|||
--
|
||||
-- Minetest blueprints mod
|
||||
--
|
||||
-- © 2018 by luk3yx
|
||||
--
|
||||
|
||||
local path = minetest.get_modpath('blueprints')
|
||||
|
||||
-- Load the core functions
|
||||
dofile(path .. '/core.lua')
|
||||
|
||||
-- Add the registering API
|
||||
dofile(path .. '/register.lua')
|
||||
|
||||
-- Register the default blueprints
|
||||
blueprints.register_blank_blueprint('blueprints:blank', {
|
||||
description = 'Blank blueprint'
|
||||
})
|
||||
blueprints.register_blueprint('blueprints:print')
|
||||
|
||||
-- Crafting
|
||||
if minetest.get_modpath('basic_materials') then
|
||||
minetest.register_craft({
|
||||
output = 'blueprints:blank',
|
||||
recipe = {
|
||||
{'basic_materials:plastic_strip', 'basic_materials:plastic_strip',
|
||||
'basic_materials:plastic_strip'},
|
||||
{'basic_materials:plastic_strip', 'default:paper',
|
||||
'basic_materials:plastic_strip'},
|
||||
{'basic_materials:plastic_strip', 'basic_materials:plastic_strip',
|
||||
'basic_materials:plastic_strip'}
|
||||
}
|
||||
})
|
||||
end
|
||||
|
||||
-- Pipeworks integration
|
||||
if minetest.get_modpath('pipeworks') then
|
||||
dofile(path .. '/pipeworks.lua')
|
||||
end
|
||||
|
||||
-- Mesecons integration
|
||||
if minetest.get_modpath('mesecons') then
|
||||
dofile(path .. '/mesecons.lua')
|
||||
end
|
|
@ -0,0 +1,24 @@
|
|||
--
|
||||
-- Minetest blueprints mod: Mesecons integration
|
||||
--
|
||||
|
||||
-- Microcontroller blueprints
|
||||
local microcontrollers = {}
|
||||
for _, rawname in ipairs({'fpga', 'microcontroller', 'luacontroller'}) do
|
||||
local basename = 'mesecons_' .. rawname .. ':' .. rawname
|
||||
local name0 = basename .. '0000'
|
||||
if minetest.registered_nodes[name0] then
|
||||
for a = 0, 1 do for b = 0, 1 do for c = 0, 1 do for d = 0, 1 do
|
||||
local name = basename .. a .. b .. c .. d
|
||||
blueprints.register_alias(name, name0)
|
||||
end end end end
|
||||
end
|
||||
microcontrollers[#microcontrollers + 1] = name0
|
||||
end
|
||||
|
||||
blueprints.easy_override('blueprints:microcontroller', microcontrollers, {
|
||||
allowed = true,
|
||||
meta = true,
|
||||
pvmeta = {'code', 'lc_memory'}
|
||||
})
|
||||
microcontrollers = nil
|
|
@ -0,0 +1,75 @@
|
|||
--
|
||||
-- Minetest blueprints mod: Pipeworks integration
|
||||
--
|
||||
|
||||
-- Filters
|
||||
local rules = {
|
||||
allowed = true,
|
||||
param2 = true,
|
||||
meta = true,
|
||||
inv_lists = {'main'}
|
||||
}
|
||||
|
||||
blueprints.easy_override('blueprints:pipeworks_filter', {
|
||||
'pipeworks:filter', 'pipeworks:mese_filter', 'pipeworks:digiline_filter'
|
||||
}, rules)
|
||||
|
||||
-- Alias "old-style" tubes
|
||||
local alias_pipeworks_tube = function(basename, no_underscore)
|
||||
local _ = '_'
|
||||
if no_underscore then _ = '' end
|
||||
local name0 = basename .. _ .. '000000'
|
||||
for a = 0, 1 do
|
||||
local name1 = basename .. _ .. a
|
||||
for b = 0, 1 do
|
||||
local name2 = name1 .. b
|
||||
for c = 0, 1 do
|
||||
local name3 = name2 .. c
|
||||
for d = 0, 1 do
|
||||
local name4 = name3 .. d
|
||||
for e = 0, 1 do
|
||||
local name5 = name4 .. e
|
||||
for f = 0, 1 do
|
||||
local name = name5 .. f
|
||||
blueprints.register_alias(name, name0)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
return name0
|
||||
end
|
||||
|
||||
-- Sorting tubes
|
||||
rules.inv_lists = {'line1', 'line2', 'line3', 'line4', 'line5', 'line6'}
|
||||
local tubes = {'pipeworks:mese_tube', 'pipeworks:lua_tube'}
|
||||
for _, tube in ipairs(tubes) do
|
||||
local sane = false
|
||||
if minetest.registered_items[tube .. '000000'] then
|
||||
sane = true
|
||||
elseif minetest.registered_items[tube .. '_000000'] then
|
||||
sane = '_'
|
||||
end
|
||||
|
||||
if sane then
|
||||
print(' - ' .. tube)
|
||||
tubes[_] = alias_pipeworks_tube(tube, sane ~= '_')
|
||||
end
|
||||
end
|
||||
blueprints.easy_override('blueprints:pipeworks_tube', tubes, rules)
|
||||
tubes = nil
|
||||
|
||||
-- Autocrafters
|
||||
rules.inv_lists = {'recipe', 'output'}
|
||||
blueprints.easy_override('blueprints:pipeworks_autocrafter',
|
||||
'pipeworks:autocrafter', rules)
|
||||
|
||||
-- Disable teleportation tube blueprinting
|
||||
if minetest.registered_nodes['pipeworks:teleport_tube_1'] then
|
||||
minetest.override_item('pipeworks:teleport_tube_1', {
|
||||
_blueprints = {
|
||||
allowed = false
|
||||
}
|
||||
})
|
||||
end
|
|
@ -0,0 +1,220 @@
|
|||
--
|
||||
-- Minetest blueprints mod: Register blueprint items
|
||||
--
|
||||
|
||||
-- Create image name from item name
|
||||
local function image_from_item(name)
|
||||
return name:gsub(':', '_') .. '.png'
|
||||
end
|
||||
|
||||
-- Handle on_use for non-blank blueprints.
|
||||
blueprints.on_use = function(itemstack, user, pointed_thing)
|
||||
user = user:get_player_name()
|
||||
if pointed_thing.type ~= 'node' then
|
||||
if user then
|
||||
minetest.chat_send_player(user,
|
||||
'You can only apply blueprints to a node.')
|
||||
end
|
||||
return
|
||||
end
|
||||
local pos = pointed_thing.under
|
||||
if blueprints.check_protection(pos, user) then return end
|
||||
|
||||
-- Sanity check on the blueprint
|
||||
local blueprint = itemstack:get_meta():get_string('blueprint')
|
||||
blueprint = minetest.deserialize(blueprint)
|
||||
if not blueprint or not blueprint.name then
|
||||
if user then
|
||||
minetest.chat_send_player(user, 'Invalid blueprint!')
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
-- Attempt to apply the blueprint
|
||||
local success = blueprints.apply_blueprint(pos, blueprint, true)
|
||||
if not success and user then
|
||||
-- Check if the nodes match
|
||||
local node = minetest.get_node(pos)
|
||||
if node.name ~= blueprint.name then
|
||||
minetest.chat_send_player(user,
|
||||
'You can only apply this blueprint to "' .. blueprint.name
|
||||
.. '" nodes.')
|
||||
else
|
||||
minetest.chat_send_player(user,
|
||||
'The blueprint failed to be applied!')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Handle on_place for not-blank blueprints.
|
||||
blueprints.on_place = function(itemstack, placer, pointed_thing)
|
||||
if not placer then return end
|
||||
local inv = placer:get_inventory()
|
||||
placer = placer:get_player_name()
|
||||
if #placer == 0 then placer = false end
|
||||
if pointed_thing.type ~= 'node' then
|
||||
if placer then
|
||||
minetest.chat_send_player(placer,
|
||||
'You can only place blueprints on a node.')
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
-- Check protection
|
||||
local pos = pointed_thing.above
|
||||
if blueprints.check_protection(pos, placer) then return end
|
||||
|
||||
-- Validate the blueprint
|
||||
local blueprint = itemstack:get_meta():get_string('blueprint')
|
||||
blueprint = minetest.deserialize(blueprint)
|
||||
if not blueprint or not blueprint.name then
|
||||
if placer then
|
||||
minetest.chat_send_player(placer, 'Invalid blueprint!')
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
if not inv:contains_item('main', blueprint.name) then
|
||||
if placer then
|
||||
minetest.chat_send_player(placer,
|
||||
'You do not have enough items to place this blueprint.')
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
local success = blueprints.apply_blueprint(pos, blueprint)
|
||||
if success then
|
||||
inv:remove_item('main', blueprint.name)
|
||||
elseif placer then
|
||||
minetest.chat_send_player(placer,
|
||||
'The blueprint failed to be applied!')
|
||||
end
|
||||
end
|
||||
|
||||
-- Register non-blank blueprints.
|
||||
blueprints.register_blueprint = function(name, def)
|
||||
-- Set the on_use and add a blueprints group
|
||||
if not def then def = {} end
|
||||
if not def.groups then def.groups = {} end
|
||||
if not def.description then
|
||||
def.description = 'Blueprint'
|
||||
end
|
||||
def.on_use = blueprints.on_use
|
||||
def.on_place = blueprints.on_place
|
||||
def.groups.blueprint = 1
|
||||
def.groups.not_in_creative_inventory = 1
|
||||
def.stack_max = 1
|
||||
|
||||
local blank = 'blueprints:blank'
|
||||
if def._blank then
|
||||
blank = def._blank
|
||||
def._blank = nil
|
||||
end
|
||||
|
||||
if not def.inventory_image then
|
||||
def.inventory_image = image_from_item(blank) .. '^' ..
|
||||
image_from_item(name)
|
||||
end
|
||||
|
||||
-- Register the craftitem
|
||||
minetest.register_craftitem(name, def)
|
||||
|
||||
-- Allow the blueprint to be crafted back to the empty one.
|
||||
minetest.register_craft({
|
||||
output = blank,
|
||||
type = 'shapeless',
|
||||
recipe = {name}
|
||||
})
|
||||
end
|
||||
|
||||
-- Register blank blueprints
|
||||
blueprints.blank_on_use = function(itemstack, user, pointed_thing)
|
||||
if user and type(user) ~= 'string' then user = user:get_player_name() end
|
||||
if pointed_thing.type ~= 'node' then
|
||||
if user then
|
||||
minetest.chat_send_player(user,
|
||||
'You can only take blueprints of nodes.')
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
-- Get the blueprint rules
|
||||
local pos = pointed_thing.under
|
||||
if blueprints.check_protection(pos, user) then return end
|
||||
local node = minetest.get_node(pos)
|
||||
node.name = blueprints.check_alias(node.name)
|
||||
local rules = blueprints.get_rules(node)
|
||||
|
||||
-- Is the node allowed to become a blueprint?
|
||||
if not rules.allowed then
|
||||
if user then
|
||||
minetest.chat_send_player(user,
|
||||
'You cannot take a blueprint of that node.')
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
-- Take the blueprint
|
||||
local blueprint = blueprints.get_blueprint(pos)
|
||||
if not blueprint then
|
||||
if user then
|
||||
minetest.chat_send_player(user,
|
||||
'Error taking the blueprint.')
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
-- Add it to an itemstack
|
||||
local stack = ItemStack(rules.item)
|
||||
local meta = stack:get_meta()
|
||||
meta:set_string('blueprint', blueprint)
|
||||
meta:set_string('description',
|
||||
minetest.registered_nodes[node.name].description .. ' blueprint')
|
||||
return stack
|
||||
end
|
||||
|
||||
-- Register blank blueprints.
|
||||
blueprints.register_blank_blueprint = function(name, def)
|
||||
-- Set the on_use and add a blueprints group
|
||||
if not def.groups then def.groups = {} end
|
||||
def.on_use = blueprints.blank_on_use
|
||||
def.groups.blank_blueprint = 1
|
||||
def.stack_max = 1
|
||||
|
||||
if not def.inventory_image then
|
||||
def.inventory_image = image_from_item(name)
|
||||
end
|
||||
|
||||
-- Register the craftitem
|
||||
minetest.register_craftitem(name, def)
|
||||
end
|
||||
|
||||
-- Create an easy node overriding function
|
||||
blueprints.easy_override = function(blueprintname, names, raw_rules)
|
||||
if type(names) == 'string' then names = {names} end
|
||||
|
||||
-- Copy the rules table and add the blueprint name to the rules.
|
||||
local rules = {}
|
||||
if raw_rules then
|
||||
for k, v in pairs(raw_rules) do
|
||||
if blueprints.default_rules[k] ~= nil then
|
||||
rules[k] = v
|
||||
end
|
||||
end
|
||||
end
|
||||
rules.item = blueprintname
|
||||
|
||||
-- Override all the nodes that exist.
|
||||
local o = false
|
||||
for _, name in ipairs(names) do
|
||||
if minetest.registered_nodes[name] then
|
||||
o = true
|
||||
minetest.override_item(name, {_blueprints = rules})
|
||||
end
|
||||
end
|
||||
|
||||
-- Create the blueprint if required.
|
||||
if o then
|
||||
blueprints.register_blueprint(blueprintname)
|
||||
end
|
||||
end
|
After Width: | Height: | Size: 288 B |
After Width: | Height: | Size: 222 B |
After Width: | Height: | Size: 211 B |
After Width: | Height: | Size: 207 B |
After Width: | Height: | Size: 258 B |
After Width: | Height: | Size: 193 B |