1
0
mirror of https://github.com/pyrollo/display_modpack.git synced 2025-06-28 22:26:41 +02:00

17 Commits
v1.1.1 ... v1.2

Author SHA1 Message Date
01ba1d47b1 Updated changelog 2018-11-01 18:56:59 +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
20 changed files with 566 additions and 275 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

@ -1,5 +1,5 @@
# Display Modpack
Version 1.1.1
Version 1.2
This modpack provides mods with dynamic display. Mods are :
@ -19,6 +19,14 @@ For more information, see the [forum topic](https://forum.minetest.net/viewtopic
## Changelog
### 2018-11-01 (Version 1.2)
- Labels and woodend signs added.
- Fallback mechanism for missing chars (For example: "é" --> "e" --> "E").
- Several bug fixes by 12Me21 and naturefreshmilk.
### 2018-07-16 (Version 1.1.1)
- Boards mod added.

View File

@ -2,3 +2,4 @@ Code by Pierre-Yves Rollo (pyrollo)
Contributors:
(gpcf): Compatibility with signs lib
(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
local wallmounted_values = {
[0]={dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, -- Should never be used
{dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=1}, -- Should never be used
{dx=-1, dz=0, rx=0, rz=-1, yaw=-math.pi/2, rotate=5},
{dx=1, dz=0, rx=0, rz=1, yaw=math.pi/2, rotate=4},
{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}
[2]={dx=-1, dz=0, rx=0, rz=-1, yaw=-math.pi/2},
[3]={dx=1, dz=0, rx=0, rz=1, yaw=math.pi/2 },
[4]={dx=0, dz=-1, rx=1, rz=0, yaw=0 },
[5]={dx=0, dz=1, rx=-1, rz=0, yaw=math.pi }
}
-- Miscelaneous values depending on facedir param2
local facedir_values = {
[0]={dx=0, dz=-1, rx=1, rz=0, yaw=0, rotate=1},
{dx=-1, dz=0, rx=0, rz=-1, yaw=-math.pi/2, rotate=2},
{dx=0, dz=1, rx=-1, rz=0, yaw=math.pi, rotate=3},
{dx=1, dz=0, rx=0, rz=1, yaw=math.pi/2, rotate=0},
-- 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},
}
[0]={dx=0, dz=-1, rx=1, rz=0, yaw=0 },
[1]={dx=-1, dz=0, rx=0, rz=-1, yaw=-math.pi/2},
[2]={dx=0, dz=1, rx=-1, rz=0, yaw=math.pi },
[3]={dx=1, dz=0, rx=0, rz=1, yaw=math.pi/2 }
}
-- dx/dy = depth vector, rx/ly = right vector, yaw = yaw of entity,
-- rotate = next facedir/wallmount on rotate
local function get_values(node)
local ndef = minetest.registered_nodes[node.name]
if ndef then
if ndef.paramtype2 == "wallmounted" then
return wallmounted_values[node.param2]
end
if ndef.paramtype2 == "facedir" then
return facedir_values[node.param2]
local paramtype2 = ndef.paramtype2
if paramtype2 == "wallmounted" or paramtype2 == "colorwallmounted" then
return wallmounted_values[node.param2 % 8]
elseif paramtype2 == "facedir" or paramtype2 == "colorfacedir" then
return facedir_values[node.param2 % 32]
end
end
end
@ -97,13 +72,13 @@ local function get_entities(pos)
if ndef and ndef.display_entities then
for _, objref in ipairs(minetest.get_objects_inside_radius(pos, 1.5)) do
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
objref:remove()
objref:remove()
else
objrefs[entity.name] = objref
end
end
end
end
end
return objrefs
@ -123,9 +98,9 @@ local function place_entities(pos)
local ndef = minetest.registered_nodes[node.name]
local values = get_values(node)
local objrefs = get_entities(pos)
if values and ndef and ndef.display_entities then
for entity_name, props in pairs(ndef.display_entities) do
local depth = clip_pos_prop(props.depth)
local right = clip_pos_prop(props.right)
@ -133,12 +108,12 @@ local function place_entities(pos)
if not objrefs[entity_name] then
objrefs[entity_name] = minetest.add_entity(pos, entity_name)
end
objrefs[entity_name]:setpos({
x = pos.x - values.dx * depth + values.rx * right,
y = pos.y - top,
z = pos.z - values.dz * depth + values.rz * right})
objrefs[entity_name]:setyaw(values.yaw)
end
end
@ -151,7 +126,7 @@ local function call_node_on_display_update(pos, objref)
local entity = objref:get_luaentity()
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)
end
end
end
--- Force entity update
@ -160,7 +135,7 @@ function display_api.update_entities(pos)
for _, objref in pairs(objrefs) do
objref:get_luaentity().pos = minetest.hash_node_position(pos)
call_node_on_display_update(pos, objref)
end
end
end
--- 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
--- 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 above = pointed_thing.above
local under = pointed_thing.under
local dir = {x = under.x - above.x,
y = under.y - above.y,
z = under.z - above.z}
y = 0,
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.paramtype2 == "wallmounted" then
local wdir = minetest.dir_to_wallmounted(dir)
if wdir == 0 or wdir == 1 then
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))
local paramtype2 = ndef.paramtype2
if paramtype2 == "wallmounted" or paramtype2 == "colorwallmounted" then
param2 = minetest.dir_to_wallmounted(dir)
elseif paramtype2 == "facedir" or paramtype2 == "colorfacedir" then
param2 = minetest.dir_to_facedir(dir)
end
end
return minetest.item_place(itemstack, placer, pointed_thing, param2 + (override_param2 or 0))
end
--- On_construct callback for display_api items. Creates entities and update them.
@ -227,14 +201,11 @@ function display_api.on_destruct(pos)
end
end
-- On_rotate (screwdriver) callback for display_api items. Prevents axis rotation and reorients entities.
function display_api.on_rotate(pos, node, user, mode, new_param2)
if mode ~= 1 then return false end
local values = get_values(node)
if values then
minetest.swap_node(pos, {name = node.name, param1 = node.param1, param2 = values.rotate})
-- On_rotate (screwdriver) callback for display_api items. Prevents invalid rotations and reorients entities.
function display_api.on_rotate(pos, node, user, _, new_param2)
node.param2 = new_param2
if get_values(node) then
minetest.swap_node(pos, node)
place_entities(pos)
return true
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/>.
--]]
-- Fallback table
local fallbacks = dofile(font_api.path.."/fallbacks.lua")
-- Local functions
------------------
-- Table deep copy
local function deep_copy(input)
local output = {}
local key, value
for key, value in pairs(input) do
if type(value) == 'table' then
output[key] = deep_copy(value)
else
output[key] = value
end
-- Returns number of UTF8 bytes of the first char of the string
local function get_char_bytes(str)
local msb = str:byte(1)
if msb ~= nil then
if msb < 0x80 then return 1 end
if msb >= 0xF0 then return 4 end
if msb >= 0xE0 then return 3 end
if msb >= 0xC2 then return 2 end
end
return output
end
-- Returns next char, managing ascii and unicode plane 0 (0000-FFFF).
local function get_next_char(text, pos)
local msb = text:byte(pos)
-- 1 byte char, ascii equivalent codepoints
if msb < 0x80 then
return msb, pos + 1
-- Returns the unicode codepoint of the first char of the string
local function char_to_codepoint(str)
local bytes = get_char_bytes(str)
if bytes == 1 then
return str:byte(1)
elseif bytes == 2 then
return (str:byte(1) - 0xC2) * 0x40
+ 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
-- 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
-- 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 splits = text:split("\n")
if maxlines then
local lines = {}
for num = 1,maxlines do
lines[num] = splits[num]
end
return lines
else
return splits
end
local lines = {}
local pos = 1
repeat
local found = string.find(text, "\n", pos)
found = found or #text + 1
lines[#lines + 1] = string.sub(text, pos, found - 1)
pos = found + 1
until (maxlines and (#lines >= maxlines)) or (pos > (#text + 1))
return lines
end
--------------------------------------------------------------------------------
--- 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
minetest.log("error", "Font definition must be a table.")
minetest.log("error",
"[font_api] Font definition must be a table.")
return nil
end
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
end
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
end
if def.widths[0] == nil then
minetest.log("error",
"Font must have a char with codepoint 0 (=unknown char).")
minetest.log("error",
"[font_api] Font must have a char with codepoint 0 (=unknown char).")
return nil
end
local font = deep_copy(def)
local font = table.copy(def)
setmetatable(font, self)
self.__index = self
return font
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
-- @param char : codepoint of the char
-- @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
if self.widths[char] ~= nil then
return self.widths[char]
@ -134,13 +152,13 @@ end
-- @param nb_of_lines : number of text lines (default 1)
-- @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 > 0 then
return
return
(
(self.height or 0) +
(self.height or 0) +
(self.margintop or 0) +
(self.marginbottom or 0)
) * nb_of_lines +
@ -154,16 +172,14 @@ end
-- @param line Line of text which the width will be computed.
-- @return Text width
function font_api.Font:get_width(line)
local char
function Font:get_width(line)
local codepoint
local width = 0
local pos = 1
line = line or ''
-- TODO: Use iterator
while pos <= #line do
char, pos = get_next_char(line, pos)
width = width + self:get_char_width(char)
while line ~= "" do
codepoint, line = self:get_next_char(line)
width = width + self:get_char_width(codepoint)
end
return width
@ -176,30 +192,21 @@ end
-- @param y Vertical position of the line in texture
-- @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 char
local pos = 1
line = line or ''
-- TODO: Use iterator
while pos <= #line do
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
while line ~= '' do
codepoint, line = self:get_next_char(line)
-- 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..
string.format(":%d,%d=font_%s_%04x.png",
x, y, self.name, char)
x, y, self.name, codepoint)
end
x = x + self.widths[char]
x = x + self.widths[codepoint]
end
return texture
@ -215,13 +222,13 @@ end
-- @param color Color of the text (optional)
-- @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)
local texture = ""
local lines = {}
local textheight = 0
local y
-- Split text into lines (limited to maxlines fist lines)
for num, line in pairs(split_lines(text, maxlines)) do
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
end
end
y = y + (self.margintop or 0)
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
return texture
end

View File

@ -2,17 +2,60 @@ minetest.register_craft({
output = 'signs:wooden_right_sign',
recipe = {
{'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({
output = 'signs:paper_poster',
recipe = {
{'default:paper', 'default:paper', ''},
{'default:paper', 'default:paper', 'dye:black'},
{'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 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)
-- Title texture
local titletexture = font:make_text_texture(
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)
if not minetest.is_protected(pos, player:get_player_name()) and fields then
if formname == node.name.."@"..minetest.pos_to_string(pos)..":display" and
fields.edit then
if formname == node.name.."@"..minetest.pos_to_string(pos)..":display"
and fields.edit then
edit_poster(pos, node, player)
end
if formname == node.name.."@"..minetest.pos_to_string(pos)..":edit" and
(fields.write or fields.key_enter) then
if formname == node.name.."@"..minetest.pos_to_string(pos)..":edit"
and (fields.write or fields.key_enter) then
meta:set_string("display_text", fields.display_text)
meta:set_string("text", fields.text)
meta:set_string("infotext", "\""..fields.display_text
@ -98,10 +98,40 @@ display_api.register_display_entity("signs:display_text")
-- Sign models and registration
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 = {
depth = 1/16,
width = 14/16,
height = 7/16,
depth = 1/16, width = 14/16, height = 7/16,
entity_fields = {
right = -3/32,
size = { x = 12/16, y = 6/16 },
@ -111,19 +141,18 @@ local models = {
node_fields = {
description = S("Wooden direction sign"),
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',
on_place = signs_api.on_place_direction,
drawtype = "mesh",
mesh = "signs_dir_right.obj",
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}},
groups= { dig_immediate = 2 },
},
},
wooden_left_sign = {
depth = 1/16,
width = 14/16,
height = 7/16,
depth = 1/16, width = 14/16, height = 7/16,
entity_fields = {
right = 3/32,
size = { x = 12/16, y = 6/16 },
@ -133,20 +162,18 @@ local models = {
node_fields = {
description = S("Wooden direction sign"),
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',
drawtype = "mesh",
mesh = "signs_dir_left.obj",
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}},
groups = { not_in_creative_inventory = 1 },
groups = { not_in_creative_inventory = 1, dig_immediate = 2 },
drop = "signs:wooden_right_sign",
},
},
paper_poster = {
depth = 1/32,
width = 26/32,
height = 30/32,
depth = 1/32, width = 26/32, height = 30/32,
entity_fields = {
top = -11/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.png" },
inventory_image = "signs_poster_inventory.png",
groups= { dig_immediate = 3 },
on_construct = display_api.on_construct,
on_rightclick = display_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
@ -171,4 +227,3 @@ for name, model in pairs(models)
do
signs_api.register_sign("signs", name, model)
end

View File

@ -15,8 +15,8 @@
height="32px"
id="svg2985"
version="1.1"
inkscape:version="0.48.4 r9939"
sodipodi:docname="affiche.svg"
inkscape:version="0.92.3 (2405546, 2018-03-11)"
sodipodi:docname="poster.svg"
inkscape:export-filename="/home/pyrollo/dev/minetest-mods/signs/textures/signs_poster.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90">
@ -73,18 +73,18 @@
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="11.197802"
inkscape:cx="-4.798213"
inkscape:cy="9.6735437"
inkscape:current-layer="layer5"
inkscape:zoom="22.395604"
inkscape:cx="15.573035"
inkscape:cy="16.977299"
inkscape:current-layer="layer2"
showgrid="true"
inkscape:grid-bbox="true"
inkscape:document-units="px"
inkscape:window-width="1239"
inkscape:window-height="776"
inkscape:window-x="41"
inkscape:window-y="24"
inkscape:window-maximized="1"
inkscape:window-width="785"
inkscape:window-height="447"
inkscape:window-x="2459"
inkscape:window-y="340"
inkscape:window-maximized="0"
showguides="true"
inkscape:guide-bbox="true"
inkscape:object-paths="true">
@ -95,11 +95,13 @@
visible="true"
enabled="true"
snapvisiblegridlinesonly="true"
spacingx="0.5px"
spacingy="0.5px"
spacingx="0.5"
spacingy="0.5"
dotted="false"
color="#ff0000"
opacity="0.1254902" />
opacity="0.1254902"
originx="0"
originy="0" />
</sodipodi:namedview>
<metadata
id="metadata2990">
@ -109,7 +111,7 @@
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
<dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
@ -127,7 +129,7 @@
height="32.081406"
width="32.003735" />
<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"
width="32"
height="32"
@ -136,18 +138,22 @@
<flowRoot
xml:space="preserve"
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
id="flowRegion5630"><rect
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"
style="font-family:sans-serif"><rect
id="rect5632"
width="3.6625218"
height="4.6728725"
x="12.692533"
y="-10.876763" /></flowRegion><flowPara
id="flowPara5634" /></flowRoot> </g>
y="-10.876763"
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
inkscape:groupmode="layer"
id="layer4"
inkscape:label="Fond inv">
inkscape:label="Fond inv"
style="display:inline">
<image
style="display:inline"
y="-0.081405997"
@ -158,7 +164,7 @@
width="32.003735"
clip-path="url(#clipPath4132)" />
<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"
width="26"
height="30"
@ -175,260 +181,281 @@
transform="matrix(1,0,0,1.3429336,0,-1.0576018)">
<text
transform="scale(0.85711508,1.1667045)"
sodipodi:linespacing="125%"
id="text4138"
y="5.1426907"
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
y="5.1426907"
x="18.756834"
id="tspan4140"
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
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
id="layer1"
inkscape:label="Texte"
inkscape:groupmode="layer"
style="display:inline">
style="display:none">
<path
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"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
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"
inkscape:connector-curvature="0" />
<path
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"
inkscape:connector-curvature="0" />
<path
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"
inkscape:connector-curvature="0" />
<path
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"
inkscape:connector-curvature="0" />
<path
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"
inkscape:connector-curvature="0" />
<path
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"
inkscape:connector-curvature="0" />
<path
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"
inkscape:connector-curvature="0" />
<path
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"
inkscape:connector-curvature="0" />
<path
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"
inkscape:connector-curvature="0" />
<path
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"
inkscape:connector-curvature="0" />
<path
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"
inkscape:connector-curvature="0" />
<path
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"
inkscape:connector-curvature="0" />
<path
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"
inkscape:connector-curvature="0" />
<path
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"
inkscape:connector-curvature="0" />
<path
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"
inkscape:connector-curvature="0" />
<path
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"
inkscape:connector-curvature="0" />
<path
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"
inkscape:connector-curvature="0" />
<path
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"
inkscape:connector-curvature="0" />
<path
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"
inkscape:connector-curvature="0" />
<path
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"
inkscape:connector-curvature="0" />
<path
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"
inkscape:connector-curvature="0" />
<path
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"
inkscape:connector-curvature="0" />
<path
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"
inkscape:connector-curvature="0" />
<path
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"
inkscape:connector-curvature="0" />
<path
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"
inkscape:connector-curvature="0" />
<path
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"
inkscape:connector-curvature="0" />
<path
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"
inkscape:connector-curvature="0" />
<path
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"
inkscape:connector-curvature="0" />
<path
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"
inkscape:connector-curvature="0" />
<path
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"
inkscape:connector-curvature="0" />
<path
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"
inkscape:connector-curvature="0" />
<path
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"
inkscape:connector-curvature="0" />
<path
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"
inkscape:connector-curvature="0" />
<path
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"
inkscape:connector-curvature="0" />
<path
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"
inkscape:connector-curvature="0" />
<path
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"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
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"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
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"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
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"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
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"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
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"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
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"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
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"
inkscape:connector-curvature="0" />
<path
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"
inkscape:connector-curvature="0" />
<path
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"
inkscape:connector-curvature="0" />
</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

@ -132,18 +132,19 @@ function signs_api.on_place_direction(itemstack, placer, pointed_thing)
end
-- 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)
if mode == 2 then
local ndef = minetest.registered_nodes[node.name]
if ndef.signs_other_dir then
minetest.swap_node(pos, {name = ndef.signs_other_dir,
param1 = node.param1, param2 = node.param2})
if ndef.signs_other_dir then
minetest.swap_node(pos, {name = ndef.signs_other_dir,
param1 = node.param1, param2 = node.param2})
display_api.update_entities(pos)
end
else
display_api.on_rotate(pos, node, user, mode, new_param2)
return true
end
end
return false;
return display_api.on_rotate(pos, node, user, mode, new_param2)
end
function signs_api.register_sign(mod, name, model)

View File

@ -189,7 +189,7 @@ local models = {
drawtype = "mesh",
mesh = "signs_dir_right.obj",
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 = {
@ -237,7 +237,7 @@ local models = {
drawtype = "mesh",
mesh = "signs_dir_right.obj",
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 = {
@ -285,7 +285,7 @@ local models = {
drawtype = "mesh",
mesh = "signs_dir_right.obj",
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 = {

View File

@ -59,7 +59,7 @@ for i, material in ipairs(steles.materials) do
},
on_place = function(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,
on_construct = function(pos)
local meta = minetest.get_meta(pos)