203 lines
7.4 KiB
Lua
203 lines
7.4 KiB
Lua
--[[
|
|
Raw Ore Blocks — adds block forms of metal lumps to Luanti
|
|
Copyright © 2022-2026, Silver Sandstone <@SilverSandstone@craftodon.social>
|
|
|
|
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.
|
|
]]
|
|
|
|
|
|
--- Public API functions.
|
|
-- @module api
|
|
|
|
|
|
local S = core.get_translator('lumpblocks');
|
|
|
|
|
|
local get_sounds;
|
|
if core.get_modpath('default') then
|
|
get_sounds = default.node_sound_metal_defaults or default.node_sound_stone_defaults;
|
|
elseif core.get_modpath('mcl_sounds') then
|
|
get_sounds = mcl_sounds.node_sounds_metal_defaults;
|
|
elseif core.get_modpath('rp_sounds') then
|
|
get_sounds = rp_sounds.node_sound_defaults;
|
|
end;
|
|
|
|
if not get_sounds then
|
|
function get_sounds(sounds)
|
|
return sounds or {};
|
|
end;
|
|
end;
|
|
|
|
|
|
local function update(dest, ...)
|
|
for index = 1, select('#', ...) do
|
|
local src = select(index, ...);
|
|
if src then
|
|
for key, value in pairs(src) do
|
|
dest[key] = value;
|
|
end;
|
|
end;
|
|
end;
|
|
return dest;
|
|
end;
|
|
|
|
|
|
--- Registers a raw ore block.
|
|
-- @param name [string] The name of the raw ore block to register.
|
|
-- @param options [table] A table of options.
|
|
-- @param options.lump [string] The name of the lump item.
|
|
-- @param options.texture [string] Overrides the node's texture.
|
|
-- @param options.light_colour [ColourSpec] The lighter colour of the texture.
|
|
-- @param options.dark_colour [ColourSpec] The darker (or only) colour of the texture.
|
|
-- @param options.colour [ColourSpec] Alias for `dark_colour`.
|
|
-- @param options.colours [ColourSpec[2]] A table of {dark_colour, light_colour}.
|
|
-- @param options.description [string] Overrides the node's description.
|
|
-- @param options.groups [{string: integer}] Overrides the node's groups.
|
|
-- @param options.def [NodeDef] Overrides arbitrary properties of the node's definition.
|
|
-- @return [string|nil] The name of the registered node, or nil on failure.
|
|
function lumpblocks.register_lump_block(name, options)
|
|
if type(name) == 'table' then
|
|
options = name;
|
|
name = nil;
|
|
end;
|
|
|
|
local lump_name;
|
|
local texture;
|
|
local dark_colour;
|
|
local light_colour;
|
|
local description;
|
|
local override;
|
|
local groups = {};
|
|
for key, value in pairs(options) do
|
|
if key == 'base_name' or key == 1 then
|
|
name = ('lumpblocks:%s_block'):format(value);
|
|
elseif key == 'lump' or key == 2 then
|
|
lump_name = value;
|
|
elseif key == 'name' then
|
|
name = value;
|
|
elseif key == 'texture' then
|
|
texture = value;
|
|
elseif key == 'dark_colour' or key == 'colour' then
|
|
dark_colour = value;
|
|
elseif key == 'light_colour' then
|
|
light_colour = value;
|
|
elseif key == 'colours' then
|
|
dark_colour, light_colour = unpack(value);
|
|
elseif key == 'description' then
|
|
description = value;
|
|
elseif key == 'def' then
|
|
override = value;
|
|
elseif key == 'groups' then
|
|
groups = value;
|
|
else
|
|
core.log('error', ('Invalid key [%q] in lumpblocks.register_lump_block().'):format(key));
|
|
end;
|
|
end;
|
|
|
|
assert(name, 'No block name specified!');
|
|
assert(lump_name, 'No lump name specified!');
|
|
assert(texture or dark_colour, 'No texture or colour specified!');
|
|
|
|
local lump_def = core.registered_items[lump_name];
|
|
if not lump_def then
|
|
return nil;
|
|
end;
|
|
|
|
local def = {};
|
|
def.description = description or S('@1 Block', lump_def.description);
|
|
def.groups = update({cracky = 3, lump_block = 1}, groups);
|
|
def.tiles = {texture or lumpblocks.generate_lumpblock_texture(dark_colour, light_colour)};
|
|
def.sounds = update(get_sounds(), options.sounds);
|
|
def._doc_items_longdesc = S('A compressed block form of @1 for decoration or efficient storage.', lump_def.description);
|
|
|
|
update(def, override);
|
|
|
|
core.register_node(':' .. name, def);
|
|
|
|
-- Crafting recipes:
|
|
core.register_craft(
|
|
{
|
|
output = name;
|
|
recipe =
|
|
{
|
|
{lump_name, lump_name, lump_name},
|
|
{lump_name, lump_name, lump_name},
|
|
{lump_name, lump_name, lump_name},
|
|
};
|
|
});
|
|
|
|
core.register_craft(
|
|
{
|
|
type = 'shapeless';
|
|
output = lump_name .. ' 9';
|
|
recipe = {name};
|
|
});
|
|
|
|
if core.get_modpath('rp_crafting') then
|
|
crafting.register_craft(
|
|
{
|
|
output = name;
|
|
items = {lump_name .. ' 9'};
|
|
});
|
|
|
|
crafting.register_craft(
|
|
{
|
|
output = lump_name .. ' 9';
|
|
items = {name};
|
|
});
|
|
end;
|
|
|
|
return name;
|
|
end;
|
|
|
|
|
|
-- Generates a raw ore block texture in the specified colours.
|
|
-- @param dark_colour [ColourSpec] The darker (or only) colour.
|
|
-- @param light_colour [ColourSpec|nil] The lighter colour.
|
|
-- @return [string] A texture string.
|
|
function lumpblocks.generate_lumpblock_texture(dark_colour, light_colour)
|
|
assert(dark_colour, 'No colour specified!');
|
|
if light_colour then
|
|
-- Gradient-based colouring system:
|
|
dark_colour = core.colorspec_to_colorstring(dark_colour);
|
|
light_colour = core.colorspec_to_colorstring(light_colour);
|
|
local mask = 'lumpblocks_lump_block_mask.png';
|
|
return ('(%s^[multiply:#00000000^[invert:a^[colorize:%s:255)^(%s^[multiply:%s)'):format(mask, dark_colour, mask, light_colour);
|
|
else
|
|
-- Multiplication-based colouring system:
|
|
local colour = core.colorspec_to_colorstring(dark_colour);
|
|
local inverted = lumpblocks.invert_colour(colour);
|
|
local base = 'lumpblocks_lump_block.png';
|
|
return ('((%s^[invert:rgb)^[multiply:%s^[invert:rgb)^(%s^[multiply:%s^[opacity:127)'):format(base, inverted, base, colour);
|
|
end;
|
|
end;
|
|
|
|
|
|
--- Inverts a colour in RGB space.
|
|
-- @param colour [ColourSpec] The colour to invert.
|
|
-- @return [ColourString] The inverted colour.
|
|
function lumpblocks.invert_colour(colour)
|
|
local bytes = core.colorspec_to_bytes(colour);
|
|
local values = {nil, nil, nil, bytes:byte(4)};
|
|
for index = 1, 3 do
|
|
values[index] = 255 - bytes:byte(index);
|
|
end;
|
|
return ('#%02X%02X%02X%02X'):format(unpack(values));
|
|
end;
|