From a71ae8e01314d0653f785a022a898636cdf54424 Mon Sep 17 00:00:00 2001 From: Pierre-Yves Rollo Date: Sat, 13 Jan 2018 12:38:55 +0100 Subject: Version 1.0 --- signs/README.md | 2 +- signs/nodes.lua | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'signs') diff --git a/signs/README.md b/signs/README.md index 9e678de..0282d2e 100644 --- a/signs/README.md +++ b/signs/README.md @@ -2,7 +2,7 @@ This mod provides various signs with text display. Text is locked if area is protected. -For more information, see the [forum topic](https://forum.minetest.net/viewtopic.php?f=11&t=13563) at the Minetest forums. +For more information, see the [forum topic](https://forum.minetest.net/viewtopic.php?t=19365) at the Minetest forums. **Dependancies**: default, display\_lib, font\_lib diff --git a/signs/nodes.lua b/signs/nodes.lua index 2b8ab66..926d6e3 100644 --- a/signs/nodes.lua +++ b/signs/nodes.lua @@ -104,7 +104,7 @@ local models = { entity_fields = { right = -3/32, size = { x = 12/16, y = 6/16 }, - resolution = { x = 112, y = 64 }, + resolution = { x = 9, y = 5 }, maxlines = 2, color="#000", }, @@ -127,7 +127,7 @@ local models = { entity_fields = { right = 3/32, size = { x = 12/16, y = 6/16 }, - resolution = { x = 112, y = 64 }, + resolution = { x = 9, y = 5 }, maxlines = 2, color = "#000", }, @@ -149,7 +149,7 @@ local models = { width = 26/32, height = 30/32, entity_fields = { - resolution = { x = 144, y = 64 }, + resolution = { x = 11, y = 5 }, maxlines = 1, color="#000", valign="top", -- cgit v1.2.3 From ea36ed50d886677c79ec7ddf056c9815f040835e Mon Sep 17 00:00:00 2001 From: Pierre-Yves Rollo Date: Thu, 18 Jan 2018 21:46:10 +0100 Subject: Added display_lib.entity_spacing variable to centralize entity spacing. --- display_lib/init.lua | 5 +++++ signs/common.lua | 2 +- steles/nodes.lua | 2 +- 3 files changed, 7 insertions(+), 2 deletions(-) (limited to 'signs') diff --git a/display_lib/init.lua b/display_lib/init.lua index 210aac9..59a8529 100644 --- a/display_lib/init.lua +++ b/display_lib/init.lua @@ -19,6 +19,11 @@ display_lib = {} +-- Prefered gap between node and entity +-- Entity positionment is up to mods but it is a good practice to use this +-- variable as spacing between entity and node +display_lib.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 diff --git a/signs/common.lua b/signs/common.lua index 49c6dd4..b49716e 100644 --- a/signs/common.lua +++ b/signs/common.lua @@ -158,7 +158,7 @@ function signs.register_sign(mod, name, model) display_entities = { ["signs:display_text"] = { on_display_update = font_lib.on_display_update, - depth = 0.499 - model.depth, + depth = 0.5 - display_lib.entity_spacing - model.depth, size = { x = model.width, y = model.height }, resolution = { x = 64, y = 64 }, maxlines = 1, diff --git a/steles/nodes.lua b/steles/nodes.lua index 87f4e9b..5dba981 100644 --- a/steles/nodes.lua +++ b/steles/nodes.lua @@ -59,7 +59,7 @@ for i, material in ipairs(steles.materials) do display_entities = { ["steles:text"] = { on_display_update = font_lib.on_display_update, - depth = -2/16-0.001, height = 2/16, + depth = -2/16 - display_lib.entity_spacing, height = 2/16, size = { x = 14/16, y = 12/16 }, resolution = { x = 11, y = 5 }, maxlines = 3, -- cgit v1.2.3 From 1c1be8a7c13cb664551503b88516c75b189aed87 Mon Sep 17 00:00:00 2001 From: Thomas--S Date: Sat, 27 Jan 2018 17:40:42 +0100 Subject: Update the entities as soon as mapblock is loaded Useful e.g. after /clearobjects Introduces the group `display_lib_node` --- display_lib/API.md | 2 ++ display_lib/init.lua | 8 +++++++- ontime_clocks/nodes.lua | 12 ++++++------ signs/common.lua | 2 +- steles/nodes.lua | 4 +++- 5 files changed, 19 insertions(+), 9 deletions(-) (limited to 'signs') diff --git a/display_lib/API.md b/display_lib/API.md index 148db60..de08090 100644 --- a/display_lib/API.md +++ b/display_lib/API.md @@ -80,4 +80,6 @@ This is a helper to register entities used for display. }) +**Note:** Nodes in the `display_lib_node` group will have their entities updated as soon as the mapblock is loaded (Useful after /clearobjects). + diff --git a/display_lib/init.lua b/display_lib/init.lua index 59a8529..11ed60e 100644 --- a/display_lib/init.lua +++ b/display_lib/init.lua @@ -230,5 +230,11 @@ function display_lib.register_display_entity(entity_name) end end - +minetest.register_lbm({ + label = "Update display_lib entities", + name = "display_lib:update_entities", + run_at_every_load = true, + nodenames = {"group:display_lib_node"}, + action = function(pos, node) display_lib.update_entities(pos) end, +}) diff --git a/ontime_clocks/nodes.lua b/ontime_clocks/nodes.lua index 70bbfd1..d8007e8 100644 --- a/ontime_clocks/nodes.lua +++ b/ontime_clocks/nodes.lua @@ -35,7 +35,7 @@ minetest.register_node("ontime_clocks:green_digital", { wall_top = { -0.5, -0.5, -0.5, 0.5, 0.5, 0.5 } }, tiles = {"ontime_clocks_digital.png"}, - groups = {oddly_breakable_by_hand=1,not_blocking_trains=1}, + groups = {oddly_breakable_by_hand = 1, not_blocking_trains = 1, display_lib_node = 1}, display_entities = { ["ontime_clocks:display"] = { depth = 13/32 - 0.01, @@ -73,7 +73,7 @@ minetest.register_node("ontime_clocks:red_digital", { wall_top = { -0.5, -0.5, -0.5, 0.5, 0.5, 0.5 } }, tiles = {"ontime_clocks_digital.png"}, - groups = {oddly_breakable_by_hand=1,not_blocking_trains=1}, + groups = {oddly_breakable_by_hand = 1, not_blocking_trains = 1, display_lib_node = 1}, display_entities = { ["ontime_clocks:display"] = { depth = 13/32 - 0.01, @@ -111,7 +111,7 @@ minetest.register_node("ontime_clocks:white", { wall_top = { -7/16, 0.5, -7/16, 7/16, 7/16, 7/16}, }, tiles = {"ontime_clocks_white.png"}, - groups = {choppy=1,oddly_breakable_by_hand=1,not_blocking_trains=1}, + groups = {choppy = 1, oddly_breakable_by_hand = 1, not_blocking_trains = 1, display_lib_node = 1}, display_entities = { ["ontime_clocks:display"] = { depth = 6/16 - 0.01, @@ -148,7 +148,7 @@ minetest.register_node("ontime_clocks:frameless_black", { wall_top = { -0.5, -0.5, -0.5, 0.5, 0.5, 0.5 } }, tiles = {"ontime_clocks_frameless.png"}, - groups = {choppy=1,oddly_breakable_by_hand=1,not_blocking_trains=1}, + groups = {choppy = 1, oddly_breakable_by_hand = 1, not_blocking_trains = 1, display_lib_node = 1}, display_entities = { ["ontime_clocks:display"] = { depth = 7/16, @@ -185,7 +185,7 @@ minetest.register_node("ontime_clocks:frameless_gold", { wall_top = { -0.5, -0.5, -0.5, 0.5, 0.5, 0.5 } }, tiles = {"ontime_clocks_frameless.png^[colorize:#FF0"}, - groups = {choppy=1,oddly_breakable_by_hand=1,not_blocking_trains=1}, + groups = {choppy = 1, oddly_breakable_by_hand = 1, not_blocking_trains = 1, display_lib_node = 1}, display_entities = { ["ontime_clocks:display"] = { depth = 7/16, @@ -222,7 +222,7 @@ minetest.register_node("ontime_clocks:frameless_white", { wall_top = { -0.5, -0.5, -0.5, 0.5, 0.5, 0.5 } }, tiles = {"ontime_clocks_frameless.png^[colorize:#FFF"}, - groups = {choppy=1,oddly_breakable_by_hand=1,not_blocking_trains=1}, + groups = {choppy = 1, oddly_breakable_by_hand = 1, not_blocking_trains = 1, display_lib_node = 1}, display_entities = { ["ontime_clocks:display"] = { depth = 7/16, diff --git a/signs/common.lua b/signs/common.lua index b49716e..8e899ef 100644 --- a/signs/common.lua +++ b/signs/common.lua @@ -153,7 +153,7 @@ function signs.register_sign(mod, name, model) fixed = {-model.width/2, -model.height/2, 0.5, model.width/2, model.height/2, 0.5 - model.depth}, }, - groups = {choppy=2, dig_immediate=2, not_blocking_trains = 1}, + groups = {choppy=2, dig_immediate=2, not_blocking_trains = 1, display_lib_node = 1}, sounds = default.node_sound_defaults(), display_entities = { ["signs:display_text"] = { diff --git a/steles/nodes.lua b/steles/nodes.lua index 7bad5ae..80995c2 100644 --- a/steles/nodes.lua +++ b/steles/nodes.lua @@ -26,6 +26,8 @@ display_lib.register_display_entity("steles:text") for i, material in ipairs(steles.materials) do local ndef = minetest.registered_nodes[material] + local groups = table.copy(ndef.groups) + groups.display_lib_node = 1 if ndef then local parts = material:split(":") @@ -44,7 +46,7 @@ for i, material in ipairs(steles.materials) do {-7/16, -0.5, -4/16, 7/16, -4/16, 4/16} } }, - groups = ndef.groups, + groups = groups, display_entities = { ["steles:text"] = { on_display_update = font_lib.on_display_update, -- cgit v1.2.3 From 60e80180c61ad2d851a6f6794c73b5b3b6d002b8 Mon Sep 17 00:00:00 2001 From: Pierre-Yves Rollo Date: Sun, 28 Jan 2018 19:08:07 +0100 Subject: Copyright notices update --- display_lib/copyright.txt | 4 +++- font_lib/copyright.txt | 3 ++- ontime_clocks/copyright.txt | 8 ++++++-- signs/copyright.txt | 10 ++++++++-- signs_road/copyright.txt | 10 +++++++--- steles/copyright.txt | 8 ++++++++ 6 files changed, 34 insertions(+), 9 deletions(-) (limited to 'signs') diff --git a/display_lib/copyright.txt b/display_lib/copyright.txt index 5d4adad..e3a15e9 100644 --- a/display_lib/copyright.txt +++ b/display_lib/copyright.txt @@ -1,2 +1,4 @@ Code by Pierre-Yves Rollo (pyrollo) - +Contributors: +(gpcf): Compatibility with signs lib +(Thomas--S): Fix /clearobjects bug diff --git a/font_lib/copyright.txt b/font_lib/copyright.txt index eb0ec6a..ceb5446 100644 --- a/font_lib/copyright.txt +++ b/font_lib/copyright.txt @@ -1,2 +1,3 @@ Code by Pierre-Yves Rollo (pyrollo) -Textures by Vanessa Ezekowitz (VanessaE) +Contributors: +Andrzej Pieńkowski (apienk): Unicode support and tool for creating texturess diff --git a/ontime_clocks/copyright.txt b/ontime_clocks/copyright.txt index b752dff..a2afd94 100644 --- a/ontime_clocks/copyright.txt +++ b/ontime_clocks/copyright.txt @@ -1,4 +1,8 @@ Code, Textures and Models by Pierre-Yves Rollo (pyrollo) -intllib support (i18n) by fat115 +intllib support (i18n) by (fat115) intllib fallback code and tools by Diego Martínez (kaeza) - +Extra contibutors: +(Thomas--S) +Translations: +Muhammad Nur Hidayat Yasuyoshi (MuhdNurHidayat) +(fat115) diff --git a/signs/copyright.txt b/signs/copyright.txt index d6f87c4..9e3b294 100644 --- a/signs/copyright.txt +++ b/signs/copyright.txt @@ -1,4 +1,10 @@ Code, Textures and Models by Pierre-Yves Rollo (pyrollo) -intllib support (i18n) by fat115 +intllib support (i18n) by (fat115) intllib fallback code and tools by Diego Martínez (kaeza) -Extra contributors : (gpcf) +Extra contributors: +(gpcf) +(Thomas--S) +Translations: +Muhammad Nur Hidayat Yasuyoshi (MuhdNurHidayat) +(fat115) + diff --git a/signs_road/copyright.txt b/signs_road/copyright.txt index c53bf3d..bb7adc8 100644 --- a/signs_road/copyright.txt +++ b/signs_road/copyright.txt @@ -1,5 +1,9 @@ Code, Textures and Models by Pierre-Yves Rollo (pyrollo) -intllib support (i18n) by fat115 +intllib support (i18n) by (fat115) intllib fallback code and tools by Diego Martínez (kaeza) -Extra contributors : (gpcf) - +Extra contributors: +(gpcf) +(Thomas--S) +Translations: +Muhammad Nur Hidayat Yasuyoshi (MuhdNurHidayat) +(fat115) diff --git a/steles/copyright.txt b/steles/copyright.txt index 63371e7..1a4e167 100644 --- a/steles/copyright.txt +++ b/steles/copyright.txt @@ -1 +1,9 @@ Code by Pierre-Yves Rollo +intllib support (i18n) by (fat115) +intllib fallback code and tools by Diego Martínez (kaeza) +Extra contibutors: +(Thomas--S) +Translations: +Muhammad Nur Hidayat Yasuyoshi (MuhdNurHidayat) +(fat115) + -- cgit v1.2.3 From 3483f34fa9ac7c537f2ccf1d52b52f147e736659 Mon Sep 17 00:00:00 2001 From: Thomas--S Date: Wed, 31 Jan 2018 21:13:03 +0100 Subject: Use default formspec style --- signs/common.lua | 2 ++ signs/nodes.lua | 1 + steles/nodes.lua | 1 + 3 files changed, 4 insertions(+) (limited to 'signs') diff --git a/signs/common.lua b/signs/common.lua index 8e899ef..3665ab5 100644 --- a/signs/common.lua +++ b/signs/common.lua @@ -37,6 +37,7 @@ function signs.set_formspec(pos) if maxlines == 1 then formspec = "size[6,3]".. + default.gui_bg .. default.gui_bg_img .. default.gui_slots .. "field[0.5,0.7;5.5,1;display_text;"..F("Text")..";${display_text}]".. "button_exit[2,2;2,1;ok;"..F("Write").."]" else @@ -46,6 +47,7 @@ function signs.set_formspec(pos) end formspec = "size[6,4]".. + default.gui_bg .. default.gui_bg_img .. default.gui_slots .. "textarea[0.5,0.7;5.5,2;display_text;"..F("Text")..""..extralabel..";${display_text}]".. "button_exit[2,3;2,1;ok;"..F("Write").."]" end diff --git a/signs/nodes.lua b/signs/nodes.lua index 926d6e3..354bfd6 100644 --- a/signs/nodes.lua +++ b/signs/nodes.lua @@ -59,6 +59,7 @@ local function edit_poster(pos, node, player) if not minetest.is_protected(pos, player:get_player_name()) then formspec = "size[6.5,7.5]".. + default.gui_bg .. default.gui_bg_img .. default.gui_slots .. "field[0.5,0.7;6,1;display_text;"..F("Title")..";".. minetest.formspec_escape(meta:get_string("display_text")).."]".. "textarea[0.5,1.7;6,6;text;"..F("Text")..";".. diff --git a/steles/nodes.lua b/steles/nodes.lua index 80995c2..4eff56f 100644 --- a/steles/nodes.lua +++ b/steles/nodes.lua @@ -63,6 +63,7 @@ for i, material in ipairs(steles.materials) do on_construct = function(pos) local meta = minetest.get_meta(pos) meta:set_string("formspec", "size[6,4]" + ..default.gui_bg .. default.gui_bg_img .. default.gui_slots .."textarea[0.5,0.7;5.5,2;display_text;" ..F("Displayed text (3 lines max)") ..";${display_text}]" -- cgit v1.2.3 From f3970f641eb60bf92492b6715084273cc1bceb74 Mon Sep 17 00:00:00 2001 From: Thomas--S Date: Thu, 1 Feb 2018 16:54:55 +0100 Subject: Seperate signs API from signs definitions Change modnames from *_lib to *_api --- README.md | 5 +- display_api/API.md | 91 ++++++++++ display_api/LICENSE.txt | 166 +++++++++++++++++ display_api/README.md | 14 ++ display_api/copyright.txt | 4 + display_api/depends.txt | 0 display_api/init.lua | 242 ++++++++++++++++++++++++ display_lib/API.md | 91 ---------- display_lib/LICENSE.txt | 166 ----------------- display_lib/README.md | 14 -- display_lib/copyright.txt | 4 - display_lib/depends.txt | 0 display_lib/init.lua | 240 ------------------------ font_api/API.md | 110 +++++++++++ font_api/LICENSE.txt | 166 +++++++++++++++++ font_api/README.md | 14 ++ font_api/copyright.txt | 3 + font_api/depends.txt | 0 font_api/init.lua | 343 +++++++++++++++++++++++++++++++++++ font_api/settingtypes.txt | 1 + font_api/tools/make_font_lua.sh | 56 ++++++ font_api/tools/make_font_textures.sh | 111 ++++++++++++ font_epilepsy/README.md | 4 +- font_epilepsy/depends.txt | 2 +- font_epilepsy/init.lua | 2 +- font_lib/API.md | 110 ----------- font_lib/LICENSE.txt | 166 ----------------- font_lib/README.md | 14 -- font_lib/copyright.txt | 3 - font_lib/depends.txt | 0 font_lib/init.lua | 340 ---------------------------------- font_lib/settingtypes.txt | 1 - font_lib/tools/make_font_lua.sh | 56 ------ font_lib/tools/make_font_textures.sh | 111 ------------ ontime_clocks/README.md | 2 +- ontime_clocks/common.lua | 2 +- ontime_clocks/depends.txt | 2 +- ontime_clocks/nodes.lua | 72 ++++---- signs/common.lua | 173 +++--------------- signs/compatibility.lua | 6 +- signs/depends.txt | 5 +- signs/nodes.lua | 28 +-- signs_api/LICENSE.txt | 166 +++++++++++++++++ signs_api/README.md | 29 +++ signs_api/common.lua | 188 +++++++++++++++++++ signs_api/copyright.txt | 10 + signs_api/depends.txt | 4 + signs_api/init.lua | 33 ++++ signs_api/intllib.lua | 45 +++++ signs_api/locale/fr.po | 49 +++++ signs_api/locale/ms.po | 46 +++++ signs_api/locale/template.pot | 31 ++++ signs_api/tools/updatepo.sh | 25 +++ signs_road/compatibility.lua | 6 +- signs_road/depends.txt | 6 +- signs_road/nodes.lua | 48 ++--- steles/depends.txt | 4 +- steles/nodes.lua | 20 +- 58 files changed, 2077 insertions(+), 1573 deletions(-) create mode 100644 display_api/API.md create mode 100644 display_api/LICENSE.txt create mode 100644 display_api/README.md create mode 100644 display_api/copyright.txt create mode 100644 display_api/depends.txt create mode 100644 display_api/init.lua delete mode 100644 display_lib/API.md delete mode 100644 display_lib/LICENSE.txt delete mode 100644 display_lib/README.md delete mode 100644 display_lib/copyright.txt delete mode 100644 display_lib/depends.txt delete mode 100644 display_lib/init.lua create mode 100644 font_api/API.md create mode 100644 font_api/LICENSE.txt create mode 100644 font_api/README.md create mode 100644 font_api/copyright.txt create mode 100644 font_api/depends.txt create mode 100644 font_api/init.lua create mode 100644 font_api/settingtypes.txt create mode 100755 font_api/tools/make_font_lua.sh create mode 100755 font_api/tools/make_font_textures.sh delete mode 100644 font_lib/API.md delete mode 100644 font_lib/LICENSE.txt delete mode 100644 font_lib/README.md delete mode 100644 font_lib/copyright.txt delete mode 100644 font_lib/depends.txt delete mode 100644 font_lib/init.lua delete mode 100644 font_lib/settingtypes.txt delete mode 100755 font_lib/tools/make_font_lua.sh delete mode 100755 font_lib/tools/make_font_textures.sh create mode 100644 signs_api/LICENSE.txt create mode 100644 signs_api/README.md create mode 100644 signs_api/common.lua create mode 100644 signs_api/copyright.txt create mode 100644 signs_api/depends.txt create mode 100644 signs_api/init.lua create mode 100644 signs_api/intllib.lua create mode 100644 signs_api/locale/fr.po create mode 100644 signs_api/locale/ms.po create mode 100644 signs_api/locale/template.pot create mode 100755 signs_api/tools/updatepo.sh (limited to 'signs') diff --git a/README.md b/README.md index def1949..f7f8146 100644 --- a/README.md +++ b/README.md @@ -2,9 +2,10 @@ This modpack provides mods with dynamic display. Mods are : -- **display_lib**: A library for adding display entities to nodes; -- **font_lib**: A library for displaying fonts on entities; +- **display_api**: A library for adding display entities to nodes; +- **font_api**: A library for displaying fonts on entities; - **ontime_clocks**: A mod providing clocks which display the ingame time; +- **signs_api**: A library for the easy creation of signs; - **signs**: A mod providing signs and direction signs displaying text; - **signs_road**: A mod providing road signs displaying text; - **steles**: A mod providing stone steles with text; diff --git a/display_api/API.md b/display_api/API.md new file mode 100644 index 0000000..b133c8a --- /dev/null +++ b/display_api/API.md @@ -0,0 +1,91 @@ +# Display Lib API +This document describes Display Lib API. Display Lib allows to add a dynamic display on a node. Display Lib limits node rotations. For wallmounted, only vertical positionning is available, and for facedir, only first four position are availabel (those with default axis). + +## Provided methods +### update\_entities +**display\_lib.update\_entities(pos)** + +This method triggers entities update for the display node at pos. Actual entity update is made by `on_display_update` callback associated to the entity. + +`pos`: Position of the node +### register\_display\_entity +**display\_lib.register\_display\_entity(entity_name)** + +This is a helper to register entities used for display. + +`entity_name`: Name of the entity to register. +## Provided callback implementations +### on_place +**display\_lib.on\_place(itemstack, placer, pointed\_thing)** + +`on_place` node callback implementation. Display nodes should have this callback (avoid placement of horizontal display node). +### on_construct +**display\_lib.on\_construct(pos)** + +`on_construct` node callback implementation. Display nodes should have this callback (creates, places and updates display entities on node construction). +### on_destruct +**display\_lib.on_destruct(pos)** + +`on_destruct` node callback implementation. Display nodes should have this callback (removes display entities on node destruction). +### on_rotate +**display\_lib.on\_rotate(pos, node, user, mode, new_param2)** + +`on_rotate` node callback implementation. Display nodes should have this callback (restricts rotations and rotates display entities associated with node). +### on_activate +**display\_lib.on_activate(entity, staticdata)** + +`On_activate` entity callback implementation for display entities. No need of this method if display entities have been registered using `register_display_entity` (callback is already set). + +## Howto register a display node +* Register display entities with `register_display_entity` + +* Register node with : + - `on_place`, `on_construct`, `on_destruct` and `on_rotate` callbacks using display_api callbacks. +  + - `display_modpack_node` group. This will make this node have their entities updated as soon as the mapblock is loaded (Useful after /clearobjects). +  + - a `display_entities` field in node definition containing a entity name indexed table. See below for description of each display_entities fields. + +### Display_entities fields +`on_display_update` is a callback in charge of setting up entity texture. If not set, entity will have no texture and will be displayed as unknown item. + +`depth`, `right` and `heigh` : Entity position regarding to node facedir/wallmounted main axis. Values for these fields can be any number between -0.5 and 0.5 (default value is 0). Position 0,0,0 is the center of the node. `depth` goes from front (-0.5) to rear (0.5), `height` goes from bottom (-0.5) to top (0.5) and `right` goes from left (-0.5) to right (0.5). + +In order to avoid flickering text, it's better to have text a little behind node surface. A good spacing value is given by `display_api.entity_spacing` variable. + +### Example + + display_api.register_display_entity("mymod:entity1") + display_api.register_display_entity("mymod:entity2") + + function my_display_update1(pos, objref) + objref:set_properties({ textures= {"mytexture1.png"}, + visual_size = {x=1, y=1} }) + end + + function my_display_update2(pos, objref) + objref:set_properties({ textures= {"mytexture2.png"}, +                         visual_size = {x=1, y=1} }) + end + + minetest.register_node("mymod:test_display_node", { + ... + paramtype2 = "facedir", + ... + groups = { display_modpack_node = 1, ... }, + ... + display_entities = { + ["mymod:entity1"] = { + depth = 0.3, + on_display_update = my_display_update1 }, + ["mymod:entity1"] = { + depth = 0.2, height = 0.1, + on_display_update = my_display_update2 }, + }, + ... + on_place = display_api.on_place, + on_construct = display_api.on_construct, + on_destruct = display_api.on_destruct, + on_rotate = display_api.on_rotate, + ... + }) diff --git a/display_api/LICENSE.txt b/display_api/LICENSE.txt new file mode 100644 index 0000000..341c30b --- /dev/null +++ b/display_api/LICENSE.txt @@ -0,0 +1,166 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. + diff --git a/display_api/README.md b/display_api/README.md new file mode 100644 index 0000000..f51996d --- /dev/null +++ b/display_api/README.md @@ -0,0 +1,14 @@ +# Display Lib + +This library's purpose is to ease creation of nodes with one or more displays on sides. For example, signs and clocks. Display can be dynamic and/or different for each node instance. + +**Limitations**: This lib uses entities to draw display. This means display has to be vertical. So display nodes rotation are limitated to "upside up" positions. + +**Dependancies**:default + +**License**: LPGL + +**API**: See [API.md](https://github.com/pyrollo/display_modpack/blob/master/display_api/API.md) document please. + +For more information, see the [forum topic](https://forum.minetest.net/viewtopic.php?t=19365) at the Minetest forums. + diff --git a/display_api/copyright.txt b/display_api/copyright.txt new file mode 100644 index 0000000..e3a15e9 --- /dev/null +++ b/display_api/copyright.txt @@ -0,0 +1,4 @@ +Code by Pierre-Yves Rollo (pyrollo) +Contributors: +(gpcf): Compatibility with signs lib +(Thomas--S): Fix /clearobjects bug diff --git a/display_api/depends.txt b/display_api/depends.txt new file mode 100644 index 0000000..e69de29 diff --git a/display_api/init.lua b/display_api/init.lua new file mode 100644 index 0000000..7439119 --- /dev/null +++ b/display_api/init.lua @@ -0,0 +1,242 @@ +--[[ + display_api mod for Minetest - Library to add dynamic display + capabilities to nodes + (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 . +--]] + +display_api = {} + +-- Prefered gap between node and entity +-- Entity positionment is up to mods but it is a good practice to use this +-- variable as spacing between entity and node +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} +} + +-- 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}, + } + +-- 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] + end + end +end + +--- Gets the display entities attached with a node. Removes extra ones +local function get_entities(pos) + local objrefs = {} + local ndef = minetest.registered_nodes[minetest.get_node(pos).name] + if ndef and ndef.display_entities then + for _, objref in ipairs(minetest.get_objects_inside_radius(pos, 0.5)) do + local entity = objref:get_luaentity() + if entity and ndef.display_entities[entity.name] then + if objrefs[entity.name] then + objref:remove() + else + objrefs[entity.name] = objref + end + end + end + end + return objrefs +end + +local function clip_pos_prop(posprop) + if posprop then + return math.max(-0.5, math.min(0.5, posprop)) + else + return 0 + end +end + +--- (Create and) place display entities according to the node orientation +local function place_entities(pos) + local node = minetest.get_node(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 height = clip_pos_prop(props.height) + local right = clip_pos_prop(props.right) + 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 + height, + z = pos.z - values.dz * depth + values.rz * right}) + + objrefs[entity_name]:setyaw(values.yaw) + end + end + return objrefs +end + +--- Call on_display_update callback of a node for one of its display entities +local function call_node_on_display_update(pos, objref) + local ndef = minetest.registered_nodes[minetest.get_node(pos).name] + 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 + +--- Force entity update +function display_api.update_entities(pos) + local objrefs = place_entities(pos) + for _, objref in pairs(objrefs) do + call_node_on_display_update(pos, objref) + end +end + +--- On_activate callback for display_api entities. Calls on_display_update callbacks +--- of corresponding node for each entity. +function display_api.on_activate(entity, staticdata) + if entity then + entity.object:set_armor_groups({immortal=1}) + call_node_on_display_update(entity.object:getpos(), entity.object) + end +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) + 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} + + 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)) + end + end + +end + +--- On_construct callback for display_api items. Creates entities and update them. +function display_api.on_construct(pos) + display_api.update_entities(pos) +end + +--- On_destruct callback for display_api items. Removes entities. +function display_api.on_destruct(pos) + local objrefs = get_entities(pos) + + for _, objref in pairs(objrefs) do + objref:remove() + 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}) + place_entities(pos) + return true + else + return false + end +end + +--- Creates display entity with some fields and the on_activate callback +function display_api.register_display_entity(entity_name) + if not minetest.registered_entity then + minetest.register_entity(':'..entity_name, { + collisionbox = { 0, 0, 0, 0, 0, 0 }, + visual = "upright_sprite", + textures = {}, + on_activate = display_api.on_activate, + }) + end +end + +minetest.register_lbm({ + label = "Update display_api entities", + name = "display_api:update_entities", + run_at_every_load = true, + nodenames = {"group:display_modpack_node", "group:display_lib_node"}, + action = function(pos, node) display_api.update_entities(pos) end, +}) + +-- Compatibility +display_lib = display_api \ No newline at end of file diff --git a/display_lib/API.md b/display_lib/API.md deleted file mode 100644 index 5c05999..0000000 --- a/display_lib/API.md +++ /dev/null @@ -1,91 +0,0 @@ -# Display Lib API -This document describes Display Lib API. Display Lib allows to add a dynamic display on a node. Display Lib limits node rotations. For wallmounted, only vertical positionning is available, and for facedir, only first four position are availabel (those with default axis). - -## Provided methods -### update\_entities -**display\_lib.update\_entities(pos)** - -This method triggers entities update for the display node at pos. Actual entity update is made by `on_display_update` callback associated to the entity. - -`pos`: Position of the node -### register\_display\_entity -**display\_lib.register\_display\_entity(entity_name)** - -This is a helper to register entities used for display. - -`entity_name`: Name of the entity to register. -## Provided callback implementations -### on_place -**display\_lib.on\_place(itemstack, placer, pointed\_thing)** - -`on_place` node callback implementation. Display nodes should have this callback (avoid placement of horizontal display node). -### on_construct -**display\_lib.on\_construct(pos)** - -`on_construct` node callback implementation. Display nodes should have this callback (creates, places and updates display entities on node construction). -### on_destruct -**display\_lib.on_destruct(pos)** - -`on_destruct` node callback implementation. Display nodes should have this callback (removes display entities on node destruction). -### on_rotate -**display\_lib.on\_rotate(pos, node, user, mode, new_param2)** - -`on_rotate` node callback implementation. Display nodes should have this callback (restricts rotations and rotates display entities associated with node). -### on_activate -**display\_lib.on_activate(entity, staticdata)** - -`On_activate` entity callback implementation for display entities. No need of this method if display entities have been registered using `register_display_entity` (callback is already set). - -## Howto register a display node -* Register display entities with `register_display_entity` - -* Register node with : - - `on_place`, `on_construct`, `on_destruct` and `on_rotate` callbacks using display_lib callbacks. -  - - `display_lib_node` group. This will make this node have their entities updated as soon as the mapblock is loaded (Useful after /clearobjects). -  - - a `display_entities` field in node definition containing a entity name indexed table. See below for description of each display_entities fields. - -### Display_entities fields -`on_display_update` is a callback in charge of setting up entity texture. If not set, entity will have no texture and will be displayed as unknown item. - -`depth`, `right` and `heigh` : Entity position regarding to node facedir/wallmounted main axis. Values for these fields can be any number between -0.5 and 0.5 (default value is 0). Position 0,0,0 is the center of the node. `depth` goes from front (-0.5) to rear (0.5), `height` goes from bottom (-0.5) to top (0.5) and `right` goes from left (-0.5) to right (0.5). - -In order to avoid flickering text, it's better to have text a little behind node surface. A good spacing value is given by `display_lib.entity_spacing` variable. - -### Example - - display_lib.register_display_entity("mymod:entity1") - display_lib.register_display_entity("mymod:entity2") - - function my_display_update1(pos, objref) - objref:set_properties({ textures= {"mytexture1.png"}, - visual_size = {x=1, y=1} }) - end - - function my_display_update2(pos, objref) - objref:set_properties({ textures= {"mytexture2.png"}, -                         visual_size = {x=1, y=1} }) - end - - minetest.register_node("mymod:test_display_node", { - ... - paramtype2 = "facedir", - ... - groups = { display_lib_node = 1, ... }, - ... - display_entities = { - ["mymod:entity1"] = { - depth = 0.3, - on_display_update = my_display_update1 }, - ["mymod:entity1"] = { - depth = 0.2, height = 0.1, - on_display_update = my_display_update2 }, - }, - ... - on_place = display_lib.on_place, - on_construct = display_lib.on_construct, - on_destruct = display_lib.on_destruct, - on_rotate = display_lib.on_rotate, - ... - }) diff --git a/display_lib/LICENSE.txt b/display_lib/LICENSE.txt deleted file mode 100644 index 341c30b..0000000 --- a/display_lib/LICENSE.txt +++ /dev/null @@ -1,166 +0,0 @@ - GNU LESSER GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - - This version of the GNU Lesser General Public License incorporates -the terms and conditions of version 3 of the GNU General Public -License, supplemented by the additional permissions listed below. - - 0. Additional Definitions. - - As used herein, "this License" refers to version 3 of the GNU Lesser -General Public License, and the "GNU GPL" refers to version 3 of the GNU -General Public License. - - "The Library" refers to a covered work governed by this License, -other than an Application or a Combined Work as defined below. - - An "Application" is any work that makes use of an interface provided -by the Library, but which is not otherwise based on the Library. -Defining a subclass of a class defined by the Library is deemed a mode -of using an interface provided by the Library. - - A "Combined Work" is a work produced by combining or linking an -Application with the Library. The particular version of the Library -with which the Combined Work was made is also called the "Linked -Version". - - The "Minimal Corresponding Source" for a Combined Work means the -Corresponding Source for the Combined Work, excluding any source code -for portions of the Combined Work that, considered in isolation, are -based on the Application, and not on the Linked Version. - - The "Corresponding Application Code" for a Combined Work means the -object code and/or source code for the Application, including any data -and utility programs needed for reproducing the Combined Work from the -Application, but excluding the System Libraries of the Combined Work. - - 1. Exception to Section 3 of the GNU GPL. - - You may convey a covered work under sections 3 and 4 of this License -without being bound by section 3 of the GNU GPL. - - 2. Conveying Modified Versions. - - If you modify a copy of the Library, and, in your modifications, a -facility refers to a function or data to be supplied by an Application -that uses the facility (other than as an argument passed when the -facility is invoked), then you may convey a copy of the modified -version: - - a) under this License, provided that you make a good faith effort to - ensure that, in the event an Application does not supply the - function or data, the facility still operates, and performs - whatever part of its purpose remains meaningful, or - - b) under the GNU GPL, with none of the additional permissions of - this License applicable to that copy. - - 3. Object Code Incorporating Material from Library Header Files. - - The object code form of an Application may incorporate material from -a header file that is part of the Library. You may convey such object -code under terms of your choice, provided that, if the incorporated -material is not limited to numerical parameters, data structure -layouts and accessors, or small macros, inline functions and templates -(ten or fewer lines in length), you do both of the following: - - a) Give prominent notice with each copy of the object code that the - Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the object code with a copy of the GNU GPL and this license - document. - - 4. Combined Works. - - You may convey a Combined Work under terms of your choice that, -taken together, effectively do not restrict modification of the -portions of the Library contained in the Combined Work and reverse -engineering for debugging such modifications, if you also do each of -the following: - - a) Give prominent notice with each copy of the Combined Work that - the Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the Combined Work with a copy of the GNU GPL and this license - document. - - c) For a Combined Work that displays copyright notices during - execution, include the copyright notice for the Library among - these notices, as well as a reference directing the user to the - copies of the GNU GPL and this license document. - - d) Do one of the following: - - 0) Convey the Minimal Corresponding Source under the terms of this - License, and the Corresponding Application Code in a form - suitable for, and under terms that permit, the user to - recombine or relink the Application with a modified version of - the Linked Version to produce a modified Combined Work, in the - manner specified by section 6 of the GNU GPL for conveying - Corresponding Source. - - 1) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (a) uses at run time - a copy of the Library already present on the user's computer - system, and (b) will operate properly with a modified version - of the Library that is interface-compatible with the Linked - Version. - - e) Provide Installation Information, but only if you would otherwise - be required to provide such information under section 6 of the - GNU GPL, and only to the extent that such information is - necessary to install and execute a modified version of the - Combined Work produced by recombining or relinking the - Application with a modified version of the Linked Version. (If - you use option 4d0, the Installation Information must accompany - the Minimal Corresponding Source and Corresponding Application - Code. If you use option 4d1, you must provide the Installation - Information in the manner specified by section 6 of the GNU GPL - for conveying Corresponding Source.) - - 5. Combined Libraries. - - You may place library facilities that are a work based on the -Library side by side in a single library together with other library -facilities that are not Applications and are not covered by this -License, and convey such a combined library under terms of your -choice, if you do both of the following: - - a) Accompany the combined library with a copy of the same work based - on the Library, uncombined with any other library facilities, - conveyed under the terms of this License. - - b) Give prominent notice with the combined library that part of it - is a work based on the Library, and explaining where to find the - accompanying uncombined form of the same work. - - 6. Revised Versions of the GNU Lesser General Public License. - - The Free Software Foundation may publish revised and/or new versions -of the GNU Lesser General Public License from time to time. Such new -versions will be similar in spirit to the present version, but may -differ in detail to address new problems or concerns. - - Each version is given a distinguishing version number. If the -Library as you received it specifies that a certain numbered version -of the GNU Lesser General Public License "or any later version" -applies to it, you have the option of following the terms and -conditions either of that published version or of any later version -published by the Free Software Foundation. If the Library as you -received it does not specify a version number of the GNU Lesser -General Public License, you may choose any version of the GNU Lesser -General Public License ever published by the Free Software Foundation. - - If the Library as you received it specifies that a proxy can decide -whether future versions of the GNU Lesser General Public License shall -apply, that proxy's public statement of acceptance of any version is -permanent authorization for you to choose that version for the -Library. - diff --git a/display_lib/README.md b/display_lib/README.md deleted file mode 100644 index 88a39ee..0000000 --- a/display_lib/README.md +++ /dev/null @@ -1,14 +0,0 @@ -# Display Lib - -This library's purpose is to ease creation of nodes with one or more displays on sides. For example, signs and clocks. Display can be dynamic and/or different for each node instance. - -**Limitations**: This lib uses entities to draw display. This means display has to be vertical. So display nodes rotation are limitated to "upside up" positions. - -**Dependancies**:default - -**License**: LPGL - -**API**: See [API.md](https://github.com/pyrollo/display_modpack/blob/master/display_lib/API.md) document please. - -For more information, see the [forum topic](https://forum.minetest.net/viewtopic.php?t=19365) at the Minetest forums. - diff --git a/display_lib/copyright.txt b/display_lib/copyright.txt deleted file mode 100644 index e3a15e9..0000000 --- a/display_lib/copyright.txt +++ /dev/null @@ -1,4 +0,0 @@ -Code by Pierre-Yves Rollo (pyrollo) -Contributors: -(gpcf): Compatibility with signs lib -(Thomas--S): Fix /clearobjects bug diff --git a/display_lib/depends.txt b/display_lib/depends.txt deleted file mode 100644 index e69de29..0000000 diff --git a/display_lib/init.lua b/display_lib/init.lua deleted file mode 100644 index 11ed60e..0000000 --- a/display_lib/init.lua +++ /dev/null @@ -1,240 +0,0 @@ ---[[ - display_lib mod for Minetest - Library to add dynamic display - capabilities to nodes - (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 . ---]] - -display_lib = {} - --- Prefered gap between node and entity --- Entity positionment is up to mods but it is a good practice to use this --- variable as spacing between entity and node -display_lib.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} -} - --- 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}, - } - --- 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] - end - end -end - ---- Gets the display entities attached with a node. Removes extra ones -local function get_entities(pos) - local objrefs = {} - local ndef = minetest.registered_nodes[minetest.get_node(pos).name] - if ndef and ndef.display_entities then - for _, objref in ipairs(minetest.get_objects_inside_radius(pos, 0.5)) do - local entity = objref:get_luaentity() - if entity and ndef.display_entities[entity.name] then - if objrefs[entity.name] then - objref:remove() - else - objrefs[entity.name] = objref - end - end - end - end - return objrefs -end - -local function clip_pos_prop(posprop) - if posprop then - return math.max(-0.5, math.min(0.5, posprop)) - else - return 0 - end -end - ---- (Create and) place display entities according to the node orientation -local function place_entities(pos) - local node = minetest.get_node(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 height = clip_pos_prop(props.height) - local right = clip_pos_prop(props.right) - 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 + height, - z = pos.z - values.dz * depth + values.rz * right}) - - objrefs[entity_name]:setyaw(values.yaw) - end - end - return objrefs -end - ---- Call on_display_update callback of a node for one of its display entities -local function call_node_on_display_update(pos, objref) - local ndef = minetest.registered_nodes[minetest.get_node(pos).name] - 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 - ---- Force entity update -function display_lib.update_entities(pos) - local objrefs = place_entities(pos) - for _, objref in pairs(objrefs) do - call_node_on_display_update(pos, objref) - end -end - ---- On_activate callback for display_lib entities. Calls on_display_update callbacks ---- of corresponding node for each entity. -function display_lib.on_activate(entity, staticdata) - if entity then - entity.object:set_armor_groups({immortal=1}) - call_node_on_display_update(entity.object:getpos(), entity.object) - end -end - ---- On_place callback for display_lib items. Does nothing more than preventing item ---- from being placed on ceiling or ground -function display_lib.on_place(itemstack, placer, pointed_thing) - 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} - - 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)) - end - end - -end - ---- On_construct callback for display_lib items. Creates entities and update them. -function display_lib.on_construct(pos) - display_lib.update_entities(pos) -end - ---- On_destruct callback for display_lib items. Removes entities. -function display_lib.on_destruct(pos) - local objrefs = get_entities(pos) - - for _, objref in pairs(objrefs) do - objref:remove() - end -end - --- On_rotate (screwdriver) callback for display_lib items. Prevents axis rotation and reorients entities. -function display_lib.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}) - place_entities(pos) - return true - else - return false - end -end - ---- Creates display entity with some fields and the on_activate callback -function display_lib.register_display_entity(entity_name) - if not minetest.registered_entity then - minetest.register_entity(':'..entity_name, { - collisionbox = { 0, 0, 0, 0, 0, 0 }, - visual = "upright_sprite", - textures = {}, - on_activate = display_lib.on_activate, - }) - end -end - -minetest.register_lbm({ - label = "Update display_lib entities", - name = "display_lib:update_entities", - run_at_every_load = true, - nodenames = {"group:display_lib_node"}, - action = function(pos, node) display_lib.update_entities(pos) end, -}) - diff --git a/font_api/API.md b/font_api/API.md new file mode 100644 index 0000000..a4aee6d --- /dev/null +++ b/font_api/API.md @@ -0,0 +1,110 @@ +# Font Lib API +This document describes Font Lib API. Font Lib creates textures for font display on entities. + +## Settings +### default_font +Name of the font to be used when no font is given. The font should be registered. +If no default\_font given or if default\_font given but not registered, the first registered font will be used as default. + +## Provided methods +### get\_text\_size +**font\_lib.get\_text\_size(font\_name, text)** + +Computes size for a given font and text + +**font\_name**: Font name of registered font to use +**text**: Text to be rendered +**Returns**: rendered text width, height + +### make\_line\_texture +**font\_lib.make\_line\_texture(font\_name, text, width, x, y)** + +Builds texture part for a text line + +**font\_name**: Font name of registered font to use +**text**: Text to be rendered +**texturew**: Width of the texture (extra text is not rendered) +**x**: Starting x position in texture +**y**: Vertical position of the line in texture +**Returns**: Texture string + +### make\_multiline\_texture +**font\_lib.make\_multiline\_texture(font\_name, text, width, height, maxlines, halign, valign, color)** + +Builds texture for a multiline colored text + +**font\_name**: Font name of registered font to use +**text**: Text to be rendered +**texturew**: Width of the texture (extra text will be truncated) +**textureh**: Height of the texture +**maxlines**: Maximum number of lines +**halign**: Horizontal text align ("left", "right" or "center") (optional) +**valign**: Vertical text align ("top", "bottom" or "center") (optional) +**color**: Color of the text (optional) +**Returns**: Texture string + +### register\_font +**font\_lib.register_font(font\_name, height, widths)** + +Registers a new font in font_api. + +**font\_name**: Name of the font to register (this name will be used to address the font later) +If registering different sizes of the same font, add size in the font name (e.g. times\_10, times\_12...). +**height**: Font height in pixels (all font textures should have the same height) +**widths** : Array of character widths in pixels, indexed by UTF codepoints + +Font must have a char 0 which will be used to display any unknown char. + +All textures corresponding to the indexes in **widths** array should be present in textures directory with a name matching the pattern : + +**font\__.png** + +****: Name of the font as given in the first argument +****: UTF code of the char in 4 hexadecimal digits + +To ease that declaration, a shell is provided to build a .lua file from the texture files (see provided tools). + +## Provided tools + +Still in early stage of development, these tools are helpers to create font mods. + +### make_font_texture.sh + +This scripts takes a .ttf file as input and create one .png file per char, that can be used as font texture. Launch it from your future font mod directory. + +__Advice__ + +This script works much better with pixels font, providing the correct height. There is no antialiasing at all, vector fonts and bad heights gives very ugly results. + +__Syntax__ + +**make\_font\_texture.sh ** + +****: A TTF font file to use to create textures. +****: The font name to be used in font_api (should be simple, with no spaces). +****: Font height to be rendered. + +### make_font_lua.sh + +This script analyses textures in textures directory and creates a font\_.lua files with a call to register_font with images information. Launch it from your future font mod directory. + +Once the font\_.lua created, it can be included by a init.lua file or directly renamed to init.lua if you are creating a simple font mod. + +__Syntax__ + +**make\_font_lua.sh ** + +****: The font name to be used in font_api (same as given to make\_font\_texture.sh) + +### An exemple generating a font mod + + mkdir font_myfont + cd font_myfont + //tools/make_font_texture.sh myfont.ttf myfont 12 + //tools/make_font_lua.sh myfont + mv font_myfont.lua init.lua + + + + + diff --git a/font_api/LICENSE.txt b/font_api/LICENSE.txt new file mode 100644 index 0000000..341c30b --- /dev/null +++ b/font_api/LICENSE.txt @@ -0,0 +1,166 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. + diff --git a/font_api/README.md b/font_api/README.md new file mode 100644 index 0000000..c7ae64b --- /dev/null +++ b/font_api/README.md @@ -0,0 +1,14 @@ +# Font Lib + +This library for font display on entities (to be used with display_api for sign creation). + +**Dependancies**: default + +**License**: LGPL + +(Default font taken from VanessaE's homedecor/signs_lib, originally under WTFPL) + +**API**: See [API.md](https://github.com/pyrollo/display_modpack/blob/master/font_api/API.md) document please. + +For more information, see the [forum topic](https://forum.minetest.net/viewtopic.php?t=13563) at the Minetest forums. + diff --git a/font_api/copyright.txt b/font_api/copyright.txt new file mode 100644 index 0000000..ceb5446 --- /dev/null +++ b/font_api/copyright.txt @@ -0,0 +1,3 @@ +Code by Pierre-Yves Rollo (pyrollo) +Contributors: +Andrzej Pieńkowski (apienk): Unicode support and tool for creating texturess diff --git a/font_api/depends.txt b/font_api/depends.txt new file mode 100644 index 0000000..e69de29 diff --git a/font_api/init.lua b/font_api/init.lua new file mode 100644 index 0000000..f407f8b --- /dev/null +++ b/font_api/init.lua @@ -0,0 +1,343 @@ +--[[ + 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 . +--]] + +-- Global variables +------------------- + +font_api = {} +font_api.name = minetest.get_current_modname() +font_api.path = minetest.get_modpath(font_api.name) +font_api.registered_fonts = {} + +-- Local variables +------------------ + +local default_font = false + +-- Local functions +------------------ + +-- Split multiline text into array of lines, with maximum lines. + +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 +end + +-- Gets a default (settings or fist font) + +local function get_default_font() + -- First call + if default_font == false then + default_font = nil + + -- First, try with settings + local settings_font = minetest.settings:get("default_font") + + if settings_font ~= nil and settings_font ~= "" then + default_font = font_api.registered_fonts[settings_font] + + if default_font == nil then + minetest.log("warning", "Default font in settings (\"".. + settings_font.."\") is not registered.") + end + end + + -- If failed, choose first font + if default_font == nil then + for _, font in pairs(font_api.registered_fonts) do + default_font = font + break + end + end + + -- Error, no font registered + if default_font == nil then + minetest.log("error", + "No font registred, unable to choose a default font.") + end + end + + return default_font +end + +-- Returns font properties to be used according to font_name + +local function get_font(font_name) + local font = font_api.registered_fonts[font_name] + + if font == nil then + local message + + if font_name == nil then + message = "No font given" + else + message = "Font \""..font_name.."\" unregistered" + end + + font = get_default_font() + + if font ~= nil then + minetest.log("info", message..", using font \""..font.name.."\".") + end + end + + return font +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 + 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 + +-- API functions +---------------- + +-- Computes text size for a given font and text (ignores new lines) +-- @param font_name Font to be used +-- @param text Text to be rendered +-- @return Rendered text (width, height) + +function font_api.get_text_size(font_name, text) + local char + local width = 0 + local pos = 1 + local font = get_font(font_name) + + if font == nil then + return 0, 0 + else + while pos <= #text do + char, pos = get_next_char(text, pos) + -- Replace chars with no texture by the NULL(0) char + if font.widths[char] ~= nil then + width = width + font.widths[char] + else + width = width + font.widths[0] + end + end + end + + return width, font.height +end + +--- Builds texture part for a text line +-- @param font_name Font to be used +-- @param text Text to be rendered +-- @param width Width of the texture (extra text is not rendered) +-- @param x Starting x position in texture +-- @param y Vertical position of the line in texture +-- @return Texture string + +function font_api.make_line_texture(font_name, text, width, x, y) + local texture = "" + local char + local pos = 1 + local font = get_font(font_name) + + if font ~= nil then + while pos <= #text do + char, pos = get_next_char(text, pos) + + -- Replace chars with no texture by the NULL(0) char + if font.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) + if x + font.widths[char] >= 0 and x <= width then + texture = texture.. + string.format(":%d,%d=font_%s_%04x.png", + x, y, font.name, char) + end + x = x + font.widths[char] + end + end + + return texture +end + +--- Builds texture for a multiline colored text +-- @param font_name Font to be used +-- @param text Text to be rendered +-- @param texturew Width of the texture (extra text will be truncated) +-- @param textureh Height of the texture +-- @param maxlines Maximum number of lines +-- @param halign Horizontal text align ("left"/"center"/"right") (optional) +-- @param valign Vertical text align ("top"/"center"/"bottom") (optional) +-- @param color Color of the text (optional) +-- @return Texture string + +function font_api.make_multiline_texture(font_name, text, width, height, + maxlines, halign, valign, color) + local texture = "" + local lines = {} + local textheight = 0 + local y, w, h + + for num, line in pairs(split_lines(text, maxlines)) do + w, h = font_api.get_text_size(font_name, line) + lines[num] = { text = line, width = w, height = h, } + textheight = textheight + h + end + + if #lines then + if valign == "top" then + y = 0 + elseif valign == "bottom" then + y = height - textheight + else + y = (height - textheight) / 2 + end + end + + for _, line in pairs(lines) do + if halign == "left" then + texture = texture.. + font_api.make_line_texture(font_name, line.text, width, + 0, y) + elseif halign == "right" then + texture = texture.. + font_api.make_line_texture(font_name, line.text, width, + width - line.width, y) + else + texture = texture.. + font_api.make_line_texture(font_name, line.text, width, + (width - line.width) / 2, y) + end + y = y + line.height + end + + texture = string.format("[combine:%dx%d", width, height)..texture + if color then texture = texture.."^[colorize:"..color end + return texture +end + +--- Register a new font +-- Textures corresponding to the font should be named after following patern : +-- font__.png +-- : name of the font +-- : 4 digit hexadecimal unicode of the char +-- @param font_name Name of the font to register +-- If registering different sizes of the same font, add size in the font name +-- (e.g. times_10, times_12...). +-- @param height Font height in pixels +-- @param widths Array of character widths in pixels, indexed by UTF codepoints + +function font_api.register_font(font_name, height, widths) + + if font_api.registered_fonts[font_name] ~= nil then + minetest.log("error", "Font \""..font_name.."\" already registered.") + return + end + + if height == nil or height <= 0 then + minetest.log("error", "Font \""..font_name.. + "\" must have a positive height.") + return + end + + if type(widths) ~= "table" then + minetest.log("error", "Font \""..font_name.. + "\" must have a widths array.") + return + end + + if widths[0] == nil then + minetest.log("error", "Font \""..font_name.. + "\" must have a char with codepoint 0 (=unknown char).") + return + end + + font_api.registered_fonts[font_name] = + { name = font_name, height = height, widths = widths } + + -- Force to choose again default font + -- (allows use of fonts registered after start) + default_font = false +end + +--- Standard on_display_update entity callback. +-- Node should have a corresponding display_entity with size, resolution and +-- maxlines fields and optionally halign, valign and color fields +-- @param pos Node position +-- @param objref Object reference of entity + +function font_api.on_display_update(pos, objref) + local meta = minetest.get_meta(pos) + local text = meta:get_string("display_text") + local ndef = minetest.registered_nodes[minetest.get_node(pos).name] + local entity = objref:get_luaentity() + + if entity and ndef.display_entities[entity.name] then + local def = ndef.display_entities[entity.name] + local font = get_font(def.font_name) + + objref:set_properties({ + textures={font_api.make_multiline_texture( + def.font_name, text, + def.size.x * def.resolution.x * font.height, + def.size.y * def.resolution.y * font.height, + def.maxlines, def.halign, def.valign, def.color)}, + visual_size = def.size + }) + end +end + +-- Compatibility +font_lib = font_api + diff --git a/font_api/settingtypes.txt b/font_api/settingtypes.txt new file mode 100644 index 0000000..d111159 --- /dev/null +++ b/font_api/settingtypes.txt @@ -0,0 +1 @@ +default_font(Default font) string diff --git a/font_api/tools/make_font_lua.sh b/font_api/tools/make_font_lua.sh new file mode 100755 index 0000000..ae24001 --- /dev/null +++ b/font_api/tools/make_font_lua.sh @@ -0,0 +1,56 @@ +#!/bin/bash + +scriptname=$(basename $0) +identify="identify" + +font_name=$1 + +for f in textures/font_${font_name}_????.png +do + if [[ $f =~ textures/font_${font_name}_([0-9a-fA-F]{4}).png ]] + then + code=$((16#${BASH_REMATCH[1]})) + size=$(identify $f | cut -d " " -f 3) + w=$(echo $size | cut -d "x" -f 1) + h=$(echo $size | cut -d "x" -f 2) + + if [ -z "$font_height" ] + then + font_height=$h + else + if [ $font_height -ne $h ] + then + echo "Error : $f as height of $h pixels, previous textures have a height of $font_height pixels. All textures should have the same height." + fi + fi + + if [ -z "$font_widths" ] + then + font_widths="[$code]=$w" + else + font_widths="$font_widths, [$code]=$w" + fi + fi +done + +echo "--[[ + +$luafile generated by $scriptname $(LANG=en_US date) + +--]] + +font_api.register_font( + '$font_name', + $font_height, + { $font_widths } +); +" > font_$font_name.lua + +if grep -q font_api depends.txt &>/dev/null +then + echo "font_api already in depends.txt." +else + echo "adding font_api to depends.txt." + echo "font_api" >> depends.txt +fi + diff --git a/font_api/tools/make_font_textures.sh b/font_api/tools/make_font_textures.sh new file mode 100755 index 0000000..6f4959d --- /dev/null +++ b/font_api/tools/make_font_textures.sh @@ -0,0 +1,111 @@ +#!/bin/bash + +# This program generates a bitmap font for font_api mod for Minetest game. +# (c) Andrzej Pieńkowski +# (c) Pierre-Yves Rollo +# License: GPL + +usage() { + echo "Usage: $0 fontfile fontname fontsize" + echo "fontfile: A TTF font file to use to create textures." + echo "fontname: The font name to be used in font_api (should be simple, with no spaces)." + echo "fontsize: Font height to be rendered." +} + +if [ $# -ne 3 ] +then + usage + exit 1 +fi + +fontfile=$1 +fontname=$2 +fontsize=$3 + +if [ ! -r "$fontfile" ] +then + echo "$fontfile not readable." + exit 1 +fi + +# check imagemagick +hash convert &>/dev/null +if [ $? -eq 1 ]; then + echo -e "Error: This program requires convert from ImageMagick! Please install it by typing 'sudo apt-get install imagemagick' in terminal." + abort=1 +fi + +# check ttx +hash ttx &>/dev/null +if [ $? -eq 1 ]; then + echo -e "Error: This program requires ttx from FontTools! Please install it by typing 'sudo apt-get install fonttools' in terminal." + abort=1 +fi + +if [ $abort ] +then + exit 1 +fi + +generate() { + for i in $(seq $((0x$1)) $((0x$2))) + do + if echo "$codepoints" | grep -qi $(printf "0x%x" $i) + then + hex=$(printf "%04x" $i) + echo -e "Generating textures/font_${fontname}_$hex.png file for \"\\U$hex\" char." + if [[ "$hex" == "005c" ]] # Backslash char + then + convert -background none -fill black -font "$fontfile" -pointsize $fontsize label:"\\\\" -colorspace gray -channel alpha -threshold 50% textures/font_${fontname}_$hex.png + else + convert -background none -fill black -font "$fontfile" -pointsize $fontsize label:"$(echo -en "\\U$hex")" -colorspace gray -channel alpha -threshold 50% textures/font_${fontname}_$hex.png + fi + fi + done +} + +mkdir textures + +# Reads all available code points in the font. +codepoints=$(ttx -o - $fontfile | grep "_.png** - -****: Name of the font as given in the first argument -****: UTF code of the char in 4 hexadecimal digits - -To ease that declaration, a shell is provided to build a .lua file from the texture files (see provided tools). - -## Provided tools - -Still in early stage of development, these tools are helpers to create font mods. - -### make_font_texture.sh - -This scripts takes a .ttf file as input and create one .png file per char, that can be used as font texture. Launch it from your future font mod directory. - -__Advice__ - -This script works much better with pixels font, providing the correct height. There is no antialiasing at all, vector fonts and bad heights gives very ugly results. - -__Syntax__ - -**make\_font\_texture.sh ** - -****: A TTF font file to use to create textures. -****: The font name to be used in font_lib (should be simple, with no spaces). -****: Font height to be rendered. - -### make_font_lua.sh - -This script analyses textures in textures directory and creates a font\_.lua files with a call to register_font with images information. Launch it from your future font mod directory. - -Once the font\_.lua created, it can be included by a init.lua file or directly renamed to init.lua if you are creating a simple font mod. - -__Syntax__ - -**make\_font_lua.sh ** - -****: The font name to be used in font_lib (same as given to make\_font\_texture.sh) - -### An exemple generating a font mod - - mkdir font_myfont - cd font_myfont - //tools/make_font_texture.sh myfont.ttf myfont 12 - //tools/make_font_lua.sh myfont - mv font_myfont.lua init.lua - - - - - diff --git a/font_lib/LICENSE.txt b/font_lib/LICENSE.txt deleted file mode 100644 index 341c30b..0000000 --- a/font_lib/LICENSE.txt +++ /dev/null @@ -1,166 +0,0 @@ - GNU LESSER GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - - This version of the GNU Lesser General Public License incorporates -the terms and conditions of version 3 of the GNU General Public -License, supplemented by the additional permissions listed below. - - 0. Additional Definitions. - - As used herein, "this License" refers to version 3 of the GNU Lesser -General Public License, and the "GNU GPL" refers to version 3 of the GNU -General Public License. - - "The Library" refers to a covered work governed by this License, -other than an Application or a Combined Work as defined below. - - An "Application" is any work that makes use of an interface provided -by the Library, but which is not otherwise based on the Library. -Defining a subclass of a class defined by the Library is deemed a mode -of using an interface provided by the Library. - - A "Combined Work" is a work produced by combining or linking an -Application with the Library. The particular version of the Library -with which the Combined Work was made is also called the "Linked -Version". - - The "Minimal Corresponding Source" for a Combined Work means the -Corresponding Source for the Combined Work, excluding any source code -for portions of the Combined Work that, considered in isolation, are -based on the Application, and not on the Linked Version. - - The "Corresponding Application Code" for a Combined Work means the -object code and/or source code for the Application, including any data -and utility programs needed for reproducing the Combined Work from the -Application, but excluding the System Libraries of the Combined Work. - - 1. Exception to Section 3 of the GNU GPL. - - You may convey a covered work under sections 3 and 4 of this License -without being bound by section 3 of the GNU GPL. - - 2. Conveying Modified Versions. - - If you modify a copy of the Library, and, in your modifications, a -facility refers to a function or data to be supplied by an Application -that uses the facility (other than as an argument passed when the -facility is invoked), then you may convey a copy of the modified -version: - - a) under this License, provided that you make a good faith effort to - ensure that, in the event an Application does not supply the - function or data, the facility still operates, and performs - whatever part of its purpose remains meaningful, or - - b) under the GNU GPL, with none of the additional permissions of - this License applicable to that copy. - - 3. Object Code Incorporating Material from Library Header Files. - - The object code form of an Application may incorporate material from -a header file that is part of the Library. You may convey such object -code under terms of your choice, provided that, if the incorporated -material is not limited to numerical parameters, data structure -layouts and accessors, or small macros, inline functions and templates -(ten or fewer lines in length), you do both of the following: - - a) Give prominent notice with each copy of the object code that the - Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the object code with a copy of the GNU GPL and this license - document. - - 4. Combined Works. - - You may convey a Combined Work under terms of your choice that, -taken together, effectively do not restrict modification of the -portions of the Library contained in the Combined Work and reverse -engineering for debugging such modifications, if you also do each of -the following: - - a) Give prominent notice with each copy of the Combined Work that - the Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the Combined Work with a copy of the GNU GPL and this license - document. - - c) For a Combined Work that displays copyright notices during - execution, include the copyright notice for the Library among - these notices, as well as a reference directing the user to the - copies of the GNU GPL and this license document. - - d) Do one of the following: - - 0) Convey the Minimal Corresponding Source under the terms of this - License, and the Corresponding Application Code in a form - suitable for, and under terms that permit, the user to - recombine or relink the Application with a modified version of - the Linked Version to produce a modified Combined Work, in the - manner specified by section 6 of the GNU GPL for conveying - Corresponding Source. - - 1) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (a) uses at run time - a copy of the Library already present on the user's computer - system, and (b) will operate properly with a modified version - of the Library that is interface-compatible with the Linked - Version. - - e) Provide Installation Information, but only if you would otherwise - be required to provide such information under section 6 of the - GNU GPL, and only to the extent that such information is - necessary to install and execute a modified version of the - Combined Work produced by recombining or relinking the - Application with a modified version of the Linked Version. (If - you use option 4d0, the Installation Information must accompany - the Minimal Corresponding Source and Corresponding Application - Code. If you use option 4d1, you must provide the Installation - Information in the manner specified by section 6 of the GNU GPL - for conveying Corresponding Source.) - - 5. Combined Libraries. - - You may place library facilities that are a work based on the -Library side by side in a single library together with other library -facilities that are not Applications and are not covered by this -License, and convey such a combined library under terms of your -choice, if you do both of the following: - - a) Accompany the combined library with a copy of the same work based - on the Library, uncombined with any other library facilities, - conveyed under the terms of this License. - - b) Give prominent notice with the combined library that part of it - is a work based on the Library, and explaining where to find the - accompanying uncombined form of the same work. - - 6. Revised Versions of the GNU Lesser General Public License. - - The Free Software Foundation may publish revised and/or new versions -of the GNU Lesser General Public License from time to time. Such new -versions will be similar in spirit to the present version, but may -differ in detail to address new problems or concerns. - - Each version is given a distinguishing version number. If the -Library as you received it specifies that a certain numbered version -of the GNU Lesser General Public License "or any later version" -applies to it, you have the option of following the terms and -conditions either of that published version or of any later version -published by the Free Software Foundation. If the Library as you -received it does not specify a version number of the GNU Lesser -General Public License, you may choose any version of the GNU Lesser -General Public License ever published by the Free Software Foundation. - - If the Library as you received it specifies that a proxy can decide -whether future versions of the GNU Lesser General Public License shall -apply, that proxy's public statement of acceptance of any version is -permanent authorization for you to choose that version for the -Library. - diff --git a/font_lib/README.md b/font_lib/README.md deleted file mode 100644 index 6b53a6b..0000000 --- a/font_lib/README.md +++ /dev/null @@ -1,14 +0,0 @@ -# Font Lib - -This library for font display on entities (to be used with display_lib for sign creation). - -**Dependancies**: default - -**License**: LGPL - -(Default font taken from VanessaE's homedecor/signs_lib, originally under WTFPL) - -**API**: See [API.md](https://github.com/pyrollo/display_modpack/blob/master/font_lib/API.md) document please. - -For more information, see the [forum topic](https://forum.minetest.net/viewtopic.php?t=13563) at the Minetest forums. - diff --git a/font_lib/copyright.txt b/font_lib/copyright.txt deleted file mode 100644 index ceb5446..0000000 --- a/font_lib/copyright.txt +++ /dev/null @@ -1,3 +0,0 @@ -Code by Pierre-Yves Rollo (pyrollo) -Contributors: -Andrzej Pieńkowski (apienk): Unicode support and tool for creating texturess diff --git a/font_lib/depends.txt b/font_lib/depends.txt deleted file mode 100644 index e69de29..0000000 diff --git a/font_lib/init.lua b/font_lib/init.lua deleted file mode 100644 index 76a6b38..0000000 --- a/font_lib/init.lua +++ /dev/null @@ -1,340 +0,0 @@ ---[[ - font_lib mod for Minetest - Library to add font display capability - to display_lib 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 . ---]] - --- Global variables -------------------- - -font_lib = {} -font_lib.name = minetest.get_current_modname() -font_lib.path = minetest.get_modpath(font_lib.name) -font_lib.registered_fonts = {} - --- Local variables ------------------- - -local default_font = false - --- Local functions ------------------- - --- Split multiline text into array of lines, with maximum lines. - -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 -end - --- Gets a default (settings or fist font) - -local function get_default_font() - -- First call - if default_font == false then - default_font = nil - - -- First, try with settings - local settings_font = minetest.settings:get("default_font") - - if settings_font ~= nil and settings_font ~= "" then - default_font = font_lib.registered_fonts[settings_font] - - if default_font == nil then - minetest.log("warning", "Default font in settings (\"".. - settings_font.."\") is not registered.") - end - end - - -- If failed, choose first font - if default_font == nil then - for _, font in pairs(font_lib.registered_fonts) do - default_font = font - break - end - end - - -- Error, no font registered - if default_font == nil then - minetest.log("error", - "No font registred, unable to choose a default font.") - end - end - - return default_font -end - --- Returns font properties to be used according to font_name - -local function get_font(font_name) - local font = font_lib.registered_fonts[font_name] - - if font == nil then - local message - - if font_name == nil then - message = "No font given" - else - message = "Font \""..font_name.."\" unregistered" - end - - font = get_default_font() - - if font ~= nil then - minetest.log("info", message..", using font \""..font.name.."\".") - end - end - - return font -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 - 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 - --- API functions ----------------- - --- Computes text size for a given font and text (ignores new lines) --- @param font_name Font to be used --- @param text Text to be rendered --- @return Rendered text (width, height) - -function font_lib.get_text_size(font_name, text) - local char - local width = 0 - local pos = 1 - local font = get_font(font_name) - - if font == nil then - return 0, 0 - else - while pos <= #text do - char, pos = get_next_char(text, pos) - -- Replace chars with no texture by the NULL(0) char - if font.widths[char] ~= nil then - width = width + font.widths[char] - else - width = width + font.widths[0] - end - end - end - - return width, font.height -end - ---- Builds texture part for a text line --- @param font_name Font to be used --- @param text Text to be rendered --- @param width Width of the texture (extra text is not rendered) --- @param x Starting x position in texture --- @param y Vertical position of the line in texture --- @return Texture string - -function font_lib.make_line_texture(font_name, text, width, x, y) - local texture = "" - local char - local pos = 1 - local font = get_font(font_name) - - if font ~= nil then - while pos <= #text do - char, pos = get_next_char(text, pos) - - -- Replace chars with no texture by the NULL(0) char - if font.widths[char] == nil then - print(string.format("["..font_lib.name - .."] Missing char %d (%04x)",char,char)) - char = 0 - end - - -- Add image only if it is visible (at least partly) - if x + font.widths[char] >= 0 and x <= width then - texture = texture.. - string.format(":%d,%d=font_%s_%04x.png", - x, y, font.name, char) - end - x = x + font.widths[char] - end - end - - return texture -end - ---- Builds texture for a multiline colored text --- @param font_name Font to be used --- @param text Text to be rendered --- @param texturew Width of the texture (extra text will be truncated) --- @param textureh Height of the texture --- @param maxlines Maximum number of lines --- @param halign Horizontal text align ("left"/"center"/"right") (optional) --- @param valign Vertical text align ("top"/"center"/"bottom") (optional) --- @param color Color of the text (optional) --- @return Texture string - -function font_lib.make_multiline_texture(font_name, text, width, height, - maxlines, halign, valign, color) - local texture = "" - local lines = {} - local textheight = 0 - local y, w, h - - for num, line in pairs(split_lines(text, maxlines)) do - w, h = font_lib.get_text_size(font_name, line) - lines[num] = { text = line, width = w, height = h, } - textheight = textheight + h - end - - if #lines then - if valign == "top" then - y = 0 - elseif valign == "bottom" then - y = height - textheight - else - y = (height - textheight) / 2 - end - end - - for _, line in pairs(lines) do - if halign == "left" then - texture = texture.. - font_lib.make_line_texture(font_name, line.text, width, - 0, y) - elseif halign == "right" then - texture = texture.. - font_lib.make_line_texture(font_name, line.text, width, - width - line.width, y) - else - texture = texture.. - font_lib.make_line_texture(font_name, line.text, width, - (width - line.width) / 2, y) - end - y = y + line.height - end - - texture = string.format("[combine:%dx%d", width, height)..texture - if color then texture = texture.."^[colorize:"..color end - return texture -end - ---- Register a new font --- Textures corresponding to the font should be named after following patern : --- font__.png --- : name of the font --- : 4 digit hexadecimal unicode of the char --- @param font_name Name of the font to register --- If registering different sizes of the same font, add size in the font name --- (e.g. times_10, times_12...). --- @param height Font height in pixels --- @param widths Array of character widths in pixels, indexed by UTF codepoints - -function font_lib.register_font(font_name, height, widths) - - if font_lib.registered_fonts[font_name] ~= nil then - minetest.log("error", "Font \""..font_name.."\" already registered.") - return - end - - if height == nil or height <= 0 then - minetest.log("error", "Font \""..font_name.. - "\" must have a positive height.") - return - end - - if type(widths) ~= "table" then - minetest.log("error", "Font \""..font_name.. - "\" must have a widths array.") - return - end - - if widths[0] == nil then - minetest.log("error", "Font \""..font_name.. - "\" must have a char with codepoint 0 (=unknown char).") - return - end - - font_lib.registered_fonts[font_name] = - { name = font_name, height = height, widths = widths } - - -- Force to choose again default font - -- (allows use of fonts registered after start) - default_font = false -end - ---- Standard on_display_update entity callback. --- Node should have a corresponding display_entity with size, resolution and --- maxlines fields and optionally halign, valign and color fields --- @param pos Node position --- @param objref Object reference of entity - -function font_lib.on_display_update(pos, objref) - local meta = minetest.get_meta(pos) - local text = meta:get_string("display_text") - local ndef = minetest.registered_nodes[minetest.get_node(pos).name] - local entity = objref:get_luaentity() - - if entity and ndef.display_entities[entity.name] then - local def = ndef.display_entities[entity.name] - local font = get_font(def.font_name) - - objref:set_properties({ - textures={font_lib.make_multiline_texture( - def.font_name, text, - def.size.x * def.resolution.x * font.height, - def.size.y * def.resolution.y * font.height, - def.maxlines, def.halign, def.valign, def.color)}, - visual_size = def.size - }) - end -end - diff --git a/font_lib/settingtypes.txt b/font_lib/settingtypes.txt deleted file mode 100644 index d111159..0000000 --- a/font_lib/settingtypes.txt +++ /dev/null @@ -1 +0,0 @@ -default_font(Default font) string diff --git a/font_lib/tools/make_font_lua.sh b/font_lib/tools/make_font_lua.sh deleted file mode 100755 index 607ff95..0000000 --- a/font_lib/tools/make_font_lua.sh +++ /dev/null @@ -1,56 +0,0 @@ -#!/bin/bash - -scriptname=$(basename $0) -identify="identify" - -font_name=$1 - -for f in textures/font_${font_name}_????.png -do - if [[ $f =~ textures/font_${font_name}_([0-9a-fA-F]{4}).png ]] - then - code=$((16#${BASH_REMATCH[1]})) - size=$(identify $f | cut -d " " -f 3) - w=$(echo $size | cut -d "x" -f 1) - h=$(echo $size | cut -d "x" -f 2) - - if [ -z "$font_height" ] - then - font_height=$h - else - if [ $font_height -ne $h ] - then - echo "Error : $f as height of $h pixels, previous textures have a height of $font_height pixels. All textures should have the same height." - fi - fi - - if [ -z "$font_widths" ] - then - font_widths="[$code]=$w" - else - font_widths="$font_widths, [$code]=$w" - fi - fi -done - -echo "--[[ - -$luafile generated by $scriptname $(LANG=en_US date) - ---]] - -font_lib.register_font( - '$font_name', - $font_height, - { $font_widths } -); -" > font_$font_name.lua - -if grep -q font_lib depends.txt &>/dev/null -then - echo "font_lib already in depends.txt." -else - echo "adding font_lib to depends.txt." - echo "font_lib" >> depends.txt -fi - diff --git a/font_lib/tools/make_font_textures.sh b/font_lib/tools/make_font_textures.sh deleted file mode 100755 index ade2e32..0000000 --- a/font_lib/tools/make_font_textures.sh +++ /dev/null @@ -1,111 +0,0 @@ -#!/bin/bash - -# This program generates a bitmap font for font_lib mod for Minetest game. -# (c) Andrzej Pieńkowski -# (c) Pierre-Yves Rollo -# License: GPL - -usage() { - echo "Usage: $0 fontfile fontname fontsize" - echo "fontfile: A TTF font file to use to create textures." - echo "fontname: The font name to be used in font_lib (should be simple, with no spaces)." - echo "fontsize: Font height to be rendered." -} - -if [ $# -ne 3 ] -then - usage - exit 1 -fi - -fontfile=$1 -fontname=$2 -fontsize=$3 - -if [ ! -r "$fontfile" ] -then - echo "$fontfile not readable." - exit 1 -fi - -# check imagemagick -hash convert &>/dev/null -if [ $? -eq 1 ]; then - echo -e "Error: This program requires convert from ImageMagick! Please install it by typing 'sudo apt-get install imagemagick' in terminal." - abort=1 -fi - -# check ttx -hash ttx &>/dev/null -if [ $? -eq 1 ]; then - echo -e "Error: This program requires ttx from FontTools! Please install it by typing 'sudo apt-get install fonttools' in terminal." - abort=1 -fi - -if [ $abort ] -then - exit 1 -fi - -generate() { - for i in $(seq $((0x$1)) $((0x$2))) - do - if echo "$codepoints" | grep -qi $(printf "0x%x" $i) - then - hex=$(printf "%04x" $i) - echo -e "Generating textures/font_${fontname}_$hex.png file for \"\\U$hex\" char." - if [[ "$hex" == "005c" ]] # Backslash char - then - convert -background none -fill black -font "$fontfile" -pointsize $fontsize label:"\\\\" -colorspace gray -channel alpha -threshold 50% textures/font_${fontname}_$hex.png - else - convert -background none -fill black -font "$fontfile" -pointsize $fontsize label:"$(echo -en "\\U$hex")" -colorspace gray -channel alpha -threshold 50% textures/font_${fontname}_$hex.png - fi - fi - done -} - -mkdir textures - -# Reads all available code points in the font. -codepoints=$(ttx -o - $fontfile | grep " 0 then - itemstack:set_name(ndef.signs_other_dir) - end - itemstack = minetest.item_place(itemstack, placer, pointed_thing, ndir) - itemstack:set_name(name) +signs.on_place_direction = function(...) + minetest.log("warning", "signs.on_place_direction() is deprecated, please use signs_api.on_place_direction() instead.") + return signs_api.on_place_direction(...) +end - return itemstack - else - return minetest.item_place(itemstack, placer, pointed_thing, ndir) - end +signs.on_rotate = function(...) + minetest.log("warning", "signs.on_rotate() is deprecated, please use signs_api.on_rotate() instead.") + return signs_api.on_rotate(...) end --- Handles screwdriver rotation. Direction is affected for direction signs -function signs.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}) - display_lib.update_entities(pos) - end - else - display_lib.on_rotate(pos, node, user, mode, new_param2) - end - return false; +signs.register_sign = function(...) + minetest.log("warning", "signs.register_sign() is deprecated, please use signs_api.register_sign() instead.") + return signs_api.register_sign(...) end + -- Generic callback for show_formspec displayed formspecs of "sign" mod minetest.register_on_player_receive_fields(function(player, formname, fields) @@ -142,59 +69,3 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) end end end) - -function signs.register_sign(mod, name, model) - -- Default fields - local fields = { - sunlight_propagates = true, - paramtype = "light", - paramtype2 = "facedir", - drawtype = "nodebox", - node_box = { - type = "fixed", - fixed = {-model.width/2, -model.height/2, 0.5, - model.width/2, model.height/2, 0.5 - model.depth}, - }, - groups = {choppy=2, dig_immediate=2, not_blocking_trains = 1, display_lib_node = 1}, - sounds = default.node_sound_defaults(), - display_entities = { - ["signs:display_text"] = { - on_display_update = font_lib.on_display_update, - depth = 0.5 - display_lib.entity_spacing - model.depth, - size = { x = model.width, y = model.height }, - resolution = { x = 64, y = 64 }, - maxlines = 1, - }, - - }, - on_place = display_lib.on_place, - on_construct = function(pos) - signs.set_formspec(pos) - display_lib.on_construct(pos) - end, - on_destruct = display_lib.on_destruct, - on_rotate = signs.on_rotate, - on_receive_fields = signs.on_receive_fields, - on_punch = function(pos, node, player, pointed_thing) display_lib.update_entities(pos) end, - } - - -- Node fields override - for key, value in pairs(model.node_fields) do - if key == "groups" then - for key2, value2 in pairs(value) do - fields[key][key2] = value2 - end - else - fields[key] = value - end - end - - if not fields.wield_image then fields.wield_image = fields.inventory_image end - - -- Entity fields override - for key, value in pairs(model.entity_fields) do - fields.display_entities["signs:display_text"][key] = value - end - - minetest.register_node(mod..":"..name, fields) -end diff --git a/signs/compatibility.lua b/signs/compatibility.lua index 3284230..e798a67 100644 --- a/signs/compatibility.lua +++ b/signs/compatibility.lua @@ -43,9 +43,9 @@ local function compatibility_check_1(pos, node) node.name = convert_nodes[node.name] if node.name then node.param2 = wallmounted_to_facedir[node.param2] - display_lib.on_destruct(pos) + display_api.on_destruct(pos) minetest.swap_node(pos, node) - display_lib.on_construct(pos) + display_api.on_construct(pos) end end @@ -76,7 +76,7 @@ local function compatibility_check_2(pos, node) end end -- Create new entity - display_lib.update_entities(pos) + display_api.update_entities(pos) end minetest.register_lbm({ name = "signs:conpatibility_2", diff --git a/signs/depends.txt b/signs/depends.txt index 3feca07..ad3bb8f 100644 --- a/signs/depends.txt +++ b/signs/depends.txt @@ -1,4 +1,5 @@ default intllib? -display_lib -font_lib +display_api +font_api +signs_api diff --git a/signs/nodes.lua b/signs/nodes.lua index 354bfd6..18bf1d6 100644 --- a/signs/nodes.lua +++ b/signs/nodes.lua @@ -28,7 +28,7 @@ local function display_poster(pos, node, player) local def = minetest.registered_nodes[node.name].display_entities["signs:display_text"] -- Title texture - local titletexture = font_lib.make_multiline_texture( + local titletexture = font_api.make_multiline_texture( def.font_name, meta:get_string("display_text"), 116, 12, def.maxlines, def.valign, def.color) @@ -61,9 +61,9 @@ local function edit_poster(pos, node, player) "size[6.5,7.5]".. default.gui_bg .. default.gui_bg_img .. default.gui_slots .. "field[0.5,0.7;6,1;display_text;"..F("Title")..";".. - minetest.formspec_escape(meta:get_string("display_text")).."]".. + minetest.formspec_escape(meta:get_string("display_text")).."]".. "textarea[0.5,1.7;6,6;text;"..F("Text")..";".. - minetest.formspec_escape(meta:get_string("text")).."]".. + minetest.formspec_escape(meta:get_string("text")).."]".. "button_exit[2.25,7;2,1;write;"..F("Write").."]" minetest.show_formspec(player:get_player_name(), node.name.."@"..minetest.pos_to_string(pos)..":edit", @@ -87,14 +87,14 @@ local function on_receive_fields_poster(pos, formname, fields, player) meta:set_string("text", fields.text) meta:set_string("infotext", "\""..fields.display_text .."\"\n"..S("(right-click to read more text)")) - display_lib.update_entities(pos) + display_api.update_entities(pos) display_poster(pos, node, player) end end end -- Text entity for all signs -display_lib.register_display_entity("signs:display_text") +display_api.register_display_entity("signs:display_text") -- Sign models and registration local models = { @@ -103,7 +103,7 @@ local models = { width = 14/16, height = 7/16, entity_fields = { - right = -3/32, + right = -3/32, size = { x = 12/16, y = 6/16 }, resolution = { x = 9, y = 5 }, maxlines = 2, @@ -113,8 +113,8 @@ local models = { description = S("Wooden direction sign"), tiles = { "signs_wooden_direction.png" }, inventory_image = "signs_wooden_inventory.png", - signs_other_dir = 'signs:wooden_left_sign', - on_place = signs.on_place_direction, + 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}}, @@ -126,7 +126,7 @@ local models = { width = 14/16, height = 7/16, entity_fields = { - right = 3/32, + right = 3/32, size = { x = 12/16, y = 6/16 }, resolution = { x = 9, y = 5 }, maxlines = 2, @@ -136,7 +136,7 @@ local models = { description = S("Wooden direction sign"), tiles = { "signs_wooden_direction.png" }, inventory_image = "signs_wooden_inventory.png", - signs_other_dir = 'signs:wooden_right_sign', + 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}}, @@ -158,10 +158,10 @@ local models = { node_fields = { description = S("Poster"), tiles = { "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_sides.png", + "signs_poster_sides.png", "signs_poster.png" }, inventory_image = "signs_poster_inventory.png", - on_construct = display_lib.on_construct, + on_construct = display_api.on_construct, on_rightclick = display_poster, on_receive_fields = on_receive_fields_poster, }, @@ -171,6 +171,6 @@ local models = { -- Node registration for name, model in pairs(models) do - signs.register_sign("signs", name, model) + signs_api.register_sign("signs", name, model) end diff --git a/signs_api/LICENSE.txt b/signs_api/LICENSE.txt new file mode 100644 index 0000000..341c30b --- /dev/null +++ b/signs_api/LICENSE.txt @@ -0,0 +1,166 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. + diff --git a/signs_api/README.md b/signs_api/README.md new file mode 100644 index 0000000..99ff20a --- /dev/null +++ b/signs_api/README.md @@ -0,0 +1,29 @@ +# Signs API + +This mod provides various helper functions for registereing signs with text display. Text is locked if area is protected. +No actual signs get registered by this mod, the signs are defined in the sign submod. + +For more information, see the [forum topic](https://forum.minetest.net/viewtopic.php?t=19365) at the Minetest forums. + +**Dependancies**: default, display\_lib, font\_lib + +**License**: Code under LGPL, Textures and models under CC-BY-SA + +## API Functions +### `signs_api.set_display_text(pos, text)` +Sets the text of a sign. Usually called in `on_receive_fields`. + +### `signs_api.set_formspec(pos)` +Usually called in `on_construct` to set the formspec. + +### `signs_api.on_receive_fields(pos, formname, fields, player)` +Helper function for `on_receive_fields`. Sets the display text and checks for protection. + +### `signs_api.on_place_direction(itemstack, placer, pointed_thing)` +On place callback for direction signs (chooses which sign according to look direction). + +### `signs_api.on_rotate(pos, node, player, mode, new_param2)` +Handles screwdriver rotation. Direction is affected for direction signs. + +### `signs_api.register_sign(mod, name, model)` +A method to quickly register signs. diff --git a/signs_api/common.lua b/signs_api/common.lua new file mode 100644 index 0000000..2528ff5 --- /dev/null +++ b/signs_api/common.lua @@ -0,0 +1,188 @@ +--[[ + signs mod for Minetest - Various signs with text displayed on + (c) Pierre-Yves Rollo + + This file is part of signs. + + signs 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. + + signs 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 signs. If not, see . +--]] + +local S = signs_api.intllib +local F = function(...) return minetest.formspec_escape(S(...)) end + +function signs_api.set_display_text(pos,text) + local meta = minetest.get_meta(pos) + meta:set_string("display_text", text) + meta:set_string("infotext", "\""..text.."\"") + display_api.update_entities(pos) +end + +function signs_api.set_formspec(pos) + local meta = minetest.get_meta(pos) + local ndef = minetest.registered_nodes[minetest.get_node(pos).name] + if ndef and ndef.display_entities and ndef.display_entities["signs:display_text"] then + local maxlines = ndef.display_entities["signs:display_text"].maxlines + local formspec + + if maxlines == 1 then + formspec = "size[6,3]".. + default.gui_bg .. default.gui_bg_img .. default.gui_slots .. + "field[0.5,0.7;5.5,1;display_text;"..F("Text")..";${display_text}]".. + "button_exit[2,2;2,1;ok;"..F("Write").."]" + else + local extralabel = "" + if maxlines then + extralabel = F(" (first %s lines only)"):format(maxlines) + end + + formspec = "size[6,4]".. + default.gui_bg .. default.gui_bg_img .. default.gui_slots .. + "textarea[0.5,0.7;5.5,2;display_text;"..F("Text")..""..extralabel..";${display_text}]".. + "button_exit[2,3;2,1;ok;"..F("Write").."]" + end + + meta:set_string("formspec", formspec) + end +end + +function signs_api.on_receive_fields(pos, formname, fields, player) + if not minetest.is_protected(pos, player:get_player_name()) then + if fields and (fields.ok or fields.key_enter) then + signs_api.set_display_text(pos, fields.display_text) + end + end +end + +-- On place callback for direction signs +-- (chooses which sign according to look direction) +function signs_api.on_place_direction(itemstack, placer, pointed_thing) + local name = itemstack:get_name() + local ndef = minetest.registered_nodes[name] + + local bdir = {x = pointed_thing.under.x - pointed_thing.above.x, + y = pointed_thing.under.y - pointed_thing.above.y, + z = pointed_thing.under.z - pointed_thing.above.z} + local pdir = placer:get_look_dir() + + local ndir, test + + if ndef.paramtype2 == "facedir" then + if bdir.x == 0 and bdir.z == 0 then + -- Ceiling or floor pointed (facedir chosen from player dir) + ndir = minetest.dir_to_facedir({x=pdir.x, y=0, z=pdir.z}) + else + -- Wall pointed + ndir = minetest.dir_to_facedir(bdir) + end + + test = {[0]=-pdir.x, pdir.z, pdir.x, -pdir.z} + end + + if ndef.paramtype2 == "wallmounted" then + ndir = minetest.dir_to_wallmounted(bdir) + if ndir == 0 or ndir == 1 then + -- Ceiling or floor + ndir = minetest.dir_to_wallmounted({x=pdir.x, y=0, z=pdir.z}) + end + + test = {0, pdir.z, -pdir.z, -pdir.x, pdir.x} + end + + -- Only for direction signs + if ndef.signs_other_dir then + if test[ndir] > 0 then + itemstack:set_name(ndef.signs_other_dir) + end + itemstack = minetest.item_place(itemstack, placer, pointed_thing, ndir) + itemstack:set_name(name) + + return itemstack + else + return minetest.item_place(itemstack, placer, pointed_thing, ndir) + end +end + +-- Handles screwdriver rotation. Direction is affected for direction signs +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}) + display_api.update_entities(pos) + end + else + display_api.on_rotate(pos, node, user, mode, new_param2) + end + return false; +end + +function signs_api.register_sign(mod, name, model) + -- Default fields + local fields = { + sunlight_propagates = true, + paramtype = "light", + paramtype2 = "facedir", + drawtype = "nodebox", + node_box = { + type = "fixed", + fixed = {-model.width/2, -model.height/2, 0.5, + model.width/2, model.height/2, 0.5 - model.depth}, + }, + groups = {choppy=2, dig_immediate=2, not_blocking_trains = 1, display_modpack_node = 1}, + sounds = default.node_sound_defaults(), + display_entities = { + ["signs:display_text"] = { + on_display_update = font_api.on_display_update, + depth = 0.5 - display_api.entity_spacing - model.depth, + size = { x = model.width, y = model.height }, + resolution = { x = 64, y = 64 }, + maxlines = 1, + }, + + }, + on_place = display_api.on_place, + on_construct = function(pos) + signs_api.set_formspec(pos) + display_api.on_construct(pos) + end, + on_destruct = display_api.on_destruct, + on_rotate = signs_api.on_rotate, + on_receive_fields = signs_api.on_receive_fields, + on_punch = function(pos, node, player, pointed_thing) display_api.update_entities(pos) end, + } + + -- Node fields override + for key, value in pairs(model.node_fields) do + if key == "groups" then + for key2, value2 in pairs(value) do + fields[key][key2] = value2 + end + else + fields[key] = value + end + end + + if not fields.wield_image then fields.wield_image = fields.inventory_image end + + -- Entity fields override + for key, value in pairs(model.entity_fields) do + fields.display_entities["signs:display_text"][key] = value + end + + minetest.register_node(mod..":"..name, fields) +end + +-- Text entity for all signs +display_api.register_display_entity("signs:display_text") diff --git a/signs_api/copyright.txt b/signs_api/copyright.txt new file mode 100644 index 0000000..b70e051 --- /dev/null +++ b/signs_api/copyright.txt @@ -0,0 +1,10 @@ +Code by Pierre-Yves Rollo (pyrollo) +intllib support (i18n) by (fat115) +intllib fallback code and tools by Diego Martínez (kaeza) +Extra contributors: +(gpcf) +(Thomas--S) +Translations: +Muhammad Nur Hidayat Yasuyoshi (MuhdNurHidayat) +(fat115) + diff --git a/signs_api/depends.txt b/signs_api/depends.txt new file mode 100644 index 0000000..f75ffcc --- /dev/null +++ b/signs_api/depends.txt @@ -0,0 +1,4 @@ +default +intllib? +display_api +font_api diff --git a/signs_api/init.lua b/signs_api/init.lua new file mode 100644 index 0000000..c13a253 --- /dev/null +++ b/signs_api/init.lua @@ -0,0 +1,33 @@ +--[[ + signs mod for Minetest - Various signs with text displayed on + (c) Pierre-Yves Rollo + + This file is part of signs. + + signs 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. + + signs 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 signs. If not, see . +--]] + +signs_api = {} +signs_api.name = minetest.get_current_modname() +signs_api.path = minetest.get_modpath(signs_api.name) + +-- Load support for intllib. +local S, NS = dofile(signs_api.path.."/intllib.lua") +signs_api.intllib = S + +dofile(signs_api.path.."/common.lua") + + + + diff --git a/signs_api/intllib.lua b/signs_api/intllib.lua new file mode 100644 index 0000000..6669d72 --- /dev/null +++ b/signs_api/intllib.lua @@ -0,0 +1,45 @@ + +-- Fallback functions for when `intllib` is not installed. +-- Code released under Unlicense . + +-- Get the latest version of this file at: +-- https://raw.githubusercontent.com/minetest-mods/intllib/master/lib/intllib.lua + +local function format(str, ...) + local args = { ... } + local function repl(escape, open, num, close) + if escape == "" then + local replacement = tostring(args[tonumber(num)]) + if open == "" then + replacement = replacement..close + end + return replacement + else + return "@"..open..num..close + end + end + return (str:gsub("(@?)@(%(?)(%d+)(%)?)", repl)) +end + +local gettext, ngettext +if minetest.get_modpath("intllib") then + if intllib.make_gettext_pair then + -- New method using gettext. + gettext, ngettext = intllib.make_gettext_pair() + else + -- Old method using text files. + gettext = intllib.Getter() + end +end + +-- Fill in missing functions. + +gettext = gettext or function(msgid, ...) + return format(msgid, ...) +end + +ngettext = ngettext or function(msgid, msgid_plural, n, ...) + return format(n==1 and msgid or msgid_plural, ...) +end + +return gettext, ngettext diff --git a/signs_api/locale/fr.po b/signs_api/locale/fr.po new file mode 100644 index 0000000..e490d1b --- /dev/null +++ b/signs_api/locale/fr.po @@ -0,0 +1,49 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2018-02-01 05:56+0100\n" +"PO-Revision-Date: 2017-05-08 07:08+0200\n" +"Last-Translator: Peppy \n" +"Language-Team: \n" +"Language: fr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 1.8.12\n" + +#: common.lua +msgid "Text" +msgstr "Texte" + +#: common.lua +msgid "Write" +msgstr "Écrire" + +#: common.lua +#, lua-format +msgid " (first %s lines only)" +msgstr " (uniquement les %s premières lignes)" + +#~ msgid "Title" +#~ msgstr "Titre" + +#~ msgid "Close" +#~ msgstr "Fermer" + +#~ msgid "(right-click to read more text)" +#~ msgstr "(Clic-droit pour afficher le texte entier)" + +#~ msgid "Wooden direction sign" +#~ msgstr "Panneau de direction en bois" + +#~ msgid "Poster" +#~ msgstr "Affiche" + +#~ msgid "Textd" +#~ msgstr "Texte" diff --git a/signs_api/locale/ms.po b/signs_api/locale/ms.po new file mode 100644 index 0000000..9c8aab8 --- /dev/null +++ b/signs_api/locale/ms.po @@ -0,0 +1,46 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# Muhammad Nur Hidayat , 2017. +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2018-02-01 05:56+0100\n" +"PO-Revision-Date: 2017-08-27 15:50+0800\n" +"Last-Translator: Muhammad Nur Hidayat \n" +"Language-Team: Malay \n" +"Language: ms\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" +"X-Generator: Vé 0.1.4\n" + +#: common.lua +msgid "Text" +msgstr "Teks" + +#: common.lua +msgid "Write" +msgstr "Tulis" + +#: common.lua +#, lua-format +msgid " (first %s lines only)" +msgstr "( %s baris pertama sahaja )" + +#~ msgid "Title" +#~ msgstr "Tajuk" + +#~ msgid "Close" +#~ msgstr "Tutup" + +#~ msgid "(right-click to read more text)" +#~ msgstr "(klik-kanan untuk baca teks penuh)" + +#~ msgid "Wooden direction sign" +#~ msgstr "Papan tanda arah kayu" + +#~ msgid "Poster" +#~ msgstr "Poster" diff --git a/signs_api/locale/template.pot b/signs_api/locale/template.pot new file mode 100644 index 0000000..6004024 --- /dev/null +++ b/signs_api/locale/template.pot @@ -0,0 +1,31 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2018-02-01 05:56+0100\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=CHARSET\n" +"Content-Transfer-Encoding: 8bit\n" + +#: common.lua +msgid "Text" +msgstr "" + +#: common.lua +msgid "Write" +msgstr "" + +#: common.lua +#, lua-format +msgid " (first %s lines only)" +msgstr "" diff --git a/signs_api/tools/updatepo.sh b/signs_api/tools/updatepo.sh new file mode 100755 index 0000000..feb2504 --- /dev/null +++ b/signs_api/tools/updatepo.sh @@ -0,0 +1,25 @@ +#! /bin/bash + +# To create a new translation: +# msginit --locale=ll_CC -o locale/ll_CC.po -i locale/template.pot + +cd "$(dirname "${BASH_SOURCE[0]}")/.."; + +# Extract translatable strings. +xgettext --from-code=UTF-8 \ + --language=Lua \ + --sort-by-file \ + --keyword=S \ + --keyword=NS:1,2 \ + --keyword=N_ \ + --keyword=F \ + --add-comments='Translators:' \ + --add-location=file \ + -o locale/template.pot \ + $(find . -name '*.lua') + +# Update translations. +find locale -name '*.po' | while read -r file; do + echo $file + msgmerge --update $file locale/template.pot; +done diff --git a/signs_road/compatibility.lua b/signs_road/compatibility.lua index fa5f94b..9e6b29b 100644 --- a/signs_road/compatibility.lua +++ b/signs_road/compatibility.lua @@ -45,9 +45,9 @@ local function compatibility_check(pos, node) node.name = convert_nodes[node.name] if node.name then node.param2 = wallmounted_to_facedir[node.param2] - display_lib.on_destruct(pos) + display_api.on_destruct(pos) minetest.swap_node(pos, node) - display_lib.on_construct(pos) + display_api.on_construct(pos) end end @@ -69,7 +69,7 @@ local function compatibility_check_2(pos, node) end end -- Create new entity - display_lib.update_entities(pos) + display_api.update_entities(pos) end minetest.register_lbm({ name = "signs_road:conpatibility_2", diff --git a/signs_road/depends.txt b/signs_road/depends.txt index 730e727..eeb3b01 100644 --- a/signs_road/depends.txt +++ b/signs_road/depends.txt @@ -1,6 +1,6 @@ default intllib? dye -display_lib -font_lib -signs +display_api +font_api +signs_api diff --git a/signs_road/nodes.lua b/signs_road/nodes.lua index b167db8..c4c0b04 100644 --- a/signs_road/nodes.lua +++ b/signs_road/nodes.lua @@ -131,7 +131,7 @@ local models = { width = 1, height = 0.5, entity_fields = { - resolution = { x = 7, y = 5 }, + resolution = { x = 7, y = 5 }, maxlines = 1, color = "#000", }, @@ -142,8 +142,8 @@ local models = { "signs_road_sides.png", "signs_road_black_dir_right.png" }, inventory_image = "signs_road_black_dir_inventory.png", signs_other_dir = "signs_road:black_left_sign", - on_place = signs.on_place_direction, - on_rightclick = signs.on_right_click_direction, + on_place = signs_api.on_place_direction, + on_rightclick = signs_api.on_right_click_direction, }, }, black_left_sign = { @@ -164,8 +164,8 @@ local models = { signs_other_dir = "signs_road:black_right_sign", groups = { not_in_creative_inventory = 1 }, drop = "signs_road:black_right_sign", - on_place = signs.on_place_direction, - on_rightclick = signs.on_right_click_direction, + on_place = signs_api.on_place_direction, + on_rightclick = signs_api.on_right_click_direction, }, }, @@ -174,7 +174,7 @@ local models = { width = 14/16, height = 7/16, entity_fields = { - right = -3/32, + right = -3/32, size = { x = 12/16, y = 6/16 }, resolution = { x = 9, y = 5.5 }, maxlines = 2, @@ -185,8 +185,8 @@ local models = { tiles = { "signs_road_green_direction.png" }, inventory_image = "signs_road_green_dir_inventory.png", signs_other_dir = "signs_road:green_left_sign", - on_place = signs.on_place_direction, - on_rightclick = signs.on_right_click_direction, + on_place = signs_api.on_place_direction, + on_rightclick = signs_api.on_right_click_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 } }, @@ -198,7 +198,7 @@ local models = { width = 14/16, height = 7/16, entity_fields = { - right = 3/32, + right = 3/32, size = { x = 12/16, y = 6/16 }, resolution = { x = 9, y = 5.5 }, maxlines = 2, @@ -209,8 +209,8 @@ local models = { tiles = { "signs_road_green_direction.png" }, inventory_image = "signs_road_green_dir_inventory.png", signs_other_dir = "signs_road:green_right_sign", - on_place = signs.on_place_direction, - on_rightclick = signs.on_right_click_direction, + on_place = signs_api.on_place_direction, + on_rightclick = signs_api.on_right_click_direction, drawtype = "mesh", mesh = "signs_dir_left.obj", selection_box = { type = "fixed", fixed = { -7/16, -7/32, 0.5, 0.5, 7/32, 7/16 } }, @@ -224,7 +224,7 @@ local models = { width = 14/16, height = 7/16, entity_fields = { - right = -3/32, + right = -3/32, size = { x = 12/16, y = 6/16 }, resolution = { x = 9, y = 5.5 }, maxlines = 2, @@ -235,8 +235,8 @@ local models = { tiles = { "signs_road_yellow_direction.png" }, inventory_image = "signs_road_yellow_dir_inventory.png", signs_other_dir = "signs_road:yellow_left_sign", - on_place = signs.on_place_direction, - on_rightclick = signs.on_right_click_direction, + on_place = signs_api.on_place_direction, + on_rightclick = signs_api.on_right_click_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 } }, @@ -248,7 +248,7 @@ local models = { width = 14/16, height = 7/16, entity_fields = { - right = 3/32, + right = 3/32, size = { x = 12/16, y = 6/16 }, resolution = { x = 9, y = 5.5 }, maxlines = 2, @@ -259,8 +259,8 @@ local models = { tiles = { "signs_road_yellow_direction.png" }, inventory_image = "signs_road_yellow_dir_inventory.png", signs_other_dir = "signs_road:yellow_right_sign", - on_place = signs.on_place_direction, - on_rightclick = signs.on_right_click_direction, + on_place = signs_api.on_place_direction, + on_rightclick = signs_api.on_right_click_direction, drawtype = "mesh", mesh = "signs_dir_left.obj", selection_box = { type = "fixed", fixed = { -7/16, -7/32, 0.5, 0.5, 7/32, 7/16 } }, @@ -274,7 +274,7 @@ local models = { width = 14/16, height = 7/16, entity_fields = { - right = -3/32, + right = -3/32, size = { x = 12/16, y = 6/16 }, resolution = { x = 9, y = 5.5 }, maxlines = 2, @@ -285,8 +285,8 @@ local models = { tiles = { "signs_road_white_direction.png" }, inventory_image = "signs_road_white_dir_inventory.png", signs_other_dir = "signs_road:white_left_sign", - on_place = signs.on_place_direction, - on_rightclick = signs.on_right_click_direction, + on_place = signs_api.on_place_direction, + on_rightclick = signs_api.on_right_click_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 } }, @@ -298,7 +298,7 @@ local models = { width = 14/16, height = 7/16, entity_fields = { - right = 3/32, + right = 3/32, size = { x = 12/16, y = 6/16 }, resolution = { x = 9, y = 5.5 }, maxlines = 2, @@ -309,8 +309,8 @@ local models = { tiles = { "signs_road_white_direction.png" }, inventory_image = "signs_road_white_dir_inventory.png", signs_other_dir = "signs_road:white_right_sign", - on_place=signs.on_place_direction, - on_rightclick = signs.on_right_click_direction, + on_place=signs_api.on_place_direction, + on_rightclick = signs_api.on_right_click_direction, drawtype = "mesh", mesh = "signs_dir_left.obj", selection_box = { type = "fixed", fixed = { -7/16, -7/32, 0.5, 0.5, 7/32, 7/16 } }, @@ -324,7 +324,7 @@ local models = { -- Node registration for name, model in pairs(models) do - signs.register_sign("signs_road", name, model) + signs_api.register_sign("signs_road", name, model) end diff --git a/steles/depends.txt b/steles/depends.txt index 35625c0..ba43223 100644 --- a/steles/depends.txt +++ b/steles/depends.txt @@ -1,5 +1,5 @@ default intllib? -display_lib -font_lib +display_api +font_api technic? diff --git a/steles/nodes.lua b/steles/nodes.lua index d2fb504..eabb096 100644 --- a/steles/nodes.lua +++ b/steles/nodes.lua @@ -21,7 +21,7 @@ local S = steles.intllib local F = function(...) return minetest.formspec_escape(S(...)) end -display_lib.register_display_entity("steles:text") +display_api.register_display_entity("steles:text") for i, material in ipairs(steles.materials) do @@ -30,7 +30,7 @@ for i, material in ipairs(steles.materials) do if ndef then local groups = table.copy(ndef.groups) local parts = material:split(":") - groups.display_lib_node = 1 + groups.display_modpack_node = 1 minetest.register_node("steles:"..parts[2].."_stele", { description = steles.materials_desc[i], @@ -49,8 +49,8 @@ for i, material in ipairs(steles.materials) do groups = groups, display_entities = { ["steles:text"] = { - on_display_update = font_lib.on_display_update, - depth = -2/16 - display_lib.entity_spacing, height = 2/16, + on_display_update = font_api.on_display_update, + depth = -2/16 - display_api.entity_spacing, height = 2/16, size = { x = 14/16, y = 12/16 }, resolution = { x = 11, y = 5 }, maxlines = 3, @@ -58,7 +58,7 @@ for i, material in ipairs(steles.materials) do }, on_place = function(itemstack, placer, pointed_thing) minetest.rotate_node(itemstack, placer, pointed_thing) - display_lib.on_place(itemstack, placer, pointed_thing) + display_api.on_place(itemstack, placer, pointed_thing) end, on_construct = function(pos) local meta = minetest.get_meta(pos) @@ -68,21 +68,21 @@ for i, material in ipairs(steles.materials) do ..F("Displayed text (3 lines max)") ..";${display_text}]" .."button_exit[2,3;2,1;ok;"..F("Write").."]") - display_lib.on_construct(pos) + display_api.on_construct(pos) end, - on_destruct = display_lib.on_destruct, - on_rotate = display_lib.on_rotate, + on_destruct = display_api.on_destruct, + on_rotate = display_api.on_rotate, on_receive_fields = function(pos, formname, fields, player) if not minetest.is_protected(pos, player:get_player_name()) then local meta = minetest.get_meta(pos) if fields and fields.ok then meta:set_string("display_text", fields.display_text) meta:set_string("infotext", "\""..fields.display_text.."\"") - display_lib.update_entities(pos) + display_api.update_entities(pos) end end end, - on_punch = display_lib.update_entities, + on_punch = display_api.update_entities, }) end end -- cgit v1.2.3 From 8661a5ca622f35284b6631b0a4364e1961dbfaec Mon Sep 17 00:00:00 2001 From: Pierre-Yves Rollo Date: Mon, 9 Jul 2018 13:55:07 +0200 Subject: Fixed crash when opening Poster formspec due to change in font_api. --- signs/nodes.lua | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'signs') diff --git a/signs/nodes.lua b/signs/nodes.lua index 18bf1d6..bad9811 100644 --- a/signs/nodes.lua +++ b/signs/nodes.lua @@ -28,9 +28,8 @@ local function display_poster(pos, node, player) local def = minetest.registered_nodes[node.name].display_entities["signs:display_text"] -- Title texture - local titletexture = font_api.make_multiline_texture( - def.font_name, meta:get_string("display_text"), - 116, 12, def.maxlines, def.valign, def.color) + local titletexture = font:make_text_texture( + meta:get_string("display_text"), 116, 12, 1, "center") formspec = "size[7,9]".. -- cgit v1.2.3 From e51afb851c996ad60d59b2c1f3e608b0d9b50864 Mon Sep 17 00:00:00 2001 From: Pierre-Yves Rollo Date: Mon, 9 Jul 2018 14:04:51 +0200 Subject: Fix Poster crash (amend) --- signs/nodes.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'signs') diff --git a/signs/nodes.lua b/signs/nodes.lua index bad9811..d635f8f 100644 --- a/signs/nodes.lua +++ b/signs/nodes.lua @@ -26,7 +26,8 @@ local function display_poster(pos, node, player) local formspec 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"), 116, 12, 1, "center") -- cgit v1.2.3 From 8c7557e45d4744fe35ad058950062cf771640126 Mon Sep 17 00:00:00 2001 From: Pierre-Yves Rollo Date: Fri, 13 Jul 2018 20:41:53 +0200 Subject: Rework all nodes displaying text according to new font_api --- display_api/init.lua | 6 +- font_api/font.lua | 16 ++--- font_api/init.lua | 12 ++-- signs/nodes.lua | 12 ++-- signs_api/common.lua | 188 ------------------------------------------------- signs_api/init.lua | 194 ++++++++++++++++++++++++++++++++++++++++++++++++++- signs_road/nodes.lua | 26 +++---- steles/nodes.lua | 13 ++-- 8 files changed, 233 insertions(+), 234 deletions(-) delete mode 100644 signs_api/common.lua (limited to 'signs') diff --git a/display_api/init.lua b/display_api/init.lua index 240ce21..2cd15a0 100644 --- a/display_api/init.lua +++ b/display_api/init.lua @@ -128,15 +128,15 @@ local function place_entities(pos) for entity_name, props in pairs(ndef.display_entities) do local depth = clip_pos_prop(props.depth) - local height = clip_pos_prop(props.height) local right = clip_pos_prop(props.right) + local top = clip_pos_prop(props.top) 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 + height, + y = pos.y - top, z = pos.z - values.dz * depth + values.rz * right}) objrefs[entity_name]:setyaw(values.yaw) @@ -268,4 +268,4 @@ minetest.register_lbm({ }) -- Compatibility -display_lib = display_api \ No newline at end of file +display_lib = display_api diff --git a/font_api/font.lua b/font_api/font.lua index 6c848f6..4619e7a 100644 --- a/font_api/font.lua +++ b/font_api/font.lua @@ -17,11 +17,6 @@ along with this program. If not, see . --]] - ---[[ - Margins, spacings, can be negative numbers -]]-- - -- Local functions ------------------ @@ -146,10 +141,10 @@ function font_api.Font:get_height(nb_of_lines) return ( (self.height or 0) + - (self.margin_top or 0) + - (self.margin_bottom or 0) + (self.margintop or 0) + + (self.marginbottom or 0) ) * nb_of_lines + - (self.line_spacing or 0) * (nb_of_lines -1) + (self.linespacing or 0) * (nb_of_lines -1) else return nb_of_lines == 0 and 0 or nil end @@ -192,6 +187,7 @@ function font_api.Font:make_line_texture(line, texturew, x, y) -- Replace chars with no texture by the NULL(0) char if self.widths[char] == nil +or char == 88 then print(string.format("["..font_api.name .."] Missing char %d (%04x)",char,char)) @@ -243,6 +239,8 @@ 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 if halign == "left" then @@ -259,7 +257,7 @@ function font_api.Font:make_text_texture(text, texturew, textureh, maxlines, (texturew - line.width) / 2, y) end - y = y + self:get_height() + (self.line_spacing or 0) + y = y + self:get_height() + (self.linespacing or 0) end texture = string.format("[combine:%dx%d", texturew, textureh)..texture diff --git a/font_api/init.lua b/font_api/init.lua index 2dc38ec..06619be 100644 --- a/font_api/init.lua +++ b/font_api/init.lua @@ -45,10 +45,14 @@ function font_api.on_display_update(pos, objref) if entity and ndef.display_entities[entity.name] then local def = ndef.display_entities[entity.name] local font = font_api.get_font(meta:get_string("font") or def.font_name) - objref:set_properties({ - textures={font:make_text_texture(text, - def.size.x * def.resolution.x * font.height, - def.size.y * def.resolution.y * font.height, + + local maxlines = def.maxlines or 1 -- TODO:How to do w/o maxlines ? + + objref:set_properties({ + textures={font:make_text_texture(text, + font:get_height(maxlines) * def.size.x / def.size.y + / (def.aspect_ratio or 1), + font:get_height(maxlines), def.maxlines, def.halign, def.valign, def.color)}, visual_size = def.size }) diff --git a/signs/nodes.lua b/signs/nodes.lua index d635f8f..7e2dbe8 100644 --- a/signs/nodes.lua +++ b/signs/nodes.lua @@ -30,12 +30,12 @@ local function display_poster(pos, node, player) -- Title texture local titletexture = font:make_text_texture( - meta:get_string("display_text"), 116, 12, 1, "center") + meta:get_string("display_text"), font:get_height()*8.4, font:get_height(), 1, "center") formspec = "size[7,9]".. "background[0,0;7,9;signs_poster_formspec.png]".. - "image[0,0;8.4,1.5;"..titletexture.."]".. + "image[0,-0.2;8.4,2;"..titletexture.."]".. "textarea[0.3,1.5;7,8;;"..minetest.colorize("#111", minetest.formspec_escape(meta:get_string("text")))..";]".. "bgcolor[#0000]" @@ -105,7 +105,6 @@ local models = { entity_fields = { right = -3/32, size = { x = 12/16, y = 6/16 }, - resolution = { x = 9, y = 5 }, maxlines = 2, color="#000", }, @@ -128,7 +127,6 @@ local models = { entity_fields = { right = 3/32, size = { x = 12/16, y = 6/16 }, - resolution = { x = 9, y = 5 }, maxlines = 2, color = "#000", }, @@ -150,10 +148,10 @@ local models = { width = 26/32, height = 30/32, entity_fields = { - resolution = { x = 11, y = 5 }, + top = -11/32, + size = { x = 26/32, y = 6/32 }, maxlines = 1, - color="#000", - valign="top", + color = "#000", }, node_fields = { description = S("Poster"), diff --git a/signs_api/common.lua b/signs_api/common.lua deleted file mode 100644 index 2528ff5..0000000 --- a/signs_api/common.lua +++ /dev/null @@ -1,188 +0,0 @@ ---[[ - signs mod for Minetest - Various signs with text displayed on - (c) Pierre-Yves Rollo - - This file is part of signs. - - signs 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. - - signs 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 signs. If not, see . ---]] - -local S = signs_api.intllib -local F = function(...) return minetest.formspec_escape(S(...)) end - -function signs_api.set_display_text(pos,text) - local meta = minetest.get_meta(pos) - meta:set_string("display_text", text) - meta:set_string("infotext", "\""..text.."\"") - display_api.update_entities(pos) -end - -function signs_api.set_formspec(pos) - local meta = minetest.get_meta(pos) - local ndef = minetest.registered_nodes[minetest.get_node(pos).name] - if ndef and ndef.display_entities and ndef.display_entities["signs:display_text"] then - local maxlines = ndef.display_entities["signs:display_text"].maxlines - local formspec - - if maxlines == 1 then - formspec = "size[6,3]".. - default.gui_bg .. default.gui_bg_img .. default.gui_slots .. - "field[0.5,0.7;5.5,1;display_text;"..F("Text")..";${display_text}]".. - "button_exit[2,2;2,1;ok;"..F("Write").."]" - else - local extralabel = "" - if maxlines then - extralabel = F(" (first %s lines only)"):format(maxlines) - end - - formspec = "size[6,4]".. - default.gui_bg .. default.gui_bg_img .. default.gui_slots .. - "textarea[0.5,0.7;5.5,2;display_text;"..F("Text")..""..extralabel..";${display_text}]".. - "button_exit[2,3;2,1;ok;"..F("Write").."]" - end - - meta:set_string("formspec", formspec) - end -end - -function signs_api.on_receive_fields(pos, formname, fields, player) - if not minetest.is_protected(pos, player:get_player_name()) then - if fields and (fields.ok or fields.key_enter) then - signs_api.set_display_text(pos, fields.display_text) - end - end -end - --- On place callback for direction signs --- (chooses which sign according to look direction) -function signs_api.on_place_direction(itemstack, placer, pointed_thing) - local name = itemstack:get_name() - local ndef = minetest.registered_nodes[name] - - local bdir = {x = pointed_thing.under.x - pointed_thing.above.x, - y = pointed_thing.under.y - pointed_thing.above.y, - z = pointed_thing.under.z - pointed_thing.above.z} - local pdir = placer:get_look_dir() - - local ndir, test - - if ndef.paramtype2 == "facedir" then - if bdir.x == 0 and bdir.z == 0 then - -- Ceiling or floor pointed (facedir chosen from player dir) - ndir = minetest.dir_to_facedir({x=pdir.x, y=0, z=pdir.z}) - else - -- Wall pointed - ndir = minetest.dir_to_facedir(bdir) - end - - test = {[0]=-pdir.x, pdir.z, pdir.x, -pdir.z} - end - - if ndef.paramtype2 == "wallmounted" then - ndir = minetest.dir_to_wallmounted(bdir) - if ndir == 0 or ndir == 1 then - -- Ceiling or floor - ndir = minetest.dir_to_wallmounted({x=pdir.x, y=0, z=pdir.z}) - end - - test = {0, pdir.z, -pdir.z, -pdir.x, pdir.x} - end - - -- Only for direction signs - if ndef.signs_other_dir then - if test[ndir] > 0 then - itemstack:set_name(ndef.signs_other_dir) - end - itemstack = minetest.item_place(itemstack, placer, pointed_thing, ndir) - itemstack:set_name(name) - - return itemstack - else - return minetest.item_place(itemstack, placer, pointed_thing, ndir) - end -end - --- Handles screwdriver rotation. Direction is affected for direction signs -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}) - display_api.update_entities(pos) - end - else - display_api.on_rotate(pos, node, user, mode, new_param2) - end - return false; -end - -function signs_api.register_sign(mod, name, model) - -- Default fields - local fields = { - sunlight_propagates = true, - paramtype = "light", - paramtype2 = "facedir", - drawtype = "nodebox", - node_box = { - type = "fixed", - fixed = {-model.width/2, -model.height/2, 0.5, - model.width/2, model.height/2, 0.5 - model.depth}, - }, - groups = {choppy=2, dig_immediate=2, not_blocking_trains = 1, display_modpack_node = 1}, - sounds = default.node_sound_defaults(), - display_entities = { - ["signs:display_text"] = { - on_display_update = font_api.on_display_update, - depth = 0.5 - display_api.entity_spacing - model.depth, - size = { x = model.width, y = model.height }, - resolution = { x = 64, y = 64 }, - maxlines = 1, - }, - - }, - on_place = display_api.on_place, - on_construct = function(pos) - signs_api.set_formspec(pos) - display_api.on_construct(pos) - end, - on_destruct = display_api.on_destruct, - on_rotate = signs_api.on_rotate, - on_receive_fields = signs_api.on_receive_fields, - on_punch = function(pos, node, player, pointed_thing) display_api.update_entities(pos) end, - } - - -- Node fields override - for key, value in pairs(model.node_fields) do - if key == "groups" then - for key2, value2 in pairs(value) do - fields[key][key2] = value2 - end - else - fields[key] = value - end - end - - if not fields.wield_image then fields.wield_image = fields.inventory_image end - - -- Entity fields override - for key, value in pairs(model.entity_fields) do - fields.display_entities["signs:display_text"][key] = value - end - - minetest.register_node(mod..":"..name, fields) -end - --- Text entity for all signs -display_api.register_display_entity("signs:display_text") diff --git a/signs_api/init.lua b/signs_api/init.lua index c13a253..e8a2b2b 100644 --- a/signs_api/init.lua +++ b/signs_api/init.lua @@ -25,8 +25,200 @@ signs_api.path = minetest.get_modpath(signs_api.name) -- Load support for intllib. local S, NS = dofile(signs_api.path.."/intllib.lua") signs_api.intllib = S +local F = function(...) return minetest.formspec_escape(S(...)) end -dofile(signs_api.path.."/common.lua") +local function update_font_index_meta(meta) + local font = meta:get_string("font") + local count = 0 + for key, def in pairs(font_api.registered_fonts) do + count = count + 1 + if font == key then + meta:set_string("font_idx", count) + end + end +end + +function signs_api.set_display_text(pos,text,font) + local meta = minetest.get_meta(pos) + meta:set_string("display_text", text) + meta:set_string("infotext", "\""..text.."\"") + meta:set_string("font", font) + update_font_index_meta(meta) + display_api.update_entities(pos) +end + +function signs_api.set_formspec(pos) + local meta = minetest.get_meta(pos) + local ndef = minetest.registered_nodes[minetest.get_node(pos).name] + if ndef and ndef.display_entities + and ndef.display_entities["signs:display_text"] then + local maxlines = ndef.display_entities["signs:display_text"].maxlines + local formspec, formheight + + if maxlines == 1 then + formspec = + "field[0.5,0.7;5.5,1;display_text;"..F("Text").. + ";${display_text}]" + formheight = 2 + else + local extralabel = "" + if maxlines then + extralabel = F(" (first %s lines only)"):format(maxlines) + end + + formspec = + "textarea[0.5,0.7;5.5,2;display_text;"..F("Text").."".. + extralabel..";${display_text}]" + formheight = 3 + end + + formspec = formspec.."button_exit[2,"..formheight..";2,1;ok;".. + F("Write").."]" + formheight = formheight + 1 + formspec = "size[6,"..formheight.."]"..default.gui_bg.. + default.gui_bg_img..default.gui_slots..formspec + + meta:set_string("formspec", formspec) + end +end + +function signs_api.on_receive_fields(pos, formname, fields, player) + if not minetest.is_protected(pos, player:get_player_name()) then + if fields and (fields.ok or fields.key_enter) then + signs_api.set_display_text(pos, fields.display_text, fields.font) + end + end +end + +-- On place callback for direction signs +-- (chooses which sign according to look direction) +function signs_api.on_place_direction(itemstack, placer, pointed_thing) + local name = itemstack:get_name() + local ndef = minetest.registered_nodes[name] + + local bdir = {x = pointed_thing.under.x - pointed_thing.above.x, + y = pointed_thing.under.y - pointed_thing.above.y, + z = pointed_thing.under.z - pointed_thing.above.z} + local pdir = placer:get_look_dir() + + local ndir, test + + if ndef.paramtype2 == "facedir" then + if bdir.x == 0 and bdir.z == 0 then + -- Ceiling or floor pointed (facedir chosen from player dir) + ndir = minetest.dir_to_facedir({x=pdir.x, y=0, z=pdir.z}) + else + -- Wall pointed + ndir = minetest.dir_to_facedir(bdir) + end + + test = {[0]=-pdir.x, pdir.z, pdir.x, -pdir.z} + end + + if ndef.paramtype2 == "wallmounted" then + ndir = minetest.dir_to_wallmounted(bdir) + if ndir == 0 or ndir == 1 then + -- Ceiling or floor + ndir = minetest.dir_to_wallmounted({x=pdir.x, y=0, z=pdir.z}) + end + + test = {0, pdir.z, -pdir.z, -pdir.x, pdir.x} + end + + -- Only for direction signs + if ndef.signs_other_dir then + if test[ndir] > 0 then + itemstack:set_name(ndef.signs_other_dir) + end + itemstack = minetest.item_place(itemstack, placer, pointed_thing, ndir) + itemstack:set_name(name) + + return itemstack + else + return minetest.item_place(itemstack, placer, pointed_thing, ndir) + end +end + +-- Handles screwdriver rotation. Direction is affected for direction signs +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}) + display_api.update_entities(pos) + end + else + display_api.on_rotate(pos, node, user, mode, new_param2) + end + return false; +end + +function signs_api.register_sign(mod, name, model) + -- Default fields + local fields = { + sunlight_propagates = true, + paramtype = "light", + paramtype2 = "facedir", + drawtype = "nodebox", + node_box = { + type = "fixed", + fixed = {-model.width/2, -model.height/2, 0.5, + model.width/2, model.height/2, 0.5 - model.depth}, + }, + groups = {choppy=2, dig_immediate=2, not_blocking_trains = 1, display_modpack_node = 1}, + sounds = default.node_sound_defaults(), + display_entities = { + ["signs:display_text"] = { + on_display_update = font_api.on_display_update, + depth = 0.5 - display_api.entity_spacing - model.depth, + size = { x = model.width, y = model.height }, + aspect_ratio = 1/2, + maxlines = 1, + }, + + }, + on_place = display_api.on_place, + on_construct = function(pos) + local ndef = minetest.registered_nodes[minetest.get_node(pos).name] + local meta = minetest.get_meta(pos) + meta:set_string("font", ndef.display_entities.font_name or + font_api.get_default_font_name()) + update_font_index_meta(meta) + signs_api.set_formspec(pos) + display_api.on_construct(pos) + end, + on_destruct = display_api.on_destruct, + on_rotate = signs_api.on_rotate, + on_receive_fields = signs_api.on_receive_fields, + on_punch = function(pos, node, player, pointed_thing) + display_api.update_entities(pos) + end, + } + + -- Node fields override + for key, value in pairs(model.node_fields) do + if key == "groups" then + for key2, value2 in pairs(value) do + fields[key][key2] = value2 + end + else + fields[key] = value + end + end + + if not fields.wield_image then fields.wield_image = fields.inventory_image end + + -- Entity fields override + for key, value in pairs(model.entity_fields) do + fields.display_entities["signs:display_text"][key] = value + end + + minetest.register_node(mod..":"..name, fields) +end + +-- Text entity for all signs +display_api.register_display_entity("signs:display_text") diff --git a/signs_road/nodes.lua b/signs_road/nodes.lua index c4c0b04..ab95b2b 100644 --- a/signs_road/nodes.lua +++ b/signs_road/nodes.lua @@ -27,7 +27,7 @@ local models = { width = 14/16, height = 12/16, entity_fields = { - resolution = { x = 11, y = 5.5 }, + size = { x = 14/16, y = 10/16 }, maxlines = 3, color = "#fff", }, @@ -44,7 +44,6 @@ local models = { width = 64/16, height = 12/16, entity_fields = { - resolution = { x = 2.5, y = 1.5 }, maxlines = 1, color = "#000", }, @@ -57,13 +56,12 @@ local models = { inventory_image = "signs_road_white.png", }, }, - red_street_sign = { depth = 1/16, width = 1, height = 7/16, entity_fields = { - resolution = { x = 8, y = 4 }, + size = { x = 1, y = 4/16 }, maxlines = 1, color = "#000", }, @@ -80,7 +78,7 @@ local models = { width = 1, height = 7/16, entity_fields = { - resolution = { x = 9, y = 5.5 }, + size = { x = 1, y = 6/16 }, maxlines = 2, color = "#000", }, @@ -97,7 +95,7 @@ local models = { width = 1, height = 7/16, entity_fields = { - resolution = { x = 9, y = 5.5 }, + size = { x = 1, y = 6/16 }, maxlines = 2, color = "#fff", }, @@ -114,7 +112,7 @@ local models = { width = 1, height = 7/16, entity_fields = { - resolution = { x = 9, y = 5.5 }, + size = { x = 1, y = 6/16 }, maxlines = 2, color = "#000", }, @@ -131,7 +129,8 @@ local models = { width = 1, height = 0.5, entity_fields = { - resolution = { x = 7, y = 5 }, + aspect_ratio = 3/4, + size = { x = 1, y = 3/16 }, maxlines = 1, color = "#000", }, @@ -151,7 +150,8 @@ local models = { width = 1, height = 0.5, entity_fields = { - resolution = { x = 7, y = 5 }, + aspect_ratio = 3/4, + size = { x = 1, y = 3/16 }, maxlines = 1, color = "#000", }, @@ -176,7 +176,6 @@ local models = { entity_fields = { right = -3/32, size = { x = 12/16, y = 6/16 }, - resolution = { x = 9, y = 5.5 }, maxlines = 2, color = "#fff", }, @@ -200,7 +199,6 @@ local models = { entity_fields = { right = 3/32, size = { x = 12/16, y = 6/16 }, - resolution = { x = 9, y = 5.5 }, maxlines = 2, color="#fff", }, @@ -226,7 +224,6 @@ local models = { entity_fields = { right = -3/32, size = { x = 12/16, y = 6/16 }, - resolution = { x = 9, y = 5.5 }, maxlines = 2, color = "#000", }, @@ -250,7 +247,6 @@ local models = { entity_fields = { right = 3/32, size = { x = 12/16, y = 6/16 }, - resolution = { x = 9, y = 5.5 }, maxlines = 2, color = "#000", }, @@ -266,7 +262,7 @@ local models = { 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 }, - drop = "signs_road:yellow_left_sign", + drop = "signs_road:yellow_right_sign", }, }, white_right_sign = { @@ -276,7 +272,6 @@ local models = { entity_fields = { right = -3/32, size = { x = 12/16, y = 6/16 }, - resolution = { x = 9, y = 5.5 }, maxlines = 2, color = "#000", }, @@ -300,7 +295,6 @@ local models = { entity_fields = { right = 3/32, size = { x = 12/16, y = 6/16 }, - resolution = { x = 9, y = 5.5 }, maxlines = 2, color = "#000", }, diff --git a/steles/nodes.lua b/steles/nodes.lua index eabb096..9fb65dd 100644 --- a/steles/nodes.lua +++ b/steles/nodes.lua @@ -42,17 +42,18 @@ for i, material in ipairs(steles.materials) do node_box = { type = "fixed", fixed = { - {-5/16, -4/16, -2/16, 5/16, 0.5, 2/16}, - {-7/16, -0.5, -4/16, 7/16, -4/16, 4/16} - } + {-5/16, -5/16, -2/16, 5/16, 0.5, 2/16}, + {-7/16, -0.5, -4/16, 7/16, -5/16, 4/16} + }, }, groups = groups, display_entities = { ["steles:text"] = { on_display_update = font_api.on_display_update, - depth = -2/16 - display_api.entity_spacing, height = 2/16, - size = { x = 14/16, y = 12/16 }, - resolution = { x = 11, y = 5 }, + depth = -2/16 - display_api.entity_spacing, + top = -2/16, + aspect_ratio = 0.4, + size = { x = 10/16, y = 12/16 }, maxlines = 3, }, }, -- cgit v1.2.3 From 2793e0ab8f67b28120bc19086efe126c96cd79dd Mon Sep 17 00:00:00 2001 From: Pierre-Yves Rollo Date: Thu, 20 Sep 2018 15:27:42 +0200 Subject: Added simple wooden sign --- signs/nodes.lua | 24 +++++++++++++++++++----- signs/textures/signs_wooden_inventory.png | Bin 606 -> 581 bytes 2 files changed, 19 insertions(+), 5 deletions(-) (limited to 'signs') diff --git a/signs/nodes.lua b/signs/nodes.lua index 7e2dbe8..7500297 100644 --- a/signs/nodes.lua +++ b/signs/nodes.lua @@ -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,7 +77,7 @@ 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 + if formname == node.name.."@"..minetest.pos_to_string(pos)..":display" and fields.edit then edit_poster(pos, node, player) end @@ -98,6 +98,21 @@ 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", + }, + }, wooden_right_sign = { depth = 1/16, width = 14/16, @@ -111,7 +126,7 @@ 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", @@ -133,7 +148,7 @@ 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", @@ -171,4 +186,3 @@ for name, model in pairs(models) do signs_api.register_sign("signs", name, model) end - diff --git a/signs/textures/signs_wooden_inventory.png b/signs/textures/signs_wooden_inventory.png index d997480..bb7e949 100644 Binary files a/signs/textures/signs_wooden_inventory.png and b/signs/textures/signs_wooden_inventory.png differ -- cgit v1.2.3 From c1f7b571b8a7592b79fd2f9d01507e642ed35597 Mon Sep 17 00:00:00 2001 From: Pierre-Yves Rollo Date: Thu, 20 Sep 2018 21:15:23 +0200 Subject: Add missing textures --- signs/textures/signs_wooden.png | Bin 0 -> 574 bytes signs/textures/signs_wooden_direction_inventory.png | Bin 0 -> 546 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 signs/textures/signs_wooden.png create mode 100644 signs/textures/signs_wooden_direction_inventory.png (limited to 'signs') diff --git a/signs/textures/signs_wooden.png b/signs/textures/signs_wooden.png new file mode 100644 index 0000000..164948a Binary files /dev/null and b/signs/textures/signs_wooden.png differ diff --git a/signs/textures/signs_wooden_direction_inventory.png b/signs/textures/signs_wooden_direction_inventory.png new file mode 100644 index 0000000..1b8e3d4 Binary files /dev/null and b/signs/textures/signs_wooden_direction_inventory.png differ -- cgit v1.2.3 From c1835931e52769bf50425990370b60dfc9d17f63 Mon Sep 17 00:00:00 2001 From: Pierre-Yves Rollo Date: Thu, 1 Nov 2018 18:10:26 +0100 Subject: Added labels and wooden signs --- signs/crafts.lua | 47 +++++- signs/nodes.lua | 75 +++++++-- signs/svg/poster.svg | 171 ++++++++++++--------- signs/textures/signs_label.png | Bin 0 -> 404 bytes signs/textures/signs_label_medium_inventory.png | Bin 0 -> 406 bytes signs/textures/signs_label_small_inventory.png | Bin 0 -> 417 bytes .../textures/signs_wooden_direction_inventory.png | Bin 546 -> 710 bytes signs/textures/signs_wooden_long.png | Bin 0 -> 524 bytes signs/textures/signs_wooden_long_inventory.png | Bin 0 -> 636 bytes 9 files changed, 202 insertions(+), 91 deletions(-) create mode 100644 signs/textures/signs_label.png create mode 100644 signs/textures/signs_label_medium_inventory.png create mode 100644 signs/textures/signs_label_small_inventory.png create mode 100644 signs/textures/signs_wooden_long.png create mode 100644 signs/textures/signs_wooden_long_inventory.png (limited to 'signs') diff --git a/signs/crafts.lua b/signs/crafts.lua index b4e0206..ef82dbc 100644 --- a/signs/crafts.lua +++ b/signs/crafts.lua @@ -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'}, + } +}) diff --git a/signs/nodes.lua b/signs/nodes.lua index 7500297..c74ab6f 100644 --- a/signs/nodes.lua +++ b/signs/nodes.lua @@ -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 @@ -99,9 +99,7 @@ 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, + depth = 1/16, width = 14/16, height = 12/16, entity_fields = { size = { x = 12/16, y = 10/16 }, maxlines = 3, @@ -111,12 +109,29 @@ local models = { 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 }, @@ -133,12 +148,11 @@ local models = { 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 }, @@ -154,14 +168,12 @@ local models = { 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 }, @@ -174,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 diff --git a/signs/svg/poster.svg b/signs/svg/poster.svg index 4f6f774..f2388a8 100644 --- a/signs/svg/poster.svg +++ b/signs/svg/poster.svg @@ -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" /> @@ -109,7 +111,7 @@ image/svg+xml - + @@ -127,7 +129,7 @@ height="32.081406" width="32.003735" /> + y="-10.876763" + style="font-family:sans-serif" />  + inkscape:label="Fond inv" + style="display:inline"> READ ME ! + style="font-weight:bold;font-size:3.42845988px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:'Sans Bold'">READ ME ! + + + + + style="display:none"> diff --git a/signs/textures/signs_label.png b/signs/textures/signs_label.png new file mode 100644 index 0000000..4cf7edc Binary files /dev/null and b/signs/textures/signs_label.png differ diff --git a/signs/textures/signs_label_medium_inventory.png b/signs/textures/signs_label_medium_inventory.png new file mode 100644 index 0000000..9622201 Binary files /dev/null and b/signs/textures/signs_label_medium_inventory.png differ diff --git a/signs/textures/signs_label_small_inventory.png b/signs/textures/signs_label_small_inventory.png new file mode 100644 index 0000000..2dd60af Binary files /dev/null and b/signs/textures/signs_label_small_inventory.png differ diff --git a/signs/textures/signs_wooden_direction_inventory.png b/signs/textures/signs_wooden_direction_inventory.png index 1b8e3d4..c4be3af 100644 Binary files a/signs/textures/signs_wooden_direction_inventory.png and b/signs/textures/signs_wooden_direction_inventory.png differ diff --git a/signs/textures/signs_wooden_long.png b/signs/textures/signs_wooden_long.png new file mode 100644 index 0000000..c23a56a Binary files /dev/null and b/signs/textures/signs_wooden_long.png differ diff --git a/signs/textures/signs_wooden_long_inventory.png b/signs/textures/signs_wooden_long_inventory.png new file mode 100644 index 0000000..78d2545 Binary files /dev/null and b/signs/textures/signs_wooden_long_inventory.png differ -- cgit v1.2.3 From d9b10f6c3e7b133b5539e39c6da0ffebde1f4b59 Mon Sep 17 00:00:00 2001 From: Pierre-Yves Rollo Date: Tue, 13 Nov 2018 17:20:06 +0100 Subject: Update depends.txt --- signs/depends.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'signs') diff --git a/signs/depends.txt b/signs/depends.txt index ad3bb8f..aaf5bff 100644 --- a/signs/depends.txt +++ b/signs/depends.txt @@ -1,5 +1,6 @@ default -intllib? +dye display_api font_api signs_api +intllib? -- cgit v1.2.3 From 4eb72f0c3f3bdbd7cd6f2320f508d4376b6ce3b5 Mon Sep 17 00:00:00 2001 From: Pierre-Yves Rollo Date: Sun, 18 Nov 2018 15:31:53 +0100 Subject: Moved compatibility functions to compatibility.lua --- signs/common.lua | 34 ---------------------------------- signs/compatibility.lua | 29 ++++++++++++++++++++++++++++- 2 files changed, 28 insertions(+), 35 deletions(-) (limited to 'signs') diff --git a/signs/common.lua b/signs/common.lua index 2b40db2..733a44c 100644 --- a/signs/common.lua +++ b/signs/common.lua @@ -21,40 +21,6 @@ local S = signs.intllib local F = function(...) return minetest.formspec_escape(S(...)) end - ---Backwards compatibility functions - -signs.set_display_text = function(...) - minetest.log("warning", "signs.set_display_text() is deprecated, please use signs_api.set_display_text() instead.") - return signs_api.set_display_text(...) -end - -signs.set_formspec = function(...) - minetest.log("warning", "signs.set_formspec() is deprecated, please use signs_api.set_formspec() instead.") - return signs_api.set_formspec(...) -end - -signs.on_receive_fields = function(...) - minetest.log("warning", "signs.on_receive_fields() is deprecated, please use signs_api.on_receive_fields() instead.") - return signs_api.on_receive_fields(...) -end - -signs.on_place_direction = function(...) - minetest.log("warning", "signs.on_place_direction() is deprecated, please use signs_api.on_place_direction() instead.") - return signs_api.on_place_direction(...) -end - -signs.on_rotate = function(...) - minetest.log("warning", "signs.on_rotate() is deprecated, please use signs_api.on_rotate() instead.") - return signs_api.on_rotate(...) -end - -signs.register_sign = function(...) - minetest.log("warning", "signs.register_sign() is deprecated, please use signs_api.register_sign() instead.") - return signs_api.register_sign(...) -end - - -- Generic callback for show_formspec displayed formspecs of "sign" mod minetest.register_on_player_receive_fields(function(player, formname, fields) diff --git a/signs/compatibility.lua b/signs/compatibility.lua index e798a67..dea8750 100644 --- a/signs/compatibility.lua +++ b/signs/compatibility.lua @@ -23,7 +23,7 @@ ------------------------------------ local wallmounted_to_facedir = { - [0]=1, -- Should not happend with signs + [0]=1, -- Should not happend with signs [1]=1, -- Should not happend with signs [2]=1, [3]=3, @@ -84,7 +84,34 @@ minetest.register_lbm({ name = "signs:conpatibility_2", action = compatibility_check_2, }) +--Backwards compatibility API functions +signs.set_display_text = function(...) + minetest.log("warning", "signs.set_display_text() is deprecated, please use signs_api.set_display_text() instead.") + return signs_api.set_display_text(...) +end + +signs.set_formspec = function(...) + minetest.log("warning", "signs.set_formspec() is deprecated, please use signs_api.set_formspec() instead.") + return signs_api.set_formspec(...) +end + +signs.on_receive_fields = function(...) + minetest.log("warning", "signs.on_receive_fields() is deprecated, please use signs_api.on_receive_fields() instead.") + return signs_api.on_receive_fields(...) +end +signs.on_place_direction = function(...) + minetest.log("warning", "signs.on_place_direction() is deprecated, please use signs_api.on_place_direction() instead.") + return signs_api.on_place_direction(...) +end +signs.on_rotate = function(...) + minetest.log("warning", "signs.on_rotate() is deprecated, please use signs_api.on_rotate() instead.") + return signs_api.on_rotate(...) +end +signs.register_sign = function(...) + minetest.log("warning", "signs.register_sign() is deprecated, please use signs_api.register_sign() instead.") + return signs_api.register_sign(...) +end -- cgit v1.2.3 From db66553fbfd5f251b4a26e8b4867cebd021a5647 Mon Sep 17 00:00:00 2001 From: Pierre-Yves Rollo Date: Sun, 18 Nov 2018 15:34:49 +0100 Subject: Update poster.svg --- signs/svg/poster.svg | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) (limited to 'signs') diff --git a/signs/svg/poster.svg b/signs/svg/poster.svg index f2388a8..cc9e8fd 100644 --- a/signs/svg/poster.svg +++ b/signs/svg/poster.svg @@ -75,15 +75,15 @@ inkscape:pageshadow="2" inkscape:zoom="22.395604" inkscape:cx="15.573035" - inkscape:cy="16.977299" + inkscape:cy="16.910322" inkscape:current-layer="layer2" showgrid="true" inkscape:grid-bbox="true" inkscape:document-units="px" - inkscape:window-width="785" - inkscape:window-height="447" - inkscape:window-x="2459" - inkscape:window-y="340" + inkscape:window-width="1441" + inkscape:window-height="1038" + inkscape:window-x="2012" + inkscape:window-y="467" inkscape:window-maximized="0" showguides="true" inkscape:guide-bbox="true" @@ -197,7 +197,7 @@ inkscape:groupmode="layer" id="layer2" inkscape:label="Label frame" - style="display:inline"> + style="display:none"> + ry="0" + inkscape:export-filename="/home/pyrollo/dev/minetest-mods/display_modpack/signs/textures/signs_label.png" + inkscape:export-xdpi="90" + inkscape:export-ydpi="90" /> Date: Fri, 23 Nov 2018 11:34:55 +0100 Subject: Fonts configurable in signs, posters and steles --- font_api/fontform.lua | 33 ++++++++++++------ signs/nodes.lua | 93 +++++++++++++++++++++++++++++++-------------------- signs_api/init.lua | 2 +- steles/nodes.lua | 22 +++++++----- 4 files changed, 94 insertions(+), 56 deletions(-) (limited to 'signs') diff --git a/font_api/fontform.lua b/font_api/fontform.lua index 01929dd..e4952ed 100644 --- a/font_api/fontform.lua +++ b/font_api/fontform.lua @@ -101,16 +101,18 @@ local function show_font_formspec(playername) 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]' + local fs = string.format( + "size[4,%s]%s%s%sbutton_exit[0,%s;4,1;cancel;Cancel]", + #fonts + 0.8, default.gui_bg, default.gui_bg_img, default.gui_slots, + #fonts) 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, + local texture = 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..';]' + fs = string.format( + "%simage[0.1,%s;4.5,0.8;%s]button_exit[0,%s;4,1;font_%s;]", + fs, line-0.9, texture, line-1, font.name) end minetest.show_formspec(context.playername, modname..':font_list', fs) end @@ -127,7 +129,8 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) local playername = player:get_player_name() local context = get_context(playername) - if minetest.is_protected(context.pos, playername) then + if not context.pos + or minetest.is_protected(context.pos, playername) then return true end @@ -139,16 +142,26 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) 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) + + if context.callback and type(context.callback) == "function" then + -- Using after to avoid the "double close" bug + minetest.after(0, context.callback, playername, context.pos) + else + -- Using after to avoid the "double close" bug + minetest.after(0, show_node_formspec, playername, context.pos) + end end return true end) -function font_api.show_font_list_from_pos(player, pos) +-- @param player Player viewing the form +-- @param pos Node pos +-- @param callback function(playername, pos) to be called on form close +function font_api.show_font_list(player, pos, callback) if minetest.is_player(player) then local context = get_context(player:get_player_name()) context.pos = pos + context.callback = callback show_font_formspec(player:get_player_name()) end end diff --git a/signs/nodes.lua b/signs/nodes.lua index c74ab6f..8e65e27 100644 --- a/signs/nodes.lua +++ b/signs/nodes.lua @@ -23,51 +23,58 @@ local F = function(...) return minetest.formspec_escape(S(...)) end -- Poster specific formspec local function display_poster(pos, node, player) - local formspec 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) + local fs + local fname = string.format("%s@%s:display", + node.name, minetest.pos_to_string(pos)) + -- Title texture local titletexture = font:make_text_texture( - meta:get_string("display_text"), font:get_height()*8.4, font:get_height(), 1, "center") - - formspec = - "size[7,9]".. - "background[0,0;7,9;signs_poster_formspec.png]".. - "image[0,-0.2;8.4,2;"..titletexture.."]".. - "textarea[0.3,1.5;7,8;;"..minetest.colorize("#111", minetest.formspec_escape(meta:get_string("text")))..";]".. - "bgcolor[#0000]" + meta:get_string("display_text"), font:get_height()*8.4, + font:get_height(), 1, "center") + + fs = string.format([=[ + size[7,9]bgcolor[#0000] + background[0,0;7,9;signs_poster_formspec.png] + image[0,-0.2;8.4,2;%s] + textarea[0.3,1.5;7,8;;%s;]]=], + titletexture, + minetest.colorize("#111", + minetest.formspec_escape(meta:get_string("text")))) if minetest.is_protected(pos, player:get_player_name()) then - formspec = formspec.. - "button_exit[2.5,8;2,1;ok;"..F("Close").."]" + fs = string.format("%sbutton_exit[2.5,8;2,1;ok;%s]", fs, F("Close")) else - formspec = formspec.. - "button[1,8;2,1;edit;"..F("Edit").."]".. - "button_exit[4,8;2,1;ok;"..F("Close").."]" + fs = string.format( + "%sbutton[1,8;2,1;edit;%s]button_exit[4,8;2,1;ok;%s]", + fs, F("Edit"), F("Close")) end - minetest.show_formspec(player:get_player_name(), - node.name.."@"..minetest.pos_to_string(pos)..":display", - formspec) + minetest.show_formspec(player:get_player_name(), fname, fs) end local function edit_poster(pos, node, player) - local formspec local meta = minetest.get_meta(pos) + local fs + local fname = string.format("%s@%s:edit", + node.name, minetest.pos_to_string(pos)) + if not minetest.is_protected(pos, player:get_player_name()) then - formspec = - "size[6.5,7.5]".. - default.gui_bg .. default.gui_bg_img .. default.gui_slots .. - "field[0.5,0.7;6,1;display_text;"..F("Title")..";".. - minetest.formspec_escape(meta:get_string("display_text")).."]".. - "textarea[0.5,1.7;6,6;text;"..F("Text")..";".. - minetest.formspec_escape(meta:get_string("text")).."]".. - "button_exit[2.25,7;2,1;write;"..F("Write").."]" - minetest.show_formspec(player:get_player_name(), - node.name.."@"..minetest.pos_to_string(pos)..":edit", - formspec) + fs = string.format([=[ + size[6.5,7.5]%s%s%s + field[0.5,0.7;6,1;display_text;%s;%s] + textarea[0.5,1.7;6,6;text;%s;%s] + button[1.25,7;2,1;font;%s] + button_exit[3.25,7;2,1;write;%s]]=], + default.gui_bg, default.gui_bg_img, default.gui_slots, F("Title"), + minetest.formspec_escape(meta:get_string("display_text")), + F("Text"), minetest.formspec_escape(meta:get_string("text")), + F("Title font"), F("Write")) + minetest.show_formspec(player:get_player_name(), fname, fs) end end @@ -80,15 +87,29 @@ local function on_receive_fields_poster(pos, formname, fields, player) if formname == node.name.."@"..minetest.pos_to_string(pos)..":display" and fields.edit then edit_poster(pos, node, player) + return true end 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 - .."\"\n"..S("(right-click to read more text)")) - display_api.update_entities(pos) - display_poster(pos, node, player) + then + if (fields.write or fields.font 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 + .."\"\n"..S("(right-click to read more text)")) + display_api.update_entities(pos) + end + if (fields.write or fields.key_enter) then + display_poster(pos, node, player) + elseif (fields.font) then + font_api.show_font_list(player, pos, function (playername, pos) + local player = minetest.get_player_by_name(playername) + local node = minetest.get_node(pos) + if player and node then + edit_poster(pos, node, player) + end + end) + end + return true end end end diff --git a/signs_api/init.lua b/signs_api/init.lua index 4f21495..9fcaa10 100644 --- a/signs_api/init.lua +++ b/signs_api/init.lua @@ -81,7 +81,7 @@ function signs_api.on_receive_fields(pos, formname, fields, player) 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) + font_api.show_font_list(player, pos) end end end diff --git a/steles/nodes.lua b/steles/nodes.lua index 9b23b8d..79a9ed3 100644 --- a/steles/nodes.lua +++ b/steles/nodes.lua @@ -50,7 +50,7 @@ for i, material in ipairs(steles.materials) do display_entities = { ["steles:text"] = { on_display_update = font_api.on_display_update, - depth = -2/16 - display_api.entity_spacing, + depth = -2/16 - display_api.entity_spacing, top = -2/16, aspect_ratio = 0.4, size = { x = 10/16, y = 12/16 }, @@ -63,12 +63,14 @@ for i, material in ipairs(steles.materials) do end, on_construct = function(pos) local meta = minetest.get_meta(pos) - meta:set_string("formspec", "size[6,4]" - ..default.gui_bg .. default.gui_bg_img .. default.gui_slots - .."textarea[0.5,0.7;5.5,2;display_text;" - ..F("Displayed text (3 lines max)") - ..";${display_text}]" - .."button_exit[2,3;2,1;ok;"..F("Write").."]") + meta:set_string("formspec", string.format([=[ + size[6,4]%s%s%s + textarea[0.5,0.7;5.5,2;display_text;%s;${display_text}] + button[1,3;2,1;font;%s] + button_exit[3,3;2,1;ok;%s]]=], + default.gui_bg, default.gui_bg_img, default.gui_slots, + F("Displayed text (3 lines max)"), + F("Font"), F("Write"))) display_api.on_construct(pos) end, on_destruct = display_api.on_destruct, @@ -76,15 +78,17 @@ for i, material in ipairs(steles.materials) do on_receive_fields = function(pos, formname, fields, player) if not minetest.is_protected(pos, player:get_player_name()) then local meta = minetest.get_meta(pos) - if fields and fields.ok then + if fields.ok or fields.font then meta:set_string("display_text", fields.display_text) meta:set_string("infotext", "\""..fields.display_text.."\"") display_api.update_entities(pos) end + if fields.font then + font_api.show_font_list(player, pos) + end end end, on_punch = display_api.update_entities, }) end end - -- cgit v1.2.3