]> git.lizzy.rs Git - signs_lib.git/blob - API.md
Locked Wood Signs
[signs_lib.git] / API.md
1 # Signs_lib API
2
3 In this text, common terms such as `pos`, `node`, or `placer`/`digger` will not be explained unless they have a different meaning than what's usually used in Minetest mods.  See [minetest/doc/lua_api.txt](https://github.com/minetest/minetest/blob/master/doc/lua_api.txt) for details on these and other common terms, if necessary.  Similarly, common shorthand such as `int`, `float`, etc. should require no explanation.
4
5 ## Registering a sign
6
7 * `signs_lib.register_sign(nodename, def)`
8
9   To put it simply, where you'd have used `minetest.register_node()` before, just replace it with this call.  The syntax is identical, and in general, all settings/items allowed there are allowed here as well.  Anything that `signs_lib` doesn't need to override or alter will be passed straight through to `register_node()`, unchanged (such as `description`, `tiles`, or `inventory_image`).
10
11   The supplied node name will be prepended with ":", so that any mod can register signs under any other mod's namespace, if desired.
12
13   Many items have default settings applied when omitted, most of which would produce something equivalent to "default:sign_wall_wood" if enough other node defintion settings were to be included.
14
15   * `drawtype = "string"`
16
17     Default: "mesh"
18
19   * `tiles = {table}`
20
21     Since this is a sign-specific library, this parameter behaves rather different from what you would normally use in `minetest.register_node()`.  The first two entries are mandatory.  The third, fourth and fifth entries are optional, depending on which mounting styles are enabled for a given node.
22
23     * entry 1: the front and back of the sign.
24     * entry 2: the sides/edges
25     * entry 3: texture for the pole mount.  If unspecified, the standard pole mount image is used, if needed.
26     * entry 4: texture for the hanging part.  If unspecified, the standard hanging chains image is used, if needed.
27     * entry 5: texture for the yard sign stick.  If unspecified, "default_wood.png" is used, if needed.
28     * entry 6: ignored.
29
30   * `mesh = "string"`
31
32     Default: "signs_lib_standard_wall_sign.obj".
33
34   * `paramtype = "string"`
35
36     Default: "light"
37
38   * `paramtype2 = "string"`
39
40     As with any other node, this determines how param2 is interpreted.  Since these are signs, only two modes make sense: "wallmounted" and "facedir".  Any other string is the same as "facedir".
41
42     Default: "wallmounted"
43
44   * `wield_image = "string"`
45
46     Default: whatever the `inventory_image` is set to (if anything).
47
48   * `selection_box = {table}`
49
50     Works the same as usual.  A helper function exists to create boxes by specifying only and X/Y size and offset:
51     `signs_lib.make_selection_boxes()` (see below).
52
53   * `groups = {table}`
54
55     Sets the sign's groups, as usual.  In addition to whatever arbitrary groups you may have in mind, there are two presets available (both of which have `attached_node` removed, and `sign = 1` added):
56
57     * `signs_lib.standard_wood_groups`, inherited from "default:sign_wall_wood"
58     * `signs_lib.standard_steel_groups`, inherited from "default:sign_wall_steel"
59
60     Default: `signs_lib.standard_wood_groups`
61
62   * `sounds = something`
63
64     Sets the sign's sound profile, as usual.  In addition to whatever sound profile you may have in mind, there are two presets available:
65
66     * `signs_lib.standard_wood_sign_sounds`, inherited from "default:sign_wall_wood"
67     * `signs_lib.standard_steel_sign_sounds`, inherited from "default:sign_wall_steel"
68
69     Default: `signs_lib.standard_wood_sign_sounds`
70
71   * `drop = something`
72
73     Default: inherited from the `nodename` argument given to `signs_lib.register_sign()`
74
75   * `after_place_node = function(pos, placer, itemstack, pointed_thing, locked)`
76
77     See below under "Main functions".
78
79     Default: `signs_lib.after_place_node`
80
81   * `on_rightclick = function(pos)`
82
83     See below under "Main functions".
84
85     Default: `signs_lib.construct_sign`
86
87   * `on_construct = function(pos)`
88
89     See below under "Main functions".
90
91     Default: `signs_lib.construct_sign`
92
93   * `on_destruct = function(pos)`
94
95     See below under "Main functions".
96
97     Default: `signs_lib.destruct_sign`
98
99   * `on_receive_fields = function(pos, formname, fields, sender)`
100
101     See below under "Main functions".
102
103     Default: `signs_lib.receive_fields`
104
105   * `on_punch = function(pos)`
106
107     See below under "Main functions".
108
109     Default: `signs_lib.update_sign`
110
111   * `onpole_mesh = "string"`
112   * `hanging_mesh = "string"`
113   * `yard_mesh = "string"`
114
115     If your node needs a custom model for its on-pole, hanging, and/or yard variants, specify them here, as needed.  The materials and textures behave the same on these as on other sign models.  All sign model filenames are still derived from the base sign model, when not overridden here (so these can be totally arbitrary filenames).
116
117     Defaults: the normal "_onpole", "_hanging", or "_yard" version of the model specified by `mesh`.
118
119   * `selection_box = {table}`
120   * `node_box = {table}`
121
122   As usual, the former sets the sign's selection box, while the latter sets its collision information (since signs use model meshes).  At the very least, you'll want to specify `selection_box`.  If the sign node is in "wallmounted" mode, this must contain proper `wall_top`, `wall_side`, and `wall_bottom` entries, as one normally uses with such nodes.  Signs that use "facedir" mode just need the usual `fixed` setting.
123
124   Defaults:  `selection_box` is a box that fits the standard wall sign, if not specified.  `node_box` takes on the value given to `selection_box`, if not specified (or the standard wall sign setting, if neither is present).
125
126   * `onpole_selection_box = {table}`
127   * `hanging_selection_box = {table}`
128   * `yard_selection_box = {table}`
129   * `onpole_node_box = {table}`
130   * `hanging_node_box = {table}`
131   * `yard_node_box = {table}`
132
133     If your node needs special handling for its onpole-, hanging-, or yard-mode selection boxes or for their collision info (which `signs_lib` always uses the node's `node_box` item for), you can specify them here.  Same syntax as the regular `selection_box` setting.
134
135     Defaults:  whatever the `selection_box` and `node_box` entries are set to.
136
137   * `default_color = "string"`
138
139     Sets the default text color for this sign, in hexadecimal (one digit, lowercase), from the standard Linux/IRC/CGA color palette.  Same as the colors shown in the sign's formspec.
140
141     Default: "0" (black)
142
143   * `number_of_lines = int`
144
145     Just what it says on the tin.  How many lines you can fit will vary with overall sign node size, font size, scaling, line spacing, etc.
146
147     Default: 6
148
149   * `horiz_scaling = float`
150   * `vert_scaling = float`
151
152     Scaling factor applied to the entity texture horizontal or vertical resolution.  Larger values increase the resolution.  Since a given sign's entity is always displayed at a fixed visual scale, increasing these squeezes more pixels into the same space, making the text appear narrower or shorter.  Increasing `vert_scaling` also increases the number of lines of text the sign will hold.
153
154     Defaults: 1.0 for both
155
156   * `line_spacing = int`
157
158     Number of blank pixels to add between lines.
159
160     Default: 1
161
162   * `font_size = int`
163
164     Selects which font to use, either 15 or 31 (pixel height).  This setting directly affects the sign's vertical resolution.
165
166     Default: 15
167
168   * `x_offset = int`
169   * `y_offset = int`
170
171     Starting X and Y position in pixels, relative to the text entity UV map upper-left corner.
172
173     Defaults: 4 for X, 0 for Y
174
175   * `chars_per_line = int`
176
177     Approximate number of characters that should fit on a line.  This, the selected font's average character width, and the `horiz_scaling` together set the horizontal resolution of the text entity's texture.
178
179     Default: 35
180
181   * `entity_info = something`
182
183     Describes the entity model and yaw table to use.  May be one of:
184
185     * A table specifying the two settings directly, such as:
186
187         ```lua
188         entity_info = {
189           mesh = "signs_lib_standard_wall_sign_entity.obj",
190           yaw = signs_lib.wallmounted_yaw
191         }
192         ```
193       * `signs_lib.standard_yaw` is also available as a yaw preset, if desired.
194
195     * a string reading "standard", which tells `signs_lib` to use the standard wood/steel sign model, in wallmounted mode.  Equivalent to the example above.
196     * nothing at all: if omitted, the sign will not have a formspec, basically all text-related settings will be ignored and/or omitted entirely, and no entity will be spawned for this sign, thus the sign will not be writable.  This is the default, and is of course what one would want for any sign that's just an image wrapped around a model, as in most of the signs in [my street signs mod](https://forum.minetest.net/viewtopic.php?t=20866).
197
198     Default:  **nil**
199
200   * `allow_hanging = bool`
201   * `allow_onpole = bool`
202   * `allow_onpole_horizontal = bool`
203   * `allow_yard = bool`
204
205
206     If **true**, these allow the registration function to create versions of the initial, base sign node that either hang from the ceiling, are mounted on a vertical pole/post, are mounted on a horizontal pole, or are free-standing, on a small stick.  Their node names will be the same as the base wall sign node, except with "_hanging", "_onpole", "_onpole_horiz", or "_yard", respectively, appended to the end of the node name.  If the base node name has "_wall" in it, that bit is deleted before appending the above.
207
208     These options are independent of one another.
209
210     Defaults: all **nil**
211
212   * `allow_widefont = bool`
213
214     Just what it says on the tin.  If enabled, the formspec will have a little "on/off switch" left of the "Write" button, to select the font width.
215
216     Default: **nil**
217
218   * `locked = bool`
219
220     Sets this sign to be locked/owned, like the original default steel wall sign.
221
222     Default: **nil**
223
224 ### Example sign definition:
225
226 ```lua
227 signs_lib.register_sign("basic_signs:sign_wall_glass", {
228         description = S("Glass Sign"),
229         yard_mesh = "signs_lib_standard_sign_yard_two_sticks.obj",
230         tiles = {
231                 { name = "basic_signs_sign_wall_glass.png", backface_culling = true},
232                 "basic_signs_sign_wall_glass_edges.png",
233                 "basic_signs_pole_mount_glass.png",
234                 nil,
235                 nil,
236                 "default_steel_block.png" -- the sticks on back of the yard sign model
237         },
238         inventory_image = "basic_signs_sign_wall_glass_inv.png",
239         default_color = "c",
240         locked = true,
241         entity_info = "standard",
242         sounds = default.node_sound_glass_defaults(),
243         groups = {cracky = 3, oddly_breakable_by_hand = 3},
244         allow_hanging = true,
245         allow_widefont = true,
246         allow_onpole = true,
247         allow_onpole_horizontal = true,
248         allow_yard = true,
249         use_texture_alpha = true,
250 })
251 ```
252
253 ### Main functions used within a sign definition
254
255 * `signs_lib.after_place_node(pos, placer, itemstack, pointed_thing, locked)`
256
257   Determines if the `pointed_thing` is a wall, floor, ceiling, or pole/post, and swaps the placed sign for the correct model.
258
259   * `locked`: if set to **true**, the sign's meta will be tweaked to indicate its ownership by the `placer`.
260
261 * `signs_lib.construct_sign(pos)`
262
263   Sets up the sign's formspec and infotext overlay.
264
265 * `signs_lib.destruct_sign(pos)`
266
267   Deletes the sign's entity, if any, when the sign is dug.
268
269 * `signs_lib.receive_fields(pos, formname, fields, sender)`
270
271   This handles the text input and wide font on/off switch, logging any actions the user takes.  Bails-out silently if the user is not allowed to edit the sign.  See the standard Minetest lua_api.txt for details.
272
273 * `signs_lib.update_sign(pos, fields)`
274
275   If the sign's writable, this deletes any sign-related entities in the sign's node space, spawns a new one, and renders whatever text is in the sign's meta.
276
277 * `signs_lib.can_modify(pos, player)`
278
279   Returns **true** if the player is allowed to dig, edit, or change the font width of the sign.
280
281 * `signs_lib.handle_rotation(pos, node, player, mode)`
282
283   Just what it says on the tin.  Limits the sign's rotation as needed (for example, a sign on a horizontal pole can only flip from one side to the other).
284
285   * `mode`: the screwdriver's mode, as passed from the screwdriver mod.
286
287   Returns **false** if the user tried to right-click with the screwdriver, **true** otherwise.
288
289 * `signs_lib.make_selection_boxes(x_size, y_size, foo, x_offset, y_offset, z_offset, is_facedir)`
290
291   * `x_size`/`y_size`: dimensions in inches.  One node is 39.37 inches on a side.  This function uses inches instead of metric because it started out as a selection box maker for [MUTCD-2009](https://mutcd.fhwa.dot.gov/pdfs/2009r1r2/mutcd2009r1r2edition.pdf)-compliant signs, which are measured in inches.
292   * `x_offset`/`y_offset`/`z_offset`: shift the selection box (inches, defaults to centered, with the back face flush with the back of the node).
293   * `is_facedir`: if unset, the selection boxes will be created with the assumption that `paramtype2 = "wallmounted"` mode is set on the node the box will be used on.  Any other value creates a selection box for "facedir" mode.
294   * `foo` is ignored (leftover from an argument that's long since been rendered obsolete.
295
296   Returns a table suitable for the `selection_box` node definition entry.
297
298 #### Helper functions
299
300 You probably won't need to call any of these directly.
301
302 * `signs_lib.read_image_size(filename)`
303
304   Returns width and height of the indicated PNG file (return values will be gibberish if it isn't a PNG).
305
306 * `signs_lib.split_lines_and_words(text)`
307
308   Just what it says on the tin.
309
310   Returns a table of lines, each line entry being a table of words.
311
312 * `signs_lib.delete_objects(pos)`
313
314   Deletes all entities within the node space given by `pos`.
315
316 * `signs_lib.spawn_entity(pos, texture)`
317
318   Spawns a new text entity at the given position and assigns the supplied `texture` to it, if any.
319
320 * `signs_lib.check_for_pole(pos, pointed_thing)`
321
322   Attempts to determine if the `pointed_thing` qualifies as a vertical pole or post of some kind.
323
324   Returns **true** if a suitable pole/post is found
325
326 * `signs_lib.check_for_horizontal_pole(pos, pointed_thing)`
327
328   Same idea, but for horizontal poles/posts.
329
330   Returns **true** if a suitable pole/post is found.
331
332 * `signs_lib.check_for_ceiling(pointed_thing)`
333
334   Returns **true** if the `pointed_thing` appears to be the bottom of a node.
335
336 * `signs_lib.check_for_floor(pointed_thing)`
337
338   Returns **true** if the `pointed_thing` appears to be the top of a node.
339
340 * `signs_lib.set_obj_text(pos, text)`
341
342   Cooks the supplied `text` as needed and passes it to the entity rendering code.  Essentially, this is where rendering text into an image starts.
343
344 ## Options for pole/post nodes
345
346 Occasionally, you'll run into a node that either looks like a pole/post, or has one in the middle of its node space (with room to fit a sign in there), but which isn't detected as a pole/post by the standard sign placement code.  In these situations, some kind of special check is needed.
347
348 Supplying one or both of the following in the pole/post node's definition will cause `signs_lib` to skip its usual pole/post detection code, in favor of the supplied function(s).
349
350   * `check_for_pole = function(pos, node, def, pole_pos, pole_node, pole_def)`
351
352     If supplied, this function will be run when the mod is looking for a normal vertical pole/post.  Useful if the target node's orientation and/or shape determine what sides a sign can attach to.  For example, [Pipeworks](https://forum.minetest.net/viewtopic.php?pid=27794) uses this to figure out if a sign can be attached to a tube or pipe, depending on the tube's/pipe's number of junctions, and on its orientation and that of the placed sign.
353
354     * `def`: the placed sign's node defintion
355     * `pole_pos`: the target node's position 
356     * `pole_node`: the target node itself
357     * `pole_def`: its node definition
358
359     Your code must return **true** if the sign should attach to the target node.
360
361     If desired, this entry may simply be set to `check_for_pole = true` if a sign can always attach to this node regardless of facing direction (for example, [Home Decor](https://forum.minetest.net/viewtopic.php?pid=26061) has a round brass pole/post, which always stands vertical, and [Cottages](https://forum.minetest.net/viewtopic.php?id=5120) has a simple table that's basically a fencepost with a platform on top).
362
363   * `check_for_horiz_pole = function(pos, node, def, pole_pos, pole_node, pole_def)`
364
365     If supplied, this does the same thing for horizontal poles.
366
367     Your code must return **true** if the sign should attach to the target node.