221 lines
6.5 KiB
Lua
221 lines
6.5 KiB
Lua
--
|
|
-- 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
|