2022-10-20 01:55:07 +03:00
---
--- Generated by EmmyLua(https://github.com/EmmyLua)
--- Created by Michieal (FaerRaven).
--- DateTime: 10/14/22 4:05 PM
---
2022-10-22 02:31:00 +03:00
local DEBUG = minetest.settings : get_bool ( " mcl_logging_mcl_signs " , true ) -- special debug setting.
2022-10-20 01:55:07 +03:00
local table = table -- copied from the original signs init file.
if DEBUG then
minetest.log ( " Signs API Loading " )
end
-- INITIALIZE THE GLOBAL API FOR SIGNS.
mcl_signs = { }
-- 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
-- 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
-- for testing purposes
-- local test_color = "#BC0000"
local pi = math.pi
local n = 23 / 56 - 1 / 128
-- GLOBALS
--- 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_colors_official = {
BLACK = " #000000 " ,
DARK_BLUE = " #0000AA " ,
DARK_GREEN = " #00AA00 " ,
DARK_AQUA = " #00AAAA " ,
DARK_RED = " #AA0000 " ,
DARK_PURPLE = " #AA00AA " ,
GOLD = " #FFAA00 " ,
GRAY = " #AAAAAA " ,
DARK_GRAY = " #555555 " ,
BLUE = " #5555FF " ,
GREEN = " #55FF55 " ,
AQUA = " #55FFFF " ,
RED = " #FF5555 " ,
LIGHT_PURPLE = " #FF55FF " ,
YELLOW = " #FFFF55 " ,
WHITE = " #FFFFFF "
}
mcl_signs.woods = { " mcl_core:sprucewood " , " mcl_core:darkwood " , " mcl_core:wood " , " mcl_core:birchwood " , " mcl_core:junglewood " , " mcl_core:acaciawood " , " mcl_mangrove:mangrove_wood " }
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 } ,
}
mcl_signs.signtext_info_standing = { }
mcl_signs.sign_groups = { handy = 1 , axey = 1 , deco_block = 1 , material_wood = 1 , attached_node = 1 , dig_by_piston = 1 , flammable = - 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:cyan 2 " , mcl_signs.mcl_wool_colors . unicolor_cyan } ,
{ " mcl_dye:green " , mcl_colors_official.GREEN } ,
{ " mcl_dye:green 2 " , mcl_colors_official.GREEN } ,
{ " mcl_dye:dark_green " , mcl_colors_official.DARK_GREEN } ,
{ " mcl_dye:grey " , mcl_colors_official.GRAY } ,
{ " mcl_dye:grey 2 " , mcl_signs.mcl_wool_colors . unicolor_grey } ,
{ " mcl_dye:grey 3 " , mcl_colors_official.GRAY } ,
{ " mcl_dye:dark_grey " , mcl_colors_official.DARK_GRAY } ,
{ " mcl_dye:dark_grey 2 " , mcl_signs.mcl_wool_colors . unicolor_darkgrey } ,
{ " mcl_dye:lightblue " , mcl_signs.mcl_wool_colors . unicolor_light_blue } ,
{ " mcl_dye:lightblue 2 " , mcl_signs.mcl_wool_colors . unicolor_light_blue } ,
{ " mcl_dye:lime " , mcl_signs.unicolor_green_or_lime } ,
{ " mcl_dye:magenta " , mcl_signs.mcl_wool_colors . unicolor_red_violet_magenta } ,
{ " mcl_dye:magenta 2 " , mcl_signs.mcl_wool_colors . unicolor_red_violet_magenta } ,
{ " mcl_dye:magenta 3 " , mcl_signs.mcl_wool_colors . unicolor_red_violet_magenta } ,
{ " mcl_dye:orange " , mcl_signs.mcl_wool_colors . unicolor_orange } ,
{ " mcl_dye:orange 2 " , mcl_signs.mcl_wool_colors . unicolor_dark_orange } ,
{ " mcl_dye:pink " , mcl_signs.mcl_wool_colors . unicolor_light_red_pink } ,
{ " mcl_dye:pink 2 " , 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:red 2 " , mcl_colors_official.RED } ,
{ " mcl_dye:silver " , mcl_signs.mcl_wool_colors . unicolor_grey } ,
{ " mcl_dye:violet " , mcl_colors_official.DARK_PURPLE } ,
{ " mcl_dye:violet 2 " , mcl_colors_official.DARK_PURPLE } ,
{ " mcl_dye:white " , mcl_colors_official.WHITE } ,
{ " mcl_dye:white 3 " , mcl_colors_official.WHITE } ,
{ " mcl_dye:yellow " , mcl_colors_official.YELLOW } ,
{ " mcl_dye:yellow 2 " , mcl_signs.mcl_wool_colors . unicolor_yellow } ,
}
--- This allows optional mods and helps prevent breaking.
---
--- modname: the mod that defines the wood to add; item_name: the item_string of the wood to add.
--- eventually, this will become modname, item_name, coloration_code.
function mcl_signs . register_wood ( modname , item_name )
if minetest.get_modpath ( modname ) then
table.insert ( mcl_signs.woods , item_name )
end
end
function mcl_signs . register_dye ( modname , item_name , color_code )
if minetest.get_modpath ( modname ) then
table.insert ( mcl_signs.Dyes_table , { item_name , color_code } )
end
end
-- DEFINE SIGN BASE TYPES
mcl_signs.wall_standard = { }
mcl_signs.standing_standard = { }
--- Register a new sign, tint the textures, and gives it an unique node name
--- 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).
--- type: "wall", "standing".
---
--- color: the color code to color the base sign textures.
---
--- _name: the sign's name suffix, such as "_dark" or "_red", etc.
function mcl_signs . register_sign ( modname , type , color , _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
local wsign = { }
if type == " wall " then
wsign = table.copy ( mcl_signs.wall_standard )
end
end
--- the same as register_sign, except caller defines the textures.
--- 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).
--- type: "wall", "standing".
---
--- color: the color code to color the base sign textures. (use white or grey to not color the sign)
---
--- _name: the sign's name suffix, such as "_dark" or "_red", etc.
---
--- model_texture: the texture file to use for the sign.
---
--- inventory_image: the image used for in-inventory and in hand.
function mcl_signs . register_sign_and_textures ( modname , type , color , _name , model_texture , inventory_image )
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
end
--- the same as register_sign_and_textures, except uses 1 image for all of the model textures.
--- 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).
--- type: "wall", "standing".
---
--- color: the color code to color the base sign textures. (use white or grey to not color the sign)
---
--- _name: the sign's name suffix, such as "_dark" or "_red", etc.
---
--- model_texture: the texture file to use for the sign.
---
--- inventory_image: the image used for in-inventory and in hand.
function mcl_signs . register_sign_and_tiles ( modname , type , color , _name , tiles , inventory_image )
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
end
-- Helper functions
local function string_to_array ( str )
local tab = { }
for i = 1 , string.len ( str ) do
table.insert ( tab , string.sub ( str , i , i ) )
end
return tab
end
local function string_to_line_array ( str )
local tab = { }
local current = 1
local linechar = 1
tab [ 1 ] = " "
for _ , char in ipairs ( string_to_array ( str ) ) do
-- New line
if char == " \n " then
current = current + 1
tab [ current ] = " "
linechar = 1
else
tab [ current ] = tab [ current ] .. char
linechar = linechar + 1
end
end
return tab
end
local function get_rotation_level ( facedir , nodename )
local nnames = {
{ " mcl_signs:standing_sign22_5 " , 1 } ,
{ " mcl_signs:standing_sign22_5_dark " , 1 } ,
{ " mcl_signs:standing_sign45 " , 2 } ,
{ " mcl_signs:standing_sign45_dark " , 2 } ,
{ " mcl_signs:standing_sign67_5 " , 3 } ,
{ " mcl_signs:standing_sign67_5_dark " , 3 }
}
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 ( " 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
if DEBUG then
minetest.log ( " verbose " , " Sign Color Fail - Metadata. " )
end
return false
end
if DEBUG then
minetest.log ( " verbose " , " 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
-- debug step
if DEBUG then
minetest.log ( " verbose " , " 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 )
return texture
end
function mcl_signs : create_lines ( text )
local line_num = 1
local tab = { }
for _ , line in ipairs ( string_to_line_array ( text ) ) do
if line_num > NUMBER_OF_LINES then
break
end
table.insert ( tab , line )
line_num = line_num + 1
end
return tab
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 i = 1 , # parsed do
texture = texture .. " : " .. xpos .. " , " .. ypos .. " = " .. parsed [ i ] .. " .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
if signnodename == " mcl_signs:wall_sign " or signnodename == " mcl_signs:wall_sign_dark " then
ypos = 30
else
ypos = 0
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
--local placer_pos = placer:get_pos()
-- mcl_signs:show_formspec(placer, place_pos)
-- 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 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 ( " Pre-Sign Update: " .. sign_color .. " " .. meta : get_string ( " mcl_signs:glowing_sign " ) .. " . \n " .. dump ( pos ) )
end
local sign_info
local n = minetest.get_node ( pos )
local nn = n.name
if nn == " mcl_signs:standing_sign " or nn == " mcl_signs:standing_sign22_5 " or nn == " mcl_signs:standing_sign45 " or nn == " mcl_signs:standing_sign67_5 " then
sign_info = mcl_signs.signtext_info_standing [ get_rotation_level ( n.param2 , nn ) + 1 ]
elseif nn == " mcl_signs:standing_sign_dark " or nn == " mcl_signs:standing_sign22_5_dark " or nn == " mcl_signs:standing_sign45_dark " or nn == " mcl_signs:standing_sign67_5_dark " then
sign_info = mcl_signs.signtext_info_standing [ get_rotation_level ( n.param2 , nn ) + 1 ]
elseif nn == " mcl_signs:wall_sign " or nn == " mcl_signs:wall_sign_dark " then
sign_info = mcl_signs.signtext_info_wall [ mcl_signs : get_wall_signtext_info ( n.param2 ) ]
end
if sign_info == nil then
if DEBUG then
minetest.log ( " error " , " [mcl_signs::update] Missing sign_info! " )
end
return false
end
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
if force_remove then
v : remove ( )
else
text_entity = v
break
end
end
end
if not text_entity then
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 " )
end
text_entity : get_luaentity ( ) . _signnodename = nn
-- Set the actual properties for the sign
text_entity : set_properties ( {
textures = { mcl_signs : create_lettering ( text , nn , text_color ) } ,
} )
if has_glow then
text_entity : set_properties ( {
glow = sign_glow ,
} )
end
text_entity : set_yaw ( sign_info.yaw )
-- save sign metadata.
meta : set_string ( " mcl_signs:text_color " , text_color )
-- debug step
if DEBUG then
minetest.log ( " 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 : generate_signs ( )
local node_sounds
if minetest.get_modpath ( " mcl_sounds " ) then
node_sounds = mcl_sounds.node_sound_wood_defaults ( )
end
-- wall signs' & hanging signs' base
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_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 ( )
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. If a sign is created without text, this shows the formspec again for textual entry.
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 " , " 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 " , " 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 " , " Sign Color Success. " )
end
itemstack : take_item ( )
end
end
end
end ,
_mcl_hardness = 1 ,
_mcl_blast_resistance = 1 ,
}
if DEBUG then
minetest.log ( dump ( mcl_signs.wall_standard ) )
end
-- Standing sign nodes.
-- 4 rotations at 0°, 22.5°, 45° and 67.5°.
-- These are 4 out of 16 possible rotations.
-- With facedir the remaining 12 rotations are constructed.
-- standing sign base.
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 ,
-- Not Useless Code. If a sign is created without text, this shows the formspec again for textual entry.
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 " , " 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 " , " Sign Color Success. " )
end
itemstack : take_item ( )
end
end
end
end ,
_mcl_hardness = 1 ,
_mcl_blast_resistance = 1 ,
}
minetest.register_node ( " mcl_signs:wall_sign " , mcl_signs.wall_standard )
-- 0°
minetest.register_node ( " mcl_signs:standing_sign " , mcl_signs.standing_standard )
-- 22.5°
local ssign22_5 = table.copy ( mcl_signs.standing_standard )
ssign22_5.mesh = " mcl_signs_sign22.5.obj "
ssign22_5.on_rotate = function ( pos , node , user , mode )
if mode == screwdriver.ROTATE_FACE then
node.name = " mcl_signs:standing_sign45 "
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 " , ssign22_5 )
-- 45°
local ssign45 = table.copy ( mcl_signs.standing_standard )
ssign45.mesh = " mcl_signs_sign45.obj "
ssign45.on_rotate = function ( pos , node , user , mode )
if mode == screwdriver.ROTATE_FACE then
node.name = " mcl_signs:standing_sign67_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
minetest.register_node ( " mcl_signs:standing_sign45 " , ssign45 )
-- 67.5°
local ssign67_5 = table.copy ( mcl_signs.standing_standard )
ssign67_5.mesh = " mcl_signs_sign67.5.obj "
ssign67_5.on_rotate = function ( pos , node , user , mode )
if mode == screwdriver.ROTATE_FACE then
node.name = " mcl_signs:standing_sign "
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 " , ssign67_5 )
-- standard signs, dark:
-- dark standard wall sign / hanging sign base
mcl_signs.wall_standard_dark = table.copy ( mcl_signs.wall_standard )
mcl_signs.wall_standard_dark . wield_image = " default_sign_dark.png "
mcl_signs.wall_standard_dark . tiles = { " mcl_signs_sign_dark.png " }
mcl_signs.wall_standard_dark . inventory_image = " default_sign_dark.png "
mcl_signs.wall_standard_dark . 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_dark " )
elseif rotation_level % 4 == 1 then
nodeitem : set_name ( " mcl_signs:standing_sign22_5_dark " )
elseif rotation_level % 4 == 2 then
nodeitem : set_name ( " mcl_signs:standing_sign45_dark " )
elseif rotation_level % 4 == 3 then
nodeitem : set_name ( " mcl_signs:standing_sign67_5_dark " )
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_dark " , mcl_signs.wall_standard_dark )
-- 0°
-- dark standing sign
mcl_signs.standing_standard_dark = table.copy ( mcl_signs.standing_standard )
mcl_signs.standing_standard_dark . wield_image = " default_sign_dark.png "
mcl_signs.standing_standard_dark . tiles = { " mcl_signs_sign_dark.png " }
mcl_signs.standing_standard_dark . inventory_image = " default_sign_dark.png "
mcl_signs.standing_standard_dark . drop = " mcl_signs:wall_sign_dark "
minetest.register_node ( " mcl_signs:standing_sign_dark " , mcl_signs.standing_standard_dark )
-- 22.5°
local ssign22_5d = table.copy ( mcl_signs.standing_standard_dark )
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 "
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_dark " , ssign22_5d )
-- 45°
local ssign45d = table.copy ( mcl_signs.standing_standard_dark )
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 "
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_dark " , ssign45d )
-- 67.5°
local ssign67_5d = table.copy ( mcl_signs.standing_standard_dark )
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 "
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_dark " , ssign67_5d )
end