]> git.lizzy.rs Git - signs_lib.git/blob - API.md
API changes to allow for more mounting styles
[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 `nodename` 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     Default: the normal "_onpole", "_hanging", or "_yard" version of the model specified by `mesh`.
118
119   * `onpole_selection_box = {table}`
120   * `hanging_selection_box = {table}`
121   * `yard_selection_box = {table}`
122   * `onpole_node_box = {table}`
123   * `hanging_node_box = {table}`
124   * `yard_node_box = {table}`
125
126     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.
127
128   * `default_color = "string"`
129
130     Sets the default text color for this sign, in hexadecimal (`0-9`, `a-f`), from the standard Linux/IRC/CGA color palette.  Same as the colors shown in the sign's formspec.
131
132     Default: `"0"` (black)
133
134   * `number_of_lines = int`
135
136     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.
137
138     Default: 6
139
140   * `horiz_scaling = float`
141
142     Scaling factor applied to the entity texture horizontal resolution.  Larger values increase the resolution.  Since a given sign's entity is always displayed at a fixed visual scale, increasing this setting squeezes more pixels into the same horizontal space, making the text appear narrower.
143
144     Default: 1.0
145
146   * `vert_scaling = float`
147
148     Scaling factor applied to the entity texture's vertical resolution.  Larger values increase the resolution, making the text appear shorter, and increasing the number of lines the sign can display.
149
150     Default: 1.0
151
152   * `line_spacing = int`
153
154     Number of blank pixels to add between lines.
155
156     Default: 1
157
158   * `font_size = int`
159
160     Selects which font to use, either 15 or 31 (pixel height).  This setting directly affects the sign's vertical resolution.
161
162     Default: 15
163
164   * `x_offset = int`
165
166     Starting X position in pixels, relative to the text entity UV map left edge.
167
168     Default: 4
169
170   * `y_offset = int`
171
172     Starting Y position in pixels, relative to the text entity UV map top edge.
173
174     Default: 0
175
176   * `chars_per_line = int`
177
178     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.
179
180     Default: 35
181
182   * `entity_info = something`
183
184     Describes the entity model and yaw table to use.  May be one of:
185
186     * A table specifying the two directly, such as:
187
188         ```lua
189         entity_info = {
190           mesh = "signs_lib_standard_wall_sign_entity.obj",
191           yaw = signs_lib.wallmounted_yaw
192         }
193         ```
194       * `signs_lib.standard_yaw` is also available as a yaw preset, if desired.
195
196     * `"standard"`: just use the standard wood/steel sign model, in wallmounted mode.  Equivalent to the example above.
197     * If this item is `nil`/not set, 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).
198
199   * `allow_hanging = bool`
200
201     If `true`, allow the registration function to create a "hanging from the ceiling" version of the initial, base sign node.  Its name will be the same as the base node name, with "_wall" deleted from the name (if present), and "_hanging" appended.  For example, "default:sign_wall_wood" becomes "default:sign_wood_hanging".
202
203     Default: `nil`
204
205   * `allow_onpole = bool`
206
207     Allow creation of an on-pole variant of the base sign, named the same as the base sign, with "_wall" deleted and "_onpole" appended.  Example: "default:sign_wall_wood" becomes "default:sign_wood_onpole"
208
209     Default: `nil`
210
211   * `allow_onpole_horizontal = bool`
212
213     Allow creation of an on-horizontal-pole variant.  This flag is independent of `allow_onpole`; the mod may specify either or both.  Its name will be the base node name, with "_wall" deleted and "_onpole_horiz" appended.  Example:  "default:sign_wall_wood" becomes "default:sign_wood_onpole_horiz".
214
215     Default: `nil`
216
217   * `allow_yard = bool`
218
219     Allow creation of a yard sign variant, named the same as the base sign, with "_wall" deleted and "_yard" appended.  Example: "default:sign_wall_wood" becomes "default:sign_wood_yard"
220
221   * `allow_widefont = bool`
222
223     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.
224
225     Default: `nil`
226
227   * `locked = bool`
228
229     Sets this sign to be locked/owned, like the original default steel wall sign.
230
231     Default: `nil`
232
233 ### Example sign definition:
234
235 ```lua
236 signs_lib.register_sign("basic_signs:sign_wall_glass", {
237         description = S("Glass Sign"),
238         tiles = {
239                 { name = "basic_signs_sign_wall_glass.png", backface_culling = true},
240                 "basic_signs_sign_wall_glass_edges.png",
241         },
242         inventory_image = "basic_signs_sign_wall_glass_inv.png",
243         default_color = "c",
244         locked = true,
245         entity_info = "standard",
246         sounds = default.node_sound_glass_defaults(),
247         groups = {cracky = 3, oddly_breakable_by_hand = 3},
248         allow_hanging = true,
249         allow_widefont = true,
250         allow_onpole = true,
251         allow_onpole_horizontal = true,
252         use_texture_alpha = true,
253 })
254 ```
255
256 ### Main functions used within a sign definition
257
258 * `signs_lib.after_place_node(pos, placer, itemstack, pointed_thing, locked)`
259
260   Determines if the `pointed_thing` is a wall, floor, ceiling, or pole/post, and swaps the placed sign for the correct model.
261
262   * `locked`: if set to true, the sign's meta will be tweaked to indicate its ownership by the `placer`.
263
264 * `signs_lib.construct_sign(pos)`
265
266   Sets up the sign's formspec and infotext overlay.
267
268 * `signs_lib.destruct_sign(pos)`
269
270   Deletes the sign's entity, if any, when the sign is dug.
271
272 * `signs_lib.receive_fields(pos, formname, fields, sender)`
273
274   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.
275
276 * `signs_lib.update_sign(pos, fields)`
277
278   If the sign's writable, this deletes any entities in the sign's node space, spawns a new one, and renders whatever text is in the sign's meta.
279
280 * `signs_lib.can_modify(pos, player)`
281
282   Returns `true` if the player is allowed to dig, edit, or change the font width of the sign.
283
284 * `signs_lib.handle_rotation(pos, node, player, mode)`
285
286   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).
287
288   * `mode`: the screwdriver's mode, as passed from the screwdriver mod.
289
290   Returns `false` if the user tried to right-click with the screwdriver, `true` otherwise.
291
292 * `signs_lib.make_selection_boxes(x_size, y_size, foo, x_offset, y_offset, z_offset, is_facedir)`
293
294   * `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-compliant signs, which are measured in inches.
295   * `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).
296   * `is_facedir`: if unset, the selection boxes will be created with the assumption that `paramtype2 = "wallmounted"` mode is set.  Any other value creates a selection box for "facedir" mode.
297   * `foo` is ignored (leftover from an argument that's long since been rendered obsolete.
298
299   Returns a table suitable for the `selection_box` node definition entry.
300
301 #### Helper functions
302
303 You probably won't need to call any of these directly.
304
305 * `signs_lib.read_image_size(filename)`
306
307   Returns width and height of the indicated PNG file (return values will be gibberish if it isn't a PNG).
308
309 * `signs_lib.split_lines_and_words(text)`
310
311   Just what it says on the tin.
312
313   Returns a table of lines, each line entry being a table of words.
314
315 * `signs_lib.delete_objects(pos)`
316
317   Deletes all entities within the node space given by `pos`.
318
319 * `signs_lib.spawn_entity(pos, texture)`
320
321   Spawns a new text entity at the given position and assigns the supplied `texture` to it, if any.
322
323 * `signs_lib.check_for_pole(pos, pointed_thing)`
324
325   Attempts to determine if the `pointed_thing` qualifies as a vertical pole or post of some kind.
326
327   Returns `true` if a suitable pole/post is found
328
329 * `signs_lib.check_for_horizontal_pole(pos, pointed_thing)`
330
331   Same idea, but for horizontal poles/posts.
332
333   Returns `true` if a suitable pole/post is found.
334
335 * `signs_lib.check_for_ceiling(pointed_thing)`
336
337   Returns `true` if the `pointed_thing` appears to be the bottom of a node.
338
339 * `signs_lib.check_for_floor(pointed_thing)`
340
341   Returns `true` if the `pointed_thing` appears to be the top of a node.
342
343 * `signs_lib.set_obj_text(pos, text)`
344
345   Cooks the supplied `text` as needed and passes it to the entity rendering code.  Essentially, this is where rendering text into an image starts.
346
347 ## Options for pole/post nodes
348
349 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.
350
351 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).
352
353   * `check_for_pole = function(pos, node, def, pole_pos, pole_node, pole_def)`
354
355     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.
356
357     * `def`: the placed sign's node defintion
358     * `pole_pos`: the target node's position 
359     * `pole_node`: the target node itself
360     * `pole_def`: its node definition
361
362     Your code must return `true` if the sign should attach to the target node.
363
364     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).
365
366   * `check_for_horiz_pole = function(pos, node, def, pole_pos, pole_node, pole_def)`
367
368     If supplied, this does the same thing for horizontal poles.
369
370     Your code must return `true` if the sign should attach to the target node.