From a7e643818f34269a6ef52f281907e34c2a3fb0b6 Mon Sep 17 00:00:00 2001 From: Michieal Date: Thu, 17 Nov 2022 23:27:21 +0000 Subject: [PATCH 1/4] Fix the crafting recipes for the signs. --- signs_api.lua | 2003 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 2003 insertions(+) create mode 100644 signs_api.lua diff --git a/signs_api.lua b/signs_api.lua new file mode 100644 index 000000000..1f7369ba3 --- /dev/null +++ b/signs_api.lua @@ -0,0 +1,2003 @@ +--- +--- Generated by EmmyLua. +--- Created by Michieal (FaerRaven). +--- DateTime: 10/14/22 4:05 PM +--- + +--local logging = minetest.settings:get_bool("mcl_logging_mcl_signs",true) + +local DEBUG = minetest.settings:get_bool("mcl_logging_mcl_signs", false) -- special debug setting. + +if DEBUG then + minetest.log("action", "[mcl_signs] Signs API Loading") +end + +-- LOCALIZATION +local S = minetest.get_translator("mcl_signs") +-- Signs form +local F = minetest.formspec_escape + +-- PATHs +local modpath = minetest.get_modpath("mcl_signs") + +-- CONSTANTS +local SIGN_WIDTH = 115 + +local LINE_LENGTH = 15 +local NUMBER_OF_LINES = 4 + +local LINE_HEIGHT = 14 +local CHAR_WIDTH = 5 +local TIMER_INTERVAL = 40.0 +-- ----------------------- +-- CACHE LOCAL COPIES +local table = table +local string = string + +-- CACHE NODE_SOUNDS +local node_sounds +if minetest.get_modpath("mcl_sounds") then + node_sounds = mcl_sounds.node_sound_wood_defaults() +end + +-- SET UP THE CHARACTER MAPPING +-- Load the characters map (characters.txt) +--[[ File format of characters.txt: +It's an UTF-8 encoded text file that contains metadata for all supported characters. It contains a sequence of info + blocks, one for each character. Each info block is made out of 3 lines: +Line 1: The literal UTF-8 encoded character +Line 2: Name of the texture file for this character minus the “.png” suffix; found in the “textures/” sub-directory +Line 3: Currently ignored. Previously this was for the character width in pixels + +After line 3, another info block may follow. This repeats until the end of the file. + +All character files must be 5 or 6 pixels wide (5 pixels are preferred) +]] + +local chars_file = io.open(modpath .. "/characters.txt", "r") +-- FIXME: Support more characters (many characters are missing). Currently ASCII and Latin-1 Supplement are supported. +local charmap = {} +if not chars_file then + minetest.log("error", "[mcl_signs] : character map file not found") +else + while true do + local char = chars_file:read("*l") + if char == nil then + break + end + local img = chars_file:read("*l") + chars_file:read("*l") + charmap[char] = img + end +end + +local pi = 3.1415926 -- enough accuracy, to build an engine for a car. + +local math = math + +-- locally cached copy of the official colors; this way, it updates as mcl_colors updates. +local mcl_colors_official = mcl_colors +if DEBUG then + minetest.log("verbose", "[mcl_signs]Official MCL_Colors:\n" .. dump(mcl_colors_official)) +end + +-- INITIALIZE THE GLOBAL API FOR SIGNS. +mcl_signs = {} + +-- GLOBALS +mcl_signs.sign_groups = { handy = 1, axey = 1, deco_block = 1, material_wood = 1, attached_node = 1, dig_by_piston = 1, flammable = -1 } +--- colors used for wools. +mcl_signs.mcl_wool_colors = { + unicolor_white = "#FFFFFF", + unicolor_dark_orange = "#502A00", + unicolor_grey = "#5B5B5B", + unicolor_darkgrey = "#303030", + unicolor_blue = "#0000CC", + unicolor_dark_green = "#005000", + unicolor_green_or_lime = "#50CC00", + unicolor_violet_purple = "#5000CC", + unicolor_light_red_pink = "#FF5050", + unicolor_yellow = "#CCCC00", + unicolor_orange = "#CC5000", + unicolor_red = "#CC0000", + unicolor_cyan = "#00CCCC", + unicolor_red_violet_magenta = "#CC0050", + unicolor_black = "#000000", + unicolor_light_blue = "#5050FF", +} +mcl_signs.signtext_info_wall = {} +mcl_signs.signtext_info_standing = {} -- built in build_signs_info(). +-- the rotational levels for all of the standing signs. +mcl_signs.standing_rotation_levels = {} + +-- data structure block for dynamically registered signs. +mcl_signs.registered_signs = {} +mcl_signs.registered_signs.wall_signs = {} +mcl_signs.registered_signs.standing_signs = {} +mcl_signs.registered_signs.hanging_signs = {} -- unused. prepping for future use. +-- DEFINE SIGN BASE TYPES +mcl_signs.wall_standard = {} -- initialize +mcl_signs.standing_standard = {} -- initialize + +function mcl_signs.build_signs_info() + local n = 23 / 56 - 1 / 128 -- some required magic number from the original code. + local m = -1 / 16 + 1 / 64 -- " " " " " " " " + + mcl_signs.signtext_info_wall = { + { delta = { x = 0, y = 0, z = n }, yaw = 0 }, + { delta = { x = n, y = 0, z = 0 }, yaw = pi / -2 }, + { delta = { x = 0, y = 0, z = -n }, yaw = pi }, + { delta = { x = -n, y = 0, z = 0 }, yaw = pi / 2 }, + } + + -- PLACE YAW VALUES INTO THE TABLE. + for rot = 0, 15 do + local yaw = pi * 2 - (((pi * 2) / 16) * rot) + local delta = vector.multiply(minetest.yaw_to_dir(yaw), m) + -- Offset because sign is a bit above node boundaries + delta.y = delta.y + 2 / 28 + table.insert(mcl_signs.signtext_info_standing, { delta = delta, yaw = yaw }) + end + +end + +-- wall signs' & hanging signs' base (definition) +mcl_signs.wall_standard = { + description = S("Sign"), + _tt_help = S("Can be written"), + _doc_items_longdesc = S("Signs can be written and come in two variants: Wall sign and sign on a sign post. Signs can be placed on the top and the sides of other blocks, but not below them."), + _doc_items_usagehelp = S("After placing the sign, you can write something on it. You have 4 lines of text with up to 15 characters for each line; anything beyond these limits is lost. Not all characters are supported. The text can not be changed once it has been written; you have to break and place the sign again. Can be colored and made to glow."), + inventory_image = "default_sign.png", + walkable = false, + is_ground_content = false, + wield_image = "default_sign.png", + node_placement_prediction = "", + paramtype = "light", + sunlight_propagates = true, + paramtype2 = "wallmounted", + drawtype = "mesh", + mesh = "mcl_signs_signonwallmount.obj", + selection_box = { type = "wallmounted", wall_side = { -0.5, -7 / 28, -0.5, -23 / 56, 7 / 28, 0.5 } }, + tiles = { "mcl_signs_sign.png" }, + use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "opaque" or false, + groups = mcl_signs.sign_groups, + stack_max = 16, + sounds = node_sounds, + + on_timer = function(pos) + -- fix for /ClearObjects + mcl_signs:update_sign(pos) + -- note: update_sign decides to keep the timer running based on if there is text. + -- This prevents every sign from having a timer, when not needed. + end, + + on_place = function(itemstack, placer, pointed_thing) + local above = pointed_thing.above + local under = pointed_thing.under + + -- Use pointed node's on_rightclick function first, if present + local node_under = minetest.get_node(under) + if placer and not placer:get_player_control().sneak then + if minetest.registered_nodes[node_under.name] and minetest.registered_nodes[node_under.name].on_rightclick then + return minetest.registered_nodes[node_under.name].on_rightclick(under, node_under, placer, itemstack) or itemstack + end + end + + local dir = vector.subtract(under, above) + + -- Only build when it's legal + local abovenodedef = minetest.registered_nodes[minetest.get_node(above).name] + if not abovenodedef or abovenodedef.buildable_to == false then + return itemstack + end + + local wdir = minetest.dir_to_wallmounted(dir) + + --local placer_pos = placer:get_pos() + + local fdir = minetest.dir_to_facedir(dir) + + local sign_info + local nodeitem = ItemStack(itemstack) + -- Ceiling + if wdir == 0 then + --how would you add sign to ceiling? + return itemstack + -- Floor + end + + if wdir == 1 then + -- Standing sign + + -- Determine the sign rotation based on player's yaw + local yaw = pi * 2 - placer:get_look_horizontal() + + -- Select one of 16 possible rotations (0-15) + local rotation_level = mcl_signs:round((yaw / (pi * 2)) * 16) + + if rotation_level > 15 then + rotation_level = 0 + elseif rotation_level < 0 then + rotation_level = 15 + end + + -- The actual rotation is a combination of predefined mesh and facedir (see node definition) + if rotation_level % 4 == 0 then + nodeitem:set_name("mcl_signs:standing_sign") + elseif rotation_level % 4 == 1 then + nodeitem:set_name("mcl_signs:standing_sign22_5") + elseif rotation_level % 4 == 2 then + nodeitem:set_name("mcl_signs:standing_sign45") + elseif rotation_level % 4 == 3 then + nodeitem:set_name("mcl_signs:standing_sign67_5") + end + fdir = math.floor(rotation_level / 4) + + -- Place the node! + local _, success = minetest.item_place_node(nodeitem, placer, pointed_thing, fdir) + if not success then + return itemstack + end + if not minetest.is_creative_enabled(placer:get_player_name()) then + itemstack:take_item() + end + sign_info = mcl_signs.signtext_info_standing[rotation_level + 1] + -- Side + else + -- Wall sign + local _, success = minetest.item_place_node(itemstack, placer, pointed_thing, wdir) + if not success then + return itemstack + end + sign_info = mcl_signs.signtext_info_wall[fdir + 1] + end + + -- Determine spawn position of entity + local place_pos + if minetest.registered_nodes[node_under.name].buildable_to then + place_pos = under + else + place_pos = above + end + + local text_entity = minetest.add_entity({ + x = place_pos.x + sign_info.delta.x, + y = place_pos.y + sign_info.delta.y, + z = place_pos.z + sign_info.delta.z }, "mcl_signs:text") + text_entity:set_yaw(sign_info.yaw) + text_entity:get_luaentity()._signnodename = nodeitem:get_name() + if DEBUG then + minetest.log("verbose", "[mcl_signs]Placed position:" .. dump(place_pos) .. "\nSign_info: " .. dump(sign_info)) + end + + minetest.sound_play({ name = "default_place_node_hard", gain = 1.0 }, { pos = place_pos }, true) + + mcl_signs:show_formspec(placer, place_pos) + return itemstack + end, + on_destruct = function(pos) + mcl_signs:destruct_sign(pos) + end, + + -- Not Useless Code. force updates the sign. + on_punch = function(pos, node, puncher) + mcl_signs:update_sign(pos) + end, + on_rotate = function(pos, node, user, mode) + if mode == screwdriver.ROTATE_FACE then + local r = screwdriver.rotate.wallmounted(pos, node, mode) + node.param2 = r + minetest.swap_node(pos, node) + mcl_signs:update_sign(pos, nil, nil, true) + return true + else + return false + end + end, + on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) + if DEBUG then + minetest.log("verbose", "[mcl_signs] Wall_Sign Right Click event.") + end + + -- make sure player is clicking + if not clicker or not clicker:is_player() then + return + end + + local item = clicker:get_wielded_item() + local iname = item:get_name() + + if node then + if DEBUG then + minetest.log("verbose", "[mcl_signs] Wall_Sign Right Click event on valid node.") + end + + -- handle glow from glow_ink_sac *first* + if (iname == "mcl_mobitems:glow_ink_sac") then + clicker:set_wielded_item(item) + local success = mcl_signs:glow_sign(pos) + if success then + if DEBUG then + minetest.log("verbose", "[mcl_signs] Sign Glow Success.") + end + itemstack:take_item() + end + return + end + + -- "mcl_dye:black" is a special case: it makes the sign's lettering black AND removes glow. + if (iname == "mcl_dye:black") then + clicker:set_wielded_item(item) + local success = mcl_signs:glow_sign(pos, true) + mcl_signs:color_sign(pos, mcl_colors.BLACK) + if success then + if DEBUG then + minetest.log("verbose", "[mcl_signs] Sign Glow removal Success.") + end + + itemstack:take_item() + end + return + end + + -- check the wielded item to make sure that it is a dye. + local txt_color = mcl_signs:get_color_for_sign(iname) + if txt_color ~= "false" then + clicker:set_wielded_item(item) + local success = mcl_signs:color_sign(pos, txt_color) + if success then + if DEBUG then + minetest.log("verbose", "[mcl_signs] Sign Color Success.") + end + itemstack:take_item() + end + end + end + end, + + _mcl_hardness = 1, + _mcl_blast_resistance = 1, +} +-- standing sign base (definition) +mcl_signs.standing_standard = { + paramtype = "light", + use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "opaque" or false, + sunlight_propagates = true, + walkable = false, + is_ground_content = false, + paramtype2 = "facedir", + drawtype = "mesh", + mesh = "mcl_signs_sign.obj", + selection_box = { type = "fixed", fixed = { -0.2, -0.5, -0.2, 0.2, 0.5, 0.2 } }, + tiles = { "mcl_signs_sign.png" }, + groups = mcl_signs.sign_groups, + drop = "mcl_signs:wall_sign", + stack_max = 16, + sounds = node_sounds, + + on_destruct = function(pos) + mcl_signs:destruct_sign(pos) + end, + + on_timer = function(pos) + -- fix for /ClearObjects + mcl_signs:update_sign(pos) + minetest.get_node_timer(pos):start(40.0) + end, + + -- Not Useless Code. this force updates the sign. + on_punch = function(pos, node, puncher) + mcl_signs:update_sign(pos) + end, + on_rotate = function(pos, node, user, mode) + if mode == screwdriver.ROTATE_FACE then + node.name = "mcl_signs:standing_sign22_5" + minetest.swap_node(pos, node) + elseif mode == screwdriver.ROTATE_AXIS then + return false + end + mcl_signs:update_sign(pos, nil, nil, true) + return true + end, + + on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) + + if DEBUG then + minetest.log("verbose", "[mcl_signs] Standing_Sign Right Click event.") + end + + -- make sure player is clicking + if not clicker or not clicker:is_player() then + return + end + + local item = clicker:get_wielded_item() + local iname = item:get_name() + + if node then + -- handle glow from glow_ink_sac *first* + if DEBUG then + minetest.log("verbose", "[mcl_signs] Standing_Sign Right Click event on valid node.") + end + + if (iname == "mcl_mobitems:glow_ink_sac") then + clicker:set_wielded_item(item) + local success = mcl_signs:glow_sign(pos) + if success then + if DEBUG then + minetest.log("verbose", "[mcl_signs] Sign Glow Success.") + end + itemstack:take_item() + end + return + end + + -- check the wielded item to make sure that it is a dye. + local txt_color = mcl_signs:get_color_for_sign(iname) + if txt_color ~= "false" then + clicker:set_wielded_item(item) + local success = mcl_signs:color_sign(pos, txt_color) + if success then + if DEBUG then + minetest.log("verbose", "[mcl_signs] Sign Color Success.") + end + itemstack:take_item() + end + end + end + end, + + _mcl_hardness = 1, + _mcl_blast_resistance = 1, +} + +-- HELPER FUNCTIONS' VARIABLES +local sign_glow = 6 +local Dyes_table = { + { "mcl_dye:aqua", mcl_colors_official.AQUA }, + { "mcl_dye:black", mcl_colors_official.BLACK }, + { "mcl_dye:blue", mcl_colors_official.BLUE }, + { "mcl_dye:brown", mcl_colors_official.brown }, + { "mcl_dye:cyan", mcl_signs.mcl_wool_colors.unicolor_cyan }, + { "mcl_dye:green", mcl_colors_official.GREEN }, + { "mcl_dye:dark_green", mcl_colors_official.DARK_GREEN }, + { "mcl_dye:grey", mcl_colors_official.GRAY }, + { "mcl_dye:dark_grey", mcl_colors_official.DARK_GRAY }, + { "mcl_dye:lightblue", mcl_signs.mcl_wool_colors.unicolor_light_blue }, + { "mcl_dye:lime", mcl_signs.unicolor_green_or_lime }, + { "mcl_dye:magenta", mcl_colors_official.LIGHT_PURPLE }, + { "mcl_dye:orange", mcl_signs.mcl_wool_colors.unicolor_orange }, + { "mcl_dye:pink", mcl_signs.mcl_wool_colors.unicolor_light_red_pink }, + { "mcl_dye:purple", mcl_colors_official.LIGHT_PURPLE }, + { "mcl_dye:red", mcl_signs.mcl_wool_colors.unicolor_red }, + { "mcl_dye:silver", mcl_signs.mcl_wool_colors.unicolor_grey }, + { "mcl_dye:violet", mcl_colors_official.DARK_PURPLE }, + { "mcl_dye:white", mcl_colors_official.WHITE }, + { "mcl_dye:yellow", mcl_colors_official.YELLOW }, +} + +local function update_sign_registry(type, name) + if type == "wall" then + table.insert(mcl_signs.registered_signs.wall_signs, name) + end + if type == "standing" then + table.insert(mcl_signs.registered_signs.standing_signs, name) + end + if type == "hanging" then + table.insert(mcl_signs.registered_signs.hanging_signs, name) + end +end + +function mcl_signs.make_lbm() + + local registered_sign_nodenames = {} + + for i = 0, #mcl_signs.registered_signs.wall_signs do + table.insert(registered_sign_nodenames, mcl_signs.registered_signs.wall_signs[i]) + end + + for i = 0, #mcl_signs.registered_signs.standing_signs do + table.insert(registered_sign_nodenames, mcl_signs.registered_signs.standing_signs[i]) + end + + for i = 0, #mcl_signs.registered_signs.hanging_signs do + table.insert(registered_sign_nodenames, mcl_signs.registered_signs.hanging_signs[i]) + end + + -- the above is not yet used. + minetest.register_lbm({ + name = "mcl_signs:respawn_entities", + label = "Respawn sign text entities", + run_at_every_load = true, + nodenames = registered_sign_nodenames, + action = function(pos, node) + mcl_signs:update_sign(pos) + end, + }) + +end + +function mcl_signs.register_dye (modname, item_name, color_code) + if minetest.get_modpath(modname) then + table.insert(Dyes_table, { item_name, color_code }) + end +end + +--- Register a new sign, tint the textures, and gives it an unique node name. Creates both wall and standing signs. +--- modname: optional (pass "" or "false" to ignore), for use with other mods to +--- allow the creation of a sign from the mod's wood (if installed). +--- +--- color: the color code to color the base sign textures. must be a valid html color code. +--- +--- _name: the sign's name suffix, such as "_dark" or "_red", etc., appended to "wall_sign" or "standing_sign" +--- +--- ttsign: the tool tip of the sign that gets translated. Shown when the mouse hovers the inventory sign. +--- For example: the basic, default oak (wood) sign is just "Sign"; and a spruce sign would be "Spruce Sign" +function mcl_signs.register_sign (modname, color, _name, ttsign) + local mod_name_pass = false + if modname ~= "" and modname ~= "false" then + if minetest.get_modpath(modname) then + mod_name_pass = true + end + if mod_name_pass == false then + return + end + end + local new_sign = {} + + if color == nil or color == "" then + color = "#FFFFFF" + end + + new_sign = table.copy(mcl_signs.wall_standard) + new_sign.description = S(ttsign) + + new_sign.wield_image = "(default_sign.png^[multiply:" .. color .. ")" + new_sign.tiles = { "(mcl_signs_sign.png^[multiply:" .. color .. ")" } + new_sign.inventory_image = "(default_sign.png^[multiply:" .. color .. ")" + + -- currently have to do this, because of how the base node placement works. + new_sign.on_place = function(itemstack, placer, pointed_thing) + local above = pointed_thing.above + local under = pointed_thing.under + + -- Use pointed node's on_rightclick function first, if present + local node_under = minetest.get_node(under) + if placer and not placer:get_player_control().sneak then + if minetest.registered_nodes[node_under.name] and minetest.registered_nodes[node_under.name].on_rightclick then + return minetest.registered_nodes[node_under.name].on_rightclick(under, node_under, placer, itemstack) or itemstack + end + end + + local dir = vector.subtract(under, above) + + -- Only build when it's legal + local abovenodedef = minetest.registered_nodes[minetest.get_node(above).name] + if not abovenodedef or abovenodedef.buildable_to == false then + return itemstack + end + + local wdir = minetest.dir_to_wallmounted(dir) + local fdir = minetest.dir_to_facedir(dir) + + local sign_info + local nodeitem = ItemStack(itemstack) + + local yaw = 0 + + -- Ceiling + if wdir == 0 then + --how would you add sign to ceiling? simple - hanging sign. + -- add code for placement underneath a node. + + return itemstack + -- Floor + elseif wdir == 1 then + -- Standing sign + + -- Determine the sign rotation based on player's yaw + yaw = pi * 2 - placer:get_look_horizontal() + + -- Select one of 16 possible rotations (0-15) + local rotation_level = mcl_signs:round((yaw / (pi * 2)) * 16) + + if rotation_level > 15 then + rotation_level = 0 + elseif rotation_level < 0 then + rotation_level = 15 + end + + -- The actual rotation is a combination of predefined mesh and facedir (see node definition) + if rotation_level % 4 == 0 then + nodeitem:set_name("mcl_signs:standing_sign" .. _name) + elseif rotation_level % 4 == 1 then + nodeitem:set_name("mcl_signs:standing_sign22_5" .. _name) + elseif rotation_level % 4 == 2 then + nodeitem:set_name("mcl_signs:standing_sign45" .. _name) + elseif rotation_level % 4 == 3 then + nodeitem:set_name("mcl_signs:standing_sign67_5" .. _name) + end + fdir = math.floor(rotation_level / 4) + + -- Place the node! + local _, success = minetest.item_place_node(nodeitem, placer, pointed_thing, fdir) + if not success then + return itemstack + end + if not minetest.is_creative_enabled(placer:get_player_name()) then + itemstack:take_item() + end + sign_info = mcl_signs.signtext_info_standing[rotation_level + 1] + -- Side + else + -- Wall sign + local _, success = minetest.item_place_node(itemstack, placer, pointed_thing, wdir) + if not success then + return itemstack + end + sign_info = mcl_signs.signtext_info_wall[fdir + 1] + end + + -- Determine spawn position of entity + local place_pos + if minetest.registered_nodes[node_under.name].buildable_to then + place_pos = under + else + place_pos = above + end + + if DEBUG then + minetest.log("action", "[mcl_signs] Register_Sign::Placed position:" .. dump(place_pos) .. "\nSign_info: " .. dump(sign_info)) + end + + local text_entity = minetest.add_entity({ + x = place_pos.x + sign_info.delta.x, + y = place_pos.y + sign_info.delta.y, + z = place_pos.z + sign_info.delta.z }, "mcl_signs:text") + text_entity:set_yaw(sign_info.yaw) + text_entity:get_luaentity()._signnodename = nodeitem:get_name() + + minetest.sound_play({ name = "default_place_node_hard", gain = 1.0 }, { pos = place_pos }, true) + + mcl_signs:show_formspec(placer, place_pos) + return itemstack + end + + minetest.register_node(":mcl_signs:wall_sign" .. _name, new_sign) + update_sign_registry("wall", "mcl_signs:wall_sign" .. _name) + + -- debug step + if DEBUG then + minetest.log("action", "[mcl_signs] Registered: mcl_signs:wall_sign" .. _name .. color .. "\n" .. dump(new_sign)) + minetest.log("action", "[mcl_signs] mcl_signs:wall_sign_standard\n" .. dump(mcl_signs.wall_standard)) + end + + -- standing sign base. + local new_sign_standing = {} + new_sign_standing = table.copy(mcl_signs.standing_standard) + new_sign_standing.drop = "mcl_signs:wall_sign" .. _name + new_sign_standing.wield_image = "(default_sign.png^[multiply:" .. color .. ")" + new_sign_standing.tiles = { "(mcl_signs_sign.png^[multiply:" .. color .. ")" } + new_sign_standing.inventory_image = "(default_sign.png^[multiply:" .. color .. ")" + + new_sign_standing.on_rotate = function(pos, node, user, mode) + if mode == screwdriver.ROTATE_FACE then + node.name = "mcl_signs:standing_sign22_5" .. _name + minetest.swap_node(pos, node) + elseif mode == screwdriver.ROTATE_AXIS then + return false + end + mcl_signs:update_sign(pos, nil, nil, true) + return true + end, + + minetest.register_node(":mcl_signs:standing_sign" .. _name, new_sign_standing) + update_sign_registry("standing", "mcl_signs:standing_sign" .. _name) + -- debug step + if DEBUG then + minetest.log("action", "[mcl_signs] Registered: mcl_signs:standing_sign" .. _name .. color .. "\n" .. dump(new_sign_standing)) + end + + -- 22.5° + local ssign22_5d = table.copy(new_sign_standing) + ssign22_5d.mesh = "mcl_signs_sign22.5.obj" + ssign22_5d.on_rotate = function(pos, node, user, mode) + if mode == screwdriver.ROTATE_FACE then + node.name = "mcl_signs:standing_sign45" .. _name + minetest.swap_node(pos, node) + elseif mode == screwdriver.ROTATE_AXIS then + return false + end + mcl_signs:update_sign(pos, nil, nil, true) + return true + end + minetest.register_node(":mcl_signs:standing_sign22_5" .. _name, ssign22_5d) + update_sign_registry("standing", "mcl_signs:standing_sign22_5" .. _name) + + -- 45° + local ssign45d = table.copy(new_sign_standing) + ssign45d.mesh = "mcl_signs_sign45.obj" + ssign45d.on_rotate = function(pos, node, user, mode) + if mode == screwdriver.ROTATE_FACE then + node.name = "mcl_signs:standing_sign67_5" .. _name + minetest.swap_node(pos, node) + elseif mode == screwdriver.ROTATE_AXIS then + return false + end + mcl_signs:update_sign(pos, nil, nil, true) + return true + end + minetest.register_node(":mcl_signs:standing_sign45" .. _name, ssign45d) + update_sign_registry("standing", "mcl_signs:standing_sign45" .. _name) + + -- 67.5° + local ssign67_5d = table.copy(new_sign_standing) + ssign67_5d.mesh = "mcl_signs_sign67.5.obj" + ssign67_5d.on_rotate = function(pos, node, user, mode) + if mode == screwdriver.ROTATE_FACE then + node.name = "mcl_signs:standing_sign" .. _name + node.param2 = (node.param2 + 1) % 4 + minetest.swap_node(pos, node) + elseif mode == screwdriver.ROTATE_AXIS then + return false + end + mcl_signs:update_sign(pos, nil, nil, true) + return true + end + minetest.register_node(":mcl_signs:standing_sign67_5" .. _name, ssign67_5d) + update_sign_registry("standing", "mcl_signs:standing_sign67_5" .. _name) + + -- register Doc entry + if minetest.get_modpath("doc") then + doc.add_entry_alias("nodes", "mcl_signs:wall_sign", "nodes", "mcl_signs:wall_sign" .. _name) + doc.add_entry_alias("nodes", "mcl_signs:wall_sign", "nodes", "mcl_signs:standing_sign" .. _name) + doc.add_entry_alias("nodes", "mcl_signs:wall_sign", "nodes", "mcl_signs:standing_sign22_5" .. _name) + doc.add_entry_alias("nodes", "mcl_signs:wall_sign", "nodes", "mcl_signs:standing_sign45" .. _name) + doc.add_entry_alias("nodes", "mcl_signs:wall_sign", "nodes", "mcl_signs:standing_sign67_5" .. _name) + end + + --register standing sign's rotation_levels + table.insert(mcl_signs.standing_rotation_levels, { "mcl_signs:standing_sign22_5" .. _name, 1 }) + table.insert(mcl_signs.standing_rotation_levels, { "mcl_signs:standing_sign45" .. _name, 2 }) + table.insert(mcl_signs.standing_rotation_levels, { "mcl_signs:standing_sign67_5" .. _name, 3 }) +end + +--- The same as register_sign, except caller defines the textures. Note, there is a greyscale version of the sign, +--- called "default_sign_greyscale.png" and "mcl_signs_sign_greyscale.png" for optional use in the textures directory. +--- +--- modname: optional (pass "" or "false" to ignore), for use with other mods to +--- allow the creation of a sign from the mod's wood (if installed). +--- +--- _name: the sign's name suffix, such as "_dark" or "_red", etc., appended to "wall_sign" or "standing_sign" +--- +--- tiles: the texture file to use for the sign. +--- +--- color: color the texture file to use with this color. Use white (#FFFFFF) to negate the color, +--- and just use the texture as is +--- +--- inventory_image: the texture file to use for the sign's display in inventory. +--- +--- wield_image: the texture file to use for the sign's weilded (in hand) object. +--- +--- inventory_image: the image used for in-inventory and in hand. +--- +--- ttsign: the tool tip of the sign that gets translated. Shown when the mouse hovers the inventory sign. +--- For example: the basic, default oak (wood) sign is just "Sign"; and a spruce sign would be "Spruce Sign" +function mcl_signs.register_sign_custom (modname, _name, tiles, color, inventory_image, wield_image, ttsign) + local mod_name_pass = false + if modname ~= "" and modname ~= "false" then + if minetest.get_modpath(modname) then + mod_name_pass = true + end + if mod_name_pass == false then + return + end + end + local new_sign = {} + + new_sign = table.copy(mcl_signs.wall_standard) + + new_sign.wield_image = "(" .. wield_image .. "^[multiply:" .. color .. ")" + new_sign.tiles = { "(" .. tiles .. "^[multiply:" .. color .. ")" } + new_sign.inventory_image = "(" .. inventory_image .. "^[multiply:" .. color .. ")" + new_sign.description = S(ttsign) + -- currently have to do this, because of how the base node placement works. + new_sign.on_place = function(itemstack, placer, pointed_thing) + local above = pointed_thing.above + local under = pointed_thing.under + + -- Use pointed node's on_rightclick function first, if present + local node_under = minetest.get_node(under) + if placer and not placer:get_player_control().sneak then + if minetest.registered_nodes[node_under.name] and minetest.registered_nodes[node_under.name].on_rightclick then + return minetest.registered_nodes[node_under.name].on_rightclick(under, node_under, placer, itemstack) or itemstack + end + end + + local dir = vector.subtract(under, above) + + -- Only build when it's legal + local abovenodedef = minetest.registered_nodes[minetest.get_node(above).name] + if not abovenodedef or abovenodedef.buildable_to == false then + return itemstack + end + + local wdir = minetest.dir_to_wallmounted(dir) + local fdir = minetest.dir_to_facedir(dir) + + local sign_info + local nodeitem = ItemStack(itemstack) + -- Ceiling + if wdir == 0 then + --how would you add sign to ceiling? + return itemstack + -- Floor + elseif wdir == 1 then + -- Standing sign + + -- Determine the sign rotation based on player's yaw + local yaw = pi * 2 - placer:get_look_horizontal() + + -- Select one of 16 possible rotations (0-15) + local rotation_level = mcl_signs:round((yaw / (pi * 2)) * 16) + + if rotation_level > 15 then + rotation_level = 0 + elseif rotation_level < 0 then + rotation_level = 15 + end + + -- The actual rotation is a combination of predefined mesh and facedir (see node definition) + if rotation_level % 4 == 0 then + nodeitem:set_name("mcl_signs:standing_sign" .. _name) + elseif rotation_level % 4 == 1 then + nodeitem:set_name("mcl_signs:standing_sign22_5" .. _name) + elseif rotation_level % 4 == 2 then + nodeitem:set_name("mcl_signs:standing_sign45" .. _name) + elseif rotation_level % 4 == 3 then + nodeitem:set_name("mcl_signs:standing_sign67_5" .. _name) + end + fdir = math.floor(rotation_level / 4) + + -- Place the node! + local _, success = minetest.item_place_node(nodeitem, placer, pointed_thing, fdir) + if not success then + return itemstack + end + if not minetest.is_creative_enabled(placer:get_player_name()) then + itemstack:take_item() + end + sign_info = mcl_signs.signtext_info_standing[rotation_level + 1] + -- Side + else + -- Wall sign + local _, success = minetest.item_place_node(itemstack, placer, pointed_thing, wdir) + if not success then + return itemstack + end + sign_info = mcl_signs.signtext_info_wall[fdir + 1] + end + + -- Determine spawn position of entity + local place_pos + if minetest.registered_nodes[node_under.name].buildable_to then + place_pos = under + else + place_pos = above + end + + local text_entity = minetest.add_entity({ + x = place_pos.x + sign_info.delta.x, + y = place_pos.y + sign_info.delta.y, + z = place_pos.z + sign_info.delta.z }, "mcl_signs:text") + text_entity:set_yaw(sign_info.yaw) + text_entity:get_luaentity()._signnodename = nodeitem:get_name() + + minetest.sound_play({ name = "default_place_node_hard", gain = 1.0 }, { pos = place_pos }, true) + + mcl_signs:show_formspec(placer, place_pos) + return itemstack + end + minetest.register_node(":mcl_signs:wall_sign" .. _name, new_sign) + update_sign_registry("wall", "mcl_signs:wall_sign" .. _name) + + -- standing sign base. + local new_sign_standing = {} + new_sign_standing = table.copy(mcl_signs.standing_standard) + new_sign_standing.drop = "mcl_signs:wall_sign" .. _name + new_sign_standing.wield_image = "(" .. wield_image .. "^[multiply:" .. color .. ")" + new_sign_standing.tiles = { "(" .. tiles .. "^[multiply:" .. color .. ")" } + new_sign_standing.inventory_image = "(" .. inventory_image .. "^[multiply:" .. color .. ")" + new_sign_standing.on_rotate = function(pos, node, user, mode) + if mode == screwdriver.ROTATE_FACE then + node.name = "mcl_signs:standing_sign22_5" .. _name + minetest.swap_node(pos, node) + elseif mode == screwdriver.ROTATE_AXIS then + return false + end + mcl_signs:update_sign(pos, nil, nil, true) + return true + end, + minetest.register_node(":mcl_signs:standing_sign" .. _name, new_sign_standing) + update_sign_registry("standing", "mcl_signs:standing_sign" .. _name) + + -- 22.5° + local ssign22_5d = table.copy(new_sign_standing) + ssign22_5d.mesh = "mcl_signs_sign22.5.obj" + ssign22_5d.on_rotate = function(pos, node, user, mode) + if mode == screwdriver.ROTATE_FACE then + node.name = "mcl_signs:standing_sign45" .. _name + minetest.swap_node(pos, node) + elseif mode == screwdriver.ROTATE_AXIS then + return false + end + mcl_signs:update_sign(pos, nil, nil, true) + return true + end + minetest.register_node(":mcl_signs:standing_sign22_5" .. _name, ssign22_5d) + update_sign_registry("standing", "mcl_signs:standing_sign22_5" .. _name) + + -- 45° + local ssign45d = table.copy(new_sign_standing) + ssign45d.mesh = "mcl_signs_sign45.obj" + ssign45d.on_rotate = function(pos, node, user, mode) + if mode == screwdriver.ROTATE_FACE then + node.name = "mcl_signs:standing_sign67_5" .. _name + minetest.swap_node(pos, node) + elseif mode == screwdriver.ROTATE_AXIS then + return false + end + mcl_signs:update_sign(pos, nil, nil, true) + return true + end + minetest.register_node(":mcl_signs:standing_sign45" .. _name, ssign45d) + update_sign_registry("standing", "mcl_signs:standing_sign45" .. _name) + + -- 67.5° + local ssign67_5d = table.copy(new_sign_standing) + ssign67_5d.mesh = "mcl_signs_sign67.5.obj" + ssign67_5d.on_rotate = function(pos, node, user, mode) + if mode == screwdriver.ROTATE_FACE then + node.name = "mcl_signs:standing_sign" .. _name + node.param2 = (node.param2 + 1) % 4 + minetest.swap_node(pos, node) + elseif mode == screwdriver.ROTATE_AXIS then + return false + end + mcl_signs:update_sign(pos, nil, nil, true) + return true + end + minetest.register_node(":mcl_signs:standing_sign67_5" .. _name, ssign67_5d) + update_sign_registry("standing", "mcl_signs:standing_sign67_5" .. _name) + + -- register Doc entry + if minetest.get_modpath("doc") then + doc.add_entry_alias("nodes", "mcl_signs:wall_sign", "nodes", "mcl_signs:wall_sign" .. _name) + doc.add_entry_alias("nodes", "mcl_signs:wall_sign", "nodes", "mcl_signs:standing_sign" .. _name) + doc.add_entry_alias("nodes", "mcl_signs:wall_sign", "nodes", "mcl_signs:standing_sign22_5" .. _name) + doc.add_entry_alias("nodes", "mcl_signs:wall_sign", "nodes", "mcl_signs:standing_sign45" .. _name) + doc.add_entry_alias("nodes", "mcl_signs:wall_sign", "nodes", "mcl_signs:standing_sign67_5" .. _name) + end + + --register standing sign's rotation_levels + table.insert(mcl_signs.standing_rotation_levels, { "mcl_signs:standing_sign22_5" .. _name, 1 }) + table.insert(mcl_signs.standing_rotation_levels, { "mcl_signs:standing_sign45" .. _name, 2 }) + table.insert(mcl_signs.standing_rotation_levels, { "mcl_signs:standing_sign67_5" .. _name, 3 }) + +end + +--- Override an existing sign, tint the textures, and gives it an unique node name. Creates both wall and standing signs. +--- modname: optional (pass "" or "false" to ignore), for use with other mods to +--- allow the creation of a sign from the mod's wood (if installed). +--- +--- color: the color code to color the base sign textures. must be a valid html color code. +--- +--- _name: the sign's name suffix, such as "_dark" or "_red", etc., appended to "wall_sign" or "standing_sign" +--- +--- ttsign: the tool tip of the sign that gets translated. Shown when the mouse hovers the inventory sign. +--- For example: the basic, default oak (wood) sign is just "Sign"; and a spruce sign would be "Spruce Sign" +function mcl_signs.reregister_sign (modname, color, _name, ttsign) + local mod_name_pass = false + if modname ~= "" and modname ~= "false" then + if minetest.get_modpath(modname) then + mod_name_pass = true + end + if mod_name_pass == false then + return + end + end + local new_sign = {} + + if color == nil or color == "" then + color = "#FFFFFF" + end + + new_sign = table.copy(mcl_signs.wall_standard) + new_sign.description = S(ttsign) + + new_sign.wield_image = "(default_sign.png^[multiply:" .. color .. ")" + new_sign.tiles = { "(mcl_signs_sign.png^[multiply:" .. color .. ")" } + new_sign.inventory_image = "(default_sign.png^[multiply:" .. color .. ")" + + -- currently have to do this, because of how the base node placement works. + new_sign.on_place = function(itemstack, placer, pointed_thing) + local above = pointed_thing.above + local under = pointed_thing.under + + -- Use pointed node's on_rightclick function first, if present + local node_under = minetest.get_node(under) + if placer and not placer:get_player_control().sneak then + if minetest.registered_nodes[node_under.name] and minetest.registered_nodes[node_under.name].on_rightclick then + return minetest.registered_nodes[node_under.name].on_rightclick(under, node_under, placer, itemstack) or itemstack + end + end + + local dir = vector.subtract(under, above) + + -- Only build when it's legal + local abovenodedef = minetest.registered_nodes[minetest.get_node(above).name] + if not abovenodedef or abovenodedef.buildable_to == false then + return itemstack + end + + local wdir = minetest.dir_to_wallmounted(dir) + local fdir = minetest.dir_to_facedir(dir) + + local sign_info + local nodeitem = ItemStack(itemstack) + -- Ceiling + if wdir == 0 then + --how would you add sign to ceiling? + return itemstack + -- Floor + elseif wdir == 1 then + -- Standing sign + + -- Determine the sign rotation based on player's yaw + local yaw = pi * 2 - placer:get_look_horizontal() + + -- Select one of 16 possible rotations (0-15) + local rotation_level = mcl_signs:round((yaw / (pi * 2)) * 16) + + if rotation_level > 15 then + rotation_level = 0 + elseif rotation_level < 0 then + rotation_level = 15 + end + + -- The actual rotation is a combination of predefined mesh and facedir (see node definition) + if rotation_level % 4 == 0 then + nodeitem:set_name("mcl_signs:standing_sign" .. _name) + elseif rotation_level % 4 == 1 then + nodeitem:set_name("mcl_signs:standing_sign22_5" .. _name) + elseif rotation_level % 4 == 2 then + nodeitem:set_name("mcl_signs:standing_sign45" .. _name) + elseif rotation_level % 4 == 3 then + nodeitem:set_name("mcl_signs:standing_sign67_5" .. _name) + end + fdir = math.floor(rotation_level / 4) + + -- Place the node! + local _, success = minetest.item_place_node(nodeitem, placer, pointed_thing, fdir) + if not success then + return itemstack + end + if not minetest.is_creative_enabled(placer:get_player_name()) then + itemstack:take_item() + end + sign_info = mcl_signs.signtext_info_standing[rotation_level + 1] + -- Side + else + -- Wall sign + local _, success = minetest.item_place_node(itemstack, placer, pointed_thing, wdir) + if not success then + return itemstack + end + sign_info = mcl_signs.signtext_info_wall[fdir + 1] + end + + -- Determine spawn position of entity + local place_pos + if minetest.registered_nodes[node_under.name].buildable_to then + place_pos = under + else + place_pos = above + end + + if DEBUG then + minetest.log("action", "[mcl_signs] Register_Sign::Placed position:" .. dump(place_pos) .. "\nSign_info: " .. dump(sign_info)) + end + + local text_entity = minetest.add_entity({ + x = place_pos.x + sign_info.delta.x, + y = place_pos.y + sign_info.delta.y, + z = place_pos.z + sign_info.delta.z }, "mcl_signs:text") + text_entity:set_yaw(sign_info.yaw) + text_entity:get_luaentity()._signnodename = nodeitem:get_name() + + minetest.sound_play({ name = "default_place_node_hard", gain = 1.0 }, { pos = place_pos }, true) + + mcl_signs:show_formspec(placer, place_pos) + return itemstack + end + + minetest.override_item("mcl_signs:wall_sign" .. _name, new_sign) + update_sign_registry("wall", "mcl_signs:wall_sign" .. _name) + + -- debug step + if DEBUG then + minetest.log("action", "[mcl_signs] Registered: mcl_signs:wall_sign" .. _name .. color .. "\n" .. dump(new_sign)) + minetest.log("action", "[mcl_signs] mcl_signs:wall_sign_standard\n" .. dump(mcl_signs.wall_standard)) + end + + -- standing sign base. + local new_sign_standing = {} + new_sign_standing = table.copy(mcl_signs.standing_standard) + new_sign_standing.drop = "mcl_signs:wall_sign" .. _name + new_sign_standing.wield_image = "(default_sign.png^[multiply:" .. color .. ")" + new_sign_standing.tiles = { "(mcl_signs_sign.png^[multiply:" .. color .. ")" } + new_sign_standing.inventory_image = "(default_sign.png^[multiply:" .. color .. ")" + new_sign_standing.on_rotate = function(pos, node, user, mode) + if mode == screwdriver.ROTATE_FACE then + node.name = "mcl_signs:standing_sign22_5" .. _name + minetest.swap_node(pos, node) + elseif mode == screwdriver.ROTATE_AXIS then + return false + end + mcl_signs:update_sign(pos, nil, nil, true) + return true + end, + minetest.override_item("mcl_signs:standing_sign" .. _name, new_sign_standing) + update_sign_registry("standing", "mcl_signs:standing_sign" .. _name) + -- debug step + if DEBUG then + minetest.log("action", "[mcl_signs] Registered: mcl_signs:standing_sign" .. _name .. color .. "\n" .. dump(new_sign_standing)) + end + + -- 22.5° + local ssign22_5d = table.copy(new_sign_standing) + ssign22_5d.mesh = "mcl_signs_sign22.5.obj" + ssign22_5d.on_rotate = function(pos, node, user, mode) + if mode == screwdriver.ROTATE_FACE then + node.name = "mcl_signs:standing_sign45" .. _name + minetest.swap_node(pos, node) + elseif mode == screwdriver.ROTATE_AXIS then + return false + end + mcl_signs:update_sign(pos, nil, nil, true) + return true + end + minetest.override_item("mcl_signs:standing_sign22_5" .. _name, ssign22_5d) + update_sign_registry("standing", "mcl_signs:standing_sign22_5" .. _name) + + -- 45° + local ssign45d = table.copy(new_sign_standing) + ssign45d.mesh = "mcl_signs_sign45.obj" + ssign45d.on_rotate = function(pos, node, user, mode) + if mode == screwdriver.ROTATE_FACE then + node.name = "mcl_signs:standing_sign67_5" .. _name + minetest.swap_node(pos, node) + elseif mode == screwdriver.ROTATE_AXIS then + return false + end + mcl_signs:update_sign(pos, nil, nil, true) + return true + end + minetest.override_item("mcl_signs:standing_sign45" .. _name, ssign45d) + update_sign_registry("standing", "mcl_signs:standing_sign45" .. _name) + + -- 67.5° + local ssign67_5d = table.copy(new_sign_standing) + ssign67_5d.mesh = "mcl_signs_sign67.5.obj" + ssign67_5d.on_rotate = function(pos, node, user, mode) + if mode == screwdriver.ROTATE_FACE then + node.name = "mcl_signs:standing_sign" .. _name + node.param2 = (node.param2 + 1) % 4 + minetest.swap_node(pos, node) + elseif mode == screwdriver.ROTATE_AXIS then + return false + end + mcl_signs:update_sign(pos, nil, nil, true) + return true + end + minetest.override_item("mcl_signs:standing_sign67_5" .. _name, ssign67_5d) + update_sign_registry("standing", "mcl_signs:standing_sign67_5" .. _name) + + -- register Doc entry + if minetest.get_modpath("doc") then + doc.add_entry_alias("nodes", "mcl_signs:wall_sign", "nodes", "mcl_signs:wall_sign" .. _name) + doc.add_entry_alias("nodes", "mcl_signs:wall_sign", "nodes", "mcl_signs:standing_sign" .. _name) + doc.add_entry_alias("nodes", "mcl_signs:wall_sign", "nodes", "mcl_signs:standing_sign22_5" .. _name) + doc.add_entry_alias("nodes", "mcl_signs:wall_sign", "nodes", "mcl_signs:standing_sign45" .. _name) + doc.add_entry_alias("nodes", "mcl_signs:wall_sign", "nodes", "mcl_signs:standing_sign67_5" .. _name) + end + + --register standing sign's rotation_levels + table.insert(mcl_signs.standing_rotation_levels, { "mcl_signs:standing_sign22_5" .. _name, 1 }) + table.insert(mcl_signs.standing_rotation_levels, { "mcl_signs:standing_sign45" .. _name, 2 }) + table.insert(mcl_signs.standing_rotation_levels, { "mcl_signs:standing_sign67_5" .. _name, 3 }) +end + +--- The same as reregister_sign, except caller defines the textures. Note, there is a greyscale version of the sign, +--- called "default_sign_greyscale.png" and "mcl_signs_sign_greyscale.png" for optional use in the textures directory. +--- +--- modname: optional (pass "" or "false" to ignore), for use with other mods to +--- allow the creation of a sign from the mod's wood (if installed). +--- +--- _name: the sign's name suffix, such as "_dark" or "_red", etc., appended to "wall_sign" or "standing_sign" +--- +--- tiles: the texture file to use for the sign. +--- +--- color: color the texture file to use with this color. Use white (#FFFFFF) to negate the color, +--- and just use the texture as is +--- +--- inventory_image: the texture file to use for the sign's display in inventory. +--- +--- wield_image: the texture file to use for the sign's weilded (in hand) object. +--- +--- inventory_image: the image used for in-inventory and in hand. +--- +--- ttsign: the tool tip of the sign that gets translated. Shown when the mouse hovers the inventory sign. +--- For example: the basic, default oak (wood) sign is just "Sign"; and a spruce sign would be "Spruce Sign" +function mcl_signs.reregister_sign_custom (modname, _name, tiles, color, inventory_image, wield_image, ttsign) + local mod_name_pass = false + if modname ~= "" and modname ~= "false" then + if minetest.get_modpath(modname) then + mod_name_pass = true + end + if mod_name_pass == false then + return + end + end + local new_sign = {} + + new_sign = table.copy(mcl_signs.wall_standard) + + new_sign.wield_image = "(" .. wield_image .. "^[multiply:" .. color .. ")" + new_sign.tiles = { "(" .. tiles .. "^[multiply:" .. color .. ")" } + new_sign.inventory_image = "(" .. inventory_image .. "^[multiply:" .. color .. ")" + new_sign.description = S(ttsign) + -- currently have to do this, because of how the base node placement works. + new_sign.on_place = function(itemstack, placer, pointed_thing) + local above = pointed_thing.above + local under = pointed_thing.under + + -- Use pointed node's on_rightclick function first, if present + local node_under = minetest.get_node(under) + if placer and not placer:get_player_control().sneak then + if minetest.registered_nodes[node_under.name] and minetest.registered_nodes[node_under.name].on_rightclick then + return minetest.registered_nodes[node_under.name].on_rightclick(under, node_under, placer, itemstack) or itemstack + end + end + + local dir = vector.subtract(under, above) + + -- Only build when it's legal + local abovenodedef = minetest.registered_nodes[minetest.get_node(above).name] + if not abovenodedef or abovenodedef.buildable_to == false then + return itemstack + end + + local wdir = minetest.dir_to_wallmounted(dir) + local fdir = minetest.dir_to_facedir(dir) + + local sign_info + local nodeitem = ItemStack(itemstack) + -- Ceiling + if wdir == 0 then + --how would you add sign to ceiling? + return itemstack + -- Floor + elseif wdir == 1 then + -- Standing sign + + -- Determine the sign rotation based on player's yaw + local yaw = pi * 2 - placer:get_look_horizontal() + + -- Select one of 16 possible rotations (0-15) + local rotation_level = mcl_signs:round((yaw / (pi * 2)) * 16) + + if rotation_level > 15 then + rotation_level = 0 + elseif rotation_level < 0 then + rotation_level = 15 + end + + -- The actual rotation is a combination of predefined mesh and facedir (see node definition) + if rotation_level % 4 == 0 then + nodeitem:set_name("mcl_signs:standing_sign" .. _name) + elseif rotation_level % 4 == 1 then + nodeitem:set_name("mcl_signs:standing_sign22_5" .. _name) + elseif rotation_level % 4 == 2 then + nodeitem:set_name("mcl_signs:standing_sign45" .. _name) + elseif rotation_level % 4 == 3 then + nodeitem:set_name("mcl_signs:standing_sign67_5" .. _name) + end + fdir = math.floor(rotation_level / 4) + + -- Place the node! + local _, success = minetest.item_place_node(nodeitem, placer, pointed_thing, fdir) + if not success then + return itemstack + end + if not minetest.is_creative_enabled(placer:get_player_name()) then + itemstack:take_item() + end + sign_info = mcl_signs.signtext_info_standing[rotation_level + 1] + -- Side + else + -- Wall sign + local _, success = minetest.item_place_node(itemstack, placer, pointed_thing, wdir) + if not success then + return itemstack + end + sign_info = mcl_signs.signtext_info_wall[fdir + 1] + end + + -- Determine spawn position of entity + local place_pos + if minetest.registered_nodes[node_under.name].buildable_to then + place_pos = under + else + place_pos = above + end + + local text_entity = minetest.add_entity({ + x = place_pos.x + sign_info.delta.x, + y = place_pos.y + sign_info.delta.y, + z = place_pos.z + sign_info.delta.z }, "mcl_signs:text") + text_entity:set_yaw(sign_info.yaw) + text_entity:get_luaentity()._signnodename = nodeitem:get_name() + + minetest.sound_play({ name = "default_place_node_hard", gain = 1.0 }, { pos = place_pos }, true) + + mcl_signs:show_formspec(placer, place_pos) + return itemstack + end + minetest.override_item("mcl_signs:wall_sign" .. _name, new_sign) + update_sign_registry("wall", "mcl_signs:wall_sign" .. _name) + + -- standing sign base. + local new_sign_standing = {} + new_sign_standing = table.copy(mcl_signs.standing_standard) + new_sign_standing.drop = "mcl_signs:wall_sign" .. _name + new_sign_standing.wield_image = "(" .. wield_image .. "^[multiply:" .. color .. ")" + new_sign_standing.tiles = { "(" .. tiles .. "^[multiply:" .. color .. ")" } + new_sign_standing.inventory_image = "(" .. inventory_image .. "^[multiply:" .. color .. ")" + new_sign_standing.on_rotate = function(pos, node, user, mode) + if mode == screwdriver.ROTATE_FACE then + node.name = "mcl_signs:standing_sign22_5" .. _name + minetest.swap_node(pos, node) + elseif mode == screwdriver.ROTATE_AXIS then + return false + end + mcl_signs:update_sign(pos, nil, nil, true) + return true + end, + minetest.override_item("mcl_signs:standing_sign" .. _name, new_sign_standing) + update_sign_registry("standing", "mcl_signs:standing_sign" .. _name) + + -- 22.5° + local ssign22_5d = table.copy(new_sign_standing) + ssign22_5d.mesh = "mcl_signs_sign22.5.obj" + ssign22_5d.on_rotate = function(pos, node, user, mode) + if mode == screwdriver.ROTATE_FACE then + node.name = "mcl_signs:standing_sign45" .. _name + minetest.swap_node(pos, node) + elseif mode == screwdriver.ROTATE_AXIS then + return false + end + mcl_signs:update_sign(pos, nil, nil, true) + return true + end + minetest.override_item("mcl_signs:standing_sign22_5" .. _name, ssign22_5d) + update_sign_registry("standing", "mcl_signs:standing_sign22_5" .. _name) + + -- 45° + local ssign45d = table.copy(new_sign_standing) + ssign45d.mesh = "mcl_signs_sign45.obj" + ssign45d.on_rotate = function(pos, node, user, mode) + if mode == screwdriver.ROTATE_FACE then + node.name = "mcl_signs:standing_sign67_5" .. _name + minetest.swap_node(pos, node) + elseif mode == screwdriver.ROTATE_AXIS then + return false + end + mcl_signs:update_sign(pos, nil, nil, true) + return true + end + minetest.override_item("mcl_signs:standing_sign45" .. _name, ssign45d) + update_sign_registry("standing", "mcl_signs:standing_sign45" .. _name) + + -- 67.5° + local ssign67_5d = table.copy(new_sign_standing) + ssign67_5d.mesh = "mcl_signs_sign67.5.obj" + ssign67_5d.on_rotate = function(pos, node, user, mode) + if mode == screwdriver.ROTATE_FACE then + node.name = "mcl_signs:standing_sign" .. _name + node.param2 = (node.param2 + 1) % 4 + minetest.swap_node(pos, node) + elseif mode == screwdriver.ROTATE_AXIS then + return false + end + mcl_signs:update_sign(pos, nil, nil, true) + return true + end + minetest.override_item("mcl_signs:standing_sign67_5" .. _name, ssign67_5d) + update_sign_registry("standing", "mcl_signs:standing_sign67_5" .. _name) + + -- register Doc entry + if minetest.get_modpath("doc") then + doc.add_entry_alias("nodes", "mcl_signs:wall_sign", "nodes", "mcl_signs:wall_sign" .. _name) + doc.add_entry_alias("nodes", "mcl_signs:wall_sign", "nodes", "mcl_signs:standing_sign" .. _name) + doc.add_entry_alias("nodes", "mcl_signs:wall_sign", "nodes", "mcl_signs:standing_sign22_5" .. _name) + doc.add_entry_alias("nodes", "mcl_signs:wall_sign", "nodes", "mcl_signs:standing_sign45" .. _name) + doc.add_entry_alias("nodes", "mcl_signs:wall_sign", "nodes", "mcl_signs:standing_sign67_5" .. _name) + end + + --register standing sign's rotation_levels + table.insert(mcl_signs.standing_rotation_levels, { "mcl_signs:standing_sign22_5" .. _name, 1 }) + table.insert(mcl_signs.standing_rotation_levels, { "mcl_signs:standing_sign45" .. _name, 2 }) + table.insert(mcl_signs.standing_rotation_levels, { "mcl_signs:standing_sign67_5" .. _name, 3 }) + +end + +--- Usage: Call this with the mod's name, the wood's item string (for the planks), and with the sign's suffix. +--- Registers the crafting recipe for that sign. for every registered sign, call this function to register the +--- standard recipe for the sign. Otherwise, you have to do your own register craft call. +--- +--- modname: optional (pass "" or "false" to ignore), for use with other mods to +--- allow the creation of a sign from the mod's wood (if installed). Example: "mcl_core". +--- +--- wood_item_string: example: "mcl_core:wood" or "mcl_core:sprucewood" +--- +--- _name: the sign's name suffix, such as "_dark" or "_red", etc., appended to "wall_sign" or "standing_sign" +function mcl_signs.register_sign_craft(modname, wood_item_string, _name) + local mod_name_pass = false + if modname ~= "" and modname ~= "false" then + if minetest.get_modpath(modname) then + mod_name_pass = true + end + if mod_name_pass == false then + return + end + end + + minetest.register_craft({ + type = "fuel", + recipe = "mcl_signs:wall_sign" .. _name, + burntime = 10, + }) + + -- debug step + if DEBUG then + minetest.log("action", "[mcl_signs] Register Sign Crafts: \n" .. modname .. "\n" .. wood_item_string .. "\n" .. _name) + end + + -- register crafts (actual recipe) + if minetest.get_modpath(modname) then + + local itemstring = "mcl_signs:wall_sign" + + minetest.register_craft({ + output = itemstring .. _name .. " 3", + recipe = { + { wood_item_string, wood_item_string, wood_item_string }, + { wood_item_string, wood_item_string, wood_item_string }, + { "", "mcl_core:stick", "" }, + }, + }) + end +end + +function mcl_signs.register_hanging_sign_craft(modname, wood_item_string, _name) + local mod_name_pass = false + if modname ~= "" and modname ~= "false" then + if minetest.get_modpath(modname) then + mod_name_pass = true + end + if mod_name_pass == false then + return + end + end + + minetest.register_craft({ + type = "fuel", + recipe = ":mcl_signs:wall_sign" .. _name, + burntime = 10, + }) + + -- debug step + if DEBUG then + minetest.log("action", "[mcl_signs] Register Sign Crafts: \n" .. modname .. "\n" .. wood_item_string .. "\n" .. _name) + end + + -- register crafts (actual recipe) + if minetest.get_modpath(modname) then + + local itemstring = ":mcl_signs:hanging_sign" + local quantity = "6" + + local bamboo = string.find(wood_item_string, "bamboo") + if bamboo then + quantity = "2" + end + minetest.register_craft({ + output = itemstring .. _name .. " " .. quantity, + recipe = { + { "mcl_lanterns:chain", "", "mcl_lanterns:chain" }, + { wood_item_string, wood_item_string, wood_item_string }, + { wood_item_string, wood_item_string, wood_item_string }, + }, + }) + end +end + +-- Helper functions +local function string_to_array(str) + local string_table = {} + for i = 1, string.len(str) do + table.insert(string_table, string.sub(str, i, i)) + end + return string_table +end + +local function string_to_line_array(str) + local linechar_table = {} + local current = 1 + local linechar = 1 + linechar_table[1] = "" + for _, char in ipairs(string_to_array(str)) do + -- New line + if char == "\n" then + current = current + 1 + linechar_table[current] = "" + linechar = 1 + else + linechar_table[current] = linechar_table[current] .. char + linechar = linechar + 1 + end + end + return linechar_table +end + +local function get_rotation_level(facedir, nodename) + local nnames = mcl_signs.standing_rotation_levels -- functional copy... was easier this way. #LazyAF :P + + local rl + local offset = 0 + for x = 1, #nnames do + if nnames[x][1] == nodename then + offset = nnames[x][2] + break + end + end + rl = facedir * 4 + offset + if DEBUG then + minetest.log("action", "[mcl_signs] GetRotationLevel: NodeName: " .. nodename .. " RL value: " .. rl) + end + return rl +end + +function mcl_signs:round(num, idp) + local mult = 10 ^ (idp or 0) + return math.floor(num * mult + 0.5) / mult +end + +function mcl_signs:get_color_for_sign(item_name) + + for d = 1, #Dyes_table do + if Dyes_table[d][1] == item_name then + return Dyes_table[d][2] + end + end + return "false" +end + +function mcl_signs:color_sign (pos, text_color) + + local success = mcl_signs:update_sign(pos, nil, nil, true, text_color) + + -- debug step + local meta = minetest.get_meta(pos) + if not meta then + minetest.log("error", "[mcl_signs] Sign Color Fail - Metadata.") + + return false + end + if DEBUG then + minetest.log("verbose", "[mcl_signs] Post-Sign Color: " .. meta:get_string("mcl_signs:text_color") .. " " .. meta:get_string("mcl_signs:glowing_sign") .. ".\n" .. dump(pos)) + end + + return success + +end + +function mcl_signs:glow_sign (pos, remove_glow) + local success = true + -- Get Meta Data for the sign. + local meta = minetest.get_meta(pos) + + if not meta then + return false + end + local text = meta:get_string("text") + if text == nil then + text = "" + end + + -- we can't make the text glow if there isn't any text + if text == "" then + return false + end + + if remove_glow == nil then + remove_glow = false + end + + -- set up text glow + local objects = minetest.get_objects_inside_radius(pos, 0.5) + local text_entity + for _, v in ipairs(objects) do + local ent = v:get_luaentity() + if ent and ent.name == "mcl_signs:text" then + text_entity = v + break + end + end + if remove_glow == true then + text_entity:set_properties({ + glow = nil, + }) + meta:set_string("mcl_signs:glowing_sign", "false") + else + text_entity:set_properties({ + glow = sign_glow, + }) + meta:set_string("mcl_signs:glowing_sign", "true") + end + if not text_entity then + return false + end + text_entity:get_luaentity()._glowing_sign = meta:get_string("mcl_signs:glowing_sign") + + -- debug step + if DEBUG then + minetest.log("verbose", "[mcl_signs] Post-Sign Glow: " .. meta:get_string("mcl_signs:text_color") .. " " .. meta:get_string("mcl_signs:glowing_sign") .. ".\n" .. dump(pos)) + end + return success +end + +function mcl_signs:create_lettering(text, signnodename, sign_color) + if sign_color == nil then + sign_color = mcl_colors.BLACK + end + local texture = mcl_signs:generate_texture(mcl_signs:create_lines(text), signnodename, sign_color) + + -- debug step + if DEBUG then + minetest.log("action", "[mcl_signs] Creating sign text; text:" .. text) + end + + return texture +end + +function mcl_signs:create_lines(text) + local line_num = 1 + local text_table = {} + for _, line in ipairs(string_to_line_array(text)) do + if line_num > NUMBER_OF_LINES then + break + end + table.insert(text_table, line) + line_num = line_num + 1 + end + return text_table +end + +function mcl_signs:generate_line(s, ypos) + local i = 1 + local parsed = {} + local width = 0 + local chars = 0 + local printed_char_width = CHAR_WIDTH + 1 + while chars < LINE_LENGTH and i <= #s do + local file + -- Get and render character + if charmap[s:sub(i, i)] then + file = charmap[s:sub(i, i)] + i = i + 1 + elseif i < #s and charmap[s:sub(i, i + 1)] then + file = charmap[s:sub(i, i + 1)] + i = i + 2 + else + -- No character image found. + -- Use replacement character: + file = "_rc" + i = i + 1 + if DEBUG then + minetest.log("verbose", "[mcl_signs] Unknown symbol in '" .. s .. "' at " .. i) + end + end + if file then + width = width + printed_char_width + table.insert(parsed, file) + chars = chars + 1 + end + end + width = width - 1 + + local texture = "" + local xpos = math.floor((SIGN_WIDTH - width) / 2) + + for j = 1, #parsed do + texture = texture .. ":" .. xpos .. "," .. ypos .. "=" .. parsed[j] .. ".png" + xpos = xpos + printed_char_width + end + return texture +end + +function mcl_signs:generate_texture(lines, signnodename, letter_color) + local texture = "[combine:" .. SIGN_WIDTH .. "x" .. SIGN_WIDTH + local ypos = 0 + + -- Handle all of the dynamically created signs. + for x = 1, #mcl_signs.registered_signs.wall_signs do + if signnodename == mcl_signs.registered_signs.wall_signs[x] then + ypos = 30 + break + end + end + for x = 1, #mcl_signs.registered_signs.standing_signs do + if signnodename == mcl_signs.registered_signs.standing_signs[x] then + ypos = 0 + break + end + end + -- for future inclusion, when the hanging sings are made. + --[[ + for x = 1, #mcl_signs.registered_signs.hanging_signs do + if signnodename == mcl_signs.registered_signs.hanging_signs[x] then + ypos = 30 + break + end + end + ]] + + -- kept in for now, compatibility with existing hard coded signs. TODO: Remove after done with api. + if signnodename == "mcl_signs:wall_sign" or signnodename == "mcl_signs:wall_sign_dark" then + ypos = 30 + end + + -- debug step + if DEBUG then + minetest.log("action", "[mcl_signs] Generate_Texture::Debug_Data:\nSignNodeName: " .. dump(signnodename) .. "\nYPOS: " .. ypos) + end + + for i = 1, #lines do + texture = texture .. mcl_signs:generate_line(lines[i], ypos) + ypos = ypos + LINE_HEIGHT + end + + texture = "(" .. texture .. "^[multiply:" .. letter_color .. ")" + return texture +end + +function mcl_signs:get_wall_signtext_info(param2, nodename) + local dir = minetest.wallmounted_to_dir(param2) + if dir.x > 0 then + return 2 + elseif dir.z > 0 then + return 1 + elseif dir.x < 0 then + return 4 + else + return 3 + end +end + +function mcl_signs:destruct_sign(pos) + local objects = minetest.get_objects_inside_radius(pos, 0.5) + for _, v in ipairs(objects) do + local ent = v:get_luaentity() + if ent and ent.name == "mcl_signs:text" then + v:remove() + end + end + local players = minetest.get_connected_players() + for p = 1, #players do + if vector.distance(players[p]:get_pos(), pos) <= 30 then + minetest.close_formspec(players[p]:get_player_name(), "mcl_signs:set_text_" .. pos.x .. "_" .. pos.y .. "_" .. pos.z) + end + end +end + +function mcl_signs:update_sign(pos, fields, sender, force_remove, text_color) + -- Get Meta Data for the sign. + local meta = minetest.get_meta(pos) + + if not meta then + return false + end + local text = meta:get_string("text", "") + if fields and (text == "" and fields.text) then + meta:set_string("text", fields.text) + text = fields.text + end + if text == nil then + text = "" + end + + -- find text color. + local sign_color + + if meta:get_string("mcl_signs:text_color") == "" then + -- if no sign text color has been assigned, make it black. + sign_color = mcl_colors.BLACK + meta:set_string("mcl_signs:text_color", sign_color) + else + sign_color = meta:get_string("mcl_signs:text_color") + end + + if text_color == nil or text == "" then + text_color = "false" + end + + if text_color == "false" then + text_color = sign_color --if a new color hasn't been chosen, then keep the existing color. + end + + -- find the sign's glow value + local has_glow = false + + if meta:get_string("mcl_signs:glowing_sign") == "" or meta:get_string("mcl_signs:glowing_sign") == "false" then + has_glow = false + meta:set_string("mcl_signs:glowing_sign", "false") + else + has_glow = true + end + + -- debug step + if DEBUG then + minetest.log("action", "[mcl_signs] Update_Signs: Pre-Sign Update: " .. sign_color .. " " .. meta:get_string("mcl_signs:glowing_sign") .. ".\n" .. dump(pos)) + end + + local sign_info + local npos = minetest.get_node(pos) + local npos_name = npos.name + + -- Handle all of the dynamically created signs. + for x = 1, #mcl_signs.registered_signs.wall_signs do + if npos_name == mcl_signs.registered_signs.wall_signs[x] then + sign_info = mcl_signs.signtext_info_wall[mcl_signs:get_wall_signtext_info(npos.param2)] + break + end + end + for x = 1, #mcl_signs.registered_signs.standing_signs do + if npos_name == mcl_signs.registered_signs.standing_signs[x] then + sign_info = mcl_signs.signtext_info_standing[get_rotation_level(npos.param2, npos_name) + 1] + break + end + end + -- for future inclusion, when the hanging sings are made. + --[[ + for x = 1, #mcl_signs.registered_signs.hanging_signs do + if nn == mcl_signs.registered_signs.hanging_signs[x] then + sign_info = mcl_signs.signtext_info_wall[mcl_signs:get_wall_signtext_info(n.param2)] + break + end + end + ]] + + -- the following if..elseif..end block is here for compatibility with the old code. TODO: remove this block after the new api is complete. + if npos_name == "mcl_signs:standing_sign_dark" or npos_name == "mcl_signs:standing_sign22_5_dark" or npos_name == "mcl_signs:standing_sign45_dark" or npos_name == "mcl_signs:standing_sign67_5_dark" then + sign_info = mcl_signs.signtext_info_standing[get_rotation_level(npos.param2, npos_name) + 1] + elseif npos_name == "mcl_signs:wall_sign_dark" then + sign_info = mcl_signs.signtext_info_wall[mcl_signs:get_wall_signtext_info(npos.param2)] + end + if sign_info == nil then + minetest.log("error", "[mcl_signs] Update_Signs: Missing sign_info!") + return false + end + + local text_entity + text_entity = mcl_signs:get_text_entity(pos,force_remove) + + if not text_entity then + if DEBUG then + minetest.log("action", "[mcl_signs] Update_Sign: Text_Entity - does not exist, creating it now.") + end + text_entity = minetest.add_entity({ + x = pos.x + sign_info.delta.x, + y = pos.y + sign_info.delta.y, + z = pos.z + sign_info.delta.z }, "mcl_signs:text") + + if DEBUG then + minetest.log("action", "[mcl_signs] Update_Sign: Placed position:" .. dump(pos) .. "\nSign_info: " .. dump(sign_info)) + end + end + text_entity:get_luaentity()._signnodename = npos_name + + -- set up special case: Dark Oak Sign. Dark Oak signs are soooo dark, they start off with white lettering. + if npos_name == "mcl_signs:wall_sign_darkwood" or + npos_name == "mcl_signs:standing_sign67_5_darkwood" or + npos_name == "mcl_signs:standing_sign45_darkwood" or + npos_name == "mcl_signs:standing_sign22_5_darkwood" or + npos_name == "mcl_signs:standing_sign_darkwood" + then + if text_color == "#000000" then + text_color = "#ffffff" + end + end + + -- Set the actual properties for the sign + + text_entity:set_properties({ + textures = { mcl_signs:create_lettering(text, npos_name, text_color) }, + }) + + if has_glow then + text_entity:set_properties({ + glow = sign_glow, + }) + end + + text_entity:set_yaw(sign_info.yaw) + if DEBUG then + minetest.log("verbose", "[mcl_signs] Update_Sign: After texture recreation.") + minetest.log("action", "[mcl_signs] Update_Sign: " .. npos_name .. "\nPlaced position:" .. dump(pos) .. "\nSign_info: " .. dump(sign_info)) + end + + -- save sign metadata. + meta:set_string("mcl_signs:text_color", text_color) + + -- Moved timer stuff to here, to make sure that it's called and only has one set of code. + local timer = minetest.get_node_timer(pos) + if text_entity and text ~= "" then + -- Do timer related stuff - but only if there is text to display. + -- Also, prevent excessive use with punching. (see node def.) + if timer:is_started() == false then + timer:start(TIMER_INTERVAL) + else + timer:stop() + timer:start(TIMER_INTERVAL) + end + else + if timer:is_started() == true then + timer:stop() + end + end + + -- debug step + if DEBUG then + minetest.log("action", "[mcl_signs] Update_Sign: Post-Sign Update: " .. meta:get_string("mcl_signs:text_color") .. " " .. meta:get_string("mcl_signs:glowing_sign") .. ".\n" .. dump(pos)) + end + + return true + +end + +function mcl_signs:show_formspec(player, pos) + minetest.show_formspec( + player:get_player_name(), + "mcl_signs:set_text_" .. pos.x .. "_" .. pos.y .. "_" .. pos.z, + "size[6,3]textarea[0.25,0.25;6,1.5;text;" .. F(S("Enter sign text:")) .. ";]label[0,1.5;" .. F(S("Maximum line length: 15")) .. "\n" .. F(S("Maximum lines: 4")) .. "]button_exit[0,2.5;6,1;submit;" .. F(S("Done")) .. "]" + ) +end + +function mcl_signs:get_text_entity (pos, force_remove) + local objects = minetest.get_objects_inside_radius(pos, 0.5) + local text_entity = false -- just to have a check for failure. + for _, v in ipairs(objects) do + local ent = v:get_luaentity() + if ent and ent.name == "mcl_signs:text" then + if force_remove ~= nil and force_remove == true then + v:remove() + else + text_entity = v + break + end + end + end + return text_entity +end \ No newline at end of file From 467700591bfdafdaacad287189b990f8033d8495 Mon Sep 17 00:00:00 2001 From: Michieal Date: Thu, 17 Nov 2022 23:33:31 +0000 Subject: [PATCH 2/4] revert 62fb34a029a78e74a4b768a30827961329719551 revert Fix the crafting recipes for the signs. --- signs_api.lua | 2003 ------------------------------------------------- 1 file changed, 2003 deletions(-) delete mode 100644 signs_api.lua diff --git a/signs_api.lua b/signs_api.lua deleted file mode 100644 index 1f7369ba3..000000000 --- a/signs_api.lua +++ /dev/null @@ -1,2003 +0,0 @@ ---- ---- Generated by EmmyLua. ---- Created by Michieal (FaerRaven). ---- DateTime: 10/14/22 4:05 PM ---- - ---local logging = minetest.settings:get_bool("mcl_logging_mcl_signs",true) - -local DEBUG = minetest.settings:get_bool("mcl_logging_mcl_signs", false) -- special debug setting. - -if DEBUG then - minetest.log("action", "[mcl_signs] Signs API Loading") -end - --- LOCALIZATION -local S = minetest.get_translator("mcl_signs") --- Signs form -local F = minetest.formspec_escape - --- PATHs -local modpath = minetest.get_modpath("mcl_signs") - --- CONSTANTS -local SIGN_WIDTH = 115 - -local LINE_LENGTH = 15 -local NUMBER_OF_LINES = 4 - -local LINE_HEIGHT = 14 -local CHAR_WIDTH = 5 -local TIMER_INTERVAL = 40.0 --- ----------------------- --- CACHE LOCAL COPIES -local table = table -local string = string - --- CACHE NODE_SOUNDS -local node_sounds -if minetest.get_modpath("mcl_sounds") then - node_sounds = mcl_sounds.node_sound_wood_defaults() -end - --- SET UP THE CHARACTER MAPPING --- Load the characters map (characters.txt) ---[[ File format of characters.txt: -It's an UTF-8 encoded text file that contains metadata for all supported characters. It contains a sequence of info - blocks, one for each character. Each info block is made out of 3 lines: -Line 1: The literal UTF-8 encoded character -Line 2: Name of the texture file for this character minus the “.png” suffix; found in the “textures/” sub-directory -Line 3: Currently ignored. Previously this was for the character width in pixels - -After line 3, another info block may follow. This repeats until the end of the file. - -All character files must be 5 or 6 pixels wide (5 pixels are preferred) -]] - -local chars_file = io.open(modpath .. "/characters.txt", "r") --- FIXME: Support more characters (many characters are missing). Currently ASCII and Latin-1 Supplement are supported. -local charmap = {} -if not chars_file then - minetest.log("error", "[mcl_signs] : character map file not found") -else - while true do - local char = chars_file:read("*l") - if char == nil then - break - end - local img = chars_file:read("*l") - chars_file:read("*l") - charmap[char] = img - end -end - -local pi = 3.1415926 -- enough accuracy, to build an engine for a car. - -local math = math - --- locally cached copy of the official colors; this way, it updates as mcl_colors updates. -local mcl_colors_official = mcl_colors -if DEBUG then - minetest.log("verbose", "[mcl_signs]Official MCL_Colors:\n" .. dump(mcl_colors_official)) -end - --- INITIALIZE THE GLOBAL API FOR SIGNS. -mcl_signs = {} - --- GLOBALS -mcl_signs.sign_groups = { handy = 1, axey = 1, deco_block = 1, material_wood = 1, attached_node = 1, dig_by_piston = 1, flammable = -1 } ---- colors used for wools. -mcl_signs.mcl_wool_colors = { - unicolor_white = "#FFFFFF", - unicolor_dark_orange = "#502A00", - unicolor_grey = "#5B5B5B", - unicolor_darkgrey = "#303030", - unicolor_blue = "#0000CC", - unicolor_dark_green = "#005000", - unicolor_green_or_lime = "#50CC00", - unicolor_violet_purple = "#5000CC", - unicolor_light_red_pink = "#FF5050", - unicolor_yellow = "#CCCC00", - unicolor_orange = "#CC5000", - unicolor_red = "#CC0000", - unicolor_cyan = "#00CCCC", - unicolor_red_violet_magenta = "#CC0050", - unicolor_black = "#000000", - unicolor_light_blue = "#5050FF", -} -mcl_signs.signtext_info_wall = {} -mcl_signs.signtext_info_standing = {} -- built in build_signs_info(). --- the rotational levels for all of the standing signs. -mcl_signs.standing_rotation_levels = {} - --- data structure block for dynamically registered signs. -mcl_signs.registered_signs = {} -mcl_signs.registered_signs.wall_signs = {} -mcl_signs.registered_signs.standing_signs = {} -mcl_signs.registered_signs.hanging_signs = {} -- unused. prepping for future use. --- DEFINE SIGN BASE TYPES -mcl_signs.wall_standard = {} -- initialize -mcl_signs.standing_standard = {} -- initialize - -function mcl_signs.build_signs_info() - local n = 23 / 56 - 1 / 128 -- some required magic number from the original code. - local m = -1 / 16 + 1 / 64 -- " " " " " " " " - - mcl_signs.signtext_info_wall = { - { delta = { x = 0, y = 0, z = n }, yaw = 0 }, - { delta = { x = n, y = 0, z = 0 }, yaw = pi / -2 }, - { delta = { x = 0, y = 0, z = -n }, yaw = pi }, - { delta = { x = -n, y = 0, z = 0 }, yaw = pi / 2 }, - } - - -- PLACE YAW VALUES INTO THE TABLE. - for rot = 0, 15 do - local yaw = pi * 2 - (((pi * 2) / 16) * rot) - local delta = vector.multiply(minetest.yaw_to_dir(yaw), m) - -- Offset because sign is a bit above node boundaries - delta.y = delta.y + 2 / 28 - table.insert(mcl_signs.signtext_info_standing, { delta = delta, yaw = yaw }) - end - -end - --- wall signs' & hanging signs' base (definition) -mcl_signs.wall_standard = { - description = S("Sign"), - _tt_help = S("Can be written"), - _doc_items_longdesc = S("Signs can be written and come in two variants: Wall sign and sign on a sign post. Signs can be placed on the top and the sides of other blocks, but not below them."), - _doc_items_usagehelp = S("After placing the sign, you can write something on it. You have 4 lines of text with up to 15 characters for each line; anything beyond these limits is lost. Not all characters are supported. The text can not be changed once it has been written; you have to break and place the sign again. Can be colored and made to glow."), - inventory_image = "default_sign.png", - walkable = false, - is_ground_content = false, - wield_image = "default_sign.png", - node_placement_prediction = "", - paramtype = "light", - sunlight_propagates = true, - paramtype2 = "wallmounted", - drawtype = "mesh", - mesh = "mcl_signs_signonwallmount.obj", - selection_box = { type = "wallmounted", wall_side = { -0.5, -7 / 28, -0.5, -23 / 56, 7 / 28, 0.5 } }, - tiles = { "mcl_signs_sign.png" }, - use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "opaque" or false, - groups = mcl_signs.sign_groups, - stack_max = 16, - sounds = node_sounds, - - on_timer = function(pos) - -- fix for /ClearObjects - mcl_signs:update_sign(pos) - -- note: update_sign decides to keep the timer running based on if there is text. - -- This prevents every sign from having a timer, when not needed. - end, - - on_place = function(itemstack, placer, pointed_thing) - local above = pointed_thing.above - local under = pointed_thing.under - - -- Use pointed node's on_rightclick function first, if present - local node_under = minetest.get_node(under) - if placer and not placer:get_player_control().sneak then - if minetest.registered_nodes[node_under.name] and minetest.registered_nodes[node_under.name].on_rightclick then - return minetest.registered_nodes[node_under.name].on_rightclick(under, node_under, placer, itemstack) or itemstack - end - end - - local dir = vector.subtract(under, above) - - -- Only build when it's legal - local abovenodedef = minetest.registered_nodes[minetest.get_node(above).name] - if not abovenodedef or abovenodedef.buildable_to == false then - return itemstack - end - - local wdir = minetest.dir_to_wallmounted(dir) - - --local placer_pos = placer:get_pos() - - local fdir = minetest.dir_to_facedir(dir) - - local sign_info - local nodeitem = ItemStack(itemstack) - -- Ceiling - if wdir == 0 then - --how would you add sign to ceiling? - return itemstack - -- Floor - end - - if wdir == 1 then - -- Standing sign - - -- Determine the sign rotation based on player's yaw - local yaw = pi * 2 - placer:get_look_horizontal() - - -- Select one of 16 possible rotations (0-15) - local rotation_level = mcl_signs:round((yaw / (pi * 2)) * 16) - - if rotation_level > 15 then - rotation_level = 0 - elseif rotation_level < 0 then - rotation_level = 15 - end - - -- The actual rotation is a combination of predefined mesh and facedir (see node definition) - if rotation_level % 4 == 0 then - nodeitem:set_name("mcl_signs:standing_sign") - elseif rotation_level % 4 == 1 then - nodeitem:set_name("mcl_signs:standing_sign22_5") - elseif rotation_level % 4 == 2 then - nodeitem:set_name("mcl_signs:standing_sign45") - elseif rotation_level % 4 == 3 then - nodeitem:set_name("mcl_signs:standing_sign67_5") - end - fdir = math.floor(rotation_level / 4) - - -- Place the node! - local _, success = minetest.item_place_node(nodeitem, placer, pointed_thing, fdir) - if not success then - return itemstack - end - if not minetest.is_creative_enabled(placer:get_player_name()) then - itemstack:take_item() - end - sign_info = mcl_signs.signtext_info_standing[rotation_level + 1] - -- Side - else - -- Wall sign - local _, success = minetest.item_place_node(itemstack, placer, pointed_thing, wdir) - if not success then - return itemstack - end - sign_info = mcl_signs.signtext_info_wall[fdir + 1] - end - - -- Determine spawn position of entity - local place_pos - if minetest.registered_nodes[node_under.name].buildable_to then - place_pos = under - else - place_pos = above - end - - local text_entity = minetest.add_entity({ - x = place_pos.x + sign_info.delta.x, - y = place_pos.y + sign_info.delta.y, - z = place_pos.z + sign_info.delta.z }, "mcl_signs:text") - text_entity:set_yaw(sign_info.yaw) - text_entity:get_luaentity()._signnodename = nodeitem:get_name() - if DEBUG then - minetest.log("verbose", "[mcl_signs]Placed position:" .. dump(place_pos) .. "\nSign_info: " .. dump(sign_info)) - end - - minetest.sound_play({ name = "default_place_node_hard", gain = 1.0 }, { pos = place_pos }, true) - - mcl_signs:show_formspec(placer, place_pos) - return itemstack - end, - on_destruct = function(pos) - mcl_signs:destruct_sign(pos) - end, - - -- Not Useless Code. force updates the sign. - on_punch = function(pos, node, puncher) - mcl_signs:update_sign(pos) - end, - on_rotate = function(pos, node, user, mode) - if mode == screwdriver.ROTATE_FACE then - local r = screwdriver.rotate.wallmounted(pos, node, mode) - node.param2 = r - minetest.swap_node(pos, node) - mcl_signs:update_sign(pos, nil, nil, true) - return true - else - return false - end - end, - on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) - if DEBUG then - minetest.log("verbose", "[mcl_signs] Wall_Sign Right Click event.") - end - - -- make sure player is clicking - if not clicker or not clicker:is_player() then - return - end - - local item = clicker:get_wielded_item() - local iname = item:get_name() - - if node then - if DEBUG then - minetest.log("verbose", "[mcl_signs] Wall_Sign Right Click event on valid node.") - end - - -- handle glow from glow_ink_sac *first* - if (iname == "mcl_mobitems:glow_ink_sac") then - clicker:set_wielded_item(item) - local success = mcl_signs:glow_sign(pos) - if success then - if DEBUG then - minetest.log("verbose", "[mcl_signs] Sign Glow Success.") - end - itemstack:take_item() - end - return - end - - -- "mcl_dye:black" is a special case: it makes the sign's lettering black AND removes glow. - if (iname == "mcl_dye:black") then - clicker:set_wielded_item(item) - local success = mcl_signs:glow_sign(pos, true) - mcl_signs:color_sign(pos, mcl_colors.BLACK) - if success then - if DEBUG then - minetest.log("verbose", "[mcl_signs] Sign Glow removal Success.") - end - - itemstack:take_item() - end - return - end - - -- check the wielded item to make sure that it is a dye. - local txt_color = mcl_signs:get_color_for_sign(iname) - if txt_color ~= "false" then - clicker:set_wielded_item(item) - local success = mcl_signs:color_sign(pos, txt_color) - if success then - if DEBUG then - minetest.log("verbose", "[mcl_signs] Sign Color Success.") - end - itemstack:take_item() - end - end - end - end, - - _mcl_hardness = 1, - _mcl_blast_resistance = 1, -} --- standing sign base (definition) -mcl_signs.standing_standard = { - paramtype = "light", - use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "opaque" or false, - sunlight_propagates = true, - walkable = false, - is_ground_content = false, - paramtype2 = "facedir", - drawtype = "mesh", - mesh = "mcl_signs_sign.obj", - selection_box = { type = "fixed", fixed = { -0.2, -0.5, -0.2, 0.2, 0.5, 0.2 } }, - tiles = { "mcl_signs_sign.png" }, - groups = mcl_signs.sign_groups, - drop = "mcl_signs:wall_sign", - stack_max = 16, - sounds = node_sounds, - - on_destruct = function(pos) - mcl_signs:destruct_sign(pos) - end, - - on_timer = function(pos) - -- fix for /ClearObjects - mcl_signs:update_sign(pos) - minetest.get_node_timer(pos):start(40.0) - end, - - -- Not Useless Code. this force updates the sign. - on_punch = function(pos, node, puncher) - mcl_signs:update_sign(pos) - end, - on_rotate = function(pos, node, user, mode) - if mode == screwdriver.ROTATE_FACE then - node.name = "mcl_signs:standing_sign22_5" - minetest.swap_node(pos, node) - elseif mode == screwdriver.ROTATE_AXIS then - return false - end - mcl_signs:update_sign(pos, nil, nil, true) - return true - end, - - on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) - - if DEBUG then - minetest.log("verbose", "[mcl_signs] Standing_Sign Right Click event.") - end - - -- make sure player is clicking - if not clicker or not clicker:is_player() then - return - end - - local item = clicker:get_wielded_item() - local iname = item:get_name() - - if node then - -- handle glow from glow_ink_sac *first* - if DEBUG then - minetest.log("verbose", "[mcl_signs] Standing_Sign Right Click event on valid node.") - end - - if (iname == "mcl_mobitems:glow_ink_sac") then - clicker:set_wielded_item(item) - local success = mcl_signs:glow_sign(pos) - if success then - if DEBUG then - minetest.log("verbose", "[mcl_signs] Sign Glow Success.") - end - itemstack:take_item() - end - return - end - - -- check the wielded item to make sure that it is a dye. - local txt_color = mcl_signs:get_color_for_sign(iname) - if txt_color ~= "false" then - clicker:set_wielded_item(item) - local success = mcl_signs:color_sign(pos, txt_color) - if success then - if DEBUG then - minetest.log("verbose", "[mcl_signs] Sign Color Success.") - end - itemstack:take_item() - end - end - end - end, - - _mcl_hardness = 1, - _mcl_blast_resistance = 1, -} - --- HELPER FUNCTIONS' VARIABLES -local sign_glow = 6 -local Dyes_table = { - { "mcl_dye:aqua", mcl_colors_official.AQUA }, - { "mcl_dye:black", mcl_colors_official.BLACK }, - { "mcl_dye:blue", mcl_colors_official.BLUE }, - { "mcl_dye:brown", mcl_colors_official.brown }, - { "mcl_dye:cyan", mcl_signs.mcl_wool_colors.unicolor_cyan }, - { "mcl_dye:green", mcl_colors_official.GREEN }, - { "mcl_dye:dark_green", mcl_colors_official.DARK_GREEN }, - { "mcl_dye:grey", mcl_colors_official.GRAY }, - { "mcl_dye:dark_grey", mcl_colors_official.DARK_GRAY }, - { "mcl_dye:lightblue", mcl_signs.mcl_wool_colors.unicolor_light_blue }, - { "mcl_dye:lime", mcl_signs.unicolor_green_or_lime }, - { "mcl_dye:magenta", mcl_colors_official.LIGHT_PURPLE }, - { "mcl_dye:orange", mcl_signs.mcl_wool_colors.unicolor_orange }, - { "mcl_dye:pink", mcl_signs.mcl_wool_colors.unicolor_light_red_pink }, - { "mcl_dye:purple", mcl_colors_official.LIGHT_PURPLE }, - { "mcl_dye:red", mcl_signs.mcl_wool_colors.unicolor_red }, - { "mcl_dye:silver", mcl_signs.mcl_wool_colors.unicolor_grey }, - { "mcl_dye:violet", mcl_colors_official.DARK_PURPLE }, - { "mcl_dye:white", mcl_colors_official.WHITE }, - { "mcl_dye:yellow", mcl_colors_official.YELLOW }, -} - -local function update_sign_registry(type, name) - if type == "wall" then - table.insert(mcl_signs.registered_signs.wall_signs, name) - end - if type == "standing" then - table.insert(mcl_signs.registered_signs.standing_signs, name) - end - if type == "hanging" then - table.insert(mcl_signs.registered_signs.hanging_signs, name) - end -end - -function mcl_signs.make_lbm() - - local registered_sign_nodenames = {} - - for i = 0, #mcl_signs.registered_signs.wall_signs do - table.insert(registered_sign_nodenames, mcl_signs.registered_signs.wall_signs[i]) - end - - for i = 0, #mcl_signs.registered_signs.standing_signs do - table.insert(registered_sign_nodenames, mcl_signs.registered_signs.standing_signs[i]) - end - - for i = 0, #mcl_signs.registered_signs.hanging_signs do - table.insert(registered_sign_nodenames, mcl_signs.registered_signs.hanging_signs[i]) - end - - -- the above is not yet used. - minetest.register_lbm({ - name = "mcl_signs:respawn_entities", - label = "Respawn sign text entities", - run_at_every_load = true, - nodenames = registered_sign_nodenames, - action = function(pos, node) - mcl_signs:update_sign(pos) - end, - }) - -end - -function mcl_signs.register_dye (modname, item_name, color_code) - if minetest.get_modpath(modname) then - table.insert(Dyes_table, { item_name, color_code }) - end -end - ---- Register a new sign, tint the textures, and gives it an unique node name. Creates both wall and standing signs. ---- modname: optional (pass "" or "false" to ignore), for use with other mods to ---- allow the creation of a sign from the mod's wood (if installed). ---- ---- color: the color code to color the base sign textures. must be a valid html color code. ---- ---- _name: the sign's name suffix, such as "_dark" or "_red", etc., appended to "wall_sign" or "standing_sign" ---- ---- ttsign: the tool tip of the sign that gets translated. Shown when the mouse hovers the inventory sign. ---- For example: the basic, default oak (wood) sign is just "Sign"; and a spruce sign would be "Spruce Sign" -function mcl_signs.register_sign (modname, color, _name, ttsign) - local mod_name_pass = false - if modname ~= "" and modname ~= "false" then - if minetest.get_modpath(modname) then - mod_name_pass = true - end - if mod_name_pass == false then - return - end - end - local new_sign = {} - - if color == nil or color == "" then - color = "#FFFFFF" - end - - new_sign = table.copy(mcl_signs.wall_standard) - new_sign.description = S(ttsign) - - new_sign.wield_image = "(default_sign.png^[multiply:" .. color .. ")" - new_sign.tiles = { "(mcl_signs_sign.png^[multiply:" .. color .. ")" } - new_sign.inventory_image = "(default_sign.png^[multiply:" .. color .. ")" - - -- currently have to do this, because of how the base node placement works. - new_sign.on_place = function(itemstack, placer, pointed_thing) - local above = pointed_thing.above - local under = pointed_thing.under - - -- Use pointed node's on_rightclick function first, if present - local node_under = minetest.get_node(under) - if placer and not placer:get_player_control().sneak then - if minetest.registered_nodes[node_under.name] and minetest.registered_nodes[node_under.name].on_rightclick then - return minetest.registered_nodes[node_under.name].on_rightclick(under, node_under, placer, itemstack) or itemstack - end - end - - local dir = vector.subtract(under, above) - - -- Only build when it's legal - local abovenodedef = minetest.registered_nodes[minetest.get_node(above).name] - if not abovenodedef or abovenodedef.buildable_to == false then - return itemstack - end - - local wdir = minetest.dir_to_wallmounted(dir) - local fdir = minetest.dir_to_facedir(dir) - - local sign_info - local nodeitem = ItemStack(itemstack) - - local yaw = 0 - - -- Ceiling - if wdir == 0 then - --how would you add sign to ceiling? simple - hanging sign. - -- add code for placement underneath a node. - - return itemstack - -- Floor - elseif wdir == 1 then - -- Standing sign - - -- Determine the sign rotation based on player's yaw - yaw = pi * 2 - placer:get_look_horizontal() - - -- Select one of 16 possible rotations (0-15) - local rotation_level = mcl_signs:round((yaw / (pi * 2)) * 16) - - if rotation_level > 15 then - rotation_level = 0 - elseif rotation_level < 0 then - rotation_level = 15 - end - - -- The actual rotation is a combination of predefined mesh and facedir (see node definition) - if rotation_level % 4 == 0 then - nodeitem:set_name("mcl_signs:standing_sign" .. _name) - elseif rotation_level % 4 == 1 then - nodeitem:set_name("mcl_signs:standing_sign22_5" .. _name) - elseif rotation_level % 4 == 2 then - nodeitem:set_name("mcl_signs:standing_sign45" .. _name) - elseif rotation_level % 4 == 3 then - nodeitem:set_name("mcl_signs:standing_sign67_5" .. _name) - end - fdir = math.floor(rotation_level / 4) - - -- Place the node! - local _, success = minetest.item_place_node(nodeitem, placer, pointed_thing, fdir) - if not success then - return itemstack - end - if not minetest.is_creative_enabled(placer:get_player_name()) then - itemstack:take_item() - end - sign_info = mcl_signs.signtext_info_standing[rotation_level + 1] - -- Side - else - -- Wall sign - local _, success = minetest.item_place_node(itemstack, placer, pointed_thing, wdir) - if not success then - return itemstack - end - sign_info = mcl_signs.signtext_info_wall[fdir + 1] - end - - -- Determine spawn position of entity - local place_pos - if minetest.registered_nodes[node_under.name].buildable_to then - place_pos = under - else - place_pos = above - end - - if DEBUG then - minetest.log("action", "[mcl_signs] Register_Sign::Placed position:" .. dump(place_pos) .. "\nSign_info: " .. dump(sign_info)) - end - - local text_entity = minetest.add_entity({ - x = place_pos.x + sign_info.delta.x, - y = place_pos.y + sign_info.delta.y, - z = place_pos.z + sign_info.delta.z }, "mcl_signs:text") - text_entity:set_yaw(sign_info.yaw) - text_entity:get_luaentity()._signnodename = nodeitem:get_name() - - minetest.sound_play({ name = "default_place_node_hard", gain = 1.0 }, { pos = place_pos }, true) - - mcl_signs:show_formspec(placer, place_pos) - return itemstack - end - - minetest.register_node(":mcl_signs:wall_sign" .. _name, new_sign) - update_sign_registry("wall", "mcl_signs:wall_sign" .. _name) - - -- debug step - if DEBUG then - minetest.log("action", "[mcl_signs] Registered: mcl_signs:wall_sign" .. _name .. color .. "\n" .. dump(new_sign)) - minetest.log("action", "[mcl_signs] mcl_signs:wall_sign_standard\n" .. dump(mcl_signs.wall_standard)) - end - - -- standing sign base. - local new_sign_standing = {} - new_sign_standing = table.copy(mcl_signs.standing_standard) - new_sign_standing.drop = "mcl_signs:wall_sign" .. _name - new_sign_standing.wield_image = "(default_sign.png^[multiply:" .. color .. ")" - new_sign_standing.tiles = { "(mcl_signs_sign.png^[multiply:" .. color .. ")" } - new_sign_standing.inventory_image = "(default_sign.png^[multiply:" .. color .. ")" - - new_sign_standing.on_rotate = function(pos, node, user, mode) - if mode == screwdriver.ROTATE_FACE then - node.name = "mcl_signs:standing_sign22_5" .. _name - minetest.swap_node(pos, node) - elseif mode == screwdriver.ROTATE_AXIS then - return false - end - mcl_signs:update_sign(pos, nil, nil, true) - return true - end, - - minetest.register_node(":mcl_signs:standing_sign" .. _name, new_sign_standing) - update_sign_registry("standing", "mcl_signs:standing_sign" .. _name) - -- debug step - if DEBUG then - minetest.log("action", "[mcl_signs] Registered: mcl_signs:standing_sign" .. _name .. color .. "\n" .. dump(new_sign_standing)) - end - - -- 22.5° - local ssign22_5d = table.copy(new_sign_standing) - ssign22_5d.mesh = "mcl_signs_sign22.5.obj" - ssign22_5d.on_rotate = function(pos, node, user, mode) - if mode == screwdriver.ROTATE_FACE then - node.name = "mcl_signs:standing_sign45" .. _name - minetest.swap_node(pos, node) - elseif mode == screwdriver.ROTATE_AXIS then - return false - end - mcl_signs:update_sign(pos, nil, nil, true) - return true - end - minetest.register_node(":mcl_signs:standing_sign22_5" .. _name, ssign22_5d) - update_sign_registry("standing", "mcl_signs:standing_sign22_5" .. _name) - - -- 45° - local ssign45d = table.copy(new_sign_standing) - ssign45d.mesh = "mcl_signs_sign45.obj" - ssign45d.on_rotate = function(pos, node, user, mode) - if mode == screwdriver.ROTATE_FACE then - node.name = "mcl_signs:standing_sign67_5" .. _name - minetest.swap_node(pos, node) - elseif mode == screwdriver.ROTATE_AXIS then - return false - end - mcl_signs:update_sign(pos, nil, nil, true) - return true - end - minetest.register_node(":mcl_signs:standing_sign45" .. _name, ssign45d) - update_sign_registry("standing", "mcl_signs:standing_sign45" .. _name) - - -- 67.5° - local ssign67_5d = table.copy(new_sign_standing) - ssign67_5d.mesh = "mcl_signs_sign67.5.obj" - ssign67_5d.on_rotate = function(pos, node, user, mode) - if mode == screwdriver.ROTATE_FACE then - node.name = "mcl_signs:standing_sign" .. _name - node.param2 = (node.param2 + 1) % 4 - minetest.swap_node(pos, node) - elseif mode == screwdriver.ROTATE_AXIS then - return false - end - mcl_signs:update_sign(pos, nil, nil, true) - return true - end - minetest.register_node(":mcl_signs:standing_sign67_5" .. _name, ssign67_5d) - update_sign_registry("standing", "mcl_signs:standing_sign67_5" .. _name) - - -- register Doc entry - if minetest.get_modpath("doc") then - doc.add_entry_alias("nodes", "mcl_signs:wall_sign", "nodes", "mcl_signs:wall_sign" .. _name) - doc.add_entry_alias("nodes", "mcl_signs:wall_sign", "nodes", "mcl_signs:standing_sign" .. _name) - doc.add_entry_alias("nodes", "mcl_signs:wall_sign", "nodes", "mcl_signs:standing_sign22_5" .. _name) - doc.add_entry_alias("nodes", "mcl_signs:wall_sign", "nodes", "mcl_signs:standing_sign45" .. _name) - doc.add_entry_alias("nodes", "mcl_signs:wall_sign", "nodes", "mcl_signs:standing_sign67_5" .. _name) - end - - --register standing sign's rotation_levels - table.insert(mcl_signs.standing_rotation_levels, { "mcl_signs:standing_sign22_5" .. _name, 1 }) - table.insert(mcl_signs.standing_rotation_levels, { "mcl_signs:standing_sign45" .. _name, 2 }) - table.insert(mcl_signs.standing_rotation_levels, { "mcl_signs:standing_sign67_5" .. _name, 3 }) -end - ---- The same as register_sign, except caller defines the textures. Note, there is a greyscale version of the sign, ---- called "default_sign_greyscale.png" and "mcl_signs_sign_greyscale.png" for optional use in the textures directory. ---- ---- modname: optional (pass "" or "false" to ignore), for use with other mods to ---- allow the creation of a sign from the mod's wood (if installed). ---- ---- _name: the sign's name suffix, such as "_dark" or "_red", etc., appended to "wall_sign" or "standing_sign" ---- ---- tiles: the texture file to use for the sign. ---- ---- color: color the texture file to use with this color. Use white (#FFFFFF) to negate the color, ---- and just use the texture as is ---- ---- inventory_image: the texture file to use for the sign's display in inventory. ---- ---- wield_image: the texture file to use for the sign's weilded (in hand) object. ---- ---- inventory_image: the image used for in-inventory and in hand. ---- ---- ttsign: the tool tip of the sign that gets translated. Shown when the mouse hovers the inventory sign. ---- For example: the basic, default oak (wood) sign is just "Sign"; and a spruce sign would be "Spruce Sign" -function mcl_signs.register_sign_custom (modname, _name, tiles, color, inventory_image, wield_image, ttsign) - local mod_name_pass = false - if modname ~= "" and modname ~= "false" then - if minetest.get_modpath(modname) then - mod_name_pass = true - end - if mod_name_pass == false then - return - end - end - local new_sign = {} - - new_sign = table.copy(mcl_signs.wall_standard) - - new_sign.wield_image = "(" .. wield_image .. "^[multiply:" .. color .. ")" - new_sign.tiles = { "(" .. tiles .. "^[multiply:" .. color .. ")" } - new_sign.inventory_image = "(" .. inventory_image .. "^[multiply:" .. color .. ")" - new_sign.description = S(ttsign) - -- currently have to do this, because of how the base node placement works. - new_sign.on_place = function(itemstack, placer, pointed_thing) - local above = pointed_thing.above - local under = pointed_thing.under - - -- Use pointed node's on_rightclick function first, if present - local node_under = minetest.get_node(under) - if placer and not placer:get_player_control().sneak then - if minetest.registered_nodes[node_under.name] and minetest.registered_nodes[node_under.name].on_rightclick then - return minetest.registered_nodes[node_under.name].on_rightclick(under, node_under, placer, itemstack) or itemstack - end - end - - local dir = vector.subtract(under, above) - - -- Only build when it's legal - local abovenodedef = minetest.registered_nodes[minetest.get_node(above).name] - if not abovenodedef or abovenodedef.buildable_to == false then - return itemstack - end - - local wdir = minetest.dir_to_wallmounted(dir) - local fdir = minetest.dir_to_facedir(dir) - - local sign_info - local nodeitem = ItemStack(itemstack) - -- Ceiling - if wdir == 0 then - --how would you add sign to ceiling? - return itemstack - -- Floor - elseif wdir == 1 then - -- Standing sign - - -- Determine the sign rotation based on player's yaw - local yaw = pi * 2 - placer:get_look_horizontal() - - -- Select one of 16 possible rotations (0-15) - local rotation_level = mcl_signs:round((yaw / (pi * 2)) * 16) - - if rotation_level > 15 then - rotation_level = 0 - elseif rotation_level < 0 then - rotation_level = 15 - end - - -- The actual rotation is a combination of predefined mesh and facedir (see node definition) - if rotation_level % 4 == 0 then - nodeitem:set_name("mcl_signs:standing_sign" .. _name) - elseif rotation_level % 4 == 1 then - nodeitem:set_name("mcl_signs:standing_sign22_5" .. _name) - elseif rotation_level % 4 == 2 then - nodeitem:set_name("mcl_signs:standing_sign45" .. _name) - elseif rotation_level % 4 == 3 then - nodeitem:set_name("mcl_signs:standing_sign67_5" .. _name) - end - fdir = math.floor(rotation_level / 4) - - -- Place the node! - local _, success = minetest.item_place_node(nodeitem, placer, pointed_thing, fdir) - if not success then - return itemstack - end - if not minetest.is_creative_enabled(placer:get_player_name()) then - itemstack:take_item() - end - sign_info = mcl_signs.signtext_info_standing[rotation_level + 1] - -- Side - else - -- Wall sign - local _, success = minetest.item_place_node(itemstack, placer, pointed_thing, wdir) - if not success then - return itemstack - end - sign_info = mcl_signs.signtext_info_wall[fdir + 1] - end - - -- Determine spawn position of entity - local place_pos - if minetest.registered_nodes[node_under.name].buildable_to then - place_pos = under - else - place_pos = above - end - - local text_entity = minetest.add_entity({ - x = place_pos.x + sign_info.delta.x, - y = place_pos.y + sign_info.delta.y, - z = place_pos.z + sign_info.delta.z }, "mcl_signs:text") - text_entity:set_yaw(sign_info.yaw) - text_entity:get_luaentity()._signnodename = nodeitem:get_name() - - minetest.sound_play({ name = "default_place_node_hard", gain = 1.0 }, { pos = place_pos }, true) - - mcl_signs:show_formspec(placer, place_pos) - return itemstack - end - minetest.register_node(":mcl_signs:wall_sign" .. _name, new_sign) - update_sign_registry("wall", "mcl_signs:wall_sign" .. _name) - - -- standing sign base. - local new_sign_standing = {} - new_sign_standing = table.copy(mcl_signs.standing_standard) - new_sign_standing.drop = "mcl_signs:wall_sign" .. _name - new_sign_standing.wield_image = "(" .. wield_image .. "^[multiply:" .. color .. ")" - new_sign_standing.tiles = { "(" .. tiles .. "^[multiply:" .. color .. ")" } - new_sign_standing.inventory_image = "(" .. inventory_image .. "^[multiply:" .. color .. ")" - new_sign_standing.on_rotate = function(pos, node, user, mode) - if mode == screwdriver.ROTATE_FACE then - node.name = "mcl_signs:standing_sign22_5" .. _name - minetest.swap_node(pos, node) - elseif mode == screwdriver.ROTATE_AXIS then - return false - end - mcl_signs:update_sign(pos, nil, nil, true) - return true - end, - minetest.register_node(":mcl_signs:standing_sign" .. _name, new_sign_standing) - update_sign_registry("standing", "mcl_signs:standing_sign" .. _name) - - -- 22.5° - local ssign22_5d = table.copy(new_sign_standing) - ssign22_5d.mesh = "mcl_signs_sign22.5.obj" - ssign22_5d.on_rotate = function(pos, node, user, mode) - if mode == screwdriver.ROTATE_FACE then - node.name = "mcl_signs:standing_sign45" .. _name - minetest.swap_node(pos, node) - elseif mode == screwdriver.ROTATE_AXIS then - return false - end - mcl_signs:update_sign(pos, nil, nil, true) - return true - end - minetest.register_node(":mcl_signs:standing_sign22_5" .. _name, ssign22_5d) - update_sign_registry("standing", "mcl_signs:standing_sign22_5" .. _name) - - -- 45° - local ssign45d = table.copy(new_sign_standing) - ssign45d.mesh = "mcl_signs_sign45.obj" - ssign45d.on_rotate = function(pos, node, user, mode) - if mode == screwdriver.ROTATE_FACE then - node.name = "mcl_signs:standing_sign67_5" .. _name - minetest.swap_node(pos, node) - elseif mode == screwdriver.ROTATE_AXIS then - return false - end - mcl_signs:update_sign(pos, nil, nil, true) - return true - end - minetest.register_node(":mcl_signs:standing_sign45" .. _name, ssign45d) - update_sign_registry("standing", "mcl_signs:standing_sign45" .. _name) - - -- 67.5° - local ssign67_5d = table.copy(new_sign_standing) - ssign67_5d.mesh = "mcl_signs_sign67.5.obj" - ssign67_5d.on_rotate = function(pos, node, user, mode) - if mode == screwdriver.ROTATE_FACE then - node.name = "mcl_signs:standing_sign" .. _name - node.param2 = (node.param2 + 1) % 4 - minetest.swap_node(pos, node) - elseif mode == screwdriver.ROTATE_AXIS then - return false - end - mcl_signs:update_sign(pos, nil, nil, true) - return true - end - minetest.register_node(":mcl_signs:standing_sign67_5" .. _name, ssign67_5d) - update_sign_registry("standing", "mcl_signs:standing_sign67_5" .. _name) - - -- register Doc entry - if minetest.get_modpath("doc") then - doc.add_entry_alias("nodes", "mcl_signs:wall_sign", "nodes", "mcl_signs:wall_sign" .. _name) - doc.add_entry_alias("nodes", "mcl_signs:wall_sign", "nodes", "mcl_signs:standing_sign" .. _name) - doc.add_entry_alias("nodes", "mcl_signs:wall_sign", "nodes", "mcl_signs:standing_sign22_5" .. _name) - doc.add_entry_alias("nodes", "mcl_signs:wall_sign", "nodes", "mcl_signs:standing_sign45" .. _name) - doc.add_entry_alias("nodes", "mcl_signs:wall_sign", "nodes", "mcl_signs:standing_sign67_5" .. _name) - end - - --register standing sign's rotation_levels - table.insert(mcl_signs.standing_rotation_levels, { "mcl_signs:standing_sign22_5" .. _name, 1 }) - table.insert(mcl_signs.standing_rotation_levels, { "mcl_signs:standing_sign45" .. _name, 2 }) - table.insert(mcl_signs.standing_rotation_levels, { "mcl_signs:standing_sign67_5" .. _name, 3 }) - -end - ---- Override an existing sign, tint the textures, and gives it an unique node name. Creates both wall and standing signs. ---- modname: optional (pass "" or "false" to ignore), for use with other mods to ---- allow the creation of a sign from the mod's wood (if installed). ---- ---- color: the color code to color the base sign textures. must be a valid html color code. ---- ---- _name: the sign's name suffix, such as "_dark" or "_red", etc., appended to "wall_sign" or "standing_sign" ---- ---- ttsign: the tool tip of the sign that gets translated. Shown when the mouse hovers the inventory sign. ---- For example: the basic, default oak (wood) sign is just "Sign"; and a spruce sign would be "Spruce Sign" -function mcl_signs.reregister_sign (modname, color, _name, ttsign) - local mod_name_pass = false - if modname ~= "" and modname ~= "false" then - if minetest.get_modpath(modname) then - mod_name_pass = true - end - if mod_name_pass == false then - return - end - end - local new_sign = {} - - if color == nil or color == "" then - color = "#FFFFFF" - end - - new_sign = table.copy(mcl_signs.wall_standard) - new_sign.description = S(ttsign) - - new_sign.wield_image = "(default_sign.png^[multiply:" .. color .. ")" - new_sign.tiles = { "(mcl_signs_sign.png^[multiply:" .. color .. ")" } - new_sign.inventory_image = "(default_sign.png^[multiply:" .. color .. ")" - - -- currently have to do this, because of how the base node placement works. - new_sign.on_place = function(itemstack, placer, pointed_thing) - local above = pointed_thing.above - local under = pointed_thing.under - - -- Use pointed node's on_rightclick function first, if present - local node_under = minetest.get_node(under) - if placer and not placer:get_player_control().sneak then - if minetest.registered_nodes[node_under.name] and minetest.registered_nodes[node_under.name].on_rightclick then - return minetest.registered_nodes[node_under.name].on_rightclick(under, node_under, placer, itemstack) or itemstack - end - end - - local dir = vector.subtract(under, above) - - -- Only build when it's legal - local abovenodedef = minetest.registered_nodes[minetest.get_node(above).name] - if not abovenodedef or abovenodedef.buildable_to == false then - return itemstack - end - - local wdir = minetest.dir_to_wallmounted(dir) - local fdir = minetest.dir_to_facedir(dir) - - local sign_info - local nodeitem = ItemStack(itemstack) - -- Ceiling - if wdir == 0 then - --how would you add sign to ceiling? - return itemstack - -- Floor - elseif wdir == 1 then - -- Standing sign - - -- Determine the sign rotation based on player's yaw - local yaw = pi * 2 - placer:get_look_horizontal() - - -- Select one of 16 possible rotations (0-15) - local rotation_level = mcl_signs:round((yaw / (pi * 2)) * 16) - - if rotation_level > 15 then - rotation_level = 0 - elseif rotation_level < 0 then - rotation_level = 15 - end - - -- The actual rotation is a combination of predefined mesh and facedir (see node definition) - if rotation_level % 4 == 0 then - nodeitem:set_name("mcl_signs:standing_sign" .. _name) - elseif rotation_level % 4 == 1 then - nodeitem:set_name("mcl_signs:standing_sign22_5" .. _name) - elseif rotation_level % 4 == 2 then - nodeitem:set_name("mcl_signs:standing_sign45" .. _name) - elseif rotation_level % 4 == 3 then - nodeitem:set_name("mcl_signs:standing_sign67_5" .. _name) - end - fdir = math.floor(rotation_level / 4) - - -- Place the node! - local _, success = minetest.item_place_node(nodeitem, placer, pointed_thing, fdir) - if not success then - return itemstack - end - if not minetest.is_creative_enabled(placer:get_player_name()) then - itemstack:take_item() - end - sign_info = mcl_signs.signtext_info_standing[rotation_level + 1] - -- Side - else - -- Wall sign - local _, success = minetest.item_place_node(itemstack, placer, pointed_thing, wdir) - if not success then - return itemstack - end - sign_info = mcl_signs.signtext_info_wall[fdir + 1] - end - - -- Determine spawn position of entity - local place_pos - if minetest.registered_nodes[node_under.name].buildable_to then - place_pos = under - else - place_pos = above - end - - if DEBUG then - minetest.log("action", "[mcl_signs] Register_Sign::Placed position:" .. dump(place_pos) .. "\nSign_info: " .. dump(sign_info)) - end - - local text_entity = minetest.add_entity({ - x = place_pos.x + sign_info.delta.x, - y = place_pos.y + sign_info.delta.y, - z = place_pos.z + sign_info.delta.z }, "mcl_signs:text") - text_entity:set_yaw(sign_info.yaw) - text_entity:get_luaentity()._signnodename = nodeitem:get_name() - - minetest.sound_play({ name = "default_place_node_hard", gain = 1.0 }, { pos = place_pos }, true) - - mcl_signs:show_formspec(placer, place_pos) - return itemstack - end - - minetest.override_item("mcl_signs:wall_sign" .. _name, new_sign) - update_sign_registry("wall", "mcl_signs:wall_sign" .. _name) - - -- debug step - if DEBUG then - minetest.log("action", "[mcl_signs] Registered: mcl_signs:wall_sign" .. _name .. color .. "\n" .. dump(new_sign)) - minetest.log("action", "[mcl_signs] mcl_signs:wall_sign_standard\n" .. dump(mcl_signs.wall_standard)) - end - - -- standing sign base. - local new_sign_standing = {} - new_sign_standing = table.copy(mcl_signs.standing_standard) - new_sign_standing.drop = "mcl_signs:wall_sign" .. _name - new_sign_standing.wield_image = "(default_sign.png^[multiply:" .. color .. ")" - new_sign_standing.tiles = { "(mcl_signs_sign.png^[multiply:" .. color .. ")" } - new_sign_standing.inventory_image = "(default_sign.png^[multiply:" .. color .. ")" - new_sign_standing.on_rotate = function(pos, node, user, mode) - if mode == screwdriver.ROTATE_FACE then - node.name = "mcl_signs:standing_sign22_5" .. _name - minetest.swap_node(pos, node) - elseif mode == screwdriver.ROTATE_AXIS then - return false - end - mcl_signs:update_sign(pos, nil, nil, true) - return true - end, - minetest.override_item("mcl_signs:standing_sign" .. _name, new_sign_standing) - update_sign_registry("standing", "mcl_signs:standing_sign" .. _name) - -- debug step - if DEBUG then - minetest.log("action", "[mcl_signs] Registered: mcl_signs:standing_sign" .. _name .. color .. "\n" .. dump(new_sign_standing)) - end - - -- 22.5° - local ssign22_5d = table.copy(new_sign_standing) - ssign22_5d.mesh = "mcl_signs_sign22.5.obj" - ssign22_5d.on_rotate = function(pos, node, user, mode) - if mode == screwdriver.ROTATE_FACE then - node.name = "mcl_signs:standing_sign45" .. _name - minetest.swap_node(pos, node) - elseif mode == screwdriver.ROTATE_AXIS then - return false - end - mcl_signs:update_sign(pos, nil, nil, true) - return true - end - minetest.override_item("mcl_signs:standing_sign22_5" .. _name, ssign22_5d) - update_sign_registry("standing", "mcl_signs:standing_sign22_5" .. _name) - - -- 45° - local ssign45d = table.copy(new_sign_standing) - ssign45d.mesh = "mcl_signs_sign45.obj" - ssign45d.on_rotate = function(pos, node, user, mode) - if mode == screwdriver.ROTATE_FACE then - node.name = "mcl_signs:standing_sign67_5" .. _name - minetest.swap_node(pos, node) - elseif mode == screwdriver.ROTATE_AXIS then - return false - end - mcl_signs:update_sign(pos, nil, nil, true) - return true - end - minetest.override_item("mcl_signs:standing_sign45" .. _name, ssign45d) - update_sign_registry("standing", "mcl_signs:standing_sign45" .. _name) - - -- 67.5° - local ssign67_5d = table.copy(new_sign_standing) - ssign67_5d.mesh = "mcl_signs_sign67.5.obj" - ssign67_5d.on_rotate = function(pos, node, user, mode) - if mode == screwdriver.ROTATE_FACE then - node.name = "mcl_signs:standing_sign" .. _name - node.param2 = (node.param2 + 1) % 4 - minetest.swap_node(pos, node) - elseif mode == screwdriver.ROTATE_AXIS then - return false - end - mcl_signs:update_sign(pos, nil, nil, true) - return true - end - minetest.override_item("mcl_signs:standing_sign67_5" .. _name, ssign67_5d) - update_sign_registry("standing", "mcl_signs:standing_sign67_5" .. _name) - - -- register Doc entry - if minetest.get_modpath("doc") then - doc.add_entry_alias("nodes", "mcl_signs:wall_sign", "nodes", "mcl_signs:wall_sign" .. _name) - doc.add_entry_alias("nodes", "mcl_signs:wall_sign", "nodes", "mcl_signs:standing_sign" .. _name) - doc.add_entry_alias("nodes", "mcl_signs:wall_sign", "nodes", "mcl_signs:standing_sign22_5" .. _name) - doc.add_entry_alias("nodes", "mcl_signs:wall_sign", "nodes", "mcl_signs:standing_sign45" .. _name) - doc.add_entry_alias("nodes", "mcl_signs:wall_sign", "nodes", "mcl_signs:standing_sign67_5" .. _name) - end - - --register standing sign's rotation_levels - table.insert(mcl_signs.standing_rotation_levels, { "mcl_signs:standing_sign22_5" .. _name, 1 }) - table.insert(mcl_signs.standing_rotation_levels, { "mcl_signs:standing_sign45" .. _name, 2 }) - table.insert(mcl_signs.standing_rotation_levels, { "mcl_signs:standing_sign67_5" .. _name, 3 }) -end - ---- The same as reregister_sign, except caller defines the textures. Note, there is a greyscale version of the sign, ---- called "default_sign_greyscale.png" and "mcl_signs_sign_greyscale.png" for optional use in the textures directory. ---- ---- modname: optional (pass "" or "false" to ignore), for use with other mods to ---- allow the creation of a sign from the mod's wood (if installed). ---- ---- _name: the sign's name suffix, such as "_dark" or "_red", etc., appended to "wall_sign" or "standing_sign" ---- ---- tiles: the texture file to use for the sign. ---- ---- color: color the texture file to use with this color. Use white (#FFFFFF) to negate the color, ---- and just use the texture as is ---- ---- inventory_image: the texture file to use for the sign's display in inventory. ---- ---- wield_image: the texture file to use for the sign's weilded (in hand) object. ---- ---- inventory_image: the image used for in-inventory and in hand. ---- ---- ttsign: the tool tip of the sign that gets translated. Shown when the mouse hovers the inventory sign. ---- For example: the basic, default oak (wood) sign is just "Sign"; and a spruce sign would be "Spruce Sign" -function mcl_signs.reregister_sign_custom (modname, _name, tiles, color, inventory_image, wield_image, ttsign) - local mod_name_pass = false - if modname ~= "" and modname ~= "false" then - if minetest.get_modpath(modname) then - mod_name_pass = true - end - if mod_name_pass == false then - return - end - end - local new_sign = {} - - new_sign = table.copy(mcl_signs.wall_standard) - - new_sign.wield_image = "(" .. wield_image .. "^[multiply:" .. color .. ")" - new_sign.tiles = { "(" .. tiles .. "^[multiply:" .. color .. ")" } - new_sign.inventory_image = "(" .. inventory_image .. "^[multiply:" .. color .. ")" - new_sign.description = S(ttsign) - -- currently have to do this, because of how the base node placement works. - new_sign.on_place = function(itemstack, placer, pointed_thing) - local above = pointed_thing.above - local under = pointed_thing.under - - -- Use pointed node's on_rightclick function first, if present - local node_under = minetest.get_node(under) - if placer and not placer:get_player_control().sneak then - if minetest.registered_nodes[node_under.name] and minetest.registered_nodes[node_under.name].on_rightclick then - return minetest.registered_nodes[node_under.name].on_rightclick(under, node_under, placer, itemstack) or itemstack - end - end - - local dir = vector.subtract(under, above) - - -- Only build when it's legal - local abovenodedef = minetest.registered_nodes[minetest.get_node(above).name] - if not abovenodedef or abovenodedef.buildable_to == false then - return itemstack - end - - local wdir = minetest.dir_to_wallmounted(dir) - local fdir = minetest.dir_to_facedir(dir) - - local sign_info - local nodeitem = ItemStack(itemstack) - -- Ceiling - if wdir == 0 then - --how would you add sign to ceiling? - return itemstack - -- Floor - elseif wdir == 1 then - -- Standing sign - - -- Determine the sign rotation based on player's yaw - local yaw = pi * 2 - placer:get_look_horizontal() - - -- Select one of 16 possible rotations (0-15) - local rotation_level = mcl_signs:round((yaw / (pi * 2)) * 16) - - if rotation_level > 15 then - rotation_level = 0 - elseif rotation_level < 0 then - rotation_level = 15 - end - - -- The actual rotation is a combination of predefined mesh and facedir (see node definition) - if rotation_level % 4 == 0 then - nodeitem:set_name("mcl_signs:standing_sign" .. _name) - elseif rotation_level % 4 == 1 then - nodeitem:set_name("mcl_signs:standing_sign22_5" .. _name) - elseif rotation_level % 4 == 2 then - nodeitem:set_name("mcl_signs:standing_sign45" .. _name) - elseif rotation_level % 4 == 3 then - nodeitem:set_name("mcl_signs:standing_sign67_5" .. _name) - end - fdir = math.floor(rotation_level / 4) - - -- Place the node! - local _, success = minetest.item_place_node(nodeitem, placer, pointed_thing, fdir) - if not success then - return itemstack - end - if not minetest.is_creative_enabled(placer:get_player_name()) then - itemstack:take_item() - end - sign_info = mcl_signs.signtext_info_standing[rotation_level + 1] - -- Side - else - -- Wall sign - local _, success = minetest.item_place_node(itemstack, placer, pointed_thing, wdir) - if not success then - return itemstack - end - sign_info = mcl_signs.signtext_info_wall[fdir + 1] - end - - -- Determine spawn position of entity - local place_pos - if minetest.registered_nodes[node_under.name].buildable_to then - place_pos = under - else - place_pos = above - end - - local text_entity = minetest.add_entity({ - x = place_pos.x + sign_info.delta.x, - y = place_pos.y + sign_info.delta.y, - z = place_pos.z + sign_info.delta.z }, "mcl_signs:text") - text_entity:set_yaw(sign_info.yaw) - text_entity:get_luaentity()._signnodename = nodeitem:get_name() - - minetest.sound_play({ name = "default_place_node_hard", gain = 1.0 }, { pos = place_pos }, true) - - mcl_signs:show_formspec(placer, place_pos) - return itemstack - end - minetest.override_item("mcl_signs:wall_sign" .. _name, new_sign) - update_sign_registry("wall", "mcl_signs:wall_sign" .. _name) - - -- standing sign base. - local new_sign_standing = {} - new_sign_standing = table.copy(mcl_signs.standing_standard) - new_sign_standing.drop = "mcl_signs:wall_sign" .. _name - new_sign_standing.wield_image = "(" .. wield_image .. "^[multiply:" .. color .. ")" - new_sign_standing.tiles = { "(" .. tiles .. "^[multiply:" .. color .. ")" } - new_sign_standing.inventory_image = "(" .. inventory_image .. "^[multiply:" .. color .. ")" - new_sign_standing.on_rotate = function(pos, node, user, mode) - if mode == screwdriver.ROTATE_FACE then - node.name = "mcl_signs:standing_sign22_5" .. _name - minetest.swap_node(pos, node) - elseif mode == screwdriver.ROTATE_AXIS then - return false - end - mcl_signs:update_sign(pos, nil, nil, true) - return true - end, - minetest.override_item("mcl_signs:standing_sign" .. _name, new_sign_standing) - update_sign_registry("standing", "mcl_signs:standing_sign" .. _name) - - -- 22.5° - local ssign22_5d = table.copy(new_sign_standing) - ssign22_5d.mesh = "mcl_signs_sign22.5.obj" - ssign22_5d.on_rotate = function(pos, node, user, mode) - if mode == screwdriver.ROTATE_FACE then - node.name = "mcl_signs:standing_sign45" .. _name - minetest.swap_node(pos, node) - elseif mode == screwdriver.ROTATE_AXIS then - return false - end - mcl_signs:update_sign(pos, nil, nil, true) - return true - end - minetest.override_item("mcl_signs:standing_sign22_5" .. _name, ssign22_5d) - update_sign_registry("standing", "mcl_signs:standing_sign22_5" .. _name) - - -- 45° - local ssign45d = table.copy(new_sign_standing) - ssign45d.mesh = "mcl_signs_sign45.obj" - ssign45d.on_rotate = function(pos, node, user, mode) - if mode == screwdriver.ROTATE_FACE then - node.name = "mcl_signs:standing_sign67_5" .. _name - minetest.swap_node(pos, node) - elseif mode == screwdriver.ROTATE_AXIS then - return false - end - mcl_signs:update_sign(pos, nil, nil, true) - return true - end - minetest.override_item("mcl_signs:standing_sign45" .. _name, ssign45d) - update_sign_registry("standing", "mcl_signs:standing_sign45" .. _name) - - -- 67.5° - local ssign67_5d = table.copy(new_sign_standing) - ssign67_5d.mesh = "mcl_signs_sign67.5.obj" - ssign67_5d.on_rotate = function(pos, node, user, mode) - if mode == screwdriver.ROTATE_FACE then - node.name = "mcl_signs:standing_sign" .. _name - node.param2 = (node.param2 + 1) % 4 - minetest.swap_node(pos, node) - elseif mode == screwdriver.ROTATE_AXIS then - return false - end - mcl_signs:update_sign(pos, nil, nil, true) - return true - end - minetest.override_item("mcl_signs:standing_sign67_5" .. _name, ssign67_5d) - update_sign_registry("standing", "mcl_signs:standing_sign67_5" .. _name) - - -- register Doc entry - if minetest.get_modpath("doc") then - doc.add_entry_alias("nodes", "mcl_signs:wall_sign", "nodes", "mcl_signs:wall_sign" .. _name) - doc.add_entry_alias("nodes", "mcl_signs:wall_sign", "nodes", "mcl_signs:standing_sign" .. _name) - doc.add_entry_alias("nodes", "mcl_signs:wall_sign", "nodes", "mcl_signs:standing_sign22_5" .. _name) - doc.add_entry_alias("nodes", "mcl_signs:wall_sign", "nodes", "mcl_signs:standing_sign45" .. _name) - doc.add_entry_alias("nodes", "mcl_signs:wall_sign", "nodes", "mcl_signs:standing_sign67_5" .. _name) - end - - --register standing sign's rotation_levels - table.insert(mcl_signs.standing_rotation_levels, { "mcl_signs:standing_sign22_5" .. _name, 1 }) - table.insert(mcl_signs.standing_rotation_levels, { "mcl_signs:standing_sign45" .. _name, 2 }) - table.insert(mcl_signs.standing_rotation_levels, { "mcl_signs:standing_sign67_5" .. _name, 3 }) - -end - ---- Usage: Call this with the mod's name, the wood's item string (for the planks), and with the sign's suffix. ---- Registers the crafting recipe for that sign. for every registered sign, call this function to register the ---- standard recipe for the sign. Otherwise, you have to do your own register craft call. ---- ---- modname: optional (pass "" or "false" to ignore), for use with other mods to ---- allow the creation of a sign from the mod's wood (if installed). Example: "mcl_core". ---- ---- wood_item_string: example: "mcl_core:wood" or "mcl_core:sprucewood" ---- ---- _name: the sign's name suffix, such as "_dark" or "_red", etc., appended to "wall_sign" or "standing_sign" -function mcl_signs.register_sign_craft(modname, wood_item_string, _name) - local mod_name_pass = false - if modname ~= "" and modname ~= "false" then - if minetest.get_modpath(modname) then - mod_name_pass = true - end - if mod_name_pass == false then - return - end - end - - minetest.register_craft({ - type = "fuel", - recipe = "mcl_signs:wall_sign" .. _name, - burntime = 10, - }) - - -- debug step - if DEBUG then - minetest.log("action", "[mcl_signs] Register Sign Crafts: \n" .. modname .. "\n" .. wood_item_string .. "\n" .. _name) - end - - -- register crafts (actual recipe) - if minetest.get_modpath(modname) then - - local itemstring = "mcl_signs:wall_sign" - - minetest.register_craft({ - output = itemstring .. _name .. " 3", - recipe = { - { wood_item_string, wood_item_string, wood_item_string }, - { wood_item_string, wood_item_string, wood_item_string }, - { "", "mcl_core:stick", "" }, - }, - }) - end -end - -function mcl_signs.register_hanging_sign_craft(modname, wood_item_string, _name) - local mod_name_pass = false - if modname ~= "" and modname ~= "false" then - if minetest.get_modpath(modname) then - mod_name_pass = true - end - if mod_name_pass == false then - return - end - end - - minetest.register_craft({ - type = "fuel", - recipe = ":mcl_signs:wall_sign" .. _name, - burntime = 10, - }) - - -- debug step - if DEBUG then - minetest.log("action", "[mcl_signs] Register Sign Crafts: \n" .. modname .. "\n" .. wood_item_string .. "\n" .. _name) - end - - -- register crafts (actual recipe) - if minetest.get_modpath(modname) then - - local itemstring = ":mcl_signs:hanging_sign" - local quantity = "6" - - local bamboo = string.find(wood_item_string, "bamboo") - if bamboo then - quantity = "2" - end - minetest.register_craft({ - output = itemstring .. _name .. " " .. quantity, - recipe = { - { "mcl_lanterns:chain", "", "mcl_lanterns:chain" }, - { wood_item_string, wood_item_string, wood_item_string }, - { wood_item_string, wood_item_string, wood_item_string }, - }, - }) - end -end - --- Helper functions -local function string_to_array(str) - local string_table = {} - for i = 1, string.len(str) do - table.insert(string_table, string.sub(str, i, i)) - end - return string_table -end - -local function string_to_line_array(str) - local linechar_table = {} - local current = 1 - local linechar = 1 - linechar_table[1] = "" - for _, char in ipairs(string_to_array(str)) do - -- New line - if char == "\n" then - current = current + 1 - linechar_table[current] = "" - linechar = 1 - else - linechar_table[current] = linechar_table[current] .. char - linechar = linechar + 1 - end - end - return linechar_table -end - -local function get_rotation_level(facedir, nodename) - local nnames = mcl_signs.standing_rotation_levels -- functional copy... was easier this way. #LazyAF :P - - local rl - local offset = 0 - for x = 1, #nnames do - if nnames[x][1] == nodename then - offset = nnames[x][2] - break - end - end - rl = facedir * 4 + offset - if DEBUG then - minetest.log("action", "[mcl_signs] GetRotationLevel: NodeName: " .. nodename .. " RL value: " .. rl) - end - return rl -end - -function mcl_signs:round(num, idp) - local mult = 10 ^ (idp or 0) - return math.floor(num * mult + 0.5) / mult -end - -function mcl_signs:get_color_for_sign(item_name) - - for d = 1, #Dyes_table do - if Dyes_table[d][1] == item_name then - return Dyes_table[d][2] - end - end - return "false" -end - -function mcl_signs:color_sign (pos, text_color) - - local success = mcl_signs:update_sign(pos, nil, nil, true, text_color) - - -- debug step - local meta = minetest.get_meta(pos) - if not meta then - minetest.log("error", "[mcl_signs] Sign Color Fail - Metadata.") - - return false - end - if DEBUG then - minetest.log("verbose", "[mcl_signs] Post-Sign Color: " .. meta:get_string("mcl_signs:text_color") .. " " .. meta:get_string("mcl_signs:glowing_sign") .. ".\n" .. dump(pos)) - end - - return success - -end - -function mcl_signs:glow_sign (pos, remove_glow) - local success = true - -- Get Meta Data for the sign. - local meta = minetest.get_meta(pos) - - if not meta then - return false - end - local text = meta:get_string("text") - if text == nil then - text = "" - end - - -- we can't make the text glow if there isn't any text - if text == "" then - return false - end - - if remove_glow == nil then - remove_glow = false - end - - -- set up text glow - local objects = minetest.get_objects_inside_radius(pos, 0.5) - local text_entity - for _, v in ipairs(objects) do - local ent = v:get_luaentity() - if ent and ent.name == "mcl_signs:text" then - text_entity = v - break - end - end - if remove_glow == true then - text_entity:set_properties({ - glow = nil, - }) - meta:set_string("mcl_signs:glowing_sign", "false") - else - text_entity:set_properties({ - glow = sign_glow, - }) - meta:set_string("mcl_signs:glowing_sign", "true") - end - if not text_entity then - return false - end - text_entity:get_luaentity()._glowing_sign = meta:get_string("mcl_signs:glowing_sign") - - -- debug step - if DEBUG then - minetest.log("verbose", "[mcl_signs] Post-Sign Glow: " .. meta:get_string("mcl_signs:text_color") .. " " .. meta:get_string("mcl_signs:glowing_sign") .. ".\n" .. dump(pos)) - end - return success -end - -function mcl_signs:create_lettering(text, signnodename, sign_color) - if sign_color == nil then - sign_color = mcl_colors.BLACK - end - local texture = mcl_signs:generate_texture(mcl_signs:create_lines(text), signnodename, sign_color) - - -- debug step - if DEBUG then - minetest.log("action", "[mcl_signs] Creating sign text; text:" .. text) - end - - return texture -end - -function mcl_signs:create_lines(text) - local line_num = 1 - local text_table = {} - for _, line in ipairs(string_to_line_array(text)) do - if line_num > NUMBER_OF_LINES then - break - end - table.insert(text_table, line) - line_num = line_num + 1 - end - return text_table -end - -function mcl_signs:generate_line(s, ypos) - local i = 1 - local parsed = {} - local width = 0 - local chars = 0 - local printed_char_width = CHAR_WIDTH + 1 - while chars < LINE_LENGTH and i <= #s do - local file - -- Get and render character - if charmap[s:sub(i, i)] then - file = charmap[s:sub(i, i)] - i = i + 1 - elseif i < #s and charmap[s:sub(i, i + 1)] then - file = charmap[s:sub(i, i + 1)] - i = i + 2 - else - -- No character image found. - -- Use replacement character: - file = "_rc" - i = i + 1 - if DEBUG then - minetest.log("verbose", "[mcl_signs] Unknown symbol in '" .. s .. "' at " .. i) - end - end - if file then - width = width + printed_char_width - table.insert(parsed, file) - chars = chars + 1 - end - end - width = width - 1 - - local texture = "" - local xpos = math.floor((SIGN_WIDTH - width) / 2) - - for j = 1, #parsed do - texture = texture .. ":" .. xpos .. "," .. ypos .. "=" .. parsed[j] .. ".png" - xpos = xpos + printed_char_width - end - return texture -end - -function mcl_signs:generate_texture(lines, signnodename, letter_color) - local texture = "[combine:" .. SIGN_WIDTH .. "x" .. SIGN_WIDTH - local ypos = 0 - - -- Handle all of the dynamically created signs. - for x = 1, #mcl_signs.registered_signs.wall_signs do - if signnodename == mcl_signs.registered_signs.wall_signs[x] then - ypos = 30 - break - end - end - for x = 1, #mcl_signs.registered_signs.standing_signs do - if signnodename == mcl_signs.registered_signs.standing_signs[x] then - ypos = 0 - break - end - end - -- for future inclusion, when the hanging sings are made. - --[[ - for x = 1, #mcl_signs.registered_signs.hanging_signs do - if signnodename == mcl_signs.registered_signs.hanging_signs[x] then - ypos = 30 - break - end - end - ]] - - -- kept in for now, compatibility with existing hard coded signs. TODO: Remove after done with api. - if signnodename == "mcl_signs:wall_sign" or signnodename == "mcl_signs:wall_sign_dark" then - ypos = 30 - end - - -- debug step - if DEBUG then - minetest.log("action", "[mcl_signs] Generate_Texture::Debug_Data:\nSignNodeName: " .. dump(signnodename) .. "\nYPOS: " .. ypos) - end - - for i = 1, #lines do - texture = texture .. mcl_signs:generate_line(lines[i], ypos) - ypos = ypos + LINE_HEIGHT - end - - texture = "(" .. texture .. "^[multiply:" .. letter_color .. ")" - return texture -end - -function mcl_signs:get_wall_signtext_info(param2, nodename) - local dir = minetest.wallmounted_to_dir(param2) - if dir.x > 0 then - return 2 - elseif dir.z > 0 then - return 1 - elseif dir.x < 0 then - return 4 - else - return 3 - end -end - -function mcl_signs:destruct_sign(pos) - local objects = minetest.get_objects_inside_radius(pos, 0.5) - for _, v in ipairs(objects) do - local ent = v:get_luaentity() - if ent and ent.name == "mcl_signs:text" then - v:remove() - end - end - local players = minetest.get_connected_players() - for p = 1, #players do - if vector.distance(players[p]:get_pos(), pos) <= 30 then - minetest.close_formspec(players[p]:get_player_name(), "mcl_signs:set_text_" .. pos.x .. "_" .. pos.y .. "_" .. pos.z) - end - end -end - -function mcl_signs:update_sign(pos, fields, sender, force_remove, text_color) - -- Get Meta Data for the sign. - local meta = minetest.get_meta(pos) - - if not meta then - return false - end - local text = meta:get_string("text", "") - if fields and (text == "" and fields.text) then - meta:set_string("text", fields.text) - text = fields.text - end - if text == nil then - text = "" - end - - -- find text color. - local sign_color - - if meta:get_string("mcl_signs:text_color") == "" then - -- if no sign text color has been assigned, make it black. - sign_color = mcl_colors.BLACK - meta:set_string("mcl_signs:text_color", sign_color) - else - sign_color = meta:get_string("mcl_signs:text_color") - end - - if text_color == nil or text == "" then - text_color = "false" - end - - if text_color == "false" then - text_color = sign_color --if a new color hasn't been chosen, then keep the existing color. - end - - -- find the sign's glow value - local has_glow = false - - if meta:get_string("mcl_signs:glowing_sign") == "" or meta:get_string("mcl_signs:glowing_sign") == "false" then - has_glow = false - meta:set_string("mcl_signs:glowing_sign", "false") - else - has_glow = true - end - - -- debug step - if DEBUG then - minetest.log("action", "[mcl_signs] Update_Signs: Pre-Sign Update: " .. sign_color .. " " .. meta:get_string("mcl_signs:glowing_sign") .. ".\n" .. dump(pos)) - end - - local sign_info - local npos = minetest.get_node(pos) - local npos_name = npos.name - - -- Handle all of the dynamically created signs. - for x = 1, #mcl_signs.registered_signs.wall_signs do - if npos_name == mcl_signs.registered_signs.wall_signs[x] then - sign_info = mcl_signs.signtext_info_wall[mcl_signs:get_wall_signtext_info(npos.param2)] - break - end - end - for x = 1, #mcl_signs.registered_signs.standing_signs do - if npos_name == mcl_signs.registered_signs.standing_signs[x] then - sign_info = mcl_signs.signtext_info_standing[get_rotation_level(npos.param2, npos_name) + 1] - break - end - end - -- for future inclusion, when the hanging sings are made. - --[[ - for x = 1, #mcl_signs.registered_signs.hanging_signs do - if nn == mcl_signs.registered_signs.hanging_signs[x] then - sign_info = mcl_signs.signtext_info_wall[mcl_signs:get_wall_signtext_info(n.param2)] - break - end - end - ]] - - -- the following if..elseif..end block is here for compatibility with the old code. TODO: remove this block after the new api is complete. - if npos_name == "mcl_signs:standing_sign_dark" or npos_name == "mcl_signs:standing_sign22_5_dark" or npos_name == "mcl_signs:standing_sign45_dark" or npos_name == "mcl_signs:standing_sign67_5_dark" then - sign_info = mcl_signs.signtext_info_standing[get_rotation_level(npos.param2, npos_name) + 1] - elseif npos_name == "mcl_signs:wall_sign_dark" then - sign_info = mcl_signs.signtext_info_wall[mcl_signs:get_wall_signtext_info(npos.param2)] - end - if sign_info == nil then - minetest.log("error", "[mcl_signs] Update_Signs: Missing sign_info!") - return false - end - - local text_entity - text_entity = mcl_signs:get_text_entity(pos,force_remove) - - if not text_entity then - if DEBUG then - minetest.log("action", "[mcl_signs] Update_Sign: Text_Entity - does not exist, creating it now.") - end - text_entity = minetest.add_entity({ - x = pos.x + sign_info.delta.x, - y = pos.y + sign_info.delta.y, - z = pos.z + sign_info.delta.z }, "mcl_signs:text") - - if DEBUG then - minetest.log("action", "[mcl_signs] Update_Sign: Placed position:" .. dump(pos) .. "\nSign_info: " .. dump(sign_info)) - end - end - text_entity:get_luaentity()._signnodename = npos_name - - -- set up special case: Dark Oak Sign. Dark Oak signs are soooo dark, they start off with white lettering. - if npos_name == "mcl_signs:wall_sign_darkwood" or - npos_name == "mcl_signs:standing_sign67_5_darkwood" or - npos_name == "mcl_signs:standing_sign45_darkwood" or - npos_name == "mcl_signs:standing_sign22_5_darkwood" or - npos_name == "mcl_signs:standing_sign_darkwood" - then - if text_color == "#000000" then - text_color = "#ffffff" - end - end - - -- Set the actual properties for the sign - - text_entity:set_properties({ - textures = { mcl_signs:create_lettering(text, npos_name, text_color) }, - }) - - if has_glow then - text_entity:set_properties({ - glow = sign_glow, - }) - end - - text_entity:set_yaw(sign_info.yaw) - if DEBUG then - minetest.log("verbose", "[mcl_signs] Update_Sign: After texture recreation.") - minetest.log("action", "[mcl_signs] Update_Sign: " .. npos_name .. "\nPlaced position:" .. dump(pos) .. "\nSign_info: " .. dump(sign_info)) - end - - -- save sign metadata. - meta:set_string("mcl_signs:text_color", text_color) - - -- Moved timer stuff to here, to make sure that it's called and only has one set of code. - local timer = minetest.get_node_timer(pos) - if text_entity and text ~= "" then - -- Do timer related stuff - but only if there is text to display. - -- Also, prevent excessive use with punching. (see node def.) - if timer:is_started() == false then - timer:start(TIMER_INTERVAL) - else - timer:stop() - timer:start(TIMER_INTERVAL) - end - else - if timer:is_started() == true then - timer:stop() - end - end - - -- debug step - if DEBUG then - minetest.log("action", "[mcl_signs] Update_Sign: Post-Sign Update: " .. meta:get_string("mcl_signs:text_color") .. " " .. meta:get_string("mcl_signs:glowing_sign") .. ".\n" .. dump(pos)) - end - - return true - -end - -function mcl_signs:show_formspec(player, pos) - minetest.show_formspec( - player:get_player_name(), - "mcl_signs:set_text_" .. pos.x .. "_" .. pos.y .. "_" .. pos.z, - "size[6,3]textarea[0.25,0.25;6,1.5;text;" .. F(S("Enter sign text:")) .. ";]label[0,1.5;" .. F(S("Maximum line length: 15")) .. "\n" .. F(S("Maximum lines: 4")) .. "]button_exit[0,2.5;6,1;submit;" .. F(S("Done")) .. "]" - ) -end - -function mcl_signs:get_text_entity (pos, force_remove) - local objects = minetest.get_objects_inside_radius(pos, 0.5) - local text_entity = false -- just to have a check for failure. - for _, v in ipairs(objects) do - local ent = v:get_luaentity() - if ent and ent.name == "mcl_signs:text" then - if force_remove ~= nil and force_remove == true then - v:remove() - else - text_entity = v - break - end - end - end - return text_entity -end \ No newline at end of file From 197e807684786ba282e2904bb4da3a73a241c0ec Mon Sep 17 00:00:00 2001 From: Michieal Date: Thu, 17 Nov 2022 23:34:41 +0000 Subject: [PATCH 3/4] Fix the crafting recipes for the signs. Placed in the proper place. Ugh. --- mods/ITEMS/mcl_signs/signs_api.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mods/ITEMS/mcl_signs/signs_api.lua b/mods/ITEMS/mcl_signs/signs_api.lua index 666b51020..1f7369ba3 100644 --- a/mods/ITEMS/mcl_signs/signs_api.lua +++ b/mods/ITEMS/mcl_signs/signs_api.lua @@ -1465,7 +1465,7 @@ function mcl_signs.register_sign_craft(modname, wood_item_string, _name) minetest.register_craft({ type = "fuel", - recipe = ":mcl_signs:wall_sign" .. _name, + recipe = "mcl_signs:wall_sign" .. _name, burntime = 10, }) @@ -1477,7 +1477,7 @@ function mcl_signs.register_sign_craft(modname, wood_item_string, _name) -- register crafts (actual recipe) if minetest.get_modpath(modname) then - local itemstring = ":mcl_signs:wall_sign" + local itemstring = "mcl_signs:wall_sign" minetest.register_craft({ output = itemstring .. _name .. " 3", From 7d63b07e099aac1ca56b0e586b442e94fd1469fb Mon Sep 17 00:00:00 2001 From: cora Date: Fri, 18 Nov 2022 00:45:16 +0100 Subject: [PATCH 4/4] Fix mangrove sign registrations --- mods/ITEMS/mcl_signs/init.lua | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/mods/ITEMS/mcl_signs/init.lua b/mods/ITEMS/mcl_signs/init.lua index 403b53ef8..e724def68 100644 --- a/mods/ITEMS/mcl_signs/init.lua +++ b/mods/ITEMS/mcl_signs/init.lua @@ -125,9 +125,11 @@ mcl_signs.register_sign_craft("mcl_core", "mcl_core:junglewood", "_junglewood") mcl_signs.register_sign("mcl_core", "#ea7479", "_acaciawood", "Acacia Sign") mcl_signs.register_sign_craft("mcl_core", "mcl_core:acaciawood", "_acaciawood") --- mangrove_wood Sign "#c7545c" -mcl_signs.register_sign("mcl_core", "#b8693d", "_mangrove_wood", "Mangrove Sign") -mcl_signs.register_sign_craft("mcl_core", "mcl_core:mangrove_wood", "_mangrove_wood") +if minetest.get_modpath("mcl_mangrove") then + -- mangrove_wood Sign "#c7545c" + mcl_signs.register_sign("mcl_mangrove", "#b8693d", "_mangrove_wood", "Mangrove Sign") + mcl_signs.register_sign_craft("mcl_mangrove", "mcl_mangrove:mangrove_wood", "_mangrove_wood") +end -- add in the nether wood signs if minetest.get_modpath("mcl_crimson") then