]> git.lizzy.rs Git - signs_lib.git/blob - API.md
fix bad selection box for prefab concrete rail
[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   * `mesh = "string"`
20
21     Default: `"signs_lib_standard_wall_sign.obj"`.
22
23   * `paramtype = "string"`
24
25     Default: `"light"`
26
27   * `paramtype2 = "string"`
28
29     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"`.
30
31     Default: `"wallmounted"`
32
33   * `wield_image = "string"`
34
35     Default: whatever the `inventory_image` is set to (if anything).
36
37   * `groups = {table}`
38
39     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):
40
41     * `signs_lib.standard_wood_groups`, inherited from `"default:sign_wall_wood"`
42     * `signs_lib.standard_steel_groups`, inherited from `"default:sign_wall_steel"`
43
44     Default: `signs_lib.standard_wood_groups`
45
46   * `sounds = something`
47
48     Sets the sign's sound profile, as usual.  In addition to whatever sound profile you may have in mind, there are two presets available:
49
50     * `signs_lib.standard_wood_sign_sounds`, inherited from `"default:sign_wall_wood"`
51     * `signs_lib.standard_steel_sign_sounds`, inherited from `"default:sign_wall_steel"`
52
53     Default: `signs_lib.standard_wood_sign_sounds`
54
55   * `drop = something`
56
57     Default: inherited from the `nodename` argument given to `signs_lib.register_sign()`
58
59   * `after_place_node = function(pos, placer, itemstack, pointed_thing, locked)`
60
61     See below under "Main functions".
62
63     Default: `signs_lib.after_place_node`
64
65   * `on_rightclick = function(pos)`
66
67     See below under "Main functions".
68
69     Default: `signs_lib.construct_sign`
70
71   * `on_construct = function(pos)`
72
73     See below under "Main functions".
74
75     Default: `signs_lib.construct_sign`
76
77   * `on_destruct = function(pos)`
78
79     See below under "Main functions".
80
81     Default: `signs_lib.destruct_sign`
82
83   * `on_receive_fields = function(pos, formname, fields, sender)`
84
85     See below under "Main functions".
86
87     Default: `signs_lib.receive_fields`
88
89   * `on_punch = function(pos)`
90
91     See below under "Main functions".
92
93     Default: `signs_lib.update_sign`
94
95   * `default_color = "string"`
96
97     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.
98
99     Default: `"0"` (black)
100
101   * `number_of_lines = int`
102
103     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.
104
105     Default: 6
106
107   * `horiz_scaling = float`
108
109     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.
110
111     Default: 1.0
112
113   * `vert_scaling = float`
114
115     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.
116
117     Default: 1.0
118
119   * `line_spacing = int`
120
121     Number of blank pixels to add between lines.
122
123     Default: 1
124
125   * `font_size = int`
126
127     Selects which font to use, either 15 or 31 (pixel height).  This setting directly affects the sign's vertical resolution.
128
129     Default: 15
130
131   * `x_offset = int`
132
133     Starting X position in pixels, relative to the text entity UV map left edge.
134
135     Default: 4
136
137   * `y_offset = int`
138
139     Starting Y position in pixels, relative to the text entity UV map top edge.
140
141     Default: 0
142
143   * `chars_per_line = int`
144
145     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.
146
147     Default: 35
148
149   * `entity_info = something`
150
151     Describes the entity model and yaw table to use.  May be one of:
152
153     * A table specifying the two directly, such as:
154
155         ```lua
156         entity_info = {
157           mesh = "signs_lib_standard_wall_sign_entity.obj",
158           yaw = signs_lib.wallmounted_yaw
159         }
160         ```
161       * `signs_lib.standard_yaw` is also available as a yaw preset, if desired.
162
163     * `"standard"`: just use the standard wood/steel sign model, in wallmounted mode.  Equivalent to the example above.
164     * 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).
165
166   * `allow_hanging = bool`
167
168     If `true`, allow the registration function to create a "hanging from the ceiling" version of the initial, base sign node.
169
170     Default: `nil`
171
172   * `allow_onpole = bool`
173
174     Allow creation of an on-pole variant of the base sign.
175
176     Default: `nil`
177
178   * `allow_onpole_horizontal = bool`
179
180     Allow creation of an on-horizontal-pole variant.  This flag is independent of `allow_onpole`; the mod may specify either or both.
181
182     Default: `nil`
183
184   * `allow_widefont = bool`
185
186     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.
187
188     Default: `nil`
189
190   * `locked = bool`
191
192     Sets this sign to be locked/owned, like the original default steel wall sign.
193
194     Default: `nil`
195
196 ### Example sign definition:
197
198 ```lua
199 signs_lib.register_sign("basic_signs:sign_wall_glass", {
200         description = S("Glass Sign"),
201         tiles = {
202                 { name = "basic_signs_sign_wall_glass.png", backface_culling = true},
203                 "basic_signs_sign_wall_glass_edges.png",
204         },
205         inventory_image = "basic_signs_sign_wall_glass_inv.png",
206         default_color = "c",
207         locked = true,
208         entity_info = "standard",
209         sounds = default.node_sound_glass_defaults(),
210         groups = {cracky = 3, oddly_breakable_by_hand = 3},
211         allow_hanging = true,
212         allow_widefont = true,
213         allow_onpole = true,
214         allow_onpole_horizontal = true,
215         use_texture_alpha = true,
216 })
217 ```
218
219 ### Main functions used within a sign definition
220
221 * `signs_lib.after_place_node(pos, placer, itemstack, pointed_thing, locked)`
222
223   Determines if the `pointed_thing` is a wall, floor, ceiling, or pole/post, and swaps the placed sign for the correct model.
224
225   * `locked`: if set to true, the sign's meta will be tweaked to indicate its ownership by the `placer`.
226
227 * `signs_lib.construct_sign(pos)`
228
229   Sets up the sign's formspec and infotext overlay.
230
231 * `signs_lib.destruct_sign(pos)`
232
233   Deletes the sign's entity, if any, when the sign is dug.
234
235 * `signs_lib.receive_fields(pos, formname, fields, sender)`
236
237   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.
238
239 * `signs_lib.update_sign(pos, fields)`
240
241   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.
242
243 * `signs_lib.can_modify(pos, player)`
244
245   Returns `true` if the player is allowed to dig, edit, or change the font width of the sign.
246
247 * `signs_lib.handle_rotation(pos, node, player, mode)`
248
249   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).
250
251   * `mode`: the screwdriver's mode, as passed from the screwdriver mod.
252
253   Returns `false` if the user tried to right-click with the screwdriver, `true` otherwise.
254
255 * `signs_lib.make_selection_boxes(x_size, y_size, foo, x_offset, y_offset, z_offset, is_facedir)`
256
257   * `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.
258   * `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).
259   * `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.
260   * `foo` is ignored (leftover from an argument that's long since been rendered obsolete.
261
262   Returns a table suitable for the `selection_box` node definition entry.
263
264 #### Helper functions
265
266 You probably won't need to call any of these directly.
267
268 * `signs_lib.read_image_size(filename)`
269
270   Returns width and height of the indicated PNG file (return values will be gibberish if it isn't a PNG).
271
272 * `signs_lib.split_lines_and_words(text)`
273
274   Just what it says on the tin.
275
276   Returns a table of lines, each line entry being a table of words.
277
278 * `signs_lib.delete_objects(pos)`
279
280   Deletes all entities within the node space given by `pos`.
281
282 * `signs_lib.spawn_entity(pos, texture)`
283
284   Spawns a new text entity at the given position and assigns the supplied `texture` to it, if any.
285
286 * `signs_lib.check_for_pole(pos, pointed_thing)`
287
288   Attempts to determine if the `pointed_thing` qualifies as a vertical pole or post of some kind.
289
290   Returns `true` if a suitable pole/post is found
291
292 * `signs_lib.check_for_horizontal_pole(pos, pointed_thing)`
293
294   Same idea, but for horizontal poles/posts.
295
296   Returns `true` if a suitable pole/post is found.
297
298 * `signs_lib.check_for_ceiling(pointed_thing)`
299
300   Returns `true` if the `pointed_thing` appears to be the bottom of a node.
301
302 * `signs_lib.check_for_floor(pointed_thing)`
303
304   Returns `true` if the `pointed_thing` appears to be the top of a node.
305
306 * `signs_lib.set_obj_text(pos, text)`
307
308   Cooks the supplied `text` as needed and passes it to the entity rendering code.  Essentially, this is where rendering text into an image starts.
309
310 ## Options for pole/post nodes
311
312 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.
313
314 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).
315
316   * `check_for_pole = function(pos, node, def, pole_pos, pole_node, pole_def)`
317
318     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.
319
320     * `def`: the placed sign's node defintion
321     * `pole_pos`: the target node's position 
322     * `pole_node`: the target node itself
323     * `pole_def`: its node definition
324
325     Your code must return `true` if the sign should attach to the target node.
326
327     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).
328
329   * `check_for_horiz_pole = function(pos, node, def, pole_pos, pole_node, pole_def)`
330
331     If supplied, this does the same thing for horizontal poles.
332
333     Your code must return `true` if the sign should attach to the target node.