blueprints/register.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