1
0
mirror of https://github.com/pyrollo/display_modpack.git synced 2025-06-29 14:40:59 +02:00

19 Commits

Author SHA1 Message Date
07eb4737fa Added font formspec textures 2018-11-18 15:30:37 +01:00
641dddfd51 Code simplification and securisation 2018-11-18 15:29:59 +01:00
b8357a505c New font selection formspec 2018-11-10 22:35:47 +01:00
c1835931e5 Added labels and wooden signs 2018-11-01 18:10:26 +01:00
06d35ec9bf Rewrited split_lines to avoid a string.split bug if first line empty 2018-11-01 12:25:47 +01:00
95c9da849d Changed UTF8 routines and added char fallback mechanism 2018-11-01 10:47:39 +01:00
bb24d91645 Merge pull request #24 from 12Me21/master
Fixes collision boxes on right directional signs
2018-10-08 09:13:07 +02:00
125cae3300 Fixes collision boxes on right directional signs 2018-10-07 00:32:12 -04:00
aac0ccf591 Merge pull request #23 from pandorabox-io/master 2018-10-03 10:24:03 +02:00
1c40830ddf fix infinite stack of steles 2018-10-03 09:07:42 +02:00
5586b9d1c4 Update copyright.txt 2018-09-26 19:43:33 +02:00
44b911be9e Improve on_rotate functions (#21)
Fixed bugs and improve on_rotate and support color- paramtype2s
2018-09-26 19:41:30 +02:00
d22362a4ac Reverting submodule change until zip file does not include submodule 2018-09-21 21:19:48 +02:00
12b556e929 Turned display_api into a submodule 2018-09-21 19:37:38 +02:00
508db92633 Update copyright.txt 2018-09-21 17:08:17 +02:00
30af909da5 Merge pull request #20 from 12Me21/master
Improved on_place
2018-09-21 17:07:11 +02:00
dfaf64cd61 Improved on_place
Now uses player view direction when trying to place nodes on the floor or ceiling, for both wallmounted and facedir nodes.
Also supports nodes where paramtype2 is not wallmounted or facedir.
2018-09-20 16:07:43 -04:00
c1f7b571b8 Add missing textures 2018-09-20 21:15:23 +02:00
2793e0ab8f Added simple wooden sign 2018-09-20 15:27:42 +02:00
25 changed files with 746 additions and 299 deletions

3
.gitmodules vendored Normal file
View File

@ -0,0 +1,3 @@
[submodule "display_api"]
path = display_api
url = https://github.com/pyrollo/display_api.git

View File

@ -2,3 +2,4 @@ Code by Pierre-Yves Rollo (pyrollo)
Contributors: Contributors:
(gpcf): Compatibility with signs lib (gpcf): Compatibility with signs lib
(Thomas--S): Fix /clearobjects bug (Thomas--S): Fix /clearobjects bug
(12Me21): on_place and on_rotate improvements

View File

@ -26,55 +26,30 @@ display_api.entity_spacing = 0.002
-- Miscelaneous values depending on wallmounted param2 -- Miscelaneous values depending on wallmounted param2
local wallmounted_values = { local wallmounted_values = {
[0]={dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, -- Should never be used [2]={dx=-1, dz=0, rx=0, rz=-1, yaw=-math.pi/2},
{dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=1}, -- Should never be used [3]={dx=1, dz=0, rx=0, rz=1, yaw=math.pi/2 },
{dx=-1, dz=0, rx=0, rz=-1, yaw=-math.pi/2, rotate=5}, [4]={dx=0, dz=-1, rx=1, rz=0, yaw=0 },
{dx=1, dz=0, rx=0, rz=1, yaw=math.pi/2, rotate=4}, [5]={dx=0, dz=1, rx=-1, rz=0, yaw=math.pi }
{dx=0, dz=-1, rx=1, rz=0, yaw=0, rotate=2},
{dx=0, dz=1, rx=-1, rz=0, yaw=math.pi, rotate=3}
} }
-- Miscelaneous values depending on facedir param2 -- Miscelaneous values depending on facedir param2
local facedir_values = { local facedir_values = {
[0]={dx=0, dz=-1, rx=1, rz=0, yaw=0, rotate=1}, [0]={dx=0, dz=-1, rx=1, rz=0, yaw=0 },
{dx=-1, dz=0, rx=0, rz=-1, yaw=-math.pi/2, rotate=2}, [1]={dx=-1, dz=0, rx=0, rz=-1, yaw=-math.pi/2},
{dx=0, dz=1, rx=-1, rz=0, yaw=math.pi, rotate=3}, [2]={dx=0, dz=1, rx=-1, rz=0, yaw=math.pi },
{dx=1, dz=0, rx=0, rz=1, yaw=math.pi/2, rotate=0}, [3]={dx=1, dz=0, rx=0, rz=1, yaw=math.pi/2 }
-- Forbiden values : }
{dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0},
{dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0},
{dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0},
{dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0},
{dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0},
{dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0},
{dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0},
{dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0},
{dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0},
{dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0},
{dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0},
{dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0},
{dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0},
{dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0},
{dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0},
{dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0},
{dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0},
{dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0},
{dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0},
{dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0},
}
-- dx/dy = depth vector, rx/ly = right vector, yaw = yaw of entity, -- dx/dy = depth vector, rx/ly = right vector, yaw = yaw of entity,
-- rotate = next facedir/wallmount on rotate
local function get_values(node) local function get_values(node)
local ndef = minetest.registered_nodes[node.name] local ndef = minetest.registered_nodes[node.name]
if ndef then if ndef then
if ndef.paramtype2 == "wallmounted" then local paramtype2 = ndef.paramtype2
return wallmounted_values[node.param2] if paramtype2 == "wallmounted" or paramtype2 == "colorwallmounted" then
end return wallmounted_values[node.param2 % 8]
if ndef.paramtype2 == "facedir" then elseif paramtype2 == "facedir" or paramtype2 == "colorfacedir" then
return facedir_values[node.param2] return facedir_values[node.param2 % 32]
end end
end end
end end
@ -97,13 +72,13 @@ local function get_entities(pos)
if ndef and ndef.display_entities then if ndef and ndef.display_entities then
for _, objref in ipairs(minetest.get_objects_inside_radius(pos, 1.5)) do for _, objref in ipairs(minetest.get_objects_inside_radius(pos, 1.5)) do
local entity = objref:get_luaentity() local entity = objref:get_luaentity()
if entity and ndef.display_entities[entity.name] and check_entity_pos(pos, objref) then if entity and ndef.display_entities[entity.name] and check_entity_pos(pos, objref) then
if objrefs[entity.name] then if objrefs[entity.name] then
objref:remove() objref:remove()
else else
objrefs[entity.name] = objref objrefs[entity.name] = objref
end end
end end
end end
end end
return objrefs return objrefs
@ -123,9 +98,9 @@ local function place_entities(pos)
local ndef = minetest.registered_nodes[node.name] local ndef = minetest.registered_nodes[node.name]
local values = get_values(node) local values = get_values(node)
local objrefs = get_entities(pos) local objrefs = get_entities(pos)
if values and ndef and ndef.display_entities then if values and ndef and ndef.display_entities then
for entity_name, props in pairs(ndef.display_entities) do for entity_name, props in pairs(ndef.display_entities) do
local depth = clip_pos_prop(props.depth) local depth = clip_pos_prop(props.depth)
local right = clip_pos_prop(props.right) local right = clip_pos_prop(props.right)
@ -133,12 +108,12 @@ local function place_entities(pos)
if not objrefs[entity_name] then if not objrefs[entity_name] then
objrefs[entity_name] = minetest.add_entity(pos, entity_name) objrefs[entity_name] = minetest.add_entity(pos, entity_name)
end end
objrefs[entity_name]:setpos({ objrefs[entity_name]:setpos({
x = pos.x - values.dx * depth + values.rx * right, x = pos.x - values.dx * depth + values.rx * right,
y = pos.y - top, y = pos.y - top,
z = pos.z - values.dz * depth + values.rz * right}) z = pos.z - values.dz * depth + values.rz * right})
objrefs[entity_name]:setyaw(values.yaw) objrefs[entity_name]:setyaw(values.yaw)
end end
end end
@ -151,7 +126,7 @@ local function call_node_on_display_update(pos, objref)
local entity = objref:get_luaentity() local entity = objref:get_luaentity()
if ndef and ndef.display_entities and entity and ndef.display_entities[entity.name] then if ndef and ndef.display_entities and entity and ndef.display_entities[entity.name] then
ndef.display_entities[entity.name].on_display_update(pos, objref) ndef.display_entities[entity.name].on_display_update(pos, objref)
end end
end end
--- Force entity update --- Force entity update
@ -160,7 +135,7 @@ function display_api.update_entities(pos)
for _, objref in pairs(objrefs) do for _, objref in pairs(objrefs) do
objref:get_luaentity().pos = minetest.hash_node_position(pos) objref:get_luaentity().pos = minetest.hash_node_position(pos)
call_node_on_display_update(pos, objref) call_node_on_display_update(pos, objref)
end end
end end
--- On_activate callback for display_api entities. Calls on_display_update callbacks --- On_activate callback for display_api entities. Calls on_display_update callbacks
@ -186,31 +161,30 @@ end
--- On_place callback for display_api items. Does nothing more than preventing item --- On_place callback for display_api items. Does nothing more than preventing item
--- from being placed on ceiling or ground --- from being placed on ceiling or ground
function display_api.on_place(itemstack, placer, pointed_thing) function display_api.on_place(itemstack, placer, pointed_thing, override_param2)
local ndef = itemstack:get_definition() local ndef = itemstack:get_definition()
local above = pointed_thing.above local above = pointed_thing.above
local under = pointed_thing.under local under = pointed_thing.under
local dir = {x = under.x - above.x, local dir = {x = under.x - above.x,
y = under.y - above.y, y = 0,
z = under.z - above.z} z = under.z - above.z}
-- If item is not placed on a wall, use the player's view direction instead
if dir.x == 0 and dir.z == 0 then
dir = placer:get_look_dir()
dir.y = 0
end
local param2 = 0
if ndef then if ndef then
if ndef.paramtype2 == "wallmounted" then local paramtype2 = ndef.paramtype2
if paramtype2 == "wallmounted" or paramtype2 == "colorwallmounted" then
local wdir = minetest.dir_to_wallmounted(dir) param2 = minetest.dir_to_wallmounted(dir)
elseif paramtype2 == "facedir" or paramtype2 == "colorfacedir" then
if wdir == 0 or wdir == 1 then param2 = minetest.dir_to_facedir(dir)
dir = placer:get_look_dir()
dir.y = 0
wdir = minetest.dir_to_wallmounted(dir)
end
return minetest.item_place(itemstack, placer, pointed_thing, wdir)
else
return minetest.item_place(itemstack, placer, pointed_thing, minetest.dir_to_facedir(dir))
end end
end end
return minetest.item_place(itemstack, placer, pointed_thing, param2 + (override_param2 or 0))
end end
--- On_construct callback for display_api items. Creates entities and update them. --- On_construct callback for display_api items. Creates entities and update them.
@ -227,14 +201,11 @@ function display_api.on_destruct(pos)
end end
end end
-- On_rotate (screwdriver) callback for display_api items. Prevents axis rotation and reorients entities. -- On_rotate (screwdriver) callback for display_api items. Prevents invalid rotations and reorients entities.
function display_api.on_rotate(pos, node, user, mode, new_param2) function display_api.on_rotate(pos, node, user, _, new_param2)
if mode ~= 1 then return false end node.param2 = new_param2
if get_values(node) then
local values = get_values(node) minetest.swap_node(pos, node)
if values then
minetest.swap_node(pos, {name = node.name, param1 = node.param1, param2 = values.rotate})
place_entities(pos) place_entities(pos)
return true return true
else else

176
font_api/fallbacks.lua Normal file
View File

@ -0,0 +1,176 @@
--[[
font_api mod for Minetest - Library to add font display capability
to display_api mod.
(c) Pierre-Yves Rollo
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
--]]
-- This is the unicode char fallback map. If a char is not present in
-- font, this maps indicates which char to try to use instead next.
return {
-- Lowercase chars
['a'] = 'A', ['b'] = 'B', ['c'] = 'C', ['d'] = 'D',
['e'] = 'E', ['f'] = 'F', ['g'] = 'G', ['h'] = 'H',
['i'] = 'I', ['j'] = 'J', ['k'] = 'K', ['l'] = 'L',
['m'] = 'M', ['n'] = 'N', ['o'] = 'O', ['p'] = 'P',
['q'] = 'Q', ['r'] = 'R', ['s'] = 'S', ['t'] = 'T',
['u'] = 'U', ['v'] = 'V', ['w'] = 'W', ['x'] = 'X',
['y'] = 'Y', ['z'] = 'Z',
-- Special
['¢'] = 'c', ['£'] = 'L', ['¥'] = 'Y', [''] = 'E',
['©'] = '(C)', ['®'] = '(R)', [''] = 'TM',
['ª'] = 'a', ['º'] = 'o',
['«'] = '"', ['»'] = '"', ['´'] = '\'',
['¹'] = '1', ['²'] = '2', ['³'] = '3',
['µ'] = 'u', ['¤'] = 'o',
['¼'] = '1/4', ['½'] = '1/2', ['¾'] = '3/4',
[''] = '1/8', [''] = '3/8', [''] = '5/8', [''] = '7/8',
['¿'] = '?',
-- Upper case accents
['À'] = 'A', ['Á'] = 'A', ['Â'] = 'A', ['Ã'] = 'A',
['Ä'] = 'A', ['Å'] = 'A',
['Æ'] = 'AE', ['Ç'] = 'C',
['È'] = 'E', ['É'] = 'E', ['Ê'] = 'E', ['Ë'] = 'E',
['Ì'] = 'I', ['Í'] = 'I', ['Î'] = 'I', ['Ï'] = 'I',
['Ð'] = 'D', ['Ñ'] = 'N',
['Ò'] = 'O', ['Ó'] = 'O', ['Ô'] = 'O', ['Õ'] = 'O',
['Ö'] = 'O', ['Ø'] = 'O',
['Ú'] = 'U', ['Ù'] = 'U', ['Û'] = 'U', ['Ü'] = 'U',
['×'] = 'x', ['Ý'] = 'Y',
-- Lower case accents
['à'] = 'a', ['à'] = 'a', ['á'] = 'a', ['â'] = 'a',
['ã'] = 'a', ['ä'] = 'a', ['å'] = 'a',
['æ'] = 'ae', ['ç'] = 'c',
['è'] = 'e', ['é'] = 'e', ['ê'] = 'e', ['ë'] = 'e',
['ì'] = 'i', ['í'] = 'i', ['î'] = 'i', ['ï'] = 'i',
['ð'] = 'd', ['ñ'] = 'n',
['ò'] = 'o', ['ó'] = 'o', ['ô'] = 'o', ['õ'] = 'o',
['ö'] = 'o', ['ø'] = 'o',
['ù'] = 'u', ['ú'] = 'u', ['û'] = 'u', ['ü'] = 'u',
['ý'] = 'y', ['ÿ'] = 'y',
-- Extended latin A
['Ā'] = 'A', ['ā'] = 'a', ['Ă'] = 'A', ['ă'] = 'a',
['Ą'] = 'A', ['ą'] = 'a', ['Ć'] = 'C', ['ć'] = 'c',
['Ĉ'] = 'C', ['ĉ'] = 'c', ['Ċ'] = 'C', ['ċ'] = 'c',
['Č'] = 'C', ['č'] = 'c', ['Ď'] = 'D', ['ď'] = 'd',
['Đ'] = 'D', ['đ'] = 'd', ['Ē'] = 'E', ['ē'] = 'e',
['Ĕ'] = 'E', ['ĕ'] = 'e', ['Ė'] = 'E', ['ė'] = 'e',
['Ę'] = 'E', ['ę'] = 'e', ['Ě'] = 'E', ['ě'] = 'e',
['Ĝ'] = 'G', ['Ğ'] = 'G', ['ğ'] = 'g', ['ĝ'] = 'g',
['Ġ'] = 'G', ['ġ'] = 'g', ['Ģ'] = 'G', ['ģ'] = 'g',
['Ĥ'] = 'H', ['ĥ'] = 'h', ['Ħ'] = 'H', ['ħ'] = 'h',
['Ĩ'] = 'I', ['ĩ'] = 'i', ['Ī'] = 'I', ['ī'] = 'i',
['Ĭ'] = 'I', ['ĭ'] = 'i', ['Į'] = 'I', ['į'] = 'i',
['ı'] = 'i', ['İ'] = 'I', ['IJ'] = 'IJ', ['ij'] = 'ij',
['Ĵ'] = 'J', ['ĵ'] = 'j', ['ķ'] = 'k', ['Ķ'] = 'K',
['ĸ'] = 'k',
['Ĺ'] = 'L', ['ĺ'] = 'l', ['Ļ'] = 'L', ['ļ'] = 'l',
['Ľ'] = 'L', ['ľ'] = 'l', ['Ŀ'] = 'L', ['ŀ'] = 'l',
['Ł'] = 'L', ['ł'] = 'l', ['Ń'] = 'N', ['ń'] = 'n',
['Ņ'] = 'N', ['ņ'] = 'n', ['Ň'] = 'N', ['ň'] = 'n',
['ʼn'] = 'n', ['Ŋ'] = 'n', ['ŋ'] = 'n',
['Ō'] = 'O', ['ō'] = 'o', ['Ŏ'] = 'O', ['ŏ'] = 'o',
['ő'] = 'o', ['Ő'] = 'O', ['œ'] = 'oe', ['Œ'] = 'OE',
['Ŕ'] = 'R', ['ŕ'] = 'r', ['Ŗ'] = 'R', ['ŗ'] = 'r',
['Ř'] = 'R', ['ř'] = 'r', ['Ś'] = 'S', ['ś'] = 's',
['Ŝ'] = 'S', ['ŝ'] = 's', ['Ş'] = 'S', ['ş'] = 's',
['Š'] = 'S', ['š'] = 's', ['Ţ'] = 'T', ['ţ'] = 't',
['ť'] = 't', ['Ŧ'] = 'T', ['Ť'] = 'T', ['ŧ'] = 't',
['Ũ'] = 'U', ['ũ'] = 'u', ['Ū'] = 'U', ['ū'] = 'u',
['Ŭ'] = 'U', ['ŭ'] = 'u', ['Ů'] = 'U', ['ů'] = 'u',
['Ű'] = 'U', ['ű'] = 'u', ['Ų'] = 'U', ['ų'] = 'u',
['Ŵ'] = 'W', ['ŵ'] = 'w', ['Ŷ'] = 'Y', ['ŷ'] = 'y',
['Ÿ'] = 'Y',
['Ź'] = 'Z', ['ź'] = 'z', ['Ż'] = 'Z', ['ż'] = 'z',
['Ž'] = 'Z', ['ž'] = 'z', ['ſ'] = 's',
-- Extended latin B
['ƀ'] = 'b', ['Ɓ'] = 'B', ['Ƃ'] = 'B', ['ƃ'] = 'b',
['Ɔ'] = 'O',
['Ƈ'] = 'C', ['ƈ'] = 'c', ['Ɖ'] = 'D', ['Ɗ'] = 'D',
['Ƌ'] = 'D', ['ƌ'] = 'd', ['Ǝ'] = 'E', ['Ə'] = 'e',
['Ɛ'] = 'E',
['Ƒ'] = 'F', ['ƒ'] = 'f', ['Ɠ'] = 'G',
['ƕ'] = 'hv', ['Ɨ'] = 'I', ['Ƙ'] = 'K', ['ƙ'] = 'k',
['ƚ'] = 'l', ['Ɯ'] = 'M', ['Ɲ'] = 'N', ['ƞ'] = 'n',
['Ɵ'] = 'O',
['Ơ'] = 'O', ['ơ'] = 'o', ['Ƣ'] = 'OI', ['ƣ'] = 'oi',
['Ƥ'] = 'P', ['ƥ'] = 'p', ['Ʀ'] = 'YR',
['Ƨ'] = 'S', ['ƨ'] = 's', ['ƫ'] = 't',
['Ƭ'] = 'T', ['ƭ'] = 't', ['Ʈ'] = 'T',
['Ư'] = 'U', ['ư'] = 'u', ['Ʋ'] = 'V',
['Ƴ'] = 'Y', ['ƴ'] = 'y', ['Ƶ'] = 'Z', ['ƶ'] = 'z',
['ƻ'] = '2', ['Ƽ'] = '5', ['ƽ'] = '5',
['DŽ'] = 'DZ', ['Dž'] = 'Dz', ['dž'] = 'dz',
['LJ'] = 'LJ', ['Lj'] = 'Lj', ['lj'] = 'lj',
['NJ'] = 'NJ', ['Nj'] = 'Nj', ['nj'] = 'nj',
['Ǎ'] = 'A', ['ǎ'] = 'a', ['Ǐ'] = 'I', ['ǐ'] = 'i',
['Ǒ'] = 'O', ['ǒ'] = 'o', ['Ǔ'] = 'U', ['ǔ'] = 'u',
['Ǖ'] = 'U', ['ǖ'] = 'u', ['Ǘ'] = 'U', ['ǘ'] = 'u',
['Ǚ'] = 'U', ['ǚ'] = 'u', ['Ǜ'] = 'U', ['ǜ'] = 'u',
['ǝ'] = 'e',
['Ǟ'] = 'A', ['ǟ'] = 'a', ['Ǡ'] = 'A', ['ǡ'] = 'a',
['Ǣ'] = 'Æ', ['ǣ'] = 'æ', ['Ǥ'] = 'G', ['ǥ'] = 'g',
['Ǧ'] = 'G', ['ǧ'] = 'g', ['Ǩ'] = 'K', ['ǩ'] = 'k',
['Ǫ'] = 'Q', ['ǫ'] = 'q', ['Ǭ'] = 'Q', ['ǭ'] = 'q',
['ǰ'] = 'J',
['DZ'] = 'DZ', ['Dz'] = 'Dz', ['dz'] = 'dz',
['Ǵ'] = 'G', ['ǵ'] = 'g', ['Ƕ'] = 'H',
['Ǹ'] = 'N', ['ǹ'] = 'n', ['Ǻ'] = 'A', ['ǻ'] = 'a',
['Ǽ'] = 'Æ', ['ǽ'] = 'æ', ['Ǿ'] = 'Ø', ['ǿ'] = 'ø',
['Ȁ'] = 'A', ['ȁ'] = 'a', ['Ȃ'] = 'A', ['ȃ'] = 'a',
['Ȅ'] = 'E', ['ȅ'] = 'e', ['Ȇ'] = 'E', ['ȇ'] = 'e',
['Ȉ'] = 'I', ['ȉ'] = 'i', ['Ȋ'] = 'I', ['ȋ'] = 'i',
['Ȍ'] = 'O', ['ȍ'] = 'o', ['Ȏ'] = 'O', ['ȏ'] = 'o',
['Ȑ'] = 'R', ['ȑ'] = 'r', ['Ȓ'] = 'R', ['ȓ'] = 'r',
['Ȕ'] = 'U', ['ȕ'] = 'u', ['Ȗ'] = 'U', ['ȗ'] = 'u',
['Ș'] = 'S', ['ș'] = 's', ['Ț'] = 'T', ['ț'] = 't',
['Ȟ'] = 'H', ['ȟ'] = 'h', ['Ƞ'] = 'N',
['ȡ'] = 'd',
['Ȣ'] = 'OU', ['ȣ'] = 'ou', ['Ȥ'] = 'Z', ['ȥ'] = 'z',
['Ȧ'] = 'A', ['ȧ'] = 'a', ['Ȩ'] = 'E', ['ȩ'] = 'e',
['Ȫ'] = 'O', ['ȫ'] = 'o', ['Ȭ'] = 'O', ['ȭ'] = 'o',
['Ȯ'] = 'O', ['ȯ'] = 'o', ['Ȱ'] = 'O', ['ȱ'] = 'o',
['Ȳ'] = 'Y', ['ȳ'] = 'y', ['ȴ'] = 'l',
['ȵ'] = 'n', ['ȶ'] = 't', ['ȷ'] = 'j',
['ȸ'] = 'db', ['ȹ'] = 'qp', ['Ⱥ'] = 'A',
['Ȼ'] = 'C', ['ȼ'] = 'c', ['Ƚ'] = 'L',
['Ⱦ'] = 'T', ['ȿ'] = 's', ['ɀ'] = 'z',
['Ƀ'] = 'B', ['Ʉ'] = 'U', ['Ʌ'] = 'V',
['Ɇ'] = 'E', ['ɇ'] = 'e', ['Ɉ'] = 'J', ['ɉ'] = 'j',
['Ɋ'] = 'Q', ['ɋ'] = 'q', ['Ɍ'] = 'R', ['ɍ'] = 'r',
['Ɏ'] = 'Y', ['ɏ'] = 'y', ['ɐ'] = 'a',
['ɓ'] = 'b', ['ɔ'] = 'o',
['ɕ'] = 'c', ['ɖ'] = 'd', ['ɗ'] = 'd',
['ɘ'] = 'e', ['ə'] = 'e', ['ɚ'] = 'e',
['ɛ'] = 'e', ['ɜ'] = 'e', ['ɝ'] = 'e', ['ɞ'] = 'e',
['ɟ'] = 'j',
['ɠ'] = 'g', ['ɡ'] = 'g', ['ɢ'] = 'G',
['ɥ'] = 'h', ['ɦ'] = 'h', ['ɧ'] = 'h',
['ɨ'] = 'i', ['ɪ'] = 'I',
['ɫ'] = 'l', ['ɬ'] = 'l', ['ɭ'] = 'l',
['ɮ'] = 'lz',
['ɯ'] = 'm', ['ɰ'] = 'm', ['ɱ'] = 'm',
['ɲ'] = 'n', ['ɳ'] = 'n', ['ɴ'] = 'N',
['ɵ'] = 'o', ['ɶ'] = 'Œ',
['ɹ'] = 'r', ['ɺ'] = 'r', ['ɻ'] = 'r',
['ɼ'] = 'r', ['ɽ'] = 'r', ['ɾ'] = 'r', ['ɿ'] = 'r',
}

View File

@ -17,111 +17,129 @@
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
--]] --]]
-- Fallback table
local fallbacks = dofile(font_api.path.."/fallbacks.lua")
-- Local functions -- Local functions
------------------ ------------------
-- Table deep copy -- Returns number of UTF8 bytes of the first char of the string
local function get_char_bytes(str)
local function deep_copy(input) local msb = str:byte(1)
local output = {} if msb ~= nil then
local key, value if msb < 0x80 then return 1 end
for key, value in pairs(input) do if msb >= 0xF0 then return 4 end
if type(value) == 'table' then if msb >= 0xE0 then return 3 end
output[key] = deep_copy(value) if msb >= 0xC2 then return 2 end
else
output[key] = value
end
end end
return output
end end
-- Returns next char, managing ascii and unicode plane 0 (0000-FFFF). -- Returns the unicode codepoint of the first char of the string
local function char_to_codepoint(str)
local function get_next_char(text, pos) local bytes = get_char_bytes(str)
if bytes == 1 then
local msb = text:byte(pos) return str:byte(1)
-- 1 byte char, ascii equivalent codepoints elseif bytes == 2 then
if msb < 0x80 then return (str:byte(1) - 0xC2) * 0x40
return msb, pos + 1 + str:byte(2)
elseif bytes == 3 then
return (str:byte(1) - 0xE0) * 0x1000
+ str:byte(2) % 0x40 * 0x40
+ str:byte(3) % 0x40
elseif bytes == 4 then -- Not tested
return (str:byte(1) - 0xF0) * 0x40000
+ str:byte(2) % 0x40 * 0x1000
+ str:byte(3) % 0x40 * 0x40
+ str:byte(4) % 0x40
end end
-- 4 bytes char not managed (Only 16 bits codepoints are managed)
if msb >= 0xF0 then
return 0, pos + 4
end
-- 3 bytes char
if msb >= 0xE0 then
return (msb - 0xE0) * 0x1000
+ text:byte(pos + 1) % 0x40 * 0x40
+ text:byte(pos + 2) % 0x40,
pos + 3
end
-- 2 bytes char (little endian)
if msb >= 0xC2 then
return (msb - 0xC2) * 0x40 + text:byte(pos + 1),
pos + 2
end
-- Not an UTF char
return 0, pos + 1
end end
-- Split multiline text into array of lines, with <maxlines> maximum lines. -- Split multiline text into array of lines, with <maxlines> maximum lines.
-- Can not use minetest string.split as it has bug if first line(s) empty
local function split_lines(text, maxlines) local function split_lines(text, maxlines)
local splits = text:split("\n") local lines = {}
if maxlines then local pos = 1
local lines = {} repeat
for num = 1,maxlines do local found = string.find(text, "\n", pos)
lines[num] = splits[num] found = found or #text + 1
end lines[#lines + 1] = string.sub(text, pos, found - 1)
return lines pos = found + 1
else until (maxlines and (#lines >= maxlines)) or (pos > (#text + 1))
return splits return lines
end
end end
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
--- Font class --- Font class
font_api.Font = {} local Font = {}
font_api.Font = Font
function font_api.Font:new(def) function Font:new(def)
if type(def) ~= "table" then if type(def) ~= "table" then
minetest.log("error", "Font definition must be a table.") minetest.log("error",
"[font_api] Font definition must be a table.")
return nil return nil
end end
if def.height == nil or def.height <= 0 then if def.height == nil or def.height <= 0 then
minetest.log("error", "Font definition must have a positive height.") minetest.log("error",
"[font_api] Font definition must have a positive height.")
return nil return nil
end end
if type(def.widths) ~= "table" then if type(def.widths) ~= "table" then
minetest.log("error", "Font definition must have a widths array.") minetest.log("error",
"[font_api] Font definition must have a widths array.")
return nil return nil
end end
if def.widths[0] == nil then if def.widths[0] == nil then
minetest.log("error", minetest.log("error",
"Font must have a char with codepoint 0 (=unknown char).") "[font_api] Font must have a char with codepoint 0 (=unknown char).")
return nil return nil
end end
local font = deep_copy(def) local font = table.copy(def)
setmetatable(font, self) setmetatable(font, self)
self.__index = self self.__index = self
return font return font
end end
--- Gets the next char of a text
-- @return Codepoint of first char,
-- @return Remaining string without this first char
function Font:get_next_char(text)
local bytes = get_char_bytes(text)
if bytes == nil then
minetest.log("warning",
"[font_api] Encountered a non UTF char, not displaying text.")
return nil, ''
end
local codepoint = char_to_codepoint(text)
-- Fallback mechanism
if self.widths[codepoint] == nil then
local char = text:sub(1, bytes)
if fallbacks[char] then
return self:get_next_char(fallbacks[char]..text:sub(bytes+1))
else
return 0, text:sub(bytes+1) -- Ultimate fallback
end
else
return codepoint, text:sub(bytes+1)
end
end
--- Returns the width of a given char --- Returns the width of a given char
-- @param char : codepoint of the char -- @param char : codepoint of the char
-- @return Char width -- @return Char width
function font_api.Font:get_char_width(char) function Font:get_char_width(char)
-- Replace chars with no texture by the NULL(0) char -- Replace chars with no texture by the NULL(0) char
if self.widths[char] ~= nil then if self.widths[char] ~= nil then
return self.widths[char] return self.widths[char]
@ -134,13 +152,13 @@ end
-- @param nb_of_lines : number of text lines (default 1) -- @param nb_of_lines : number of text lines (default 1)
-- @return Text height -- @return Text height
function font_api.Font:get_height(nb_of_lines) function Font:get_height(nb_of_lines)
if nb_of_lines == nil then nb_of_lines = 1 end if nb_of_lines == nil then nb_of_lines = 1 end
if nb_of_lines > 0 then if nb_of_lines > 0 then
return return
( (
(self.height or 0) + (self.height or 0) +
(self.margintop or 0) + (self.margintop or 0) +
(self.marginbottom or 0) (self.marginbottom or 0)
) * nb_of_lines + ) * nb_of_lines +
@ -154,16 +172,14 @@ end
-- @param line Line of text which the width will be computed. -- @param line Line of text which the width will be computed.
-- @return Text width -- @return Text width
function font_api.Font:get_width(line) function Font:get_width(line)
local codepoint
local char
local width = 0 local width = 0
local pos = 1 line = line or ''
-- TODO: Use iterator while line ~= "" do
while pos <= #line do codepoint, line = self:get_next_char(line)
char, pos = get_next_char(line, pos) width = width + self:get_char_width(codepoint)
width = width + self:get_char_width(char)
end end
return width return width
@ -176,30 +192,21 @@ end
-- @param y Vertical position of the line in texture -- @param y Vertical position of the line in texture
-- @return Texture string -- @return Texture string
function font_api.Font:make_line_texture(line, texturew, x, y) function Font:make_line_texture(line, texturew, x, y)
local codepoint
local texture = "" local texture = ""
local char line = line or ''
local pos = 1
-- TODO: Use iterator while line ~= '' do
while pos <= #line do codepoint, line = self:get_next_char(line)
char, pos = get_next_char(line, pos)
-- Replace chars with no texture by the NULL(0) char
if self.widths[char] == nil
then
print(string.format("["..font_api.name
.."] Missing char %d (%04x)",char,char))
char = 0
end
-- Add image only if it is visible (at least partly) -- Add image only if it is visible (at least partly)
if x + self.widths[char] >= 0 and x <= texturew then if x + self.widths[codepoint] >= 0 and x <= texturew then
texture = texture.. texture = texture..
string.format(":%d,%d=font_%s_%04x.png", string.format(":%d,%d=font_%s_%04x.png",
x, y, self.name, char) x, y, self.name, codepoint)
end end
x = x + self.widths[char] x = x + self.widths[codepoint]
end end
return texture return texture
@ -215,13 +222,13 @@ end
-- @param color Color of the text (optional) -- @param color Color of the text (optional)
-- @return Texture string -- @return Texture string
function font_api.Font:make_text_texture(text, texturew, textureh, maxlines, function Font:make_text_texture(text, texturew, textureh, maxlines,
halign, valign, color) halign, valign, color)
local texture = "" local texture = ""
local lines = {} local lines = {}
local textheight = 0 local textheight = 0
local y local y
-- Split text into lines (limited to maxlines fist lines) -- Split text into lines (limited to maxlines fist lines)
for num, line in pairs(split_lines(text, maxlines)) do for num, line in pairs(split_lines(text, maxlines)) do
lines[num] = { text = line, width = self:get_width(line) } lines[num] = { text = line, width = self:get_width(line) }
@ -238,7 +245,7 @@ function font_api.Font:make_text_texture(text, texturew, textureh, maxlines,
y = (textureh - textheight) / 2 y = (textureh - textheight) / 2
end end
end end
y = y + (self.margintop or 0) y = y + (self.margintop or 0)
for _, line in pairs(lines) do for _, line in pairs(lines) do
@ -263,4 +270,3 @@ function font_api.Font:make_text_texture(text, texturew, textureh, maxlines,
if color then texture = texture.."^[colorize:"..color end if color then texture = texture.."^[colorize:"..color end
return texture return texture
end end

154
font_api/fontform.lua Normal file
View File

@ -0,0 +1,154 @@
--[[
font_api mod for Minetest - Library to add font display capability
to display_api mod.
(c) Pierre-Yves Rollo
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
--]]
local modname = minetest.get_current_modname()
local contexts = {}
minetest.register_on_leaveplayer(function(player)
if minetest.is_player(player) then
contexts[player:get_player_name()] = nil
end
end)
local function get_context(playername)
if not contexts[playername] then
contexts[playername] = { playername = playername }
end
return contexts[playername]
end
-- Show node formspec functions
local function show_node_formspec(playername, pos)
local meta = minetest.get_meta(pos)
-- Decontextualize formspec
local fs = meta:get_string('formspec')
if not fs then
return
end
-- Change context and currrent_name references to nodemeta references
-- Change context and currrent_name references to nodemeta references
local nodemeta = string.format("nodemeta:%i,%i,%i", pos.x, pos.y ,pos.z)
fs = fs:gsub("current_name", nodemeta)
fs = fs:gsub("context", nodemeta)
-- Change all ${} to their corresponding metadata values
local s, e
repeat
s, e = fs:find('%${.*}')
if s and e then
fs = fs:sub(1, s-1)..
minetest.formspec_escape(meta:get_string(fs:sub(s+2,e-1)))..
fs:sub(e+1)
end
until s == nil
local context = get_context(playername)
context.node_pos = pos
-- Find node on_receive_fields
local ndef = minetest.registered_nodes[minetest.get_node(pos).name]
if ndef and ndef.on_receive_fields then
context.on_receive_fields = ndef.on_receive_fields
end
-- Show formspec
minetest.show_formspec(playername, modname..':context_formspec', fs)
end
minetest.register_on_player_receive_fields(function(player, formname, fields)
if formname ~= modname..':context_formspec' then
return
end
if not minetest.is_player(player) then
return true
end
local context = get_context(player:get_player_name())
if context.on_receive_fields then
context.on_receive_fields(context.pos, '', fields, player)
end
return true
end)
-- Specific functions
local function show_font_formspec(playername)
local context = get_context(playername)
local fonts = {}
for name, _ in pairs(font_api.registered_fonts) do
fonts[#fonts+1] = name
end
table.sort(fonts)
local fs = 'size[4,'..(#fonts + 0.8)..']'
..default.gui_bg..default.gui_bg_img..default.gui_slots
..'button_exit[0,'..(#fonts)..';4,1;cancel;Cancel]'
for line = 1, #fonts do
local font = font_api.get_font(fonts[line])
fs = fs..'image[0.1,'..(line-0.9)..';4.5,0.8;'
..font:make_text_texture(font.name, font:get_height()*5,
font:get_height()*1.2, 1, "center", "top", "#fff")
..']button_exit[0,'..(line-1)..';4,1;font_'..font.name..';]'
end
minetest.show_formspec(context.playername, modname..':font_list', fs)
end
minetest.register_on_player_receive_fields(function(player, formname, fields)
if formname ~= modname..':font_list' then
return
end
if not minetest.is_player(player) then
return true
end
local playername = player:get_player_name()
local context = get_context(playername)
if minetest.is_protected(context.pos, playername) then
return true
end
if fields.quit == 'true' then
for name, _ in pairs(font_api.registered_fonts) do
if fields['font_'..name] then
local meta = minetest.get_meta(context.pos)
meta:set_string("font", name)
display_api.update_entities(context.pos)
end
end
-- Using after to avoid the "double close" bug
minetest.after(0, show_node_formspec, playername, context.pos)
end
return true
end)
function font_api.show_font_list_from_pos(player, pos)
if minetest.is_player(player) then
local context = get_context(player:get_player_name())
context.pos = pos
show_font_formspec(player:get_player_name())
end
end

View File

@ -29,9 +29,10 @@ font_api.path = minetest.get_modpath(font_api.name)
dofile(font_api.path.."/font.lua") dofile(font_api.path.."/font.lua")
dofile(font_api.path.."/registry.lua") dofile(font_api.path.."/registry.lua")
dofile(font_api.path.."/fontform.lua")
--- Standard on_display_update entity callback. --- Standard on_display_update entity callback.
-- Node should have a corresponding display_entity with size, resolution and -- Node should have a corresponding display_entity with size, resolution and
-- maxlines fields and optionally halign, valign and color fields -- maxlines fields and optionally halign, valign and color fields
-- @param pos Node position -- @param pos Node position
-- @param objref Object reference of entity -- @param objref Object reference of entity
@ -49,8 +50,8 @@ function font_api.on_display_update(pos, objref)
local maxlines = def.maxlines or 1 -- TODO:How to do w/o maxlines ? local maxlines = def.maxlines or 1 -- TODO:How to do w/o maxlines ?
objref:set_properties({ objref:set_properties({
textures={font:make_text_texture(text, textures={font:make_text_texture(text,
font:get_height(maxlines) * def.size.x / def.size.y font:get_height(maxlines) * def.size.x / def.size.y
/ (def.aspect_ratio or 1), / (def.aspect_ratio or 1),
font:get_height(maxlines), font:get_height(maxlines),
@ -62,4 +63,3 @@ end
-- Compatibility -- Compatibility
font_lib = font_api font_lib = font_api

Binary file not shown.

After

Width:  |  Height:  |  Size: 224 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 238 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 220 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 222 B

View File

@ -2,17 +2,60 @@ minetest.register_craft({
output = 'signs:wooden_right_sign', output = 'signs:wooden_right_sign',
recipe = { recipe = {
{'group:wood', 'group:wood', 'group:wood'}, {'group:wood', 'group:wood', 'group:wood'},
{'group:wood', 'group:wood', ''}, {'group:wood', 'group:wood', 'dye:black'},
{'', '', ''}, {'', '', ''},
} }
}) })
minetest.register_craft({
output = 'signs:wooden_right_sign',
type = 'shapeless',
recipe = { 'signs:wooden_long_sign' }
})
minetest.register_craft({
output = 'signs:wooden_long_sign',
recipe = {
{'group:wood', 'dye:black', 'group:wood'},
{'group:wood', 'group:wood', 'group:wood'},
{'', '', ''},
}
})
minetest.register_craft({
output = 'signs:wooden_long_sign',
type = 'shapeless',
recipe = { 'signs:wooden_right_sign' }
})
minetest.register_craft({
output = 'signs:wooden_sign',
recipe = {
{'', 'dye:black', ''},
{'group:wood', 'group:wood', 'group:wood'},
{'group:wood', 'group:wood', 'group:wood'},
}
})
minetest.register_craft({ minetest.register_craft({
output = 'signs:paper_poster', output = 'signs:paper_poster',
recipe = { recipe = {
{'default:paper', 'default:paper', ''}, {'default:paper', 'default:paper', 'dye:black'},
{'default:paper', 'default:paper', ''}, {'default:paper', 'default:paper', ''},
{'default:paper', 'default:paper', ''}, {'default:paper', 'default:paper', ''},
} }
}) })
minetest.register_craft({
output = 'signs:label_small',
recipe = {
{'default:paper', 'dye:black'},
}
})
minetest.register_craft({
output = 'signs:label_small',
recipe = {
{'default:paper', 'default:paper', 'dye:black'},
}
})

View File

@ -27,7 +27,7 @@ local function display_poster(pos, node, player)
local meta = minetest.get_meta(pos) local meta = minetest.get_meta(pos)
local def = minetest.registered_nodes[node.name].display_entities["signs:display_text"] local def = minetest.registered_nodes[node.name].display_entities["signs:display_text"]
local font = font_api.get_font(meta:get_string("font") or def.font_name) local font = font_api.get_font(meta:get_string("font") or def.font_name)
-- Title texture -- Title texture
local titletexture = font:make_text_texture( local titletexture = font:make_text_texture(
meta:get_string("display_text"), font:get_height()*8.4, font:get_height(), 1, "center") meta:get_string("display_text"), font:get_height()*8.4, font:get_height(), 1, "center")
@ -77,12 +77,12 @@ local function on_receive_fields_poster(pos, formname, fields, player)
local node = minetest.get_node(pos) local node = minetest.get_node(pos)
if not minetest.is_protected(pos, player:get_player_name()) and fields then if not minetest.is_protected(pos, player:get_player_name()) and fields then
if formname == node.name.."@"..minetest.pos_to_string(pos)..":display" and if formname == node.name.."@"..minetest.pos_to_string(pos)..":display"
fields.edit then and fields.edit then
edit_poster(pos, node, player) edit_poster(pos, node, player)
end end
if formname == node.name.."@"..minetest.pos_to_string(pos)..":edit" and if formname == node.name.."@"..minetest.pos_to_string(pos)..":edit"
(fields.write or fields.key_enter) then and (fields.write or fields.key_enter) then
meta:set_string("display_text", fields.display_text) meta:set_string("display_text", fields.display_text)
meta:set_string("text", fields.text) meta:set_string("text", fields.text)
meta:set_string("infotext", "\""..fields.display_text meta:set_string("infotext", "\""..fields.display_text
@ -98,10 +98,40 @@ display_api.register_display_entity("signs:display_text")
-- Sign models and registration -- Sign models and registration
local models = { local models = {
wooden_sign = {
depth = 1/16, width = 14/16, height = 12/16,
entity_fields = {
size = { x = 12/16, y = 10/16 },
maxlines = 3,
color = "#000",
},
node_fields = {
description = S("Wooden sign"),
tiles = { "signs_wooden.png" },
inventory_image = "signs_wooden_inventory.png",
groups= { dig_immediate = 2 },
},
},
wooden_long_sign = {
depth = 1/16, width = 1, height = 7/16,
entity_fields = {
size = { x = 1, y = 6/16 },
maxlines = 2,
color = "#000",
},
node_fields = {
description = S("Wooden long sign"),
tiles = { "signs_wooden_long.png", "signs_wooden_long.png",
"signs_wooden_long.png^[transformR90",
"signs_wooden_long.png^[transformR90",
"signs_wooden_long.png", "signs_wooden_long.png",
},
inventory_image = "signs_wooden_long_inventory.png",
groups= { dig_immediate = 2 },
},
},
wooden_right_sign = { wooden_right_sign = {
depth = 1/16, depth = 1/16, width = 14/16, height = 7/16,
width = 14/16,
height = 7/16,
entity_fields = { entity_fields = {
right = -3/32, right = -3/32,
size = { x = 12/16, y = 6/16 }, size = { x = 12/16, y = 6/16 },
@ -111,19 +141,18 @@ local models = {
node_fields = { node_fields = {
description = S("Wooden direction sign"), description = S("Wooden direction sign"),
tiles = { "signs_wooden_direction.png" }, tiles = { "signs_wooden_direction.png" },
inventory_image = "signs_wooden_inventory.png", inventory_image = "signs_wooden_direction_inventory.png",
signs_other_dir = 'signs:wooden_left_sign', signs_other_dir = 'signs:wooden_left_sign',
on_place = signs_api.on_place_direction, on_place = signs_api.on_place_direction,
drawtype = "mesh", drawtype = "mesh",
mesh = "signs_dir_right.obj", mesh = "signs_dir_right.obj",
selection_box = { type="fixed", fixed = {-0.5, -7/32, 0.5, 7/16, 7/32, 7/16}}, selection_box = { type="fixed", fixed = {-0.5, -7/32, 0.5, 7/16, 7/32, 7/16}},
collision_box = { type="fixed", fixed = {-0,5, -7/32, 0.5, 7/16, 7/32, 7/16}}, collision_box = { type="fixed", fixed = {-0,5, -7/32, 0.5, 7/16, 7/32, 7/16}},
groups= { dig_immediate = 2 },
}, },
}, },
wooden_left_sign = { wooden_left_sign = {
depth = 1/16, depth = 1/16, width = 14/16, height = 7/16,
width = 14/16,
height = 7/16,
entity_fields = { entity_fields = {
right = 3/32, right = 3/32,
size = { x = 12/16, y = 6/16 }, size = { x = 12/16, y = 6/16 },
@ -133,20 +162,18 @@ local models = {
node_fields = { node_fields = {
description = S("Wooden direction sign"), description = S("Wooden direction sign"),
tiles = { "signs_wooden_direction.png" }, tiles = { "signs_wooden_direction.png" },
inventory_image = "signs_wooden_inventory.png", inventory_image = "signs_wooden_direction_inventory.png",
signs_other_dir = 'signs:wooden_right_sign', signs_other_dir = 'signs:wooden_right_sign',
drawtype = "mesh", drawtype = "mesh",
mesh = "signs_dir_left.obj", mesh = "signs_dir_left.obj",
selection_box = { type="fixed", fixed = {-7/16, -7/32, 0.5, 0.5, 7/32, 7/16}}, selection_box = { type="fixed", fixed = {-7/16, -7/32, 0.5, 0.5, 7/32, 7/16}},
collision_box = { type="fixed", fixed = {-7/16, -7/32, 0.5, 0.5, 7/32, 7/16}}, collision_box = { type="fixed", fixed = {-7/16, -7/32, 0.5, 0.5, 7/32, 7/16}},
groups = { not_in_creative_inventory = 1 }, groups = { not_in_creative_inventory = 1, dig_immediate = 2 },
drop = "signs:wooden_right_sign", drop = "signs:wooden_right_sign",
}, },
}, },
paper_poster = { paper_poster = {
depth = 1/32, depth = 1/32, width = 26/32, height = 30/32,
width = 26/32,
height = 30/32,
entity_fields = { entity_fields = {
top = -11/32, top = -11/32,
size = { x = 26/32, y = 6/32 }, size = { x = 26/32, y = 6/32 },
@ -159,11 +186,40 @@ local models = {
"signs_poster_sides.png", "signs_poster_sides.png", "signs_poster_sides.png", "signs_poster_sides.png",
"signs_poster_sides.png", "signs_poster.png" }, "signs_poster_sides.png", "signs_poster.png" },
inventory_image = "signs_poster_inventory.png", inventory_image = "signs_poster_inventory.png",
groups= { dig_immediate = 3 },
on_construct = display_api.on_construct, on_construct = display_api.on_construct,
on_rightclick = display_poster, on_rightclick = display_poster,
on_receive_fields = on_receive_fields_poster, on_receive_fields = on_receive_fields_poster,
}, },
}, },
label_small = {
depth = 1/32, width = 4/16, height = 4/16,
entity_fields = {
size = { x = 4/16, y = 4/16 },
maxlines = 1,
color = "#000",
},
node_fields = {
description = S("Small label"),
tiles = { "signs_label.png" },
inventory_image = "signs_label_small_inventory.png",
groups= { dig_immediate = 3 },
},
},
label_medium = {
depth = 1/32, width = 8/16, height = 8/16,
entity_fields = {
size = { x = 8/16, y = 8/16 },
maxlines = 2,
color = "#000",
},
node_fields = {
description = S("Label"),
tiles = { "signs_label.png" },
inventory_image = "signs_label_medium_inventory.png",
groups= { dig_immediate = 3 },
},
},
} }
-- Node registration -- Node registration
@ -171,4 +227,3 @@ for name, model in pairs(models)
do do
signs_api.register_sign("signs", name, model) signs_api.register_sign("signs", name, model)
end end

View File

@ -15,8 +15,8 @@
height="32px" height="32px"
id="svg2985" id="svg2985"
version="1.1" version="1.1"
inkscape:version="0.48.4 r9939" inkscape:version="0.92.3 (2405546, 2018-03-11)"
sodipodi:docname="affiche.svg" sodipodi:docname="poster.svg"
inkscape:export-filename="/home/pyrollo/dev/minetest-mods/signs/textures/signs_poster.png" inkscape:export-filename="/home/pyrollo/dev/minetest-mods/signs/textures/signs_poster.png"
inkscape:export-xdpi="90" inkscape:export-xdpi="90"
inkscape:export-ydpi="90"> inkscape:export-ydpi="90">
@ -73,18 +73,18 @@
borderopacity="1.0" borderopacity="1.0"
inkscape:pageopacity="0.0" inkscape:pageopacity="0.0"
inkscape:pageshadow="2" inkscape:pageshadow="2"
inkscape:zoom="11.197802" inkscape:zoom="22.395604"
inkscape:cx="-4.798213" inkscape:cx="15.573035"
inkscape:cy="9.6735437" inkscape:cy="16.977299"
inkscape:current-layer="layer5" inkscape:current-layer="layer2"
showgrid="true" showgrid="true"
inkscape:grid-bbox="true" inkscape:grid-bbox="true"
inkscape:document-units="px" inkscape:document-units="px"
inkscape:window-width="1239" inkscape:window-width="785"
inkscape:window-height="776" inkscape:window-height="447"
inkscape:window-x="41" inkscape:window-x="2459"
inkscape:window-y="24" inkscape:window-y="340"
inkscape:window-maximized="1" inkscape:window-maximized="0"
showguides="true" showguides="true"
inkscape:guide-bbox="true" inkscape:guide-bbox="true"
inkscape:object-paths="true"> inkscape:object-paths="true">
@ -95,11 +95,13 @@
visible="true" visible="true"
enabled="true" enabled="true"
snapvisiblegridlinesonly="true" snapvisiblegridlinesonly="true"
spacingx="0.5px" spacingx="0.5"
spacingy="0.5px" spacingy="0.5"
dotted="false" dotted="false"
color="#ff0000" color="#ff0000"
opacity="0.1254902" /> opacity="0.1254902"
originx="0"
originy="0" />
</sodipodi:namedview> </sodipodi:namedview>
<metadata <metadata
id="metadata2990"> id="metadata2990">
@ -109,7 +111,7 @@
<dc:format>image/svg+xml</dc:format> <dc:format>image/svg+xml</dc:format>
<dc:type <dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title> <dc:title />
</cc:Work> </cc:Work>
</rdf:RDF> </rdf:RDF>
</metadata> </metadata>
@ -127,7 +129,7 @@
height="32.081406" height="32.081406"
width="32.003735" /> width="32.003735" />
<rect <rect
style="color:#000000;fill:#feffed;fill-opacity:0.76862745;fill-rule:nonzero;stroke:none;stroke-width:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#feffed;fill-opacity:0.76862745;fill-rule:nonzero;stroke:none;stroke-width:0;marker:none;enable-background:accumulate"
id="rect5482" id="rect5482"
width="32" width="32"
height="32" height="32"
@ -136,18 +138,22 @@
<flowRoot <flowRoot
xml:space="preserve" xml:space="preserve"
id="flowRoot5628" id="flowRoot5628"
style="font-size:4px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"><flowRegion style="font-style:normal;font-weight:normal;line-height:0.01%;font-family:sans-serif;text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none"><flowRegion
id="flowRegion5630"><rect id="flowRegion5630"
style="font-family:sans-serif"><rect
id="rect5632" id="rect5632"
width="3.6625218" width="3.6625218"
height="4.6728725" height="4.6728725"
x="12.692533" x="12.692533"
y="-10.876763" /></flowRegion><flowPara y="-10.876763"
id="flowPara5634" /></flowRoot> </g> style="font-family:sans-serif" /></flowRegion><flowPara
id="flowPara5634"
style="font-size:4px;line-height:1.25;font-family:sans-serif"> </flowPara></flowRoot> </g>
<g <g
inkscape:groupmode="layer" inkscape:groupmode="layer"
id="layer4" id="layer4"
inkscape:label="Fond inv"> inkscape:label="Fond inv"
style="display:inline">
<image <image
style="display:inline" style="display:inline"
y="-0.081405997" y="-0.081405997"
@ -158,7 +164,7 @@
width="32.003735" width="32.003735"
clip-path="url(#clipPath4132)" /> clip-path="url(#clipPath4132)" />
<rect <rect
style="color:#000000;fill:#feffed;fill-opacity:0.76862745;fill-rule:nonzero;stroke:none;stroke-width:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#feffed;fill-opacity:0.76862745;fill-rule:nonzero;stroke:none;stroke-width:0;marker:none;enable-background:accumulate"
id="rect5482-0" id="rect5482-0"
width="26" width="26"
height="30" height="30"
@ -175,260 +181,281 @@
transform="matrix(1,0,0,1.3429336,0,-1.0576018)"> transform="matrix(1,0,0,1.3429336,0,-1.0576018)">
<text <text
transform="scale(0.85711508,1.1667045)" transform="scale(0.85711508,1.1667045)"
sodipodi:linespacing="125%"
id="text4138" id="text4138"
y="5.1426907" y="5.1426907"
x="18.756834" x="18.756834"
style="font-size:3.42846036px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans" style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none"
xml:space="preserve"><tspan xml:space="preserve"><tspan
y="5.1426907" y="5.1426907"
x="18.756834" x="18.756834"
id="tspan4140" id="tspan4140"
sodipodi:role="line" sodipodi:role="line"
style="font-weight:bold;-inkscape-font-specification:Sans Bold">READ ME !</tspan></text> style="font-weight:bold;font-size:3.42845988px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:'Sans Bold'">READ ME !</tspan></text>
</g> </g>
</g> </g>
<g
inkscape:groupmode="layer"
id="layer2"
inkscape:label="Label frame"
style="display:inline">
<rect
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#ff41c1;fill-opacity:0.41711228;fill-rule:nonzero;stroke:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
id="rect4585"
width="16"
height="16"
x="8"
y="8"
ry="0" />
<rect
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#ff41c1;fill-opacity:0.41711228;fill-rule:nonzero;stroke:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
id="rect4585-3"
width="8"
height="8"
x="12"
y="12"
ry="0" />
</g>
<g <g
id="layer1" id="layer1"
inkscape:label="Texte" inkscape:label="Texte"
inkscape:groupmode="layer" inkscape:groupmode="layer"
style="display:inline"> style="display:none">
<path <path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 4,11.5 4,0" d="M 4,11.5 H 8"
id="path2997-2" id="path2997-2"
inkscape:connector-curvature="0" inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" /> sodipodi:nodetypes="cc" />
<path <path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 7,9.5 4,0" d="m 7,9.5 h 4"
id="path3017" id="path3017"
inkscape:connector-curvature="0" /> inkscape:connector-curvature="0" />
<path <path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 12,9.5 1,0" d="m 12,9.5 h 1"
id="path3019" id="path3019"
inkscape:connector-curvature="0" /> inkscape:connector-curvature="0" />
<path <path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 14,9.5 3,0" d="m 14,9.5 h 3"
id="path3021" id="path3021"
inkscape:connector-curvature="0" /> inkscape:connector-curvature="0" />
<path <path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 18,9.5 4,0" d="m 18,9.5 h 4"
id="path3023" id="path3023"
inkscape:connector-curvature="0" /> inkscape:connector-curvature="0" />
<path <path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 23,9.5 1,0" d="m 23,9.5 h 1"
id="path3025" id="path3025"
inkscape:connector-curvature="0" /> inkscape:connector-curvature="0" />
<path <path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 25,9.5 3,0" d="m 25,9.5 h 3"
id="path3027" id="path3027"
inkscape:connector-curvature="0" /> inkscape:connector-curvature="0" />
<path <path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 9,11.5 3,0" d="m 9,11.5 h 3"
id="path3029" id="path3029"
inkscape:connector-curvature="0" /> inkscape:connector-curvature="0" />
<path <path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 13,11.5 1,0" d="m 13,11.5 h 1"
id="path3031" id="path3031"
inkscape:connector-curvature="0" /> inkscape:connector-curvature="0" />
<path <path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 15,11.5 4,0" d="m 15,11.5 h 4"
id="path3033" id="path3033"
inkscape:connector-curvature="0" /> inkscape:connector-curvature="0" />
<path <path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 20,11.5 3,0" d="m 20,11.5 h 3"
id="path3035" id="path3035"
inkscape:connector-curvature="0" /> inkscape:connector-curvature="0" />
<path <path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 24,11.5 1,0" d="m 24,11.5 h 1"
id="path3037" id="path3037"
inkscape:connector-curvature="0" /> inkscape:connector-curvature="0" />
<path <path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 26,11.5 2,0" d="m 26,11.5 h 2"
id="path3039" id="path3039"
inkscape:connector-curvature="0" /> inkscape:connector-curvature="0" />
<path <path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 4,13.5 1,0" d="M 4,13.5 H 5"
id="path3041" id="path3041"
inkscape:connector-curvature="0" /> inkscape:connector-curvature="0" />
<path <path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 6,13.5 7,0" d="m 6,13.5 h 7"
id="path3043" id="path3043"
inkscape:connector-curvature="0" /> inkscape:connector-curvature="0" />
<path <path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 17,13.5 -3,0" d="M 17,13.5 H 14"
id="path3045" id="path3045"
inkscape:connector-curvature="0" /> inkscape:connector-curvature="0" />
<path <path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 7,16.5 1,0" d="M 7,16.5 H 8"
id="path3047" id="path3047"
inkscape:connector-curvature="0" /> inkscape:connector-curvature="0" />
<path <path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 9,16.5 7,0" d="m 9,16.5 h 7"
id="path3049" id="path3049"
inkscape:connector-curvature="0" /> inkscape:connector-curvature="0" />
<path <path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 17,16.5 2,0" d="m 17,16.5 h 2"
id="path3051" id="path3051"
inkscape:connector-curvature="0" /> inkscape:connector-curvature="0" />
<path <path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 20,16.5 6,0" d="m 20,16.5 h 6"
id="path3053" id="path3053"
inkscape:connector-curvature="0" /> inkscape:connector-curvature="0" />
<path <path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 27,16.5 1,0" d="m 27,16.5 h 1"
id="path3055" id="path3055"
inkscape:connector-curvature="0" /> inkscape:connector-curvature="0" />
<path <path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 4,18.5 5,0" d="M 4,18.5 H 9"
id="path3057" id="path3057"
inkscape:connector-curvature="0" /> inkscape:connector-curvature="0" />
<path <path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 10,18.5 1,0" d="m 10,18.5 h 1"
id="path3059" id="path3059"
inkscape:connector-curvature="0" /> inkscape:connector-curvature="0" />
<path <path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 12,18.5 3,0" d="m 12,18.5 h 3"
id="path3061" id="path3061"
inkscape:connector-curvature="0" /> inkscape:connector-curvature="0" />
<path <path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 16,18.5 4,0" d="m 16,18.5 h 4"
id="path3063" id="path3063"
inkscape:connector-curvature="0" /> inkscape:connector-curvature="0" />
<path <path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 21,18.5 2,0" d="m 21,18.5 h 2"
id="path3065" id="path3065"
inkscape:connector-curvature="0" /> inkscape:connector-curvature="0" />
<path <path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 24,18.5 4,0" d="m 24,18.5 h 4"
id="path3067" id="path3067"
inkscape:connector-curvature="0" /> inkscape:connector-curvature="0" />
<path <path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 4,20.5 2,0" d="M 4,20.5 H 6"
id="path3069" id="path3069"
inkscape:connector-curvature="0" /> inkscape:connector-curvature="0" />
<path <path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 7,20.5 5,0" d="m 7,20.5 h 5"
id="path3071" id="path3071"
inkscape:connector-curvature="0" /> inkscape:connector-curvature="0" />
<path <path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 13,20.5 1,0" d="m 13,20.5 h 1"
id="path3073" id="path3073"
inkscape:connector-curvature="0" /> inkscape:connector-curvature="0" />
<path <path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 15,20.5 4,0" d="m 15,20.5 h 4"
id="path3075" id="path3075"
inkscape:connector-curvature="0" /> inkscape:connector-curvature="0" />
<path <path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 20,20.5 4,0" d="m 20,20.5 h 4"
id="path3077" id="path3077"
inkscape:connector-curvature="0" /> inkscape:connector-curvature="0" />
<path <path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 26,20.5 2,0" d="m 26,20.5 h 2"
id="path3079" id="path3079"
inkscape:connector-curvature="0" /> inkscape:connector-curvature="0" />
<path <path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 4,22.5 4,0" d="M 4,22.5 H 8"
id="path3081" id="path3081"
inkscape:connector-curvature="0" /> inkscape:connector-curvature="0" />
<path <path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 9,22.5 5,0" d="m 9,22.5 h 5"
id="path3083" id="path3083"
inkscape:connector-curvature="0" /> inkscape:connector-curvature="0" />
<path <path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 15,22.5 5,0" d="m 15,22.5 h 5"
id="path3085" id="path3085"
inkscape:connector-curvature="0" /> inkscape:connector-curvature="0" />
<path <path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 21,25.5 1,0" d="m 21,25.5 h 1"
id="path3087" id="path3087"
inkscape:connector-curvature="0" inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" /> sodipodi:nodetypes="cc" />
<path <path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 23,25.5 5,0" d="m 23,25.5 h 5"
id="path3089" id="path3089"
inkscape:connector-curvature="0" inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" /> sodipodi:nodetypes="cc" />
<path <path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 4,27.5 1,0" d="M 4,27.5 H 5"
id="path3091" id="path3091"
inkscape:connector-curvature="0" inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" /> sodipodi:nodetypes="cc" />
<path <path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 6,27.5 5,0" d="m 6,27.5 h 5"
id="path3093" id="path3093"
inkscape:connector-curvature="0" inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" /> sodipodi:nodetypes="cc" />
<path <path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 12,27.5 6,0" d="m 12,27.5 h 6"
id="path3095" id="path3095"
inkscape:connector-curvature="0" inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" /> sodipodi:nodetypes="cc" />
<path <path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 19,27.5 1,0" d="m 19,27.5 h 1"
id="path3097" id="path3097"
inkscape:connector-curvature="0" inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" /> sodipodi:nodetypes="cc" />
<path <path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 21,27.5 3,0" d="m 21,27.5 h 3"
id="path3099" id="path3099"
inkscape:connector-curvature="0" inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" /> sodipodi:nodetypes="cc" />
<path <path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 7,25.5 2,0" d="M 7,25.5 H 9"
id="path3101" id="path3101"
inkscape:connector-curvature="0" /> inkscape:connector-curvature="0" />
<path <path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 10,25.5 5,0" d="m 10,25.5 h 5"
id="path3103" id="path3103"
inkscape:connector-curvature="0" /> inkscape:connector-curvature="0" />
<path <path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 16,25.5 4,0" d="m 16,25.5 h 4"
id="path3105" id="path3105"
inkscape:connector-curvature="0" /> inkscape:connector-curvature="0" />
</g> </g>

Before

Width:  |  Height:  |  Size: 1.7 MiB

After

Width:  |  Height:  |  Size: 1.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 404 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 406 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 417 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 574 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 710 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 606 B

After

Width:  |  Height:  |  Size: 581 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 524 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 636 B

View File

@ -35,49 +35,62 @@ function signs_api.set_display_text(pos, text, font)
else else
meta:set_string("infotext", "") meta:set_string("infotext", "")
end end
meta:set_string("font", font) if font then
meta:set_string("font", font)
end
display_api.update_entities(pos) display_api.update_entities(pos)
end end
function signs_api.set_formspec(pos) function signs_api.set_formspec(pos)
local meta = minetest.get_meta(pos) local meta = minetest.get_meta(pos)
local ndef = minetest.registered_nodes[minetest.get_node(pos).name] local ndef = minetest.registered_nodes[minetest.get_node(pos).name]
if ndef and ndef.display_entities if ndef and ndef.display_entities
and ndef.display_entities["signs:display_text"] then and ndef.display_entities["signs:display_text"] then
local maxlines = ndef.display_entities["signs:display_text"].maxlines local maxlines = ndef.display_entities["signs:display_text"].maxlines
local formspec, formheight local fs, x, y
if maxlines == 1 then if maxlines == 1 then
formspec = fs = "field[0.5,0.7;5.5,1;display_text;"..F("Text")..
"field[0.5,0.7;5.5,1;display_text;"..F("Text").. ";${display_text}]"
";${display_text}]" y = 1.2
formheight = 2
else else
local extralabel = "" local extralabel = ""
if maxlines then if maxlines then
extralabel = F(" (first %s lines only)"):format(maxlines) extralabel = F(" (first %s lines only)"):format(maxlines)
end end
formspec = fs = "textarea[0.5,0.7;5.5,2;display_text;"..F("Text")..""..
"textarea[0.5,0.7;5.5,2;display_text;"..F("Text")..""..
extralabel..";${display_text}]" extralabel..";${display_text}]"
formheight = 3 y = 2.4
end end
formspec = formspec.."button_exit[2,"..formheight..";2,1;ok;".. x = 0.2
fs = fs.."image_button["..x..","..y..";0.5,0.5;font_api_font.png;font;]"
x = x + 0.4
fs = fs.."image_button["..x..","..y..";0.5,0.5;font_api_left.png;left;]"
x = x + 0.4
fs = fs.."image_button["..x..","..y..";0.5,0.5;font_api_center.png;center;]"
x = x + 0.4
fs = fs.."image_button["..x..","..y..";0.5,0.5;font_api_right.png;right;]"
y = y + 0.7
fs = fs.."button_exit[2,"..y..";2,1;ok;"..
F("Write").."]" F("Write").."]"
formheight = formheight + 1 y = y + 0.8
formspec = "size[6,"..formheight.."]"..default.gui_bg.. fs = "size[6,"..y.."]"..default.gui_bg..
default.gui_bg_img..default.gui_slots..formspec default.gui_bg_img..default.gui_slots..fs
meta:set_string("formspec", formspec) meta:set_string("formspec", fs)
end end
end end
function signs_api.on_receive_fields(pos, formname, fields, player) function signs_api.on_receive_fields(pos, formname, fields, player)
if not minetest.is_protected(pos, player:get_player_name()) then if not minetest.is_protected(pos, player:get_player_name()) then
if fields and (fields.ok or fields.key_enter) then if fields and (fields.ok or fields.key_enter) then
signs_api.set_display_text(pos, fields.display_text, fields.font) signs_api.set_display_text(pos, fields.display_text)
end
if fields and (fields.font) then
signs_api.set_display_text(pos, fields.display_text)
font_api.show_font_list_from_pos(player, pos)
end end
end end
end end
@ -132,18 +145,19 @@ function signs_api.on_place_direction(itemstack, placer, pointed_thing)
end end
-- Handles screwdriver rotation. Direction is affected for direction signs -- Handles screwdriver rotation. Direction is affected for direction signs
-- If rotation mode is 2 and sign is directional, swap direction.
-- Otherwise use display_api's on_rotate function.
function signs_api.on_rotate(pos, node, player, mode, new_param2) function signs_api.on_rotate(pos, node, player, mode, new_param2)
if mode == 2 then if mode == 2 then
local ndef = minetest.registered_nodes[node.name] local ndef = minetest.registered_nodes[node.name]
if ndef.signs_other_dir then if ndef.signs_other_dir then
minetest.swap_node(pos, {name = ndef.signs_other_dir, minetest.swap_node(pos, {name = ndef.signs_other_dir,
param1 = node.param1, param2 = node.param2}) param1 = node.param1, param2 = node.param2})
display_api.update_entities(pos) display_api.update_entities(pos)
end return true
else end
display_api.on_rotate(pos, node, user, mode, new_param2)
end end
return false; return display_api.on_rotate(pos, node, user, mode, new_param2)
end end
function signs_api.register_sign(mod, name, model) function signs_api.register_sign(mod, name, model)
@ -182,7 +196,8 @@ function signs_api.register_sign(mod, name, model)
on_destruct = display_api.on_destruct, on_destruct = display_api.on_destruct,
on_rotate = signs_api.on_rotate, on_rotate = signs_api.on_rotate,
on_receive_fields = signs_api.on_receive_fields, on_receive_fields = signs_api.on_receive_fields,
on_punch = function(pos, node, player, pointed_thing) on_punch = function(pos, node, player, pointed_thing)
signs_api.set_formspec(pos)
display_api.update_entities(pos) display_api.update_entities(pos)
end, end,
} }
@ -210,7 +225,3 @@ end
-- Text entity for all signs -- Text entity for all signs
display_api.register_display_entity("signs:display_text") display_api.register_display_entity("signs:display_text")

View File

@ -189,7 +189,7 @@ local models = {
drawtype = "mesh", drawtype = "mesh",
mesh = "signs_dir_right.obj", mesh = "signs_dir_right.obj",
selection_box = { type = "fixed", fixed = { -0.5, -7/32, 0.5, 7/16, 7/32, 7/16 } }, selection_box = { type = "fixed", fixed = { -0.5, -7/32, 0.5, 7/16, 7/32, 7/16 } },
collision_box = { type = "fixed", fixed = { -0,5, -7/32, 0.5, 7/16, 7/32, 7/16 } }, collision_box = { type = "fixed", fixed = { -0.5, -7/32, 0.5, 7/16, 7/32, 7/16 } },
}, },
}, },
green_left_sign = { green_left_sign = {
@ -237,7 +237,7 @@ local models = {
drawtype = "mesh", drawtype = "mesh",
mesh = "signs_dir_right.obj", mesh = "signs_dir_right.obj",
selection_box = { type = "fixed", fixed = { -0.5, -7/32, 0.5, 7/16, 7/32, 7/16 } }, selection_box = { type = "fixed", fixed = { -0.5, -7/32, 0.5, 7/16, 7/32, 7/16 } },
collision_box = { type = "fixed", fixed = { -0,5, -7/32, 0.5, 7/16, 7/32, 7/16 } }, collision_box = { type = "fixed", fixed = { -0.5, -7/32, 0.5, 7/16, 7/32, 7/16 } },
}, },
}, },
yellow_left_sign = { yellow_left_sign = {
@ -285,7 +285,7 @@ local models = {
drawtype = "mesh", drawtype = "mesh",
mesh = "signs_dir_right.obj", mesh = "signs_dir_right.obj",
selection_box = { type = "fixed", fixed = { -0.5, -7/32, 0.5, 7/16, 7/32, 7/16 } }, selection_box = { type = "fixed", fixed = { -0.5, -7/32, 0.5, 7/16, 7/32, 7/16 } },
collision_box = { type = "fixed", fixed = { -0,5, -7/32, 0.5, 7/16, 7/32, 7/16 } }, collision_box = { type = "fixed", fixed = { -0.5, -7/32, 0.5, 7/16, 7/32, 7/16 } },
}, },
}, },
white_left_sign = { white_left_sign = {

View File

@ -59,7 +59,7 @@ for i, material in ipairs(steles.materials) do
}, },
on_place = function(itemstack, placer, pointed_thing) on_place = function(itemstack, placer, pointed_thing)
minetest.rotate_node(itemstack, placer, pointed_thing) minetest.rotate_node(itemstack, placer, pointed_thing)
display_api.on_place(itemstack, placer, pointed_thing) return display_api.on_place(itemstack, placer, pointed_thing)
end, end,
on_construct = function(pos) on_construct = function(pos)
local meta = minetest.get_meta(pos) local meta = minetest.get_meta(pos)