2022-10-19 22:55:07 +00:00
---
2022-10-23 07:20:34 +00:00
--- Generated by EmmyLua.
2022-10-19 22:55:07 +00:00
--- Created by Michieal (FaerRaven).
--- DateTime: 10/14/22 4:05 PM
---
2022-10-24 00:47:56 +00:00
local DEBUG = minetest.settings : get_bool ( " mcl_logging_mcl_signs " , false ) -- special debug setting.
2022-10-19 22:55:07 +00:00
if DEBUG then
2022-11-07 17:16:07 +00:00
minetest.log ( " action " , " [mcl_signs] Signs API Loading " )
2022-10-19 22:55:07 +00:00
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
2022-11-08 00:36:25 +00:00
local TIMER_INTERVAL = 40.0
2022-10-22 02:50:39 +00:00
-- -----------------------
2022-11-07 17:16:07 +00:00
-- CACHE LOCAL COPIES
local table = table
local string = string
2022-10-22 02:50:39 +00:00
-- CACHE NODE_SOUNDS
local node_sounds
if minetest.get_modpath ( " mcl_sounds " ) then
2022-11-07 17:16:07 +00:00
node_sounds = mcl_sounds.node_sound_wood_defaults ( )
2022-10-22 02:50:39 +00:00
end
2022-10-19 22:55:07 +00:00
-- 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
2022-11-07 17:16:07 +00:00
minetest.log ( " error " , " [mcl_signs] : character map file not found " )
2022-10-19 22:55:07 +00:00
else
2022-11-07 17:16:07 +00:00
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
2022-10-19 22:55:07 +00:00
end
2022-10-22 02:50:39 +00:00
local pi = 3.1415926 -- enough accuracy, to build an engine for a car.
2022-11-03 05:29:46 +00:00
local math = math
2022-10-22 02:50:39 +00:00
-- locally cached copy of the official colors; this way, it updates as mcl_colors updates.
local mcl_colors_official = mcl_colors
if DEBUG then
2022-11-07 17:16:07 +00:00
minetest.log ( " verbose " , " [mcl_signs]Official MCL_Colors: \n " .. dump ( mcl_colors_official ) )
2022-10-22 02:50:39 +00:00
end
-- INITIALIZE THE GLOBAL API FOR SIGNS.
mcl_signs = { }
2022-10-19 22:55:07 +00:00
-- GLOBALS
2023-10-16 20:06:52 +00:00
mcl_signs.sign_groups = { handy = 1 , axey = 1 , deco_block = 1 , material_wood = 1 , attached_node = 1 , flammable = - 1 }
2022-10-19 22:55:07 +00:00
--- colors used for wools.
mcl_signs.mcl_wool_colors = {
2022-11-07 17:16:07 +00:00
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 " ,
2022-10-19 22:55:07 +00:00
}
2022-10-21 23:54:26 +00:00
mcl_signs.signtext_info_wall = { }
mcl_signs.signtext_info_standing = { } -- built in build_signs_info().
2022-10-22 02:50:39 +00:00
-- the rotational levels for all of the standing signs.
mcl_signs.standing_rotation_levels = { }
2022-10-21 23:54:26 +00:00
-- 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.
2022-10-22 02:50:39 +00:00
function mcl_signs . build_signs_info ( )
2022-11-07 17:16:07 +00:00
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
2022-10-21 23:54:26 +00:00
end
2024-04-14 06:50:19 +00:00
-- DEFINE SIGN BASE TYPES
local common_definition = {
_mcl_hardness = 1 ,
_mcl_blast_resistance = 1 ,
2022-11-07 17:16:07 +00:00
stack_max = 16 ,
sounds = node_sounds ,
2024-04-14 06:50:19 +00:00
groups = mcl_signs.sign_groups ,
use_texture_alpha = minetest.features . use_texture_alpha_string_modes and " opaque " or false ,
drawtype = " mesh " ,
paramtype = " light " ,
tiles = { " mcl_signs_sign.png " } ,
sunlight_propagates = true ,
walkable = false ,
is_ground_content = false ,
on_rightclick = function ( pos , node , clicker , itemstack , pointed_thing )
if DEBUG then
minetest.log ( " verbose " , " [mcl_signs] 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 ( )
local protected = mcl_util.check_position_protection ( pos , clicker )
if node and not protected then
if DEBUG then
minetest.log ( " verbose " , " [mcl_signs] 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
-- 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 )
-- "mcl_dye:black" is a special case: it makes the sign's lettering black AND removes glow.
if ( iname == " mcl_dye:black " ) then
success = mcl_signs : glow_sign ( pos , true )
if success and DEBUG then
minetest.log ( " verbose " , " [mcl_signs] Sign Glow removal Success. " )
end
end
if success then
if DEBUG then
minetest.log ( " verbose " , " [mcl_signs] Sign Color Success. " )
end
itemstack : take_item ( )
end
return
end
-- No modifier item in hand, open the sign for edition
local old_text = minetest.get_meta ( pos ) : get_string ( " text " )
mcl_signs : show_formspec ( clicker , pos , old_text )
end
end ,
on_destruct = function ( pos )
mcl_signs : destruct_sign ( pos )
end ,
2022-11-07 17:16:07 +00:00
2024-04-14 06:50:19 +00:00
-- Not Useless Code. this force updates the sign.
on_punch = function ( pos , node , puncher )
mcl_signs : update_sign ( pos )
end ,
}
-- wall signs' & hanging signs' base (definition)
mcl_signs.wall_standard = table.copy ( common_definition )
mcl_signs.wall_standard . description = S ( " Sign " )
mcl_signs.wall_standard . _tt_help = S ( " Can be written " )
mcl_signs.wall_standard . _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. " )
mcl_signs.wall_standard . _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. " )
mcl_signs.wall_standard . inventory_image = " mcl_signs_default_sign.png "
mcl_signs.wall_standard . wield_image = " mcl_signs_default_sign.png "
mcl_signs.wall_standard . node_placement_prediction = " "
mcl_signs.wall_standard . paramtype2 = " wallmounted "
mcl_signs.wall_standard . mesh = " mcl_signs_signonwallmount.obj "
mcl_signs.wall_standard . selection_box = { type = " wallmounted " , wall_side = { - 0.5 , - 7 / 28 , - 0.5 , - 23 / 56 , 7 / 28 , 0.5 } }
mcl_signs.wall_standard . on_timer = function ( pos )
2022-11-07 17:16:07 +00:00
-- fix for /ClearObjects
mcl_signs : update_sign ( pos )
2022-11-08 00:36:25 +00:00
-- 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.
2024-04-14 06:50:19 +00:00
end
mcl_signs.wall_standard . on_place = function ( itemstack , placer , pointed_thing )
2022-11-07 17:16:07 +00:00
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
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 ) .. " \n Sign_info: " .. dump ( sign_info ) )
end
minetest.sound_play ( { name = " default_place_node_hard " , gain = 1.0 } , { pos = place_pos } , true )
2024-04-14 06:50:19 +00:00
mcl_signs : show_formspec ( placer , place_pos , " " )
2022-11-07 17:16:07 +00:00
return itemstack
2024-04-14 06:50:19 +00:00
end
mcl_signs.wall_standard . on_rotate = function ( pos , node , user , mode )
2022-11-07 17:16:07 +00:00
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
2024-04-14 06:50:19 +00:00
end
2022-11-07 17:16:07 +00:00
2022-10-22 02:50:39 +00:00
-- standing sign base (definition)
2024-04-14 06:50:19 +00:00
mcl_signs.standing_standard = table.copy ( common_definition )
mcl_signs.standing_standard . paramtype2 = " facedir "
mcl_signs.standing_standard . mesh = " mcl_signs_sign.obj "
mcl_signs.standing_standard . selection_box = { type = " fixed " , fixed = { - 0.2 , - 0.5 , - 0.2 , 0.2 , 0.5 , 0.2 } }
mcl_signs.standing_standard . drop = " mcl_signs:wall_sign "
mcl_signs.standing_standard . on_timer = function ( pos )
2022-11-07 17:16:07 +00:00
-- fix for /ClearObjects
mcl_signs : update_sign ( pos )
minetest.get_node_timer ( pos ) : start ( 40.0 )
2024-04-14 06:50:19 +00:00
end
mcl_signs.standing_standard . on_rotate = function ( pos , node , user , mode )
2022-11-07 17:16:07 +00:00
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
2024-04-14 06:50:19 +00:00
end
2022-10-22 02:50:39 +00:00
2022-10-19 22:55:07 +00:00
-- HELPER FUNCTIONS' VARIABLES
local sign_glow = 6
local Dyes_table = {
2022-11-07 17:16:07 +00:00
{ " 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 } ,
2022-10-19 22:55:07 +00:00
}
2022-10-21 23:54:26 +00:00
local function update_sign_registry ( type , name )
2022-11-07 17:16:07 +00:00
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
2022-10-21 23:54:26 +00:00
end
2022-10-23 07:20:34 +00:00
function mcl_signs . make_lbm ( )
2022-11-07 17:16:07 +00:00
local registered_sign_nodenames = { }
2022-10-23 07:20:34 +00:00
2022-11-07 17:16:07 +00:00
for i = 0 , # mcl_signs.registered_signs . wall_signs do
table.insert ( registered_sign_nodenames , mcl_signs.registered_signs . wall_signs [ i ] )
end
2022-10-23 07:20:34 +00:00
2022-11-07 17:16:07 +00:00
for i = 0 , # mcl_signs.registered_signs . standing_signs do
table.insert ( registered_sign_nodenames , mcl_signs.registered_signs . standing_signs [ i ] )
end
2022-10-23 07:20:34 +00:00
2022-11-07 17:16:07 +00:00
for i = 0 , # mcl_signs.registered_signs . hanging_signs do
table.insert ( registered_sign_nodenames , mcl_signs.registered_signs . hanging_signs [ i ] )
end
2022-10-23 07:20:34 +00:00
2022-11-07 17:16:07 +00:00
-- 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 ,
} )
2022-10-23 07:20:34 +00:00
end
function mcl_signs . register_dye ( modname , item_name , color_code )
2022-11-07 17:16:07 +00:00
if minetest.get_modpath ( modname ) then
table.insert ( Dyes_table , { item_name , color_code } )
end
2022-10-23 07:20:34 +00:00
end
2022-10-21 23:54:26 +00:00
--- Register a new sign, tint the textures, and gives it an unique node name. Creates both wall and standing signs.
2022-10-19 22:55:07 +00:00
--- 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).
---
2022-10-21 23:54:26 +00:00
--- 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"
2022-10-19 22:55:07 +00:00
---
2022-10-21 23:54:26 +00:00
--- 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 )
2022-11-07 17:16:07 +00:00
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 )
2023-05-01 02:26:11 +00:00
new_sign.description = ttsign
2022-11-07 17:16:07 +00:00
2023-02-15 14:38:37 +00:00
new_sign.wield_image = " (mcl_signs_default_sign.png^[multiply: " .. color .. " ) "
2022-11-07 17:16:07 +00:00
new_sign.tiles = { " (mcl_signs_sign.png^[multiply: " .. color .. " ) " }
2023-02-15 14:38:37 +00:00
new_sign.inventory_image = " (mcl_signs_default_sign.png^[multiply: " .. color .. " ) "
2022-11-07 17:16:07 +00:00
-- 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 ) .. " \n Sign_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 )
2024-04-14 06:50:19 +00:00
mcl_signs : show_formspec ( placer , place_pos , " " )
2022-11-07 17:16:07 +00:00
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
2023-02-15 14:38:37 +00:00
new_sign_standing.wield_image = " (mcl_signs_default_sign.png^[multiply: " .. color .. " ) "
2022-11-07 17:16:07 +00:00
new_sign_standing.tiles = { " (mcl_signs_sign.png^[multiply: " .. color .. " ) " }
2023-02-15 14:38:37 +00:00
new_sign_standing.inventory_image = " (mcl_signs_default_sign.png^[multiply: " .. color .. " ) "
2022-11-07 17:16:07 +00:00
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 } )
2023-07-02 15:08:44 +00:00
-- register as unpushable
if minetest.get_modpath ( " mesecons_mvps " ) then
mesecon.register_mvps_stopper ( " mcl_signs:wall_sign " .. _name )
mesecon.register_mvps_stopper ( " mcl_signs:standing_sign " .. _name )
mesecon.register_mvps_stopper ( " mcl_signs:standing_sign22_5 " .. _name )
mesecon.register_mvps_stopper ( " mcl_signs:standing_sign45 " .. _name )
mesecon.register_mvps_stopper ( " mcl_signs:standing_sign67_5 " .. _name )
end
2022-10-19 22:55:07 +00:00
end
2022-10-21 23:54:26 +00:00
2022-10-22 02:50:39 +00:00
--- The same as register_sign, except caller defines the textures. Note, there is a greyscale version of the sign,
2023-02-15 14:38:37 +00:00
--- called "mcl_signs_default_sign_greyscale.png" and "mcl_signs_sign_greyscale.png" for optional use in the textures directory.
2022-10-22 02:50:39 +00:00
---
2022-10-19 22:55:07 +00:00
--- 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).
---
2022-10-21 23:54:26 +00:00
--- _name: the sign's name suffix, such as "_dark" or "_red", etc., appended to "wall_sign" or "standing_sign"
2022-10-19 22:55:07 +00:00
---
2022-10-21 23:54:26 +00:00
--- tiles: the texture file to use for the sign.
2022-10-19 22:55:07 +00:00
---
2022-10-22 02:50:39 +00:00
--- color: color the texture file to use with this color. Use white (#FFFFFF) to negate the color,
--- and just use the texture as is
---
2022-10-21 23:54:26 +00:00
--- 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.
2022-10-19 22:55:07 +00:00
---
--- inventory_image: the image used for in-inventory and in hand.
2022-10-21 23:54:26 +00:00
---
--- 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"
2022-10-22 02:50:39 +00:00
function mcl_signs . register_sign_custom ( modname , _name , tiles , color , inventory_image , wield_image , ttsign )
2022-11-07 17:16:07 +00:00
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 )
2023-05-01 01:52:43 +00:00
if not color or color == nil then
new_sign.wield_image = wield_image
new_sign.tiles = { tiles }
new_sign.inventory_image = inventory_image
else
new_sign.wield_image = " ( " .. wield_image .. " ^[multiply: " .. color .. " ) "
new_sign.tiles = { " ( " .. tiles .. " ^[multiply: " .. color .. " ) " }
new_sign.inventory_image = " ( " .. inventory_image .. " ^[multiply: " .. color .. " ) "
end
2023-05-01 02:26:11 +00:00
new_sign.description = ttsign
2023-05-01 01:52:43 +00:00
2022-11-07 17:16:07 +00:00
-- 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 )
2024-04-14 06:50:19 +00:00
mcl_signs : show_formspec ( placer , place_pos , " " )
2022-11-07 17:16:07 +00:00
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
2023-05-01 01:52:43 +00:00
if not color or color == nil then
new_sign_standing.wield_image = wield_image
new_sign_standing.tiles = { tiles }
new_sign_standing.inventory_image = inventory_image
else
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 .. " ) "
end
2022-11-07 17:16:07 +00:00
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 } )
2022-10-22 02:50:39 +00:00
2023-07-02 15:08:44 +00:00
-- register as unpushable
if minetest.get_modpath ( " mesecons_mvps " ) then
mesecon.register_mvps_stopper ( " mcl_signs:wall_sign " .. _name )
mesecon.register_mvps_stopper ( " mcl_signs:standing_sign " .. _name )
mesecon.register_mvps_stopper ( " mcl_signs:standing_sign22_5 " .. _name )
mesecon.register_mvps_stopper ( " mcl_signs:standing_sign45 " .. _name )
mesecon.register_mvps_stopper ( " mcl_signs:standing_sign67_5 " .. _name )
end
2022-10-19 22:55:07 +00:00
end
2022-10-23 07:20:34 +00:00
--- 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 )
2022-11-07 17:16:07 +00:00
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 )
2023-05-01 02:26:11 +00:00
new_sign.description = ttsign
2022-11-07 17:16:07 +00:00
2023-02-15 14:38:37 +00:00
new_sign.wield_image = " (mcl_signs_default_sign.png^[multiply: " .. color .. " ) "
2022-11-07 17:16:07 +00:00
new_sign.tiles = { " (mcl_signs_sign.png^[multiply: " .. color .. " ) " }
2023-02-15 14:38:37 +00:00
new_sign.inventory_image = " (mcl_signs_default_sign.png^[multiply: " .. color .. " ) "
2022-11-07 17:16:07 +00:00
-- 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 ) .. " \n Sign_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 )
2024-04-14 06:50:19 +00:00
mcl_signs : show_formspec ( placer , place_pos , " " )
2022-11-07 17:16:07 +00:00
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
2023-02-15 14:38:37 +00:00
new_sign_standing.wield_image = " (mcl_signs_default_sign.png^[multiply: " .. color .. " ) "
2022-11-07 17:16:07 +00:00
new_sign_standing.tiles = { " (mcl_signs_sign.png^[multiply: " .. color .. " ) " }
2023-02-15 14:38:37 +00:00
new_sign_standing.inventory_image = " (mcl_signs_default_sign.png^[multiply: " .. color .. " ) "
2022-11-07 17:16:07 +00:00
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 } )
2023-07-02 15:08:44 +00:00
-- register as unpushable
if minetest.get_modpath ( " mesecons_mvps " ) then
mesecon.register_mvps_stopper ( " mcl_signs:wall_sign " .. _name )
mesecon.register_mvps_stopper ( " mcl_signs:standing_sign " .. _name )
mesecon.register_mvps_stopper ( " mcl_signs:standing_sign22_5 " .. _name )
mesecon.register_mvps_stopper ( " mcl_signs:standing_sign45 " .. _name )
mesecon.register_mvps_stopper ( " mcl_signs:standing_sign67_5 " .. _name )
end
2022-10-23 07:20:34 +00:00
end
--- The same as reregister_sign, except caller defines the textures. Note, there is a greyscale version of the sign,
2023-02-15 14:38:37 +00:00
--- called "mcl_signs_default_sign_greyscale.png" and "mcl_signs_sign_greyscale.png" for optional use in the textures directory.
2022-10-23 07:20:34 +00:00
---
--- 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 )
2022-11-07 17:16:07 +00:00
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 )
2023-05-01 01:52:43 +00:00
if not color or color == nil then
new_sign.wield_image = wield_image
new_sign.tiles = { tiles }
new_sign.inventory_image = inventory_image
else
new_sign.wield_image = " ( " .. wield_image .. " ^[multiply: " .. color .. " ) "
new_sign.tiles = { " ( " .. tiles .. " ^[multiply: " .. color .. " ) " }
new_sign.inventory_image = " ( " .. inventory_image .. " ^[multiply: " .. color .. " ) "
end
2023-05-01 02:26:11 +00:00
new_sign.description = ttsign
2022-11-07 17:16:07 +00:00
-- 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 )
2024-04-14 06:50:19 +00:00
mcl_signs : show_formspec ( placer , place_pos , " " )
2022-11-07 17:16:07 +00:00
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 )
2023-05-01 01:52:43 +00:00
if not color or color == nil then
new_sign_standing.wield_image = wield_image
new_sign_standing.tiles = { tiles }
new_sign_standing.inventory_image = inventory_image
else
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 .. " ) "
end
2022-11-07 17:16:07 +00:00
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 } )
2022-10-23 07:20:34 +00:00
2023-07-02 15:08:44 +00:00
-- register as unpushable
if minetest.get_modpath ( " mesecons_mvps " ) then
mesecon.register_mvps_stopper ( " mcl_signs:wall_sign " .. _name )
mesecon.register_mvps_stopper ( " mcl_signs:standing_sign " .. _name )
mesecon.register_mvps_stopper ( " mcl_signs:standing_sign22_5 " .. _name )
mesecon.register_mvps_stopper ( " mcl_signs:standing_sign45 " .. _name )
mesecon.register_mvps_stopper ( " mcl_signs:standing_sign67_5 " .. _name )
end
2022-10-23 07:20:34 +00:00
end
2022-10-21 23:54:26 +00:00
--- 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.
2022-10-19 22:55:07 +00:00
---
2022-10-21 23:54:26 +00:00
--- 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".
2022-10-19 22:55:07 +00:00
---
2022-10-21 23:54:26 +00:00
--- wood_item_string: example: "mcl_core:wood" or "mcl_core:sprucewood"
2022-10-19 22:55:07 +00:00
---
2022-10-21 23:54:26 +00:00
--- _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 )
2022-11-07 17:16:07 +00:00
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 " ,
2022-11-17 23:34:41 +00:00
recipe = " mcl_signs:wall_sign " .. _name ,
2022-11-07 17:16:07 +00:00
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
2022-11-17 23:34:41 +00:00
local itemstring = " mcl_signs:wall_sign "
2022-11-07 17:16:07 +00:00
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
2022-10-21 23:54:26 +00:00
2022-11-07 17:16:07 +00:00
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
2022-10-21 23:54:26 +00:00
end
2022-10-19 22:55:07 +00:00
-- Helper functions
local function string_to_array ( str )
2022-11-07 17:16:07 +00:00
local string_table = { }
for i = 1 , string.len ( str ) do
table.insert ( string_table , string.sub ( str , i , i ) )
end
return string_table
2022-10-19 22:55:07 +00:00
end
local function string_to_line_array ( str )
2022-11-07 17:16:07 +00:00
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
2022-10-19 22:55:07 +00:00
end
local function get_rotation_level ( facedir , nodename )
2022-11-07 17:16:07 +00:00
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
2022-10-19 22:55:07 +00:00
end
function mcl_signs : round ( num , idp )
2022-11-07 17:16:07 +00:00
local mult = 10 ^ ( idp or 0 )
return math.floor ( num * mult + 0.5 ) / mult
2022-10-19 22:55:07 +00:00
end
function mcl_signs : get_color_for_sign ( item_name )
2022-11-07 17:16:07 +00:00
for d = 1 , # Dyes_table do
if Dyes_table [ d ] [ 1 ] == item_name then
return Dyes_table [ d ] [ 2 ]
end
end
return " false "
2022-10-19 22:55:07 +00:00
end
function mcl_signs : color_sign ( pos , text_color )
2022-11-07 17:16:07 +00:00
local success = mcl_signs : update_sign ( pos , nil , nil , true , text_color )
2022-10-19 22:55:07 +00:00
2022-11-07 17:16:07 +00:00
-- debug step
local meta = minetest.get_meta ( pos )
if not meta then
minetest.log ( " error " , " [mcl_signs] Sign Color Fail - Metadata. " )
2022-10-22 02:50:39 +00:00
2022-11-07 17:16:07 +00:00
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
2022-10-19 22:55:07 +00:00
2022-11-07 17:16:07 +00:00
return success
2022-10-19 22:55:07 +00:00
end
function mcl_signs : glow_sign ( pos , remove_glow )
2022-11-07 17:16:07 +00:00
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
2022-10-19 22:55:07 +00:00
end
function mcl_signs : create_lettering ( text , signnodename , sign_color )
2022-11-07 17:16:07 +00:00
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 )
2022-10-19 22:55:07 +00:00
2022-11-07 17:16:07 +00:00
-- debug step
if DEBUG then
minetest.log ( " action " , " [mcl_signs] Creating sign text; text: " .. text )
end
2022-10-22 02:50:39 +00:00
2022-11-07 17:16:07 +00:00
return texture
2022-10-19 22:55:07 +00:00
end
function mcl_signs : create_lines ( text )
2022-11-07 17:16:07 +00:00
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
2022-10-19 22:55:07 +00:00
end
function mcl_signs : generate_line ( s , ypos )
2022-11-07 17:16:07 +00:00
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
2022-10-19 22:55:07 +00:00
end
function mcl_signs : generate_texture ( lines , signnodename , letter_color )
2022-11-07 17:16:07 +00:00
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: \n SignNodeName: " .. dump ( signnodename ) .. " \n YPOS: " .. 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
2022-10-19 22:55:07 +00:00
end
function mcl_signs : get_wall_signtext_info ( param2 , nodename )
2022-11-07 17:16:07 +00:00
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
2022-10-19 22:55:07 +00:00
end
function mcl_signs : destruct_sign ( pos )
2022-11-07 17:16:07 +00:00
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
2022-10-19 22:55:07 +00:00
end
function mcl_signs : update_sign ( pos , fields , sender , force_remove , text_color )
2022-11-07 17:16:07 +00:00
-- Get Meta Data for the sign.
local meta = minetest.get_meta ( pos )
if not meta then
return false
end
2022-11-08 00:36:25 +00:00
local text = meta : get_string ( " text " , " " )
2024-04-14 06:50:19 +00:00
if fields and fields.text then
2022-11-07 17:16:07 +00:00
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
2022-11-08 00:36:25 +00:00
text_entity = mcl_signs : get_text_entity ( pos , force_remove )
2022-11-07 17:16:07 +00:00
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 ) .. " \n Sign_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 .. " \n Placed position: " .. dump ( pos ) .. " \n Sign_info: " .. dump ( sign_info ) )
end
-- save sign metadata.
meta : set_string ( " mcl_signs:text_color " , text_color )
2022-11-08 00:36:25 +00:00
-- 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
2022-11-07 17:16:07 +00:00
-- 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
2022-10-19 22:55:07 +00:00
end
2024-04-14 06:50:19 +00:00
function mcl_signs : show_formspec ( player , pos , old_text )
2022-11-07 17:16:07 +00:00
minetest.show_formspec (
player : get_player_name ( ) ,
" mcl_signs:set_text_ " .. pos.x .. " _ " .. pos.y .. " _ " .. pos.z ,
2024-04-14 06:50:19 +00:00
" size[6,3]textarea[0.25,0.25;6,1.5;text; " .. F ( S ( " Enter sign text: " ) ) .. " ; " .. F ( old_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 " ) ) .. " ] "
2022-11-07 17:16:07 +00:00
)
2022-10-19 22:55:07 +00:00
end
2022-11-08 00:36:25 +00:00
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
2023-02-15 14:38:37 +00:00
end