├── .github
└── workflows
│ └── luacheck.yml
├── .gitignore
├── .luacheckrc
├── LICENSE.txt
├── README.md
├── description.txt
├── modpack.txt
├── moremesecons_adjustable_blinkyplant
├── init.lua
├── mod.conf
└── textures
│ ├── moremesecons_blinky_plant_off.png
│ └── moremesecons_blinky_plant_on.png
├── moremesecons_adjustable_player_detector
├── init.lua
├── mod.conf
└── textures
│ ├── moremesecons_player_detector_off.png
│ └── moremesecons_player_detector_on.png
├── moremesecons_commandblock
├── init.lua
├── mod.conf
└── textures
│ ├── moremesecons_commandblock_off.png
│ └── moremesecons_commandblock_on.png
├── moremesecons_conductor_signalchanger
├── init.lua
├── mod.conf
└── textures
│ ├── moremesecons_conductor_signalchanger_off.png
│ └── moremesecons_conductor_signalchanger_on.png
├── moremesecons_dual_delayer
├── init.lua
├── mod.conf
└── textures
│ ├── moremesecons_dual_delayer_bottom.png
│ ├── moremesecons_dual_delayer_ends.png
│ ├── moremesecons_dual_delayer_overlay.png
│ ├── moremesecons_dual_delayer_side_left.png
│ └── moremesecons_dual_delayer_side_right.png
├── moremesecons_entity_detector
├── init.lua
├── mod.conf
└── textures
│ ├── moremesecons_entity_detector_off.png
│ └── moremesecons_entity_detector_on.png
├── moremesecons_igniter
├── init.lua
├── mod.conf
└── textures
│ └── moremesecons_igniter.png
├── moremesecons_induction_transmitter
├── init.lua
└── mod.conf
├── moremesecons_injector_controller
├── init.lua
├── mod.conf
└── textures
│ ├── moremesecons_injector_controller_off.png
│ ├── moremesecons_injector_controller_on.png
│ └── moremesecons_injector_controller_side.png
├── moremesecons_jammer
├── init.lua
├── mod.conf
├── sounds
│ └── moremesecons_jammer.ogg
└── textures
│ ├── moremesecons_jammer_off.png
│ └── moremesecons_jammer_on.png
├── moremesecons_luablock
├── init.lua
├── mod.conf
└── textures
│ └── moremesecons_luablock.png
├── moremesecons_luacontroller_tool
├── init.lua
├── mod.conf
└── textures
│ └── moremesecons_luacontroller_tool.png
├── moremesecons_mesechest
├── init.lua
└── mod.conf
├── moremesecons_playerkiller
├── init.lua
├── mod.conf
└── textures
│ ├── moremesecons_playerkiller_side.png
│ └── moremesecons_playerkiller_top.png
├── moremesecons_sayer
├── init.lua
└── mod.conf
├── moremesecons_signalchanger
├── init.lua
├── mod.conf
└── textures
│ ├── moremesecons_signalchanger_off.png
│ └── moremesecons_signalchanger_on.png
├── moremesecons_switchtorch
├── init.lua
├── mod.conf
└── textures
│ ├── moremesecons_switchtorch_off.png
│ ├── moremesecons_switchtorch_off_ceiling.png
│ ├── moremesecons_switchtorch_off_side.png
│ ├── moremesecons_switchtorch_on.png
│ ├── moremesecons_switchtorch_on_ceiling.png
│ └── moremesecons_switchtorch_on_side.png
├── moremesecons_teleporter
├── init.lua
├── mod.conf
└── textures
│ └── moremesecons_teleporter.png
├── moremesecons_timegate
├── init.lua
├── mod.conf
└── textures
│ ├── moremesecons_timegate_bottom.png
│ ├── moremesecons_timegate_ends_off.png
│ ├── moremesecons_timegate_ends_on.png
│ ├── moremesecons_timegate_off.png
│ ├── moremesecons_timegate_on.png
│ ├── moremesecons_timegate_sides_off.png
│ └── moremesecons_timegate_sides_on.png
├── moremesecons_utils
├── init.lua
└── mod.conf
├── moremesecons_wireless
├── init.lua
├── mod.conf
└── textures
│ ├── moremesecons_jammer_bottom.png
│ ├── moremesecons_jammer_side_off.png
│ ├── moremesecons_jammer_side_on.png
│ ├── moremesecons_jammer_top.png
│ ├── moremesecons_wireless_off.png
│ └── moremesecons_wireless_on.png
└── settingtypes.txt
/.github/workflows/luacheck.yml:
--------------------------------------------------------------------------------
1 | name: luacheck
2 | on: [push, pull_request]
3 | jobs:
4 | luacheck:
5 | runs-on: ubuntu-latest
6 | steps:
7 | - name: Checkout
8 | uses: actions/checkout@master
9 | - name: Luacheck
10 | uses: lunarmodules/luacheck@master
11 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ## Generic ignorable patterns and files
2 | *~
3 | debug.txt
4 |
5 | ## Eclipse project files & directories
6 | .project
7 | .settings
8 |
--------------------------------------------------------------------------------
/.luacheckrc:
--------------------------------------------------------------------------------
1 | read_globals = {
2 | -- Defined by Minetest
3 | "minetest", "vector", "PseudoRandom", "VoxelArea", "table",
4 |
5 | -- Mods
6 | "digiline", "default", "creative",
7 | }
8 | globals = {"moremesecons", "mesecon"}
9 | ignore = {"212", "631", "422", "432"}
10 |
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
1 | Mozilla Public License Version 2.0
2 | ==================================
3 |
4 | 1. Definitions
5 | --------------
6 |
7 | 1.1. "Contributor"
8 | means each individual or legal entity that creates, contributes to
9 | the creation of, or owns Covered Software.
10 |
11 | 1.2. "Contributor Version"
12 | means the combination of the Contributions of others (if any) used
13 | by a Contributor and that particular Contributor's Contribution.
14 |
15 | 1.3. "Contribution"
16 | means Covered Software of a particular Contributor.
17 |
18 | 1.4. "Covered Software"
19 | means Source Code Form to which the initial Contributor has attached
20 | the notice in Exhibit A, the Executable Form of such Source Code
21 | Form, and Modifications of such Source Code Form, in each case
22 | including portions thereof.
23 |
24 | 1.5. "Incompatible With Secondary Licenses"
25 | means
26 |
27 | (a) that the initial Contributor has attached the notice described
28 | in Exhibit B to the Covered Software; or
29 |
30 | (b) that the Covered Software was made available under the terms of
31 | version 1.1 or earlier of the License, but not also under the
32 | terms of a Secondary License.
33 |
34 | 1.6. "Executable Form"
35 | means any form of the work other than Source Code Form.
36 |
37 | 1.7. "Larger Work"
38 | means a work that combines Covered Software with other material, in
39 | a separate file or files, that is not Covered Software.
40 |
41 | 1.8. "License"
42 | means this document.
43 |
44 | 1.9. "Licensable"
45 | means having the right to grant, to the maximum extent possible,
46 | whether at the time of the initial grant or subsequently, any and
47 | all of the rights conveyed by this License.
48 |
49 | 1.10. "Modifications"
50 | means any of the following:
51 |
52 | (a) any file in Source Code Form that results from an addition to,
53 | deletion from, or modification of the contents of Covered
54 | Software; or
55 |
56 | (b) any new file in Source Code Form that contains any Covered
57 | Software.
58 |
59 | 1.11. "Patent Claims" of a Contributor
60 | means any patent claim(s), including without limitation, method,
61 | process, and apparatus claims, in any patent Licensable by such
62 | Contributor that would be infringed, but for the grant of the
63 | License, by the making, using, selling, offering for sale, having
64 | made, import, or transfer of either its Contributions or its
65 | Contributor Version.
66 |
67 | 1.12. "Secondary License"
68 | means either the GNU General Public License, Version 2.0, the GNU
69 | Lesser General Public License, Version 2.1, the GNU Affero General
70 | Public License, Version 3.0, or any later versions of those
71 | licenses.
72 |
73 | 1.13. "Source Code Form"
74 | means the form of the work preferred for making modifications.
75 |
76 | 1.14. "You" (or "Your")
77 | means an individual or a legal entity exercising rights under this
78 | License. For legal entities, "You" includes any entity that
79 | controls, is controlled by, or is under common control with You. For
80 | purposes of this definition, "control" means (a) the power, direct
81 | or indirect, to cause the direction or management of such entity,
82 | whether by contract or otherwise, or (b) ownership of more than
83 | fifty percent (50%) of the outstanding shares or beneficial
84 | ownership of such entity.
85 |
86 | 2. License Grants and Conditions
87 | --------------------------------
88 |
89 | 2.1. Grants
90 |
91 | Each Contributor hereby grants You a world-wide, royalty-free,
92 | non-exclusive license:
93 |
94 | (a) under intellectual property rights (other than patent or trademark)
95 | Licensable by such Contributor to use, reproduce, make available,
96 | modify, display, perform, distribute, and otherwise exploit its
97 | Contributions, either on an unmodified basis, with Modifications, or
98 | as part of a Larger Work; and
99 |
100 | (b) under Patent Claims of such Contributor to make, use, sell, offer
101 | for sale, have made, import, and otherwise transfer either its
102 | Contributions or its Contributor Version.
103 |
104 | 2.2. Effective Date
105 |
106 | The licenses granted in Section 2.1 with respect to any Contribution
107 | become effective for each Contribution on the date the Contributor first
108 | distributes such Contribution.
109 |
110 | 2.3. Limitations on Grant Scope
111 |
112 | The licenses granted in this Section 2 are the only rights granted under
113 | this License. No additional rights or licenses will be implied from the
114 | distribution or licensing of Covered Software under this License.
115 | Notwithstanding Section 2.1(b) above, no patent license is granted by a
116 | Contributor:
117 |
118 | (a) for any code that a Contributor has removed from Covered Software;
119 | or
120 |
121 | (b) for infringements caused by: (i) Your and any other third party's
122 | modifications of Covered Software, or (ii) the combination of its
123 | Contributions with other software (except as part of its Contributor
124 | Version); or
125 |
126 | (c) under Patent Claims infringed by Covered Software in the absence of
127 | its Contributions.
128 |
129 | This License does not grant any rights in the trademarks, service marks,
130 | or logos of any Contributor (except as may be necessary to comply with
131 | the notice requirements in Section 3.4).
132 |
133 | 2.4. Subsequent Licenses
134 |
135 | No Contributor makes additional grants as a result of Your choice to
136 | distribute the Covered Software under a subsequent version of this
137 | License (see Section 10.2) or under the terms of a Secondary License (if
138 | permitted under the terms of Section 3.3).
139 |
140 | 2.5. Representation
141 |
142 | Each Contributor represents that the Contributor believes its
143 | Contributions are its original creation(s) or it has sufficient rights
144 | to grant the rights to its Contributions conveyed by this License.
145 |
146 | 2.6. Fair Use
147 |
148 | This License is not intended to limit any rights You have under
149 | applicable copyright doctrines of fair use, fair dealing, or other
150 | equivalents.
151 |
152 | 2.7. Conditions
153 |
154 | Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted
155 | in Section 2.1.
156 |
157 | 3. Responsibilities
158 | -------------------
159 |
160 | 3.1. Distribution of Source Form
161 |
162 | All distribution of Covered Software in Source Code Form, including any
163 | Modifications that You create or to which You contribute, must be under
164 | the terms of this License. You must inform recipients that the Source
165 | Code Form of the Covered Software is governed by the terms of this
166 | License, and how they can obtain a copy of this License. You may not
167 | attempt to alter or restrict the recipients' rights in the Source Code
168 | Form.
169 |
170 | 3.2. Distribution of Executable Form
171 |
172 | If You distribute Covered Software in Executable Form then:
173 |
174 | (a) such Covered Software must also be made available in Source Code
175 | Form, as described in Section 3.1, and You must inform recipients of
176 | the Executable Form how they can obtain a copy of such Source Code
177 | Form by reasonable means in a timely manner, at a charge no more
178 | than the cost of distribution to the recipient; and
179 |
180 | (b) You may distribute such Executable Form under the terms of this
181 | License, or sublicense it under different terms, provided that the
182 | license for the Executable Form does not attempt to limit or alter
183 | the recipients' rights in the Source Code Form under this License.
184 |
185 | 3.3. Distribution of a Larger Work
186 |
187 | You may create and distribute a Larger Work under terms of Your choice,
188 | provided that You also comply with the requirements of this License for
189 | the Covered Software. If the Larger Work is a combination of Covered
190 | Software with a work governed by one or more Secondary Licenses, and the
191 | Covered Software is not Incompatible With Secondary Licenses, this
192 | License permits You to additionally distribute such Covered Software
193 | under the terms of such Secondary License(s), so that the recipient of
194 | the Larger Work may, at their option, further distribute the Covered
195 | Software under the terms of either this License or such Secondary
196 | License(s).
197 |
198 | 3.4. Notices
199 |
200 | You may not remove or alter the substance of any license notices
201 | (including copyright notices, patent notices, disclaimers of warranty,
202 | or limitations of liability) contained within the Source Code Form of
203 | the Covered Software, except that You may alter any license notices to
204 | the extent required to remedy known factual inaccuracies.
205 |
206 | 3.5. Application of Additional Terms
207 |
208 | You may choose to offer, and to charge a fee for, warranty, support,
209 | indemnity or liability obligations to one or more recipients of Covered
210 | Software. However, You may do so only on Your own behalf, and not on
211 | behalf of any Contributor. You must make it absolutely clear that any
212 | such warranty, support, indemnity, or liability obligation is offered by
213 | You alone, and You hereby agree to indemnify every Contributor for any
214 | liability incurred by such Contributor as a result of warranty, support,
215 | indemnity or liability terms You offer. You may include additional
216 | disclaimers of warranty and limitations of liability specific to any
217 | jurisdiction.
218 |
219 | 4. Inability to Comply Due to Statute or Regulation
220 | ---------------------------------------------------
221 |
222 | If it is impossible for You to comply with any of the terms of this
223 | License with respect to some or all of the Covered Software due to
224 | statute, judicial order, or regulation then You must: (a) comply with
225 | the terms of this License to the maximum extent possible; and (b)
226 | describe the limitations and the code they affect. Such description must
227 | be placed in a text file included with all distributions of the Covered
228 | Software under this License. Except to the extent prohibited by statute
229 | or regulation, such description must be sufficiently detailed for a
230 | recipient of ordinary skill to be able to understand it.
231 |
232 | 5. Termination
233 | --------------
234 |
235 | 5.1. The rights granted under this License will terminate automatically
236 | if You fail to comply with any of its terms. However, if You become
237 | compliant, then the rights granted under this License from a particular
238 | Contributor are reinstated (a) provisionally, unless and until such
239 | Contributor explicitly and finally terminates Your grants, and (b) on an
240 | ongoing basis, if such Contributor fails to notify You of the
241 | non-compliance by some reasonable means prior to 60 days after You have
242 | come back into compliance. Moreover, Your grants from a particular
243 | Contributor are reinstated on an ongoing basis if such Contributor
244 | notifies You of the non-compliance by some reasonable means, this is the
245 | first time You have received notice of non-compliance with this License
246 | from such Contributor, and You become compliant prior to 30 days after
247 | Your receipt of the notice.
248 |
249 | 5.2. If You initiate litigation against any entity by asserting a patent
250 | infringement claim (excluding declaratory judgment actions,
251 | counter-claims, and cross-claims) alleging that a Contributor Version
252 | directly or indirectly infringes any patent, then the rights granted to
253 | You by any and all Contributors for the Covered Software under Section
254 | 2.1 of this License shall terminate.
255 |
256 | 5.3. In the event of termination under Sections 5.1 or 5.2 above, all
257 | end user license agreements (excluding distributors and resellers) which
258 | have been validly granted by You or Your distributors under this License
259 | prior to termination shall survive termination.
260 |
261 | ************************************************************************
262 | * *
263 | * 6. Disclaimer of Warranty *
264 | * ------------------------- *
265 | * *
266 | * Covered Software is provided under this License on an "as is" *
267 | * basis, without warranty of any kind, either expressed, implied, or *
268 | * statutory, including, without limitation, warranties that the *
269 | * Covered Software is free of defects, merchantable, fit for a *
270 | * particular purpose or non-infringing. The entire risk as to the *
271 | * quality and performance of the Covered Software is with You. *
272 | * Should any Covered Software prove defective in any respect, You *
273 | * (not any Contributor) assume the cost of any necessary servicing, *
274 | * repair, or correction. This disclaimer of warranty constitutes an *
275 | * essential part of this License. No use of any Covered Software is *
276 | * authorized under this License except under this disclaimer. *
277 | * *
278 | ************************************************************************
279 |
280 | ************************************************************************
281 | * *
282 | * 7. Limitation of Liability *
283 | * -------------------------- *
284 | * *
285 | * Under no circumstances and under no legal theory, whether tort *
286 | * (including negligence), contract, or otherwise, shall any *
287 | * Contributor, or anyone who distributes Covered Software as *
288 | * permitted above, be liable to You for any direct, indirect, *
289 | * special, incidental, or consequential damages of any character *
290 | * including, without limitation, damages for lost profits, loss of *
291 | * goodwill, work stoppage, computer failure or malfunction, or any *
292 | * and all other commercial damages or losses, even if such party *
293 | * shall have been informed of the possibility of such damages. This *
294 | * limitation of liability shall not apply to liability for death or *
295 | * personal injury resulting from such party's negligence to the *
296 | * extent applicable law prohibits such limitation. Some *
297 | * jurisdictions do not allow the exclusion or limitation of *
298 | * incidental or consequential damages, so this exclusion and *
299 | * limitation may not apply to You. *
300 | * *
301 | ************************************************************************
302 |
303 | 8. Litigation
304 | -------------
305 |
306 | Any litigation relating to this License may be brought only in the
307 | courts of a jurisdiction where the defendant maintains its principal
308 | place of business and such litigation shall be governed by laws of that
309 | jurisdiction, without reference to its conflict-of-law provisions.
310 | Nothing in this Section shall prevent a party's ability to bring
311 | cross-claims or counter-claims.
312 |
313 | 9. Miscellaneous
314 | ----------------
315 |
316 | This License represents the complete agreement concerning the subject
317 | matter hereof. If any provision of this License is held to be
318 | unenforceable, such provision shall be reformed only to the extent
319 | necessary to make it enforceable. Any law or regulation which provides
320 | that the language of a contract shall be construed against the drafter
321 | shall not be used to construe this License against a Contributor.
322 |
323 | 10. Versions of the License
324 | ---------------------------
325 |
326 | 10.1. New Versions
327 |
328 | Mozilla Foundation is the license steward. Except as provided in Section
329 | 10.3, no one other than the license steward has the right to modify or
330 | publish new versions of this License. Each version will be given a
331 | distinguishing version number.
332 |
333 | 10.2. Effect of New Versions
334 |
335 | You may distribute the Covered Software under the terms of the version
336 | of the License under which You originally received the Covered Software,
337 | or under the terms of any subsequent version published by the license
338 | steward.
339 |
340 | 10.3. Modified Versions
341 |
342 | If you create software not governed by this License, and you want to
343 | create a new license for such software, you may create and use a
344 | modified version of this License if you rename the license and remove
345 | any references to the name of the license steward (except to note that
346 | such modified license differs from this License).
347 |
348 | 10.4. Distributing Source Code Form that is Incompatible With Secondary
349 | Licenses
350 |
351 | If You choose to distribute Source Code Form that is Incompatible With
352 | Secondary Licenses under the terms of this version of the License, the
353 | notice described in Exhibit B of this License must be attached.
354 |
355 | Exhibit A - Source Code Form License Notice
356 | -------------------------------------------
357 |
358 | This Source Code Form is subject to the terms of the Mozilla Public
359 | License, v. 2.0. If a copy of the MPL was not distributed with this
360 | file, You can obtain one at http://mozilla.org/MPL/2.0/.
361 |
362 | If it is not possible or desirable to put the notice in a particular
363 | file, then You may include the notice in a location (such as a LICENSE
364 | file in a relevant directory) where a recipient would be likely to look
365 | for such a notice.
366 |
367 | You may add additional accurate notices of copyright ownership.
368 |
369 | Exhibit B - "Incompatible With Secondary Licenses" Notice
370 | ---------------------------------------------------------
371 |
372 | This Source Code Form is "Incompatible With Secondary Licenses", as
373 | defined by the Mozilla Public License, v. 2.0.
374 |
375 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # MoreMesecons
2 |
3 | Based on Mesecons by Jeija
4 | By @paly2 and @HybridDog
5 | With the participation of @LeMagnesium (bugfix), @Ataron (textures), @JAPP (texture).
6 |
7 | Dependencies: [Mesecons](https://github.com/Jeija/minetest-mod-mesecons/)
8 | Optional dependencies: [digilines](https://github.com/minetest-mods/digilines)
9 |
10 | MoreMesecons is a mod for minetest which adds some mesecons items.
11 |
12 | [Here](http://github.com/minetest-mods/MoreMesecons/wiki)'s the wiki !
13 |
14 | ## New items
15 |
16 | * `Adjustable Blinky plant` : Like a mesecons blinky plant, but... adjustable. Right-click to change the interval.
17 | * `Adjustable Player Detector` : Like a mesecons player detector, but you can change its detection radius by right-click.
18 | * `Craftable Command Block` : A command block with just some commands accepted. The admin can change the accepted command (first line of the init.lua), default "tell". Only "@nearest" can be used in the commands, and the admin can change the maximum distance of "@nearest" (default 8 blocks).
19 | * `Conductor Signal Changer` : Like a diode which can be activated by sending a signal on its pin "F", and deactivated by sending a signal on its pin "O".
20 | * `Dual Delayer` : If it receives a mesecons signal, port 1 turns on immediatly and port 2 turns on 0.4 seconds later. At the end of the signal, port 2 turns off immediatly and port 1 turns off 0.4 secondes later. For example, this is useful for double extenders.
21 | * `Entity Detector` : You can use it to detect an entity. You can choose the entity to detect by right-click (use itemstring, for example "mobs:rat". To detect a dropped item, write "__builtin:item". To detect a specific dropped item, write its itemstring (for example "default:cobble")).
22 | * `Igniter` : This node is a lighter that ignites its adjacent flammable nodes (including TNT).
23 | * `Injector Controller` : This node is useful to activate/deactivate a pipeworks filter injector : it sends a blinky signal.
24 | * `Jammer` : If turned on, this node stops mesecons in a radius of 10 nodes.
25 | * `LuaBlock`: This block allows its owner to execute any Lua code in the global environment when turned on. Using it requires the server privilege.
26 | * `Luacontroller Template Tool` : This tool is very useful to manipulate templates with luacontrollers. Just click with it on a luacontroller, then you'll see a formspec.
27 | * `Player Killer` : This block kills the nearest player (with a maximal distance of 8 blocks by default) (if this player isn't its owner) when it receives a mesecons signal.
28 | * `Sayer` : This node sends a message to every players inside a radius of 8 nodes.
29 | * `Signal Changer` : If it receives a signal on its pin "F", it turns on. If it receives a signal on its pin "O", it turns off. Note : an inverted signal is sended at the other end of the arrow.
30 | * `Switch Torch` : It connects just like Mesecons Torch. If it receives a signal, it turns on, and if it receives a second signal, it turns off.
31 | * `Teleporter` : If you place one teleporter, it teleports the nearest player on itself when it receives a mesecons signal. If you place two teleporters on the same axis, when one receives a mesecons signal, it teleports the nearest player on the second (with a maximal distance of 50 nodes by default). The player teleporter must be inside a radius of 25 nodes.
32 | * `Time Gate` : If it receives a mesecons signal, whatever its duration, a mesecons signal is send with a fixed duration. You can change it in the formspec by right-clicking on the gate.
33 | * `Wireless` : Place 2 (or more) wireless somewhere. Change their channel by right-click. If you send a signal to a wireless, every wireless wich have the same channel will send the signal. Compatible with digiline mod.
34 | * `Wireless Jammer` : If it receives a mesecons signal, it deactivates all wireless (receptors) in a radius of 15 nodes.
35 |
36 | ## Settings
37 |
38 | You can set the settings by using the Minetest GUI ("Settings" tab -> Advanced settings -> Mods -> MoreMesecons).
39 |
40 | ## The Sayer and the Speech Dispatcher
41 |
42 | [Speech Dispatcher project](http://freecode.com/projects/speech-dispatcher)
43 |
44 | The Sayer item is able to speak on your speakers using the speech dispatcher, under these conditions:
45 | 1. The moremesecons_sayer mod is present in your trusted_mods setting
46 | 2. You are playing in singleplayer.
47 | 3. You are using a POSIX-compliant system and a sh-compatible shell (such as bash, dash, zsh...). Microsoft Windows is NOT POSIX-compliant.
48 | 4. The speech dispatcher is installed on your system.
49 |
50 | The mod is able to detect issues 1, 2, and 4 by itself and then disable the speech dispatcher ; however, if you are using a non-POSIX-compliant system, the mod will crash on startup and you will need to disable the speech dispatcher manually (Settings tab -> Advanced settings -> Mods -> MoreMesecons -> Sayer -> Use the Speech Dispatcher).
51 |
--------------------------------------------------------------------------------
/description.txt:
--------------------------------------------------------------------------------
1 | Adds more Mesecons items.
2 |
--------------------------------------------------------------------------------
/modpack.txt:
--------------------------------------------------------------------------------
1 | The presence of this file indicates that the current folder is a modpack.
--------------------------------------------------------------------------------
/moremesecons_adjustable_blinkyplant/init.lua:
--------------------------------------------------------------------------------
1 | local toggle_timer = function (pos, restart)
2 | local timer = minetest.get_node_timer(pos)
3 | if timer:is_started()
4 | and not restart then
5 | timer:stop()
6 | else
7 | local interval = tonumber(minetest.get_meta(pos):get_string("interval")) or 1
8 | if interval < moremesecons.setting("adjustable_blinky_plant", "min_interval", 0.5) then
9 | interval = moremesecons.setting("adjustable_blinky_plant", "min_interval", 0.5)
10 | end
11 | timer:start(interval)
12 | end
13 | end
14 |
15 | local on_timer = function(pos)
16 | if mesecon.flipstate(pos, minetest.get_node(pos)) == "on" then
17 | mesecon.receptor_on(pos)
18 | else
19 | mesecon.receptor_off(pos)
20 | end
21 | toggle_timer(pos, false)
22 | end
23 |
24 | mesecon.register_node("moremesecons_adjustable_blinkyplant:adjustable_blinky_plant", {
25 | description="Adjustable Blinky Plant",
26 | drawtype = "plantlike",
27 | inventory_image = "moremesecons_blinky_plant_off.png",
28 | paramtype = "light",
29 | walkable = false,
30 | sounds = default.node_sound_leaves_defaults(),
31 | selection_box = {
32 | type = "fixed",
33 | fixed = {-0.3, -0.5, -0.3, 0.3, -0.5+0.7, 0.3},
34 | },
35 | on_timer = on_timer,
36 | on_construct = function(pos)
37 | local meta = minetest.get_meta(pos)
38 | meta:set_string("interval", "1")
39 | meta:set_string("formspec", "field[interval;interval;${interval}]")
40 | toggle_timer(pos, true)
41 | end,
42 | on_receive_fields = function(pos, _, fields, player)
43 | local interval = tonumber(fields.interval)
44 | if interval
45 | and not minetest.is_protected(pos, player:get_player_name()) then
46 | minetest.get_meta(pos):set_string("interval", interval)
47 | toggle_timer(pos, true)
48 | end
49 | end,
50 | },{
51 | tiles = {"moremesecons_blinky_plant_off.png"},
52 | groups = {dig_immediate=3},
53 | mesecons = {receptor = { state = mesecon.state.off }}
54 | },{
55 | tiles = {"moremesecons_blinky_plant_off.png^moremesecons_blinky_plant_on.png"},
56 | groups = {dig_immediate=3, not_in_creative_inventory=1},
57 | sunlight_propagates = true,
58 | mesecons = {receptor = { state = mesecon.state.on }},
59 | })
60 |
61 |
62 | minetest.register_craft({
63 | output = "moremesecons_adjustable_blinkyplant:adjustable_blinky_plant_off 1",
64 | recipe = { {"mesecons_blinkyplant:blinky_plant_off"},
65 | {"default:mese_crystal_fragment"},}
66 | })
67 |
--------------------------------------------------------------------------------
/moremesecons_adjustable_blinkyplant/mod.conf:
--------------------------------------------------------------------------------
1 | name = moremesecons_adjustable_blinkyplant
2 | depends = mesecons,moremesecons_utils
3 | optional_depends = craft_guide
4 |
--------------------------------------------------------------------------------
/moremesecons_adjustable_blinkyplant/textures/moremesecons_blinky_plant_off.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/minetest-mods/MoreMesecons/3e93b939f3bae14fb7a8c3f94e8db5d8fc0b2c24/moremesecons_adjustable_blinkyplant/textures/moremesecons_blinky_plant_off.png
--------------------------------------------------------------------------------
/moremesecons_adjustable_blinkyplant/textures/moremesecons_blinky_plant_on.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/minetest-mods/MoreMesecons/3e93b939f3bae14fb7a8c3f94e8db5d8fc0b2c24/moremesecons_adjustable_blinkyplant/textures/moremesecons_blinky_plant_on.png
--------------------------------------------------------------------------------
/moremesecons_adjustable_player_detector/init.lua:
--------------------------------------------------------------------------------
1 | -- Adjustable Player Detector
2 | -- Detects players in a certain radius
3 | -- The radius can be changes by right-click (by default 6)
4 |
5 | local MAX_RADIUS = moremesecons.setting("adjustable_player_detector", "max_radius", 16, 0)
6 |
7 | local function make_formspec(meta)
8 | meta:set_string("formspec", "size[9,5]" ..
9 | "field[0.3, 0;9,2;scanname;Comma-separated list of the names of players to scan for (empty for any):;${scanname}]"..
10 | "field[0.3,1.5;4,2;digiline_channel;Digiline Channel (optional):;${digiline_channel}]"..
11 | "field[0.3,3;4,2;radius;Detection radius:;${radius}]"..
12 | "button_exit[3.5,3.5;2,3;;Save]")
13 | end
14 |
15 | local function object_detector_make_formspec(pos)
16 | make_formspec(minetest.get_meta(pos))
17 | end
18 |
19 | local function object_detector_on_receive_fields(pos, _, fields, player)
20 | if not fields.scanname
21 | or not fields.digiline_channel
22 | or minetest.is_protected(pos, player:get_player_name()) then
23 | return
24 | end
25 |
26 | local meta = minetest.get_meta(pos)
27 | meta:set_string("scanname", fields.scanname)
28 | meta:set_string("digiline_channel", fields.digiline_channel)
29 | local r = tonumber(fields.radius)
30 | if r then
31 | meta:set_int("radius", r)
32 | end
33 | end
34 |
35 | -- returns true if player was found, false if not
36 | local object_detector_scan = function (pos)
37 | local meta = minetest.get_meta(pos)
38 | local scanname = meta:get_string("scanname")
39 | local scan_all = scanname == ""
40 | local scan_names = scanname:split(',')
41 | local radius = math.min(meta:get_int("radius"), MAX_RADIUS)
42 | if radius <= 0 then
43 | radius = 6
44 | end
45 | for _,obj in pairs(minetest.get_objects_inside_radius(pos, radius)) do
46 | local isname = obj:get_player_name() -- "" is returned if it is not a player; "" ~= nil!
47 | if isname ~= "" then
48 | if scan_all then
49 | return true, isname
50 | end
51 | for _, name in ipairs(scan_names) do
52 | if isname == name then
53 | return true, isname
54 | end
55 | end
56 | end
57 | end
58 | return false
59 | end
60 |
61 | -- set player name when receiving a digiline signal on a specific channel
62 | local object_detector_digiline = {
63 | effector = {
64 | action = function (pos, node, channel, msg)
65 | local meta = minetest.get_meta(pos)
66 | local active_channel = meta:get_string("digiline_channel")
67 | if channel ~= active_channel then
68 | return
69 | end
70 | if type(msg) == "string" then
71 | meta:set_string("scanname", msg)
72 | make_formspec(meta)
73 | elseif type(msg) == "table" then
74 | if msg.radius then
75 | local r = tonumber(msg.radius)
76 | if r then
77 | meta:set_int("radius", tonumber(msg.radius))
78 | make_formspec(meta)
79 | end
80 | end
81 | if type(msg.scanname) == "string" then
82 | meta:set_string("scanname", msg.scanname)
83 | make_formspec(meta)
84 | end
85 | if msg.command == "get" then
86 | local found, name = object_detector_scan(pos)
87 | if not found then
88 | name = ""
89 | end
90 | digiline:receptor_send(pos, digiline.rules.default, channel, name)
91 | end
92 | end
93 | end,
94 | },
95 | receptor = {}
96 | }
97 |
98 | minetest.register_node("moremesecons_adjustable_player_detector:player_detector_off", {
99 | tiles = {"default_steel_block.png", "default_steel_block.png", "moremesecons_player_detector_off.png"},
100 | paramtype = "light",
101 | walkable = true,
102 | groups = {cracky=3},
103 | description="Adjustable Player Detector",
104 | mesecons = {receptor = {
105 | state = mesecon.state.off,
106 | rules = mesecon.rules.pplate
107 | }},
108 | on_construct = object_detector_make_formspec,
109 | on_receive_fields = object_detector_on_receive_fields,
110 | sounds = default.node_sound_stone_defaults(),
111 | digiline = object_detector_digiline
112 | })
113 |
114 | minetest.register_node("moremesecons_adjustable_player_detector:player_detector_on", {
115 | tiles = {"default_steel_block.png", "default_steel_block.png", "moremesecons_player_detector_on.png"},
116 | paramtype = "light",
117 | walkable = true,
118 | groups = {cracky=3,not_in_creative_inventory=1},
119 | drop = 'moremesecons_adjustable_player_detector:player_detector_off',
120 | mesecons = {receptor = {
121 | state = mesecon.state.on,
122 | rules = mesecon.rules.pplate
123 | }},
124 | on_construct = object_detector_make_formspec,
125 | on_receive_fields = object_detector_on_receive_fields,
126 | sounds = default.node_sound_stone_defaults(),
127 | digiline = object_detector_digiline
128 | })
129 |
130 | minetest.register_craft({
131 | output = 'moremesecons_adjustable_player_detector:player_detector_off',
132 | recipe = {
133 | {"mesecons_detector:object_detector_off"},
134 | {"default:mese_crystal_fragment"}
135 | }
136 | })
137 |
138 | minetest.register_abm({
139 | nodenames = {"moremesecons_adjustable_player_detector:player_detector_off"},
140 | interval = 1.0,
141 | chance = 1,
142 | action = function(pos)
143 | if object_detector_scan(pos) then
144 | minetest.swap_node(pos, {name = "moremesecons_adjustable_player_detector:player_detector_on"})
145 | mesecon.receptor_on(pos, mesecon.rules.pplate)
146 | end
147 | end,
148 | })
149 |
150 | minetest.register_abm({
151 | nodenames = {"moremesecons_adjustable_player_detector:player_detector_on"},
152 | interval = 1.0,
153 | chance = 1,
154 | action = function(pos)
155 | if not object_detector_scan(pos) then
156 | minetest.swap_node(pos, {name = "moremesecons_adjustable_player_detector:player_detector_off"})
157 | mesecon.receptor_off(pos, mesecon.rules.pplate)
158 | end
159 | end,
160 | })
161 |
--------------------------------------------------------------------------------
/moremesecons_adjustable_player_detector/mod.conf:
--------------------------------------------------------------------------------
1 | name = moremesecons_adjustable_player_detector
2 | depends = mesecons
3 | optional_depends = craft_guide
4 |
--------------------------------------------------------------------------------
/moremesecons_adjustable_player_detector/textures/moremesecons_player_detector_off.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/minetest-mods/MoreMesecons/3e93b939f3bae14fb7a8c3f94e8db5d8fc0b2c24/moremesecons_adjustable_player_detector/textures/moremesecons_player_detector_off.png
--------------------------------------------------------------------------------
/moremesecons_adjustable_player_detector/textures/moremesecons_player_detector_on.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/minetest-mods/MoreMesecons/3e93b939f3bae14fb7a8c3f94e8db5d8fc0b2c24/moremesecons_adjustable_player_detector/textures/moremesecons_player_detector_on.png
--------------------------------------------------------------------------------
/moremesecons_commandblock/init.lua:
--------------------------------------------------------------------------------
1 | local strip_color_codes = minetest.settings:get_bool("strip_color_codes", false)
2 |
3 | local function initialize_data(meta)
4 | local NEAREST_MAX_DISTANCE = moremesecons.setting("commandblock", "nearest_max_distance", 8, 1)
5 |
6 | local commands = meta:get_string("commands")
7 | meta:set_string("formspec",
8 | "size[9,5]" ..
9 | "textarea[0.5,0.5;8.5,4;commands;Commands;"..minetest.formspec_escape(commands).."]" ..
10 | "label[1,3.8;@nearest is replaced by the nearest player name ("..tostring(NEAREST_MAX_DISTANCE).." nodes max for the nearest distance)".."]" ..
11 | "button_exit[3.3,4.5;2,1;submit;Submit]")
12 | local owner = meta:get_string("owner")
13 | if owner == "" then
14 | owner = "not owned"
15 | else
16 | owner = "owned by " .. owner
17 | end
18 | meta:set_string("infotext", "Command Block\n" ..
19 | "(" .. owner .. ")\n" ..
20 | "Commands: "..commands)
21 | end
22 |
23 | local function construct(pos)
24 | local meta = minetest.get_meta(pos)
25 |
26 | meta:set_string("commands", "tell @nearest Commandblock unconfigured")
27 |
28 | meta:set_string("owner", "")
29 |
30 | initialize_data(meta)
31 | end
32 |
33 | local function after_place(pos, placer)
34 | if placer then
35 | local meta = minetest.get_meta(pos)
36 | meta:set_string("owner", placer:get_player_name())
37 | initialize_data(meta)
38 | end
39 | end
40 |
41 | local function receive_fields(pos, _, fields, player)
42 | if not fields.submit then
43 | return
44 | end
45 | local meta = minetest.get_meta(pos)
46 | local owner = meta:get_string("owner")
47 | if owner ~= ""
48 | and player:get_player_name() ~= owner then
49 | return
50 | end
51 | if strip_color_codes then
52 | meta:set_string("commands", minetest.strip_colors(fields.commands))
53 | else
54 | meta:set_string("commands", fields.commands)
55 | end
56 |
57 | initialize_data(meta)
58 | end
59 |
60 | local function resolve_commands(commands, pos)
61 | local nearest = ""
62 | local min_distance = math.huge
63 | local players = minetest.get_connected_players()
64 | for _, player in pairs(players) do
65 | local distance = vector.distance(pos, player:get_pos())
66 | if distance < min_distance then
67 | min_distance = distance
68 | nearest = player:get_player_name()
69 | end
70 | end
71 | local new_commands = commands:gsub("@nearest", nearest)
72 | return new_commands, min_distance, new_commands ~= commands
73 | end
74 |
75 | local function commandblock_action_on(pos, node)
76 | local NEAREST_MAX_DISTANCE = moremesecons.setting("commandblock", "nearest_max_distance", 8, 1)
77 |
78 | local accepted_commands = {}
79 | do
80 | local commands_str = moremesecons.setting("commandblock", "authorized_commands", "tell")
81 | for command in string.gmatch(commands_str, "([^ ]+)") do
82 | accepted_commands[command] = true
83 | end
84 | end
85 |
86 | if node.name ~= "moremesecons_commandblock:commandblock_off" then
87 | return
88 | end
89 |
90 | minetest.swap_node(pos, {name = "moremesecons_commandblock:commandblock_on"})
91 |
92 | local meta = minetest.get_meta(pos)
93 | local owner = meta:get_string("owner")
94 | if owner == "" then
95 | return
96 | end
97 |
98 | local commands, distance, nearest_in_commands = resolve_commands(meta:get_string("commands"), pos)
99 | if distance > NEAREST_MAX_DISTANCE and nearest_in_commands then
100 | minetest.chat_send_player(owner, "The nearest player is too far to use his name in the commands of a craftable command block.")
101 | return
102 | end
103 | for _, command in pairs(commands:split("\n")) do
104 | local pos = command:find(" ")
105 | local cmd, param = command, ""
106 | if pos then
107 | cmd = command:sub(1, pos - 1)
108 | param = command:sub(pos + 1)
109 | end
110 | local cmddef = minetest.chatcommands[cmd]
111 | if not accepted_commands[cmd] and next(accepted_commands) then
112 | minetest.chat_send_player(owner, "You can not execute the command "..cmd.." with a craftable command block ! This event will be reported.")
113 | minetest.log("action", "Player "..owner.." tryed to execute an unauthorized command with a craftable command block.")
114 | return
115 | end
116 | if not cmddef then
117 | minetest.chat_send_player(owner, "The command "..cmd.." does not exist")
118 | return
119 | end
120 | local has_privs, missing_privs = minetest.check_player_privs(owner, cmddef.privs)
121 | if not has_privs then
122 | minetest.chat_send_player(owner, "You don't have permission "
123 | .."to run "..cmd
124 | .." (missing privileges: "
125 | ..table.concat(missing_privs, ", ")..")")
126 | return
127 | end
128 | cmddef.func(owner, param)
129 | end
130 | end
131 |
132 | local function commandblock_action_off(pos, node)
133 | if node.name == "moremesecons_commandblock:commandblock_on" then
134 | minetest.swap_node(pos, {name = "moremesecons_commandblock:commandblock_off"})
135 | end
136 | end
137 |
138 | local function can_dig(pos, player)
139 | local meta = minetest.get_meta(pos)
140 | local owner = meta:get_string("owner")
141 | return owner == "" or owner == player:get_player_name()
142 | end
143 |
144 | minetest.register_node("moremesecons_commandblock:commandblock_off", {
145 | description = "Craftable Command Block",
146 | tiles = {"moremesecons_commandblock_off.png"},
147 | groups = {cracky=2, mesecon_effector_off=1},
148 | on_construct = construct,
149 | after_place_node = after_place,
150 | on_receive_fields = receive_fields,
151 | can_dig = can_dig,
152 | sounds = default.node_sound_stone_defaults(),
153 | mesecons = {effector = {
154 | action_on = commandblock_action_on
155 | }}
156 | })
157 |
158 | minetest.register_node("moremesecons_commandblock:commandblock_on", {
159 | tiles = {"moremesecons_commandblock_on.png"},
160 | groups = {cracky=2, mesecon_effector_on=1, not_in_creative_inventory=1},
161 | light_source = 10,
162 | drop = "moremesecons_commandblock:commandblock_off",
163 | on_construct = construct,
164 | after_place_node = after_place,
165 | on_receive_fields = receive_fields,
166 | can_dig = can_dig,
167 | sounds = default.node_sound_stone_defaults(),
168 | mesecons = {effector = {
169 | action_off = commandblock_action_off
170 | }}
171 | })
172 |
173 | minetest.register_craft({
174 | output = "moremesecons_commandblock:commandblock_off",
175 | recipe = {
176 | {"group:mesecon_conductor_craftable","default:mese_crystal","group:mesecon_conductor_craftable"},
177 | {"default:mese_crystal","group:mesecon_conductor_craftable","default:mese_crystal"},
178 | {"group:mesecon_conductor_craftable","default:mese_crystal","group:mesecon_conductor_craftable"}
179 | }
180 | })
181 |
--------------------------------------------------------------------------------
/moremesecons_commandblock/mod.conf:
--------------------------------------------------------------------------------
1 | name = moremesecons_commandblock
2 | depends = mesecons,moremesecons_utils
3 | optional_depends = craft_guide
4 |
--------------------------------------------------------------------------------
/moremesecons_commandblock/textures/moremesecons_commandblock_off.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/minetest-mods/MoreMesecons/3e93b939f3bae14fb7a8c3f94e8db5d8fc0b2c24/moremesecons_commandblock/textures/moremesecons_commandblock_off.png
--------------------------------------------------------------------------------
/moremesecons_commandblock/textures/moremesecons_commandblock_on.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/minetest-mods/MoreMesecons/3e93b939f3bae14fb7a8c3f94e8db5d8fc0b2c24/moremesecons_commandblock/textures/moremesecons_commandblock_on.png
--------------------------------------------------------------------------------
/moremesecons_conductor_signalchanger/init.lua:
--------------------------------------------------------------------------------
1 | local nodebox = {
2 | type = "fixed",
3 | fixed = {{-8/16, -8/16, -8/16, 8/16, -7/16, 8/16 }},
4 | }
5 |
6 | local function signalchanger_get_output_rules(node)
7 | local rules = {{x=-1, y=0, z=0}}
8 | for _ = 0, node.param2 do
9 | rules = mesecon.rotate_rules_left(rules)
10 | end
11 | return rules
12 | end
13 |
14 | local function signalchanger_get_input_rules(node)
15 | local rules = {{x=0, y=0, z=-1, name="input_on"}, {x=0, y=0, z=1, name="input_off"}, {x=1, y=0, z=0, name="input_signal"}}
16 | for _ = 0, node.param2 do
17 | rules = mesecon.rotate_rules_left(rules)
18 | end
19 | return rules
20 | end
21 |
22 | local update = function(pos, node, link, newstate)
23 | local meta = minetest.get_meta(pos)
24 | meta:set_int(link.name, newstate == "on" and 1 or 0)
25 | local input_on = meta:get_int("input_on") == 1
26 | local input_off = meta:get_int("input_off") == 1
27 | local input_signal = meta:get_int("input_signal") == 1
28 |
29 | if input_on then
30 | minetest.swap_node(pos, {name = "moremesecons_conductor_signalchanger:conductor_signalchanger_on", param2 = node.param2})
31 | elseif input_off then
32 | mesecon.receptor_off(pos, signalchanger_get_output_rules(node))
33 | minetest.swap_node(pos, {name = "moremesecons_conductor_signalchanger:conductor_signalchanger_off", param2 = node.param2})
34 | end
35 |
36 | if input_signal and minetest.get_node(pos).name == "moremesecons_conductor_signalchanger:conductor_signalchanger_on" then -- Note : we must use "minetest.get_node(pos)" and not "node" because the node may have been changed
37 | mesecon.receptor_on(pos, signalchanger_get_output_rules(node))
38 | else
39 | mesecon.receptor_off(pos, signalchanger_get_output_rules(node))
40 | end
41 | end
42 |
43 | mesecon.register_node("moremesecons_conductor_signalchanger:conductor_signalchanger", {
44 | description = "Conductor Signal Changer",
45 | inventory_image = "moremesecons_conductor_signalchanger_off.png",
46 | groups = {dig_immediate = 2},
47 | paramtype = "light",
48 | paramtype2 = "facedir",
49 | drawtype = "nodebox",
50 | selection_box = nodebox,
51 | node_box = nodebox,
52 | },{
53 | groups = {dig_immediate = 2},
54 | mesecons = {
55 | receptor = {
56 | rules = signalchanger_get_output_rules
57 | },
58 | effector = {
59 | rules = signalchanger_get_input_rules,
60 | action_change = update
61 | },
62 | },
63 | tiles = {"moremesecons_conductor_signalchanger_off.png"},
64 | },{
65 | groups = {dig_immediate = 2, not_in_creative_inventory = 1},
66 | mesecons = {
67 | receptor = {
68 | rules = signalchanger_get_output_rules,
69 | },
70 | effector = {
71 | rules = signalchanger_get_input_rules,
72 | action_change = update,
73 | },
74 | },
75 | tiles = {"moremesecons_conductor_signalchanger_on.png"},
76 | })
77 |
78 | minetest.register_craft({
79 | output = "moremesecons_conductor_signalchanger:conductor_signalchanger_off",
80 | recipe = {{"group:mesecon_conductor_craftable","moremesecons_signalchanger:signalchanger_off"}}
81 | })
82 |
--------------------------------------------------------------------------------
/moremesecons_conductor_signalchanger/mod.conf:
--------------------------------------------------------------------------------
1 | name = moremesecons_conductor_signalchanger
2 | depends = mesecons
3 | optional_depends = craft_guide
4 |
--------------------------------------------------------------------------------
/moremesecons_conductor_signalchanger/textures/moremesecons_conductor_signalchanger_off.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/minetest-mods/MoreMesecons/3e93b939f3bae14fb7a8c3f94e8db5d8fc0b2c24/moremesecons_conductor_signalchanger/textures/moremesecons_conductor_signalchanger_off.png
--------------------------------------------------------------------------------
/moremesecons_conductor_signalchanger/textures/moremesecons_conductor_signalchanger_on.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/minetest-mods/MoreMesecons/3e93b939f3bae14fb7a8c3f94e8db5d8fc0b2c24/moremesecons_conductor_signalchanger/textures/moremesecons_conductor_signalchanger_on.png
--------------------------------------------------------------------------------
/moremesecons_dual_delayer/init.lua:
--------------------------------------------------------------------------------
1 | local function dual_delayer_get_input_rules(node)
2 | local rules = {{x=1, y=0, z=0}}
3 | for _ = 0, node.param2 do
4 | rules = mesecon.rotate_rules_left(rules)
5 | end
6 | return rules
7 | end
8 |
9 | local function dual_delayer_get_output_rules(node)
10 | local rules = {{x=0, y=0, z=1}, {x=0, y=0, z=-1}}
11 | for _ = 0, node.param2 do
12 | rules = mesecon.rotate_rules_left(rules)
13 | end
14 | return rules
15 | end
16 |
17 | local dual_delayer_activate = function(pos, node)
18 | mesecon.receptor_on(pos, {dual_delayer_get_output_rules(node)[1]}) -- Turn on the port 1
19 | minetest.swap_node(pos, {name = "moremesecons_dual_delayer:dual_delayer_10", param2 = node.param2})
20 | minetest.after(0.4, function()
21 | mesecon.receptor_on(pos, {dual_delayer_get_output_rules(node)[2]}) -- Turn on the port 2
22 | minetest.swap_node(pos, {name = "moremesecons_dual_delayer:dual_delayer_11", param2 = node.param2})
23 | end)
24 | end
25 |
26 | local dual_delayer_deactivate = function(pos, node, link)
27 | mesecon.receptor_off(pos, {dual_delayer_get_output_rules(node)[2]}) -- Turn off the port 2
28 | minetest.swap_node(pos, {name = "moremesecons_dual_delayer:dual_delayer_10", param2 = node.param2})
29 | minetest.after(0.4, function()
30 | mesecon.receptor_off(pos, {dual_delayer_get_output_rules(node)[1]}) -- Turn off the port 1
31 | minetest.swap_node(pos, {name = "moremesecons_dual_delayer:dual_delayer_00", param2 = node.param2})
32 | end)
33 | end
34 |
35 |
36 | for n,i in pairs({{0,0},{1,0},{1,1}}) do
37 | local i1,i2 = unpack(i)
38 |
39 | local groups = {dig_immediate = 2}
40 | if n ~= 1 then
41 | groups.not_in_creative_inventory = 1
42 | end
43 |
44 | local top_texture = "^moremesecons_dual_delayer_overlay.png^[makealpha:255,126,126"
45 | if i1 == i2 then
46 | if i1 == 0 then
47 | top_texture = "mesecons_wire_off.png"..top_texture
48 | else
49 | top_texture = "mesecons_wire_on.png"..top_texture
50 | end
51 | else
52 | local pre = "mesecons_wire_off.png^[lowpart:50:mesecons_wire_on.png^[transformR"
53 | if i1 == 0 then
54 | pre = pre.. 90
55 | else
56 | pre = pre.. 270
57 | end
58 | top_texture = pre..top_texture
59 | end
60 |
61 | local use_texture_alpha
62 | if minetest.features.use_texture_alpha_string_modes then
63 | use_texture_alpha = "opaque"
64 | end
65 | minetest.register_node("moremesecons_dual_delayer:dual_delayer_"..i1 ..i2, {
66 | description = "Dual Delayer",
67 | drop = "moremesecons_dual_delayer:dual_delayer_00",
68 | inventory_image = top_texture,
69 | wield_image = top_texture,
70 | paramtype = "light",
71 | paramtype2 = "facedir",
72 | drawtype = "nodebox",
73 | node_box = {
74 | type = "fixed",
75 | fixed = {{-6/16, -8/16, -8/16, 6/16, -7/16, 1/16 },
76 | {-8/16, -8/16, 1/16, -6/16, -7/16, -1/16},
77 | {8/16, -8/16, -1/16, 6/16, -7/16, 1/16}}
78 | },
79 | groups = groups,
80 | tiles = {top_texture, "moremesecons_dual_delayer_bottom.png", "moremesecons_dual_delayer_side_left.png", "moremesecons_dual_delayer_side_right.png", "moremesecons_dual_delayer_ends.png", "moremesecons_dual_delayer_ends.png"},
81 | use_texture_alpha = use_texture_alpha,
82 | mesecons = {
83 | receptor = {
84 | state = mesecon.state.off,
85 | rules = dual_delayer_get_output_rules
86 | },
87 | effector = {
88 | rules = dual_delayer_get_input_rules,
89 | action_on = dual_delayer_activate,
90 | action_off = dual_delayer_deactivate
91 | }
92 | }
93 | })
94 | end
95 |
96 | minetest.register_craft({
97 | type = "shapeless",
98 | output = "moremesecons_dual_delayer:dual_delayer_00 2",
99 | recipe = {"mesecons_delayer:delayer_off_1", "mesecons_delayer:delayer_off_1"}
100 | })
101 |
--------------------------------------------------------------------------------
/moremesecons_dual_delayer/mod.conf:
--------------------------------------------------------------------------------
1 | name = moremesecons_dual_delayer
2 | depends = mesecons
3 | optional_depends = craft_guide
4 |
--------------------------------------------------------------------------------
/moremesecons_dual_delayer/textures/moremesecons_dual_delayer_bottom.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/minetest-mods/MoreMesecons/3e93b939f3bae14fb7a8c3f94e8db5d8fc0b2c24/moremesecons_dual_delayer/textures/moremesecons_dual_delayer_bottom.png
--------------------------------------------------------------------------------
/moremesecons_dual_delayer/textures/moremesecons_dual_delayer_ends.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/minetest-mods/MoreMesecons/3e93b939f3bae14fb7a8c3f94e8db5d8fc0b2c24/moremesecons_dual_delayer/textures/moremesecons_dual_delayer_ends.png
--------------------------------------------------------------------------------
/moremesecons_dual_delayer/textures/moremesecons_dual_delayer_overlay.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/minetest-mods/MoreMesecons/3e93b939f3bae14fb7a8c3f94e8db5d8fc0b2c24/moremesecons_dual_delayer/textures/moremesecons_dual_delayer_overlay.png
--------------------------------------------------------------------------------
/moremesecons_dual_delayer/textures/moremesecons_dual_delayer_side_left.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/minetest-mods/MoreMesecons/3e93b939f3bae14fb7a8c3f94e8db5d8fc0b2c24/moremesecons_dual_delayer/textures/moremesecons_dual_delayer_side_left.png
--------------------------------------------------------------------------------
/moremesecons_dual_delayer/textures/moremesecons_dual_delayer_side_right.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/minetest-mods/MoreMesecons/3e93b939f3bae14fb7a8c3f94e8db5d8fc0b2c24/moremesecons_dual_delayer/textures/moremesecons_dual_delayer_side_right.png
--------------------------------------------------------------------------------
/moremesecons_entity_detector/init.lua:
--------------------------------------------------------------------------------
1 | -- Entity detector
2 | -- Detects entitys in a certain radius
3 | -- The radius can be changes by right-click (by default 6)
4 |
5 | local MAX_RADIUS = moremesecons.setting("entity_detector", "max_radius", 16, 0)
6 |
7 | local function make_formspec(meta)
8 | meta:set_string("formspec", "size[9,5]" ..
9 | "field[0.3, 0;9,2;scanname;Comma-separated list of the names (itemstring) of entities to scan for (empty for any):;${scanname}]"..
10 | "field[0.3,1.5;4,2;digiline_channel;Digiline Channel (optional):;${digiline_channel}]"..
11 | "field[0.3,3;2,2;radius;Detection radius:;${radius}]"..
12 | "button_exit[3.5,3.5;2,3;;Save]")
13 | end
14 |
15 | local function object_detector_make_formspec(pos)
16 | make_formspec(minetest.get_meta(pos))
17 | end
18 |
19 | local function object_detector_on_receive_fields(pos, _, fields, player)
20 | if not fields.scanname
21 | or not fields.digiline_channel
22 | or minetest.is_protected(pos, player:get_player_name()) then
23 | return
24 | end
25 |
26 | local meta = minetest.get_meta(pos)
27 | meta:set_string("scanname", fields.scanname)
28 | meta:set_string("digiline_channel", fields.digiline_channel)
29 | local r = tonumber(fields.radius)
30 | if r then
31 | meta:set_int("radius", math.min(r, MAX_RADIUS))
32 | end
33 | end
34 |
35 | -- returns true if entity was found, false if not
36 | local object_detector_scan = function (pos)
37 | local meta = minetest.get_meta(pos)
38 | local scanname = meta:get_string("scanname")
39 | local scan_all = scanname == ""
40 | local scan_names = scanname:split(',')
41 | local radius = math.min(tonumber(meta:get("radius")) or 6, MAX_RADIUS)
42 | for _,obj in pairs(minetest.get_objects_inside_radius(pos, radius)) do
43 | local luaentity = obj:get_luaentity()
44 | if luaentity then
45 | if scan_all then
46 | return true
47 | end
48 | local isname = luaentity.name
49 | for _, name in ipairs(scan_names) do
50 | if isname == name or (isname == "__builtin:item" and luaentity.itemstring == name) then
51 | return true
52 | end
53 | end
54 | end
55 | end
56 | return false
57 | end
58 |
59 | -- set entity name when receiving a digiline signal on a specific channel
60 | local object_detector_digiline = {
61 | effector = {
62 | action = function (pos, node, channel, msg)
63 | local meta = minetest.get_meta(pos)
64 | local active_channel = meta:get_string("digiline_channel")
65 | if channel ~= active_channel or type(msg) ~= "string" then
66 | return
67 | end
68 | meta:set_string("scanname", msg)
69 | if meta:get_string("formspec") ~= "" then
70 | make_formspec(meta)
71 | end
72 | end,
73 | }
74 | }
75 |
76 | minetest.register_node("moremesecons_entity_detector:entity_detector_off", {
77 | tiles = {"default_steel_block.png", "default_steel_block.png", "moremesecons_entity_detector_off.png"},
78 | paramtype = "light",
79 | walkable = true,
80 | groups = {cracky=3},
81 | description="Entity Detector",
82 | mesecons = {receptor = {
83 | state = mesecon.state.off,
84 | rules = mesecon.rules.pplate
85 | }},
86 | on_construct = object_detector_make_formspec,
87 | on_receive_fields = object_detector_on_receive_fields,
88 | sounds = default.node_sound_stone_defaults(),
89 | digiline = object_detector_digiline
90 | })
91 |
92 | minetest.register_node("moremesecons_entity_detector:entity_detector_on", {
93 | tiles = {"default_steel_block.png", "default_steel_block.png", "moremesecons_entity_detector_on.png"},
94 | paramtype = "light",
95 | walkable = true,
96 | groups = {cracky=3,not_in_creative_inventory=1},
97 | drop = 'moremesecons_entity_detector:entity_detector_off',
98 | mesecons = {receptor = {
99 | state = mesecon.state.on,
100 | rules = mesecon.rules.pplate
101 | }},
102 | on_construct = object_detector_make_formspec,
103 | on_receive_fields = object_detector_on_receive_fields,
104 | sounds = default.node_sound_stone_defaults(),
105 | digiline = object_detector_digiline
106 | })
107 |
108 | minetest.register_craft({
109 | output = 'moremesecons_entity_detector:entity_detector_off',
110 | recipe = {
111 | {"default:mese_crystal_fragment"},
112 | {"mesecons_detector:object_detector_off"}
113 | }
114 | })
115 |
116 | minetest.register_abm({
117 | nodenames = {"moremesecons_entity_detector:entity_detector_off"},
118 | interval = 1.0,
119 | chance = 1,
120 | action = function(pos)
121 | if object_detector_scan(pos) then
122 | minetest.swap_node(pos, {name = "moremesecons_entity_detector:entity_detector_on"})
123 | mesecon.receptor_on(pos, mesecon.rules.pplate)
124 | end
125 | end,
126 | })
127 |
128 | minetest.register_abm({
129 | nodenames = {"moremesecons_entity_detector:entity_detector_on"},
130 | interval = 1.0,
131 | chance = 1,
132 | action = function(pos)
133 | if not object_detector_scan(pos) then
134 | minetest.swap_node(pos, {name = "moremesecons_entity_detector:entity_detector_off"})
135 | mesecon.receptor_off(pos, mesecon.rules.pplate)
136 | end
137 | end,
138 | })
139 |
--------------------------------------------------------------------------------
/moremesecons_entity_detector/mod.conf:
--------------------------------------------------------------------------------
1 | name = moremesecons_entity_detector
2 | depends = mesecons
3 | optional_depends = craft_guide
4 |
--------------------------------------------------------------------------------
/moremesecons_entity_detector/textures/moremesecons_entity_detector_off.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/minetest-mods/MoreMesecons/3e93b939f3bae14fb7a8c3f94e8db5d8fc0b2c24/moremesecons_entity_detector/textures/moremesecons_entity_detector_off.png
--------------------------------------------------------------------------------
/moremesecons_entity_detector/textures/moremesecons_entity_detector_on.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/minetest-mods/MoreMesecons/3e93b939f3bae14fb7a8c3f94e8db5d8fc0b2c24/moremesecons_entity_detector/textures/moremesecons_entity_detector_on.png
--------------------------------------------------------------------------------
/moremesecons_igniter/init.lua:
--------------------------------------------------------------------------------
1 | local function add_back_igniter(pos)
2 | local name = minetest.get_node(pos).name
3 |
4 | if name == "moremesecons_igniter:igniter" then
5 | -- this should not happen
6 | minetest.log("error", "[moremesecons_igniter] igniter is already back")
7 | return
8 | end
9 |
10 | if name == "ignore" then
11 | -- in case of unloaded chunk
12 | minetest.get_voxel_manip():read_from_map(pos, pos)
13 | name = minetest.get_node(pos).name
14 | end
15 |
16 | if name == "air"
17 | or name == "fire:basic_flame" then
18 | minetest.set_node(pos, {name="moremesecons_igniter:igniter"})
19 | else
20 | -- drop it as item if something took place there in the 0.8 seconds
21 | pos.y = pos.y+1
22 | minetest.add_item(pos, "moremesecons_igniter:igniter")
23 | pos.y = pos.y-1
24 | end
25 | end
26 |
27 | local function igniter_on(pos)
28 | minetest.set_node(pos, {name="fire:basic_flame"})
29 | minetest.after(0.8, add_back_igniter, pos)
30 | end
31 |
32 | minetest.register_node("moremesecons_igniter:igniter", {
33 | description = "Igniter",
34 | paramtype = "light",
35 | tiles = {"moremesecons_igniter.png"},
36 | groups = {cracky=3},
37 | mesecons = {
38 | effector = {
39 | action_on = igniter_on
40 | }}
41 | })
42 |
43 |
44 | minetest.register_craft({
45 | output = "moremesecons_igniter:igniter",
46 | recipe = { {"default:torch"},
47 | {"default:mese_crystal_fragment"},}
48 | })
49 |
--------------------------------------------------------------------------------
/moremesecons_igniter/mod.conf:
--------------------------------------------------------------------------------
1 | name = moremesecons_igniter
2 | depends = mesecons,fire
3 | optional_depends = craft_guide
4 |
--------------------------------------------------------------------------------
/moremesecons_igniter/textures/moremesecons_igniter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/minetest-mods/MoreMesecons/3e93b939f3bae14fb7a8c3f94e8db5d8fc0b2c24/moremesecons_igniter/textures/moremesecons_igniter.png
--------------------------------------------------------------------------------
/moremesecons_induction_transmitter/init.lua:
--------------------------------------------------------------------------------
1 | local function induction_transmitter_get_input_rules(node)
2 | -- All horizontal rules, except the output
3 | local rules = {
4 | {x=-1,y=0,z=0},
5 | {x=1,y=0,z=0},
6 | {x=0,y=0,z=-1},
7 | {x=0,y=0,z=1}
8 | }
9 | for i, r in ipairs(rules) do
10 | if vector.equals(r, minetest.facedir_to_dir(node.param2)) then
11 | table.remove(rules, i)
12 | end
13 | end
14 | return rules
15 | end
16 |
17 | local function induction_transmitter_get_output_rules(node)
18 | return {vector.multiply(minetest.facedir_to_dir(node.param2), 2)}
19 | end
20 |
21 | local function act(pos, node, state)
22 | minetest.swap_node(pos, {name = "moremesecons_induction_transmitter:induction_transmitter_"..state, param2 = node.param2})
23 |
24 | local dir = minetest.facedir_to_dir(node.param2)
25 | local target_pos = vector.add(pos, vector.multiply(dir, 2))
26 | local target_node = minetest.get_node(target_pos)
27 | if mesecon.is_effector(target_node.name) then
28 | -- Switch on an aside node, so it sends a signal to the target node
29 | local aside_rule = mesecon.effector_get_rules(target_node)[1]
30 | if not aside_rule then
31 | return
32 | end
33 | mesecon["receptor_"..state](vector.add(target_pos, aside_rule), {vector.multiply(aside_rule, -1)})
34 | elseif mesecon.is_conductor(target_node.name) then
35 | -- Switch on the conductor itself
36 | mesecon["receptor_"..state](target_pos, mesecon.conductor_get_rules(target_node))
37 | end
38 | end
39 |
40 | mesecon.register_node("moremesecons_induction_transmitter:induction_transmitter", {
41 | description = "Induction Transmitter",
42 | drawtype = "nodebox",
43 | paramtype = "light",
44 | paramtype2 = "facedir",
45 | node_box = {
46 | type = "fixed",
47 | fixed = {
48 | {-0.5, -0.5, 0.125, 0.5, 0.5, 0.5},
49 | {-0.375, -0.375, -0.1875, 0.375, 0.375, 0.125},
50 | {-0.25, -0.25, -0.5, 0.25, 0.25, -0.1875},
51 | }
52 | },
53 | selection_box = {
54 | type = "fixed",
55 | fixed = {
56 | {-0.5, -0.5, 0.125, 0.5, 0.5, 0.5},
57 | {-0.375, -0.375, -0.1875, 0.375, 0.375, 0.125},
58 | {-0.25, -0.25, -0.5, 0.25, 0.25, -0.1875},
59 | },
60 | },
61 | }, {
62 | tiles = {"default_mese_block.png"},
63 | groups = {cracky = 3},
64 | mesecons = {
65 | receptor = {
66 | state = mesecon.state.off,
67 | rules = induction_transmitter_get_output_rules
68 | },
69 | effector = {
70 | rules = induction_transmitter_get_input_rules,
71 | action_on = function(pos, node)
72 | act(pos, node, "on")
73 | end
74 | }
75 | }
76 | }, {
77 | light_source = 5,
78 | tiles = {"default_mese_block.png^[brighten"},
79 | groups = {cracky = 3, not_in_creative_inventory = 1},
80 | mesecons = {
81 | receptor = {
82 | state = mesecon.state.on,
83 | rules = induction_transmitter_get_output_rules
84 | },
85 | effector = {
86 | rules = induction_transmitter_get_input_rules,
87 | action_off = function(pos, node)
88 | act(pos, node, "off")
89 | end
90 | }
91 | }
92 | })
93 |
94 | minetest.register_craft({
95 | output = "moremesecons_induction_transmitter:induction_transmitter_off",
96 | recipe = {
97 | {"default:mese_crystal_fragment", "mesecons_torch:mesecon_torch_on", "default:mese_crystal_fragment"},
98 | {"", "default:mese_crystal_fragment", ""}
99 | }
100 | })
101 |
--------------------------------------------------------------------------------
/moremesecons_induction_transmitter/mod.conf:
--------------------------------------------------------------------------------
1 | name = moremesecons_induction_transmitter
2 | depends = mesecons,mesecons_torch,default
3 |
--------------------------------------------------------------------------------
/moremesecons_injector_controller/init.lua:
--------------------------------------------------------------------------------
1 | local injector_controller_get_output_rules = function(node)
2 | local rules = {{x = 0, y = 0, z = 1}}
3 | for _ = 0, node.param2 do
4 | rules = mesecon.rotate_rules_left(rules)
5 | end
6 | return rules
7 | end
8 |
9 | local injector_controller_get_input_rules = function(node)
10 | local rules = {{x = 0, y = 0, z = -1},
11 | {x = 1, y = 0, z = 0},
12 | {x = -1, y = 0, z = 0}}
13 | for _ = 0, node.param2 do
14 | rules = mesecon.rotate_rules_left(rules)
15 | end
16 | return rules
17 | end
18 |
19 | local start_timer = function(pos)
20 | local timer = minetest.get_node_timer(pos)
21 | timer:start(1)
22 | end
23 | local stop_timer = function(pos, node)
24 | local timer = minetest.get_node_timer(pos)
25 | timer:stop()
26 | mesecon.receptor_off(pos, injector_controller_get_output_rules(node))
27 | minetest.swap_node(pos, {name="moremesecons_injector_controller:injector_controller_off", param2=node.param2})
28 | end
29 |
30 | local on_timer = function(pos)
31 | local node = minetest.get_node(pos)
32 | if(mesecon.flipstate(pos, node) == "on") then
33 | mesecon.receptor_on(pos, injector_controller_get_output_rules(node))
34 | else
35 | mesecon.receptor_off(pos, injector_controller_get_output_rules(node))
36 | end
37 | start_timer(pos)
38 | end
39 |
40 | mesecon.register_node("moremesecons_injector_controller:injector_controller", {
41 | description="Injector Controller",
42 | drawtype = "nodebox",
43 | inventory_image = "moremesecons_injector_controller_off.png",
44 | paramtype = "light",
45 | paramtype2 = "facedir",
46 | node_box = {
47 | type = "fixed",
48 | fixed = {{-8/16, -8/16, -8/16, 8/16, -7/16, 8/16 }},
49 | },
50 | on_timer = on_timer,
51 | },{
52 | tiles = {"moremesecons_injector_controller_off.png", "moremesecons_injector_controller_side.png", "moremesecons_injector_controller_side.png"},
53 | groups = {dig_immediate=2},
54 | mesecons = {
55 | receptor = {
56 | state = mesecon.state.off,
57 | rules = injector_controller_get_output_rules
58 | },
59 | effector = {
60 | rules = injector_controller_get_input_rules,
61 | action_on = start_timer,
62 | action_off = stop_timer,
63 | }
64 | }
65 | },{
66 | tiles = {"moremesecons_injector_controller_on.png", "moremesecons_injector_controller_side.png", "moremesecons_injector_controller_side.png"},
67 | groups = {dig_immediate=2, not_in_creative_inventory=1},
68 | mesecons = {
69 | receptor = {
70 | state = mesecon.state.on,
71 | rules = injector_controller_get_output_rules
72 | },
73 | effector = {
74 | rules = injector_controller_get_input_rules,
75 | action_off = stop_timer,
76 | action_on = start_timer,
77 | }
78 | }
79 | })
80 |
81 | minetest.register_craft({
82 | output = "moremesecons_injector_controller:injector_controller_off",
83 | recipe = {{"mesecons_blinkyplant:blinky_plant_off","mesecons_gates:and_off"}}
84 | })
85 |
--------------------------------------------------------------------------------
/moremesecons_injector_controller/mod.conf:
--------------------------------------------------------------------------------
1 | name = moremesecons_injector_controller
2 | depends = mesecons
3 | optional_depends = craft_guide
4 |
--------------------------------------------------------------------------------
/moremesecons_injector_controller/textures/moremesecons_injector_controller_off.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/minetest-mods/MoreMesecons/3e93b939f3bae14fb7a8c3f94e8db5d8fc0b2c24/moremesecons_injector_controller/textures/moremesecons_injector_controller_off.png
--------------------------------------------------------------------------------
/moremesecons_injector_controller/textures/moremesecons_injector_controller_on.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/minetest-mods/MoreMesecons/3e93b939f3bae14fb7a8c3f94e8db5d8fc0b2c24/moremesecons_injector_controller/textures/moremesecons_injector_controller_on.png
--------------------------------------------------------------------------------
/moremesecons_injector_controller/textures/moremesecons_injector_controller_side.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/minetest-mods/MoreMesecons/3e93b939f3bae14fb7a8c3f94e8db5d8fc0b2c24/moremesecons_injector_controller/textures/moremesecons_injector_controller_side.png
--------------------------------------------------------------------------------
/moremesecons_jammer/init.lua:
--------------------------------------------------------------------------------
1 | -- see wireless jammer
2 | local storage = minetest.get_mod_storage()
3 |
4 | local jammers = moremesecons.load_MapDataStorage_legacy(storage, "jammers_v2",
5 | "jammers")
6 |
7 | local function update_mod_storage()
8 | storage:set_string("jammers_v2", jammers:serialize())
9 | end
10 |
11 | local function add_jammer(pos)
12 | if jammers:getAt(pos) then
13 | return
14 | end
15 | jammers:setAt(pos, true)
16 | update_mod_storage()
17 | end
18 |
19 | local function remove_jammer(pos)
20 | jammers:removeAt(pos)
21 | update_mod_storage()
22 | end
23 |
24 | local function is_jammed(pos)
25 | local JAMMER_MAX_DISTANCE = moremesecons.setting("jammer", "max_distance", 10, 1)
26 |
27 | local minp = vector.subtract(pos, JAMMER_MAX_DISTANCE)
28 | local maxp = vector.add(pos, JAMMER_MAX_DISTANCE)
29 | for p in jammers:iter(minp, maxp) do
30 | local d = vector.subtract(pos, p)
31 | if d.x ^ 2 + d.y ^ 2 + d.z ^ 2 <= JAMMER_MAX_DISTANCE^2 then
32 | return true
33 | end
34 | end
35 | return false
36 | end
37 |
38 | minetest.after(0, function() -- After loading all mods, override some functions
39 | local jammed
40 |
41 | local actual_node_get = mesecon.get_node_force
42 | local function temp_node_get(pos, ...)
43 | local node = actual_node_get(pos, ...)
44 | if jammed == nil
45 | and node then
46 | jammed = is_jammed(pos)
47 | end
48 | return node
49 | end
50 |
51 | local actual_is_conductor_off = mesecon.is_conductor_off
52 | local function temp_is_conductor_off(...)
53 | if jammed then
54 | -- go to the next elseif, there's is_effector
55 | return
56 | end
57 | local v = actual_is_conductor_off(...)
58 | if v then
59 | -- it continues to the next frontier
60 | jammed = nil
61 | end
62 | return v
63 | end
64 |
65 | local actual_is_effector = mesecon.is_effector
66 | local function temp_is_effector(...)
67 | local abort_here = jammed
68 | -- the last elseif before continuing, jammed needs to be nil then
69 | jammed = nil
70 | if abort_here then
71 | return
72 | end
73 | return actual_is_effector(...)
74 | end
75 |
76 | local actual_turnon = mesecon.turnon
77 | function mesecon.turnon(...)
78 | --set those to the temporary functions
79 | mesecon.get_node_force = temp_node_get
80 | mesecon.is_conductor_off = temp_is_conductor_off
81 | mesecon.is_effector = temp_is_effector
82 |
83 | actual_turnon(...)
84 |
85 | mesecon.get_node_force = actual_node_get
86 | mesecon.is_conductor_off = actual_is_conductor_off
87 | mesecon.is_effector = actual_is_effector
88 |
89 | -- safety
90 | jammed = nil
91 | end
92 | end)
93 |
94 | mesecon.register_node("moremesecons_jammer:jammer", {
95 | description = "Mesecons Jammer",
96 | paramtype = "light",
97 | },{
98 | tiles = {"moremesecons_jammer_off.png"},
99 | groups = {dig_immediate=2},
100 | mesecons = {effector = {
101 | action_on = function(pos)
102 | add_jammer(pos)
103 | minetest.sound_play("moremesecons_jammer", {pos = pos})
104 | minetest.swap_node(pos, {name="moremesecons_jammer:jammer_on"})
105 | end
106 | }},
107 | },{
108 | tiles = {"moremesecons_jammer_on.png"},
109 | groups = {dig_immediate=2, not_in_creative_inventory=1},
110 | mesecons = {effector = {
111 | action_off = function(pos)
112 | remove_jammer(pos)
113 | minetest.swap_node(pos, {name="moremesecons_jammer:jammer_off"})
114 | end
115 | }},
116 | on_destruct = remove_jammer,
117 | on_construct = add_jammer,
118 | })
119 |
120 | minetest.register_craft({
121 | output = "moremesecons_jammer:jammer_off",
122 | recipe = {{"group:mesecon_conductor_craftable", "default:mese", "group:mesecon_conductor_craftable"},
123 | {"", "moremesecons_wireless:jammer_off", ""}}
124 | })
125 |
126 | if moremesecons.setting("jammer", "enable_lbm", false) then
127 | minetest.register_lbm({
128 | name = "moremesecons_jammer:add_jammer",
129 | nodenames = {"moremesecons_jammer:jammer_on"},
130 | run_at_every_load = true,
131 | action = add_jammer
132 | })
133 | end
134 |
--------------------------------------------------------------------------------
/moremesecons_jammer/mod.conf:
--------------------------------------------------------------------------------
1 | name = moremesecons_jammer
2 | depends = mesecons,moremesecons_utils
3 | optional_depends = craft_guide
4 |
--------------------------------------------------------------------------------
/moremesecons_jammer/sounds/moremesecons_jammer.ogg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/minetest-mods/MoreMesecons/3e93b939f3bae14fb7a8c3f94e8db5d8fc0b2c24/moremesecons_jammer/sounds/moremesecons_jammer.ogg
--------------------------------------------------------------------------------
/moremesecons_jammer/textures/moremesecons_jammer_off.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/minetest-mods/MoreMesecons/3e93b939f3bae14fb7a8c3f94e8db5d8fc0b2c24/moremesecons_jammer/textures/moremesecons_jammer_off.png
--------------------------------------------------------------------------------
/moremesecons_jammer/textures/moremesecons_jammer_on.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/minetest-mods/MoreMesecons/3e93b939f3bae14fb7a8c3f94e8db5d8fc0b2c24/moremesecons_jammer/textures/moremesecons_jammer_on.png
--------------------------------------------------------------------------------
/moremesecons_luablock/init.lua:
--------------------------------------------------------------------------------
1 | local storage = minetest.get_mod_storage()
2 | local pos_data = moremesecons.get_storage_data(storage, "pos_data")
3 |
4 | local function set_data(pos, code, owner)
5 | local data = {
6 | code = code,
7 | owner = owner
8 | }
9 | moremesecons.set_data_to_pos(pos_data, pos, data)
10 | end
11 |
12 | local function check_data(pos, code, owner)
13 | local stored_data = moremesecons.get_data_from_pos(pos_data, pos)
14 | if not stored_data then
15 | return false
16 | end
17 | if code ~= stored_data.code
18 | or owner ~= stored_data.owner then
19 | return false
20 | end
21 | return true
22 | end
23 |
24 |
25 | local function make_formspec(meta, pos)
26 | local code = minetest.formspec_escape(meta:get_string("code"))
27 | local errmsg = minetest.formspec_escape(meta:get_string("errmsg"))
28 | meta:set_string("formspec",
29 | "size[10,8;]" ..
30 | "textarea[0.5,0.5;9.5,7;code;Code;"..code.."]" ..
31 | "label[0.1,7;"..errmsg.."]" ..
32 | "button_exit[4,7.5;2,1;submit;Submit]")
33 | end
34 |
35 | minetest.register_node("moremesecons_luablock:luablock", {
36 | description = "Lua Block",
37 | tiles = {"moremesecons_luablock.png"},
38 | groups = {cracky = 2},
39 | on_place = function(itemstack, placer, pointed_thing)
40 | local under = pointed_thing.under
41 | local node = minetest.get_node(under)
42 | local udef = minetest.registered_nodes[node.name]
43 | if udef and udef.on_rightclick and
44 | not (placer and placer:get_player_control().sneak) then
45 | return udef.on_rightclick(under, node, placer, itemstack,
46 | pointed_thing) or itemstack
47 | end
48 |
49 | local pos
50 | if minetest.registered_items[minetest.get_node(under).name].buildable_to then
51 | pos = under
52 | else
53 | pos = pointed_thing.above
54 | end
55 |
56 | local name = placer:get_player_name()
57 | if minetest.is_protected(pos, name) and
58 | not minetest.check_player_privs(name, {protection_bypass = true}) then
59 | minetest.record_protection_violation(pos, name)
60 | return itemstack
61 | end
62 | if not minetest.check_player_privs(name, {server = true}) then
63 | minetest.chat_send_player(name, "You can't use a LuaBlock without the server privilege.")
64 | return itemstack
65 | end
66 |
67 | local node_def = minetest.registered_nodes[minetest.get_node(pos).name]
68 | if not node_def or not node_def.buildable_to then
69 | return itemstack
70 | end
71 |
72 | minetest.set_node(pos, {name = "moremesecons_luablock:luablock"})
73 |
74 | local meta = minetest.get_meta(pos)
75 | meta:set_string("owner", name)
76 | meta:set_string("infotext", "LuaBlock owned by " .. name)
77 | make_formspec(meta, pos)
78 |
79 | if not (creative and creative.is_enabled_for
80 | and creative.is_enabled_for(placer:get_player_name())) then
81 | itemstack:take_item()
82 | end
83 | return itemstack
84 | end,
85 | on_receive_fields = function(pos, form_name, fields, sender)
86 | if not fields.submit then
87 | return
88 | end
89 | local name = sender:get_player_name()
90 | local meta = minetest.get_meta(pos)
91 | if name ~= meta:get_string("owner") then
92 | minetest.chat_send_player(name, "You don't own this LuaBlock.")
93 | return
94 | end
95 | if not minetest.check_player_privs(name, {server = true}) then
96 | minetest.chat_send_player(name, "You can't use a LuaBlock without the server privilege.")
97 | return
98 | end
99 |
100 | meta:set_string("code", fields.code)
101 | set_data(pos, fields.code, name)
102 | make_formspec(meta, pos)
103 | end,
104 | can_dig = function(pos, player)
105 | local meta = minetest.get_meta(pos)
106 | return meta:get_string("owner") == player:get_player_name()
107 | end,
108 | on_destruct = function(pos)
109 | moremesecons.remove_data_from_pos(pos_data, pos)
110 | end,
111 | mesecons = {effector = {
112 | action_on = function(npos, node)
113 | local meta = minetest.get_meta(npos)
114 | local code = meta:get_string("code")
115 | local owner = meta:get_string("owner")
116 | if code == "" then
117 | return
118 | end
119 | if not check_data(npos, code, owner) then
120 | minetest.log("warning", "[moremesecons_luablock] Metadata of LuaBlock at pos "..minetest.pos_to_string(npos).." does not match its mod storage data!")
121 | return
122 | end
123 |
124 | local env = {}
125 | for k, v in pairs(_G) do
126 | env[k] = v
127 | end
128 | env.pos = table.copy(npos)
129 | env.mem = minetest.deserialize(meta:get_string("mem")) or {}
130 |
131 | local func, err_syntax
132 | if _VERSION == "Lua 5.1" then
133 | func, err_syntax = loadstring(code)
134 | if func then
135 | setfenv(func, env)
136 | end
137 | else
138 | func, err_syntax = load(code, nil, "t", env)
139 | end
140 | if not func then
141 | meta:set_string("errmsg", err_syntax)
142 | make_formspec(meta, npos)
143 | return
144 | end
145 |
146 | local good, err_runtime = pcall(func)
147 |
148 | if not good then
149 | meta:set_string("errmsg", err_runtime)
150 | make_formspec(meta, npos)
151 | return
152 | end
153 |
154 | meta:set_string("mem", minetest.serialize(env.mem))
155 |
156 | meta:set_string("errmsg", "")
157 | make_formspec(meta, npos)
158 | end
159 | }}
160 | })
161 |
--------------------------------------------------------------------------------
/moremesecons_luablock/mod.conf:
--------------------------------------------------------------------------------
1 | name = moremesecons_luablock
2 | depends = mesecons,moremesecons_utils
3 |
--------------------------------------------------------------------------------
/moremesecons_luablock/textures/moremesecons_luablock.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/minetest-mods/MoreMesecons/3e93b939f3bae14fb7a8c3f94e8db5d8fc0b2c24/moremesecons_luablock/textures/moremesecons_luablock.png
--------------------------------------------------------------------------------
/moremesecons_luacontroller_tool/init.lua:
--------------------------------------------------------------------------------
1 | local templates = {MoreMesecons = {
2 | logic = [[-- AND
3 | port.a = pin.b and pin.c
4 | -- OR
5 | port.a = pin.b or pin.c
6 | -- NOT
7 | port.a = not pin.b
8 | -- NAND
9 | port.a = not (pin.b and pin.c)
10 | -- NOR
11 | port.a = not (pin.b or pin.c)
12 | -- XOR
13 | port.a = pin.b ~= pin.c
14 | -- XNOR / NXOR
15 | port.a = pin.b == pin.c]],
16 |
17 | digilinesth = [[digiline_send(channel, msg)
18 | if event.type == "digiline" then
19 | print(event.channel)
20 | print(event.msg)
21 | end]],
22 |
23 | clock = [[number_of_oscillations = 0 -- 0 for infinity
24 | interval = 1
25 | input_port = "A"
26 | output_port = "C"
27 |
28 | if event.type == "on" and event.pin.name == input_port and not mem.running then
29 | if not mem.counter then
30 | mem.counter = 0
31 | end
32 | mem.running = true
33 | port[string.lower(output_port)] = true
34 | interrupt(interval)
35 | mem.counter = mem.counter + 1
36 | elseif event.type == "off" and event.pin.name == input_port and mem.running and number_of_oscillations == 0 then
37 | mem.running = false
38 | mem.counter = 0
39 | elseif event.type == "interrupt" then
40 | if not port[string.lower(output_port)] and mem.running then
41 | port[string.lower(output_port)] = true
42 | interrupt(interval)
43 | mem.counter = mem.counter + 1
44 | else
45 | port[string.lower(output_port)] = false
46 | if mem.counter < number_of_oscillations or number_of_oscillations == 0 and mem.running then
47 | interrupt(interval)
48 | else
49 | mem.running = false
50 | mem.counter = 0
51 | end
52 | end
53 | end]],
54 |
55 | counter = [[counter_limit = 5
56 | output_time = 0.5
57 | input_port = "A"
58 | output_port = "C"
59 |
60 | if event.type == "on" and event.pin.name == input_port then
61 | if not mem.counter then
62 | mem.counter = 0
63 | end
64 | mem.counter = mem.counter + 1
65 | if mem.counter >= counter_limit then
66 | port[string.lower(output_port)] = true
67 | interrupt(output_time)
68 | mem.counter = 0
69 | end
70 | elseif event.type == "interrupt" then
71 | port[string.lower(output_port)] = false
72 | end]]
73 | }}
74 |
75 |
76 | local file_path = minetest.get_worldpath().."/MoreMesecons_lctt"
77 |
78 | -- load templates from a compressed file
79 | do
80 | local templates_file = io.open(file_path, "rb")
81 | if templates_file then
82 | local templates_raw = templates_file:read("*all")
83 | io.close(templates_file)
84 | if templates_raw
85 | and templates_raw ~= "" then
86 | local data = minetest.deserialize(minetest.decompress(templates_raw))
87 | for name,t in pairs(data) do
88 | templates[name] = t
89 | end
90 | end
91 | end
92 | end
93 |
94 | -- the save function
95 | local function save_to_file()
96 | local templates_file = io.open(file_path, "w")
97 | if not templates_file then
98 | minetest.log("error", "[MoreMesecons] Could not open file for saving!")
99 | return
100 | end
101 | local player_templates = table.copy(templates)
102 | player_templates.MoreMesecons = nil
103 | templates_file:write(minetest.compress(minetest.serialize(player_templates)))
104 | io.close(templates_file)
105 | end
106 |
107 | -- save doesn't save more than every 10s to disallow spamming
108 | local saving
109 | local function save()
110 | if saving then
111 | return
112 | end
113 | saving = true
114 | minetest.after(16, function()
115 | save_to_file()
116 | saving = false
117 | end)
118 | end
119 |
120 | minetest.register_on_shutdown(function()
121 | if saving then
122 | save_to_file()
123 | end
124 | end)
125 |
126 |
127 | -- used for the dropdown formspec element
128 | local function fill_formspec_dropdown_list(t, selected)
129 | local it,num = {},1
130 | for i in pairs(t) do
131 | it[num] = i
132 | num = num+1
133 | end
134 | num = num-1
135 | table.sort(it)
136 | local txt = ""
137 | local selected_id
138 | for i = 1,num do
139 | local t = it[i]
140 | if not selected_id
141 | and t == selected then
142 | selected_id = i
143 | end
144 | txt = txt..t -- add available indices
145 | if i ~= num then
146 | txt = txt..","
147 | end
148 | end
149 | return txt..";"..(selected_id or 1).."]"
150 | --spec = string.sub(spec, 1, -2)
151 | end
152 |
153 | local pdata = {}
154 |
155 | local function get_selection_formspec(pname, selected_template)
156 | -- templates might be removed by someone while changing sth in formspec
157 | local pl_templates = templates[pname]
158 | if not pl_templates then
159 | pname = next(templates)
160 | pl_templates = templates[pname]
161 | end
162 |
163 | local template_code = pl_templates[selected_template]
164 | if not template_code then
165 | selected_template = next(pl_templates)
166 | template_code = pl_templates[selected_template]
167 | end
168 |
169 | local spec = "size[10,10]"..
170 |
171 | -- show available players, field player_name, current player name is the selected one
172 | "dropdown[0,0;5;player_name;"..
173 | fill_formspec_dropdown_list(templates, pname)..
174 |
175 | -- show templates of pname
176 | "dropdown[5,0;5;template_name;"..
177 | fill_formspec_dropdown_list(pl_templates, selected_template)..
178 |
179 | -- show selected template
180 | "textarea[0,1;10.5,8.5;template_code;template code:;"..minetest.formspec_escape(template_code).."]"..
181 |
182 | -- save name
183 | "field[5,9.5;5,0;save_name;savename;"..selected_template.."]"..
184 |
185 | "button[0,10;2,0;button;set]"..
186 |
187 | "button[2,10;2,0;button;add]"..
188 |
189 | "button[5,10;2,0;button;save]"
190 |
191 | return spec
192 | end
193 |
194 | -- tests if the node is a luacontroller
195 | local function is_luacontroller(pos)
196 | if not pos then
197 | return false
198 | end
199 | return string.match(minetest.get_node(pos).name, "mesecons_luacontroller:luacontroller%d%d%d%d")
200 | end
201 |
202 | -- do not localize the function directly here to support possible overwritten luacontrollers
203 | local luac_def = minetest.registered_nodes["mesecons_luacontroller:luacontroller0000"]
204 | local function set_luacontroller_code(pos, code, sender)
205 | luac_def.on_receive_fields(pos, nil, {code=code, program=""}, sender)
206 | end
207 |
208 | minetest.register_tool("moremesecons_luacontroller_tool:lctt", {
209 | description = "luacontroller template tool",
210 | inventory_image = "moremesecons_luacontroller_tool.png",
211 |
212 | on_use = function(_, player, pt)
213 | if not player
214 | or not pt then
215 | return
216 | end
217 |
218 | local pname = player:get_player_name()
219 | local pos = pt.under
220 | if not is_luacontroller(pos) then
221 | minetest.chat_send_player(pname, "You can use the luacontroller template tool only on luacontroller nodes.")
222 | return
223 | end
224 |
225 | pdata[pname] = {
226 | pos = pos,
227 | player_name = pname,
228 | template_name = pdata[pname] and pdata[pname].template_name or next(templates[pname] or templates[next(templates)]),
229 | }
230 | minetest.show_formspec(pname, "moremesecons:luacontroller_tool", get_selection_formspec(pdata[pname].player_name, pdata[pname].template_name))
231 | end,
232 | })
233 |
234 | --[[ Luacontroller reset_meta function, by Jeija
235 | local function reset_meta(pos, code, errmsg)
236 | local meta = minetest.get_meta(pos)
237 | meta:set_string("code", code)
238 | code = minetest.formspec_escape(code or "")
239 | errmsg = minetest.formspec_escape(errmsg or "")
240 | meta:set_string("formspec", "size[10,8]"..
241 | "background[-0.2,-0.25;10.4,8.75;jeija_luac_background.png]"..
242 | "textarea[0.2,0.6;10.2,5;code;;"..code.."]"..
243 | "image_button[3.75,6;2.5,1;jeija_luac_runbutton.png;program;]"..
244 | "image_button_exit[9.72,-0.25;0.425,0.4;jeija_close_window.png;exit;]"..
245 | "label[0.1,5;"..errmsg.."]")
246 | meta:set_int("heat", 0)
247 | meta:set_int("luac_id", math.random(1, 65535))
248 | end--]]
249 |
250 | -- used to avoid possibly crashes
251 | local function get_code_or_nil(pname, player_name, template_name)
252 | local player_templates = templates[player_name]
253 | if not player_templates then
254 | minetest.chat_send_player(pname, "error: "..player_name.." doesn't have templates now")
255 | return
256 | end
257 | local code = player_templates[template_name]
258 | if not code then
259 | minetest.chat_send_player(pname, "error: "..template_name.." doesn't exist now")
260 | return
261 | end
262 | return code
263 | end
264 |
265 | minetest.register_on_player_receive_fields(function(player, formname, fields)
266 | if formname ~= "moremesecons:luacontroller_tool"
267 | or fields.quit
268 | or not player then
269 | return
270 | end
271 |
272 | --minetest.chat_send_all(dump(fields))
273 |
274 | local pname = player:get_player_name()
275 |
276 | if fields.player_name
277 | and fields.player_name ~= pdata[pname].player_name then
278 | -- show available templates of that player
279 | minetest.show_formspec(pname, "moremesecons:luacontroller_tool",
280 | get_selection_formspec(fields.player_name, pdata[pname].template_name)
281 | )
282 | pdata[pname].player_name = fields.player_name
283 | return
284 | end
285 |
286 | if fields.template_name
287 | and fields.template_name ~= pdata[pname].template_name then
288 | -- show selected template of that player
289 | minetest.show_formspec(pname, "moremesecons:luacontroller_tool",
290 | get_selection_formspec(pdata[pname].player_name, fields.template_name)
291 | )
292 | pdata[pname].template_name = fields.template_name
293 | return
294 | end
295 |
296 | local pos = pdata[pname].pos
297 | if not is_luacontroller(pos) then
298 | -- this can happen
299 | return
300 | end
301 |
302 | local meta = minetest.get_meta(pos)
303 |
304 | if fields.button == "set" then
305 | -- replace the code of the luacontroller with the template
306 | local code = get_code_or_nil(pname, fields.player_name, fields.template_name)
307 | if code then
308 | set_luacontroller_code(pos, code, player)
309 | minetest.chat_send_player(pname, "code set to template at "..minetest.pos_to_string(pos))
310 | end
311 | return
312 | end
313 |
314 | if fields.button == "add" then
315 | -- add the template to the end of the code of the luacontroller
316 | local code = get_code_or_nil(pname, fields.player_name, fields.template_name)
317 | if code then
318 | set_luacontroller_code(pos, meta:get_string("code").."\r"..code, player)
319 | minetest.chat_send_player(pname, "code added to luacontroller at "..minetest.pos_to_string(pos))
320 | end
321 | return
322 | end
323 |
324 | if fields.button == "save" then
325 | -- save the template, when you try to change others' templates, yours become changed
326 | local savename = fields.template_name
327 | if fields.save_name
328 | and fields.save_name ~= ""
329 | and fields.save_name ~= savename then
330 | savename = minetest.formspec_escape(fields.save_name)
331 | end
332 | local code = fields.template_code
333 | if not code then
334 | minetest.chat_send_player(pname, "error: template code missing")
335 | return
336 | end
337 | templates[pname] = templates[pname] or {}
338 | if code == "" then
339 | templates[pname][savename] = nil
340 | if not next(templates[pname]) then
341 | templates[pname] = nil
342 | end
343 | minetest.chat_send_player(pname, "template removed")
344 | save()
345 | return
346 | end
347 | code = minetest.formspec_escape(code)
348 | if templates[pname][savename] == code then
349 | minetest.chat_send_player(pname, "template not saved because it didn't change")
350 | return
351 | end
352 | templates[pname][savename] = code
353 | save()
354 | minetest.chat_send_player(pname, "template "..pname.."/"..savename.." saved")
355 | return
356 | end
357 | end)
358 |
--------------------------------------------------------------------------------
/moremesecons_luacontroller_tool/mod.conf:
--------------------------------------------------------------------------------
1 | name = moremesecons_luacontroller_tool
2 | depends = mesecons,mesecons_luacontroller,moremesecons_utils
3 |
--------------------------------------------------------------------------------
/moremesecons_luacontroller_tool/textures/moremesecons_luacontroller_tool.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/minetest-mods/MoreMesecons/3e93b939f3bae14fb7a8c3f94e8db5d8fc0b2c24/moremesecons_luacontroller_tool/textures/moremesecons_luacontroller_tool.png
--------------------------------------------------------------------------------
/moremesecons_mesechest/init.lua:
--------------------------------------------------------------------------------
1 | local function mesechest_get_output_rules(node)
2 | local rules = {{x=-1, y=0, z=0},
3 | {x=0, y=0, z=-1},
4 | {x=0, y=0, z=1}}
5 | for _ = 0, node.param2 do
6 | rules = mesecon.rotate_rules_left(rules)
7 | end
8 | return rules
9 | end
10 |
11 | -- default.chest.register_chest() doesn't allow to register most of the callbacks we need
12 | -- we have to override the chest node we registered again
13 | default.chest.register_chest("moremesecons_mesechest:mesechest", {
14 | description = "Mese Chest",
15 | tiles = {
16 | "default_chest_top.png^[colorize:#d8e002:70",
17 | "default_chest_top.png^[colorize:#d8e002:70",
18 | "default_chest_side.png^[colorize:#d8e002:70",
19 | "default_chest_side.png^[colorize:#d8e002:70",
20 | "default_chest_front.png^[colorize:#d8e002:70",
21 | "default_chest_inside.png^[colorize:#d8e002:70"
22 | },
23 | sounds = default.node_sound_wood_defaults(),
24 | sound_open = "default_chest_open",
25 | sound_close = "default_chest_close",
26 | groups = {choppy = 2, oddly_breakable_by_hand = 2},
27 | mesecons = {
28 | receptor = {
29 | rules = mesechest_get_output_rules
30 | }
31 | }
32 | })
33 |
34 | default.chest.register_chest("moremesecons_mesechest:mesechest_locked", {
35 | description = "Locked Mese Chest",
36 | tiles = {
37 | "default_chest_top.png^[colorize:#d8e002:70",
38 | "default_chest_top.png^[colorize:#d8e002:70",
39 | "default_chest_side.png^[colorize:#d8e002:70",
40 | "default_chest_side.png^[colorize:#d8e002:70",
41 | "default_chest_lock.png^[colorize:#d8e002:70",
42 | "default_chest_inside.png^[colorize:#d8e002:70"
43 | },
44 | sounds = default.node_sound_wood_defaults(),
45 | sound_open = "default_chest_open",
46 | sound_close = "default_chest_close",
47 | groups = {choppy = 2, oddly_breakable_by_hand = 2},
48 | protected = true,
49 | mesecons = {
50 | receptor = {
51 | rules = mesechest_get_output_rules
52 | }
53 | }
54 | })
55 |
56 | local moremesecons_chests = {}
57 |
58 | for _, chest in ipairs({"moremesecons_mesechest:mesechest", "moremesecons_mesechest:mesechest_locked",
59 | "moremesecons_mesechest:mesechest_open", "moremesecons_mesechest:mesechest_locked_open"}) do
60 | local old_def = minetest.registered_nodes[chest]
61 |
62 | local old_on_metadata_inventory_put = old_def.on_metadata_inventory_put
63 | local old_on_metadata_inventory_take = old_def.on_metadata_inventory_take
64 | local old_on_rightclick = old_def.on_rightclick
65 |
66 | local override = {}
67 | override.on_metadata_inventory_put = function(pos, ...)
68 | old_on_metadata_inventory_put(pos, ...)
69 | mesecon.receptor_on(pos, {mesechest_get_output_rules(minetest.get_node(pos))[2]})
70 | minetest.after(1, function(pos)
71 | mesecon.receptor_off(pos, {mesechest_get_output_rules(minetest.get_node(pos))[2]})
72 | end, pos)
73 | end
74 | override.on_metadata_inventory_take = function(pos, ...)
75 | old_on_metadata_inventory_take(pos, ...)
76 | mesecon.receptor_on(pos, {mesechest_get_output_rules(minetest.get_node(pos))[3]})
77 | minetest.after(1, function(pos)
78 | mesecon.receptor_off(pos, {mesechest_get_output_rules(minetest.get_node(pos))[3]})
79 | end, pos)
80 | end
81 | override.on_rightclick = function(pos, node, clicker, ...)
82 | if old_on_rightclick(pos, node, clicker, ...) == nil then
83 | mesecon.receptor_on(pos, {mesechest_get_output_rules(node)[1]})
84 | end
85 | end
86 |
87 | minetest.override_item(chest, override)
88 | moremesecons_chests[chest] = true
89 | end
90 |
91 | -- if the chest is getting closed, turn the signal off
92 | -- luacheck: ignore 122
93 | local old_lid_close = default.chest.chest_lid_close
94 | function default.chest.chest_lid_close(pn)
95 | local pos = default.chest.open_chests[pn].pos
96 | -- old_lid_close will return true if the chest won't be closed
97 | if old_lid_close(pn) then
98 | return true
99 | end
100 | local node = minetest.get_node(pos)
101 | if moremesecons_chests[node.name] then
102 | mesecon.receptor_off(pos, {mesechest_get_output_rules(node)[1]})
103 | end
104 | end
105 |
106 | minetest.register_craft({
107 | output = "moremesecons_mesechest:mesechest",
108 | recipe = {{"group:mesecon_conductor_craftable", "default:chest", "group:mesecon_conductor_craftable"}}
109 | })
110 |
111 | minetest.register_craft({
112 | output = "moremesecons_mesechest:mesechest_locked",
113 | recipe = {{"group:mesecon_conductor_craftable", "default:chest_locked", "group:mesecon_conductor_craftable"}}
114 | })
115 |
116 | -- Legacy
117 | minetest.register_alias("default:mesechest", "moremesecons_mesechest:mesechest")
118 | minetest.register_alias("mesechest", "moremesecons_mesechest:mesechest")
119 | minetest.register_alias("default:mesechest_locked", "moremesecons_mesechest:mesechest")
120 | minetest.register_alias("mesechest_locked", "moremesecons_mesechest:mesechest_locked")
121 |
--------------------------------------------------------------------------------
/moremesecons_mesechest/mod.conf:
--------------------------------------------------------------------------------
1 | name = moremesecons_mesechest
2 | depends = default,mesecons
3 |
--------------------------------------------------------------------------------
/moremesecons_playerkiller/init.lua:
--------------------------------------------------------------------------------
1 | local kill_nearest_player = function(pos)
2 | local MAX_DISTANCE = moremesecons.setting("playerkiller", "max_distance", 8, 1)
3 |
4 | -- Search the nearest player
5 | local nearest
6 | local min_distance = MAX_DISTANCE
7 | for _, player in pairs(minetest.get_connected_players()) do
8 | local distance = vector.distance(pos, player:getpos())
9 | if distance < min_distance then
10 | min_distance = distance
11 | nearest = player
12 | end
13 | end
14 |
15 | if not nearest then
16 | -- no nearby player
17 | return
18 | end
19 |
20 | local owner = minetest.get_meta(pos):get_string("owner")
21 | if not owner then
22 | -- maybe some mod placed it
23 | return
24 | end
25 |
26 | if owner == nearest:get_player_name() then
27 | -- don't kill the owner !
28 | return
29 | end
30 |
31 | -- And kill him
32 | nearest:set_hp(0)
33 | minetest.log("action", "Player "..owner.." kills player "..nearest:get_player_name().." using a MoreMesecons Player Killer.")
34 | end
35 |
36 | minetest.register_craft({
37 | output = "moremesecons_playerkiller:playerkiller",
38 | recipe = { {"","default:mese",""},
39 | {"default:apple","mesecons_detector:object_detector_off","default:apple"},
40 | {"","default:apple",""}}
41 | })
42 |
43 | minetest.register_node("moremesecons_playerkiller:playerkiller", {
44 | description = "Player Killer",
45 | tiles = {"moremesecons_playerkiller_top.png", "moremesecons_playerkiller_top.png", "moremesecons_playerkiller_side.png"},
46 | paramtype = "light",
47 | walkable = true,
48 | groups = {cracky=3},
49 | mesecons = {effector = {
50 | state = mesecon.state.off,
51 | action_on = kill_nearest_player
52 | }},
53 | after_place_node = function(pos, placer)
54 | if not placer then
55 | return
56 | end
57 | local meta = minetest.get_meta(pos)
58 | meta:set_string("owner", placer:get_player_name())
59 | meta:set_string("infotext", "PlayerKiller owned by " .. meta:get_string("owner"))
60 | end,
61 | sounds = default.node_sound_stone_defaults(),
62 | })
63 |
--------------------------------------------------------------------------------
/moremesecons_playerkiller/mod.conf:
--------------------------------------------------------------------------------
1 | name = moremesecons_playerkiller
2 | depends = mesecons,mesecons_materials,moremesecons_utils
3 | optional_depends = craft_guide
4 |
--------------------------------------------------------------------------------
/moremesecons_playerkiller/textures/moremesecons_playerkiller_side.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/minetest-mods/MoreMesecons/3e93b939f3bae14fb7a8c3f94e8db5d8fc0b2c24/moremesecons_playerkiller/textures/moremesecons_playerkiller_side.png
--------------------------------------------------------------------------------
/moremesecons_playerkiller/textures/moremesecons_playerkiller_top.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/minetest-mods/MoreMesecons/3e93b939f3bae14fb7a8c3f94e8db5d8fc0b2c24/moremesecons_playerkiller/textures/moremesecons_playerkiller_top.png
--------------------------------------------------------------------------------
/moremesecons_sayer/init.lua:
--------------------------------------------------------------------------------
1 | local use_speech_dispatcher = moremesecons.setting("sayer", "use_speech_dispatcher", true)
2 |
3 | local popen, execute = io.popen, os.execute
4 | if use_speech_dispatcher then
5 | if not minetest.is_singleplayer() then
6 | minetest.log("warning", "[moremesecons_sayer] use_speech_dispatcher = true, but the speech dispatcher can only be used in singleplayer")
7 | use_speech_dispatcher = false
8 | else
9 | local ie = {}
10 | if minetest.request_insecure_environment then
11 | ie = minetest.request_insecure_environment()
12 | end
13 | if not ie then
14 | minetest.log("warning", "[moremesecons_sayer] This mod needs access to insecure functions in order to use the speech dispatcher. Please add the moremesecons_sayer mod to your secure.trusted_mods settings or disable the speech dispatcher.")
15 | use_speech_dispatcher = false
16 | else
17 | popen = ie.io.popen
18 | execute = ie.os.execute
19 | end
20 | end
21 |
22 | if use_speech_dispatcher then
23 | if popen("if hash spd-say 2>/dev/null; then printf yes; fi"):read("*all") ~= "yes" then
24 | minetest.log("warning", "[moremesecons_sayer] use_speech_dispatcher = true, but it seems the speech dispatcher isn't installed on your system")
25 | use_speech_dispatcher = false
26 | end
27 | end
28 | end
29 |
30 | local sayer_activate
31 | if use_speech_dispatcher then
32 | minetest.log("info", "[moremesecons_sayer] using speech dispatcher")
33 | local tab = {
34 | "spd-say",
35 | nil,
36 | ""
37 | }
38 | local language = minetest.settings:get("language") or "en"
39 | if language ~= "en" then
40 | tab[3] = "-l "..language
41 | end
42 |
43 | function sayer_activate(pos)
44 | local MAX_DISTANCE = moremesecons.setting("sayer", "max_distance", 8, 1) ^ 2
45 |
46 | local text = minetest.get_meta(pos):get_string("text")
47 | if text == "" then
48 | -- nothing to say
49 | return
50 | end
51 | if string.find(text, '"') then
52 | text = "So, singleplayer, you want to use me to execute commands? Writing quotes is not allowed!"
53 | end
54 | tab[2] = '"'..text..'"'
55 | local ppos = minetest.get_player_by_name("singleplayer"):getpos()
56 | ppos.y = ppos.y+1.625 -- camera position (without bobbing)
57 | -- that here's just 1 volume means that it's mono
58 | local volume = math.floor(-100*(
59 | 1-MAX_DISTANCE/vector.distance(pos, ppos)^2
60 | +0.5))
61 | if volume <= -100 then
62 | -- nothing to hear
63 | return
64 | end
65 | if volume > 0 then
66 | --volume = "+"..math.min(100, volume)
67 | -- volume bigger 0 somehow isn't louder, it rather tries to scream
68 | volume = "+"..math.min(100, math.floor(volume/(MAX_DISTANCE-1)+0.5))
69 | end
70 | if volume == 0 then
71 | tab[4] = nil
72 | else
73 | tab[4] = "-i "..volume
74 | end
75 | execute(table.concat(tab, " "))
76 | end
77 | else
78 | function sayer_activate(pos)
79 | local MAX_DISTANCE = moremesecons.setting("sayer", "max_distance", 8, 1)
80 |
81 | local tab = {
82 | "Sayer at pos",
83 | nil,
84 | "says : "..minetest.get_meta(pos):get_string("text")
85 | }
86 | for _,player in pairs(minetest.get_connected_players()) do
87 | if vector.distance(pos, player:getpos()) <= MAX_DISTANCE then
88 | tab[2] = minetest.pos_to_string(pos)
89 | minetest.chat_send_player(player:get_player_name(), table.concat(tab, " "))
90 | end
91 | end
92 | end
93 | end
94 |
95 | minetest.register_node("moremesecons_sayer:sayer", {
96 | description = "sayer",
97 | tiles = {"mesecons_noteblock.png", "default_wood.png"},
98 | drawtype = "nodebox",
99 | paramtype = "light",
100 | node_box = {
101 | type = "fixed",
102 | fixed = {-0.5, -0.5, -0.5, 0.5, 0, 0.5},
103 | },
104 | groups = {dig_immediate = 2},
105 | on_construct = function(pos)
106 | minetest.get_meta(pos):set_string("formspec", "field[text;text;${text}]")
107 | end,
108 | on_receive_fields = function(pos, _, fields, player)
109 | if fields.text
110 | and not minetest.is_protected(pos, player:get_player_name()) then
111 | minetest.get_meta(pos):set_string("text", fields.text)
112 | end
113 | end,
114 | mesecons = {effector = {
115 | action_on = sayer_activate
116 | }}
117 | })
118 |
119 | minetest.register_craft({
120 | output = "moremesecons_sayer:sayer 2",
121 | recipe = {{"mesecons_luacontroller:luacontroller0000", "mesecons_noteblock:noteblock"},
122 | {"group:wood", "group:wood"}}
123 | })
124 |
--------------------------------------------------------------------------------
/moremesecons_sayer/mod.conf:
--------------------------------------------------------------------------------
1 | name = moremesecons_sayer
2 | depends = mesecons,mesecons_noteblock,moremesecons_utils,default
3 | optional_depends = craft_guide
4 |
--------------------------------------------------------------------------------
/moremesecons_signalchanger/init.lua:
--------------------------------------------------------------------------------
1 | local nodebox = {
2 | type = "fixed",
3 | fixed = {{-8/16, -8/16, -8/16, 8/16, -7/16, 8/16 }},
4 | }
5 |
6 | local function signalchanger_get_output_rules(node)
7 | local rules = {{x=-1, y=0, z=0},
8 | {x=1, y=0, z=0}}
9 | for _ = 0, node.param2 do
10 | rules = mesecon.rotate_rules_left(rules)
11 | end
12 | return rules
13 | end
14 |
15 | local function signalchanger_get_input_rules(node)
16 | local rules = {{x=0, y=0, z=-1, name="input_on"}, {x=0, y=0, z=1, name="input_off"}}
17 | for _ = 0, node.param2 do
18 | rules = mesecon.rotate_rules_left(rules)
19 | end
20 | return rules
21 | end
22 |
23 | local update = function(pos, node, link, newstate)
24 | local meta = minetest.get_meta(pos)
25 | meta:set_int(link.name, newstate == "on" and 1 or 0)
26 | local input_on = meta:get_int("input_on") == 1
27 | local input_off = meta:get_int("input_off") == 1
28 | if input_on then
29 | mesecon.receptor_on(pos, {signalchanger_get_output_rules(node)[1]})
30 | mesecon.receptor_off(pos, {signalchanger_get_output_rules(node)[2]})
31 | minetest.swap_node(pos, {name = "moremesecons_signalchanger:signalchanger_on", param2 = node.param2})
32 | elseif input_off then
33 | mesecon.receptor_off(pos, {signalchanger_get_output_rules(node)[1]})
34 | mesecon.receptor_on(pos, {signalchanger_get_output_rules(node)[2]})
35 | minetest.swap_node(pos, {name = "moremesecons_signalchanger:signalchanger_off", param2 = node.param2})
36 | end
37 | end
38 |
39 | mesecon.register_node("moremesecons_signalchanger:signalchanger", {
40 | description = "Signal Changer",
41 | inventory_image = "moremesecons_signalchanger_off.png",
42 | groups = {dig_immediate = 2},
43 | paramtype = "light",
44 | paramtype2 = "facedir",
45 | drawtype = "nodebox",
46 | selection_box = nodebox,
47 | node_box = nodebox,
48 | },{
49 | groups = {dig_immediate = 2},
50 | mesecons = {
51 | receptor = {
52 | rules = signalchanger_get_output_rules
53 | },
54 | effector = {
55 | rules = signalchanger_get_input_rules,
56 | action_change = update
57 | },
58 | },
59 | tiles = {"moremesecons_signalchanger_off.png"},
60 | on_construct = function(pos)
61 | local node = minetest.get_node(pos)
62 | mesecon.receptor_on(pos, {signalchanger_get_output_rules(node)[2]})
63 | end
64 | },{
65 | groups = {dig_immediate = 2, not_in_creative_inventory = 1},
66 | mesecons = {
67 | receptor = {
68 | rules = signalchanger_get_output_rules,
69 | },
70 | effector = {
71 | rules = signalchanger_get_input_rules,
72 | action_change = update,
73 | },
74 | },
75 | tiles = {"moremesecons_signalchanger_on.png"},
76 | })
77 |
78 | minetest.register_craft({
79 | output = "moremesecons_signalchanger:signalchanger_off",
80 | recipe = {{"group:mesecon_conductor_craftable","moremesecons_switchtorch:switchtorch_off","group:mesecon_conductor_craftable"}}
81 | })
82 |
--------------------------------------------------------------------------------
/moremesecons_signalchanger/mod.conf:
--------------------------------------------------------------------------------
1 | name = moremesecons_signalchanger
2 | depends = mesecons
3 | optional_depends = craft_guide
4 |
--------------------------------------------------------------------------------
/moremesecons_signalchanger/textures/moremesecons_signalchanger_off.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/minetest-mods/MoreMesecons/3e93b939f3bae14fb7a8c3f94e8db5d8fc0b2c24/moremesecons_signalchanger/textures/moremesecons_signalchanger_off.png
--------------------------------------------------------------------------------
/moremesecons_signalchanger/textures/moremesecons_signalchanger_on.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/minetest-mods/MoreMesecons/3e93b939f3bae14fb7a8c3f94e8db5d8fc0b2c24/moremesecons_signalchanger/textures/moremesecons_signalchanger_on.png
--------------------------------------------------------------------------------
/moremesecons_switchtorch/init.lua:
--------------------------------------------------------------------------------
1 | local rotate_torch_rules = function (rules, param2)
2 | if param2 == 5 then
3 | return mesecon.rotate_rules_right(rules)
4 | elseif param2 == 2 then
5 | return mesecon.rotate_rules_right(mesecon.rotate_rules_right(rules)) --180 degrees
6 | elseif param2 == 4 then
7 | return mesecon.rotate_rules_left(rules)
8 | elseif param2 == 1 then
9 | return mesecon.rotate_rules_down(rules)
10 | elseif param2 == 0 then
11 | return mesecon.rotate_rules_up(rules)
12 | else
13 | return rules
14 | end
15 | end
16 |
17 | local output_rules = {
18 | {x = 1, y = 0, z = 0},
19 | {x = 0, y = 0, z = 1},
20 | {x = 0, y = 0, z =-1},
21 | {x = 0, y = 1, z = 0},
22 | {x = 0, y =-1, z = 0}
23 | }
24 | local torch_get_output_rules = function(node)
25 | return rotate_torch_rules(output_rules, node.param2)
26 | end
27 |
28 | local input_rules = {
29 | {x = -2, y = 0, z = 0},
30 | {x = -1, y = 1, z = 0}
31 | }
32 | local torch_get_input_rules = function(node)
33 | return rotate_torch_rules(input_rules, node.param2)
34 | end
35 |
36 | minetest.register_craft({
37 | output = "moremesecons_switchtorch:switchtorch_off 4",
38 | recipe = {
39 | {"default:stick"},
40 | {"group:mesecon_conductor_craftable"},
41 | }
42 | })
43 |
44 | local torch_selectionbox =
45 | {
46 | type = "wallmounted",
47 | wall_top = {-0.1, 0.5-0.6, -0.1, 0.1, 0.5, 0.1},
48 | wall_bottom = {-0.1, -0.5, -0.1, 0.1, -0.5+0.6, 0.1},
49 | wall_side = {-0.5, -0.1, -0.1, -0.5+0.6, 0.1, 0.1},
50 | }
51 |
52 | minetest.register_node("moremesecons_switchtorch:switchtorch_off", {
53 | description = "Switch Torch",
54 | inventory_image = "moremesecons_switchtorch_on.png",
55 | wield_image = "moremesecons_switchtorch_on.png",
56 | drawtype = "torchlike",
57 | tiles = {"moremesecons_switchtorch_off.png", "moremesecons_switchtorch_off_ceiling.png", "moremesecons_switchtorch_off_side.png"},
58 | paramtype = "light",
59 | walkable = false,
60 | paramtype2 = "wallmounted",
61 | selection_box = torch_selectionbox,
62 | groups = {dig_immediate = 3},
63 | mesecons = {receptor = {
64 | state = mesecon.state.off,
65 | rules = torch_get_output_rules
66 | }},
67 |
68 | on_construct = function(pos)-- For EndPower
69 | minetest.get_meta(pos):set_int("EndPower", 1) -- 1 for true, 0 for false
70 | end
71 | })
72 |
73 | minetest.register_node("moremesecons_switchtorch:switchtorch_on", {
74 | drawtype = "torchlike",
75 | tiles = {"moremesecons_switchtorch_on.png", "moremesecons_switchtorch_on_ceiling.png", "moremesecons_switchtorch_on_side.png"},
76 | paramtype = "light",
77 | sunlight_propagates = true,
78 | walkable = false,
79 | paramtype2 = "wallmounted",
80 | selection_box = torch_selectionbox,
81 | groups = {dig_immediate=3, not_in_creative_inventory = 1},
82 | drop = "moremesecons_switchtorch:switchtorch_off",
83 | light_source = 9,
84 | mesecons = {receptor = {
85 | state = mesecon.state.on,
86 | rules = torch_get_output_rules
87 | }},
88 | })
89 |
90 | minetest.register_abm({
91 | nodenames = {"moremesecons_switchtorch:switchtorch_off","moremesecons_switchtorch:switchtorch_on"},
92 | interval = 1,
93 | chance = 1,
94 | action = function(pos, node)
95 | local is_powered = false
96 | for _, rule in ipairs(torch_get_input_rules(node)) do
97 | local src = vector.add(pos, rule)
98 | if mesecon.is_power_on(src) then
99 | is_powered = true
100 | break
101 | end
102 | end
103 |
104 | local meta = minetest.get_meta(pos)
105 | if meta:get_int("EndPower") == 0 == is_powered then
106 | return
107 | end
108 | if not is_powered then
109 | meta:set_int("EndPower", 1)
110 | return
111 | end
112 | if node.name == "moremesecons_switchtorch:switchtorch_on" then
113 | minetest.swap_node(pos, {name = "moremesecons_switchtorch:switchtorch_off", param2 = node.param2})
114 | mesecon.receptor_off(pos, torch_get_output_rules(node))
115 | elseif node.name == "moremesecons_switchtorch:switchtorch_off" then
116 | minetest.swap_node(pos, {name = "moremesecons_switchtorch:switchtorch_on", param2 = node.param2})
117 | mesecon.receptor_on(pos, torch_get_output_rules(node))
118 | end
119 | meta:set_int("EndPower", 0)
120 | end
121 | })
122 |
123 | -- Param2 Table (Block Attached To)
124 | -- 5 = z-1
125 | -- 3 = x-1
126 | -- 4 = z+1
127 | -- 2 = x+1
128 | -- 0 = y+1
129 | -- 1 = y-1
130 |
--------------------------------------------------------------------------------
/moremesecons_switchtorch/mod.conf:
--------------------------------------------------------------------------------
1 | name = moremesecons_switchtorch
2 | depends = mesecons
3 | optional_depends = craft_guide
4 |
--------------------------------------------------------------------------------
/moremesecons_switchtorch/textures/moremesecons_switchtorch_off.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/minetest-mods/MoreMesecons/3e93b939f3bae14fb7a8c3f94e8db5d8fc0b2c24/moremesecons_switchtorch/textures/moremesecons_switchtorch_off.png
--------------------------------------------------------------------------------
/moremesecons_switchtorch/textures/moremesecons_switchtorch_off_ceiling.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/minetest-mods/MoreMesecons/3e93b939f3bae14fb7a8c3f94e8db5d8fc0b2c24/moremesecons_switchtorch/textures/moremesecons_switchtorch_off_ceiling.png
--------------------------------------------------------------------------------
/moremesecons_switchtorch/textures/moremesecons_switchtorch_off_side.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/minetest-mods/MoreMesecons/3e93b939f3bae14fb7a8c3f94e8db5d8fc0b2c24/moremesecons_switchtorch/textures/moremesecons_switchtorch_off_side.png
--------------------------------------------------------------------------------
/moremesecons_switchtorch/textures/moremesecons_switchtorch_on.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/minetest-mods/MoreMesecons/3e93b939f3bae14fb7a8c3f94e8db5d8fc0b2c24/moremesecons_switchtorch/textures/moremesecons_switchtorch_on.png
--------------------------------------------------------------------------------
/moremesecons_switchtorch/textures/moremesecons_switchtorch_on_ceiling.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/minetest-mods/MoreMesecons/3e93b939f3bae14fb7a8c3f94e8db5d8fc0b2c24/moremesecons_switchtorch/textures/moremesecons_switchtorch_on_ceiling.png
--------------------------------------------------------------------------------
/moremesecons_switchtorch/textures/moremesecons_switchtorch_on_side.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/minetest-mods/MoreMesecons/3e93b939f3bae14fb7a8c3f94e8db5d8fc0b2c24/moremesecons_switchtorch/textures/moremesecons_switchtorch_on_side.png
--------------------------------------------------------------------------------
/moremesecons_teleporter/init.lua:
--------------------------------------------------------------------------------
1 | local storage = minetest.get_mod_storage()
2 |
3 | local teleporters = minetest.deserialize(storage:get_string("teleporters")) or {}
4 | local teleporters_rids = moremesecons.load_MapDataStorage_legacy(storage,
5 | "teleporters_rids_v2", "teleporters_rids")
6 |
7 | local function update_mod_storage()
8 | storage:set_string("teleporters", minetest.serialize(teleporters))
9 | storage:set_string("teleporters_rids_v2", teleporters_rids:serialize())
10 | end
11 |
12 |
13 | local function register(pos)
14 | if not teleporters_rids:getAt(pos) then
15 | table.insert(teleporters, pos)
16 | teleporters_rids:setAt(pos, #teleporters)
17 | update_mod_storage()
18 | end
19 | end
20 |
21 | local function teleport_nearest(pos)
22 | local MAX_TELEPORTATION_DISTANCE = moremesecons.setting("teleporter", "max_t2t_distance", 50, 1)
23 | local MAX_PLAYER_DISTANCE = moremesecons.setting("teleporter", "max_p2t_distance", 25, 1)
24 |
25 | -- Search for the nearest player
26 | local nearest = nil
27 | local min_distance_player = MAX_PLAYER_DISTANCE
28 | local players = minetest.get_connected_players()
29 | for _, player in pairs(players) do
30 | local distance = vector.distance(pos, player:getpos())
31 | if distance <= min_distance_player then
32 | min_distance_player = distance
33 | nearest = player
34 | end
35 | end
36 |
37 | if not nearest then
38 | -- If there is no nearest player (maybe too far away...)
39 | return
40 | end
41 |
42 | -- Search for the corresponding teleporter and teleport
43 | if not minetest.registered_nodes["moremesecons_teleporter:teleporter"] then return end
44 |
45 | local newpos = {}
46 | local min_distance = MAX_TELEPORTATION_DISTANCE
47 | for i = 1, #teleporters do
48 | if minetest.get_node(teleporters[i]).name == "moremesecons_teleporter:teleporter" then
49 | local tel_pos
50 | if teleporters[i].y == pos.y and teleporters[i].x == pos.x and teleporters[i].z ~= pos.z then
51 | tel_pos = {x=teleporters[i].x, y=teleporters[i].y+1, z=teleporters[i].z}
52 | elseif teleporters[i].z == pos.z and teleporters[i].x == pos.x and teleporters[i].y ~= pos.y then
53 | tel_pos = {x=teleporters[i].x, y=teleporters[i].y+1, z=teleporters[i].z}
54 | elseif teleporters[i].z == pos.z and teleporters[i].y == pos.y and teleporters[i].x ~= pos.x then
55 | tel_pos = {x=teleporters[i].x, y=teleporters[i].y+1, z=teleporters[i].z}
56 | end
57 |
58 | if tel_pos then
59 | local distance = vector.distance(tel_pos, pos)
60 | if distance <= min_distance then
61 | min_distance = distance
62 | newpos = tel_pos
63 | end
64 | end
65 | end
66 | end
67 | if not newpos.x then
68 | newpos = {x=pos.x, y=pos.y+1, z=pos.z} -- If newpos doesn't exist, teleport on the current teleporter
69 | end
70 |
71 | nearest:moveto(newpos)
72 | minetest.log("action", "Player "..nearest:get_player_name().." was teleported using a MoreMesecons Teleporter.")
73 | end
74 |
75 | minetest.register_craft({
76 | output = "moremesecons_teleporter:teleporter 2",
77 | recipe = {{"default:diamond","default:stick","default:mese"}}
78 | })
79 | minetest.register_node("moremesecons_teleporter:teleporter", {
80 | tiles = {"moremesecons_teleporter.png"},
81 | paramtype = "light",
82 | walkable = true,
83 | groups = {cracky=3},
84 | description="Teleporter",
85 | mesecons = {effector = {
86 | state = mesecon.state.off,
87 | action_on = teleport_nearest
88 | }},
89 | sounds = default.node_sound_stone_defaults(),
90 | on_construct = register,
91 | on_destruct = function(pos)
92 | local RID = teleporters_rids:getAt(pos)
93 | if RID then
94 | table.remove(teleporters, RID)
95 | teleporters_rids:removeAt(pos)
96 | update_mod_storage()
97 | end
98 | end,
99 | })
100 |
101 | if moremesecons.setting("teleporter", "enable_lbm", false) then
102 | minetest.register_lbm({
103 | name = "moremesecons_teleporter:add_teleporter",
104 | nodenames = {"moremesecons_teleporter:teleporter"},
105 | run_at_every_load = true,
106 | action = register
107 | })
108 | end
109 |
--------------------------------------------------------------------------------
/moremesecons_teleporter/mod.conf:
--------------------------------------------------------------------------------
1 | name = moremesecons_teleporter
2 | depends = mesecons,moremesecons_utils
3 | optional_depends = craft_guide
4 |
--------------------------------------------------------------------------------
/moremesecons_teleporter/textures/moremesecons_teleporter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/minetest-mods/MoreMesecons/3e93b939f3bae14fb7a8c3f94e8db5d8fc0b2c24/moremesecons_teleporter/textures/moremesecons_teleporter.png
--------------------------------------------------------------------------------
/moremesecons_timegate/init.lua:
--------------------------------------------------------------------------------
1 | local timegate_get_output_rules = function(node)
2 | local rules = {{x = 0, y = 0, z = 1}}
3 | for _ = 0, node.param2 do
4 | rules = mesecon.rotate_rules_left(rules)
5 | end
6 | return rules
7 | end
8 |
9 | local timegate_get_input_rules = function(node)
10 | local rules = {{x = 0, y = 0, z = -1}}
11 | for _ = 0, node.param2 do
12 | rules = mesecon.rotate_rules_left(rules)
13 | end
14 | return rules
15 | end
16 |
17 | -- Functions that are called after the delay time
18 |
19 | local function timegate_activate(pos, node)
20 | -- using a meta string allows writing the time in hexadecimals
21 | local time = tonumber(minetest.get_meta(pos):get_string("time"))
22 | if not time then
23 | return
24 | end
25 | node.name = "moremesecons_timegate:timegate_on"
26 | minetest.swap_node(pos, node)
27 | mesecon.receptor_on(pos)
28 | minetest.after(time, function()
29 | local node = minetest.get_node(pos)
30 | if node.name == "moremesecons_timegate:timegate_on" then
31 | mesecon.receptor_off(pos)
32 | node.name = "moremesecons_timegate:timegate_off"
33 | minetest.swap_node(pos, node)
34 | end
35 | end)
36 | end
37 |
38 | local boxes = {{ -6/16, -8/16, -6/16, 6/16, -7/16, 6/16 }, -- the main slab
39 |
40 | { -2/16, -7/16, -4/16, 2/16, -26/64, -3/16 }, -- the jeweled "on" indicator
41 | { -3/16, -7/16, -3/16, 3/16, -26/64, -2/16 },
42 | { -4/16, -7/16, -2/16, 4/16, -26/64, 2/16 },
43 | { -3/16, -7/16, 2/16, 3/16, -26/64, 3/16 },
44 | { -2/16, -7/16, 3/16, 2/16, -26/64, 4/16 },
45 |
46 | { -6/16, -7/16, -6/16, -4/16, -27/64, -4/16 }, -- the timer indicator
47 | { -8/16, -8/16, -1/16, -6/16, -7/16, 1/16 }, -- the two wire stubs
48 | { 6/16, -8/16, -1/16, 8/16, -7/16, 1/16 }}
49 |
50 | local use_texture_alpha
51 | if minetest.features.use_texture_alpha_string_modes then
52 | use_texture_alpha = "opaque"
53 | end
54 | mesecon.register_node("moremesecons_timegate:timegate", {
55 | description = "Time Gate",
56 | drawtype = "nodebox",
57 | inventory_image = "moremesecons_timegate_off.png",
58 | wield_image = "moremesecons_timegate_off.png",
59 | walkable = true,
60 | selection_box = {
61 | type = "fixed",
62 | fixed = { -8/16, -8/16, -8/16, 8/16, -6/16, 8/16 },
63 | },
64 | node_box = {
65 | type = "fixed",
66 | fixed = boxes
67 | },
68 | paramtype = "light",
69 | paramtype2 = "facedir",
70 | sunlight_propagates = true,
71 | is_ground_content = true,
72 | sounds = default.node_sound_stone_defaults(),
73 | on_construct = function(pos)
74 | minetest.get_meta(pos):set_string("formspec", "field[time;time;${time}]")
75 | end,
76 | on_receive_fields = function(pos, _, fields, player)
77 | if fields.time
78 | and not minetest.is_protected(pos, player:get_player_name()) then
79 | minetest.get_meta(pos):set_string("time", fields.time)
80 | end
81 | end
82 | },{
83 | tiles = {
84 | "moremesecons_timegate_off.png",
85 | "moremesecons_timegate_bottom.png",
86 | "moremesecons_timegate_ends_off.png",
87 | "moremesecons_timegate_ends_off.png",
88 | "moremesecons_timegate_sides_off.png",
89 | "moremesecons_timegate_sides_off.png"
90 | },
91 | use_texture_alpha = use_texture_alpha,
92 | groups = {bendy=2,snappy=1,dig_immediate=2},
93 | mesecons = {
94 | receptor =
95 | {
96 | state = mesecon.state.off,
97 | rules = timegate_get_output_rules
98 | },
99 | effector =
100 | {
101 | rules = timegate_get_input_rules,
102 | action_on = timegate_activate
103 | }
104 | },
105 | },{
106 | tiles = {
107 | "moremesecons_timegate_on.png",
108 | "moremesecons_timegate_bottom.png",
109 | "moremesecons_timegate_ends_on.png",
110 | "moremesecons_timegate_ends_on.png",
111 | "moremesecons_timegate_sides_on.png",
112 | "moremesecons_timegate_sides_on.png"
113 | },
114 | use_texture_alpha = use_texture_alpha,
115 | groups = {bendy=2,snappy=1,dig_immediate=2, not_in_creative_inventory=1},
116 | mesecons = {
117 | receptor = {
118 | state = mesecon.state.on,
119 | rules = timegate_get_output_rules
120 | },
121 | effector = {
122 | rules = timegate_get_input_rules,
123 | }
124 | },
125 | })
126 |
127 | minetest.register_craft({
128 | output = "moremesecons_timegate:timegate_off 2",
129 | recipe = {
130 | {"group:mesecon_conductor_craftable", "mesecons_delayer:delayer_off_1", "group:mesecon_conductor_craftable"},
131 | {"default:wood","default:wood", "default:wood"},
132 | }
133 | })
134 |
135 | minetest.register_alias("moremesecons_temporarygate:temporarygate_off", "moremesecons_timegate:timegate_off")
136 | minetest.register_alias("moremesecons_temporarygate:temporarygate_on", "moremesecons_timegate:timegate_on")
137 |
--------------------------------------------------------------------------------
/moremesecons_timegate/mod.conf:
--------------------------------------------------------------------------------
1 | name = moremesecons_timegate
2 | depends = mesecons
3 | optional_depends = craft_guide
4 |
--------------------------------------------------------------------------------
/moremesecons_timegate/textures/moremesecons_timegate_bottom.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/minetest-mods/MoreMesecons/3e93b939f3bae14fb7a8c3f94e8db5d8fc0b2c24/moremesecons_timegate/textures/moremesecons_timegate_bottom.png
--------------------------------------------------------------------------------
/moremesecons_timegate/textures/moremesecons_timegate_ends_off.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/minetest-mods/MoreMesecons/3e93b939f3bae14fb7a8c3f94e8db5d8fc0b2c24/moremesecons_timegate/textures/moremesecons_timegate_ends_off.png
--------------------------------------------------------------------------------
/moremesecons_timegate/textures/moremesecons_timegate_ends_on.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/minetest-mods/MoreMesecons/3e93b939f3bae14fb7a8c3f94e8db5d8fc0b2c24/moremesecons_timegate/textures/moremesecons_timegate_ends_on.png
--------------------------------------------------------------------------------
/moremesecons_timegate/textures/moremesecons_timegate_off.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/minetest-mods/MoreMesecons/3e93b939f3bae14fb7a8c3f94e8db5d8fc0b2c24/moremesecons_timegate/textures/moremesecons_timegate_off.png
--------------------------------------------------------------------------------
/moremesecons_timegate/textures/moremesecons_timegate_on.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/minetest-mods/MoreMesecons/3e93b939f3bae14fb7a8c3f94e8db5d8fc0b2c24/moremesecons_timegate/textures/moremesecons_timegate_on.png
--------------------------------------------------------------------------------
/moremesecons_timegate/textures/moremesecons_timegate_sides_off.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/minetest-mods/MoreMesecons/3e93b939f3bae14fb7a8c3f94e8db5d8fc0b2c24/moremesecons_timegate/textures/moremesecons_timegate_sides_off.png
--------------------------------------------------------------------------------
/moremesecons_timegate/textures/moremesecons_timegate_sides_on.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/minetest-mods/MoreMesecons/3e93b939f3bae14fb7a8c3f94e8db5d8fc0b2c24/moremesecons_timegate/textures/moremesecons_timegate_sides_on.png
--------------------------------------------------------------------------------
/moremesecons_utils/init.lua:
--------------------------------------------------------------------------------
1 | moremesecons = {}
2 |
3 | function moremesecons.setting(modname, settingname, default, min)
4 | local setting = "moremesecons_" .. modname .. "." .. settingname
5 |
6 | if type(default) == "boolean" then
7 | local ret = minetest.settings:get_bool(setting)
8 | if ret == nil then
9 | ret = default
10 | end
11 | return ret
12 | elseif type(default) == "string" then
13 | return minetest.settings:get(setting) or default
14 | elseif type(default) == "number" then
15 | local ret = tonumber(minetest.settings:get(setting)) or default
16 | if not ret then
17 | minetest.log("warning", "[moremesecons_"..modname.."]: setting '"..setting.."' must be a number. Set to default value ("..tostring(default)..").")
18 | ret = default
19 | elseif ret ~= ret then -- NaN
20 | minetest.log("warning", "[moremesecons_"..modname.."]: setting '"..setting.."' is NaN. Set to default value ("..tostring(default)..").")
21 | ret = default
22 | end
23 | if min and ret < min then
24 | minetest.log("warning", "[moremesecons_"..modname.."]: setting '"..setting.."' is under minimum value "..tostring(min)..". Set to minimum value ("..tostring(min)..").")
25 | ret = min
26 | end
27 | return ret
28 | end
29 | end
30 |
31 | -- Storage helpers
32 |
33 | function moremesecons.get_storage_data(storage, name)
34 | return {
35 | tab = minetest.deserialize(storage:get_string(name)) or {},
36 | name = name,
37 | storage = storage
38 | }
39 | end
40 |
41 | function moremesecons.set_data_to_pos(sto, pos, data)
42 | sto.tab[minetest.hash_node_position(pos)] = data
43 | sto.storage:set_string(sto.name, minetest.serialize(sto.tab))
44 | end
45 |
46 | function moremesecons.get_data_from_pos(sto, pos)
47 | return sto.tab[minetest.hash_node_position(pos)]
48 | end
49 |
50 | function moremesecons.remove_data_from_pos(sto, pos)
51 | sto.tab[minetest.hash_node_position(pos)] = nil
52 | sto.storage:set_string(sto.name, minetest.serialize(sto.tab))
53 | end
54 |
55 | -- Some additional vector helpers
56 |
57 | -- The same as minetest.hash_node_position; I copied it to ensure backwards
58 | -- compatibility and used hexadecimal number notation
59 | local function node_position_key(pos)
60 | return (pos.z + 0x8000) * 0x10000 * 0x10000
61 | + (pos.y + 0x8000) * 0x10000
62 | + pos.x + 0x8000
63 | end
64 |
65 | local MapDataStorage = {}
66 | setmetatable(MapDataStorage, {__call = function()
67 | local obj = {}
68 | setmetatable(obj, MapDataStorage)
69 | return obj
70 | end})
71 | MapDataStorage.__index = {
72 | getAt = function(self, pos)
73 | return self[node_position_key(pos)]
74 | end,
75 | setAt = function(self, pos, data)
76 | -- If x, y or z is omitted, the key corresponds to a position outside
77 | -- of the map (hopefully), so it can be used to skip lines and planes
78 | local vi_z = (pos.z + 0x8000) * 0x10000 * 0x10000
79 | local vi_zy = vi_z + (pos.y + 0x8000) * 0x10000
80 | local vi = vi_zy + pos.x + 0x8000
81 | local is_new = self[vi] == nil
82 | self[vi] = data
83 | if is_new then
84 | self[vi_z] = (self[vi_z] or 0) + 1
85 | self[vi_zy] = (self[vi_zy] or 0) + 1
86 | end
87 | end,
88 | setAtI = function(self, vi, data)
89 | local vi_zy = vi - vi % 0x10000
90 | local vi_z = vi - vi % (0x10000 * 0x10000)
91 | local is_new = self[vi] == nil
92 | self[vi] = data
93 | if is_new then
94 | self[vi_z] = (self[vi_z] or 0) + 1
95 | self[vi_zy] = (self[vi_zy] or 0) + 1
96 | end
97 | end,
98 | removeAt = function(self, pos)
99 | local vi_z = (pos.z + 0x8000) * 0x10000 * 0x10000
100 | local vi_zy = vi_z + (pos.y + 0x8000) * 0x10000
101 | local vi = vi_zy + pos.x + 0x8000
102 | if self[vi] == nil then
103 | -- Nothing to remove
104 | return
105 | end
106 | self[vi] = nil
107 | -- Update existence information for the xy plane and x line
108 | self[vi_z] = self[vi_z] - 1
109 | if self[vi_z] == 0 then
110 | self[vi_z] = nil
111 | self[vi_zy] = nil
112 | return
113 | end
114 | self[vi_zy] = self[vi_zy] - 1
115 | if self[vi_zy] == 0 then
116 | self[vi_zy] = nil
117 | end
118 | end,
119 | iter = function(self, pos1, pos2)
120 | local ystride = 0x10000
121 | local zstride = 0x10000 * 0x10000
122 |
123 | -- Skip z values where no data can be found
124 | pos1 = vector.new(pos1)
125 | local vi_z = (pos1.z + 0x8000) * 0x10000 * 0x10000
126 | while not self[vi_z] do
127 | pos1.z = pos1.z + 1
128 | vi_z = vi_z + zstride
129 | if pos1.z > pos2.z then
130 | -- There are no values to iterate through
131 | return function() return end
132 | end
133 | end
134 | -- Skipping y values is not yet implemented and may require much code
135 |
136 | local xrange = pos2.x - pos1.x + 1
137 | local yrange = pos2.y - pos1.y + 1
138 | local zrange = pos2.z - pos1.z + 1
139 |
140 | -- x-only and y-only parts of the vector index of pos1
141 | local vi_y = (pos1.y + 0x8000) * 0x10000
142 | local vi_x = pos1.x + 0x8000
143 |
144 | local y = 0
145 | local z = 0
146 |
147 | local vi = node_position_key(pos1)
148 | local pos = vector.new(pos1)
149 | local nextaction = vi + xrange
150 | pos.x = pos.x - 1
151 | vi = vi - 1
152 | local function iterfunc()
153 | -- continue along x until it needs to jump
154 | vi = vi + 1
155 | pos.x = pos.x + 1
156 | if vi ~= nextaction then
157 | local v = self[vi]
158 | if v == nil then
159 | -- No data here
160 | return iterfunc()
161 | end
162 | -- The returned position must not be changed
163 | return pos, v
164 | end
165 |
166 | -- Reset x position
167 | vi = vi - xrange
168 | -- Go along y until pos2.y is exceeded
169 | while true do
170 | y = y + 1
171 | pos.y = pos.y + 1
172 | -- Set vi to index(pos1.x, pos1.y + y, pos1.z + z)
173 | vi = vi + ystride
174 | if y == yrange then
175 | break
176 | end
177 | if self[vi - vi_x] then
178 | nextaction = vi + xrange
179 |
180 | vi = vi - 1
181 | pos.x = pos1.x - 1
182 | return iterfunc()
183 | end
184 | -- Nothing along this x line, so increase y again
185 | end
186 |
187 | -- Go back along y
188 | vi = vi - yrange * ystride
189 | y = 0
190 | pos.y = pos1.y
191 | -- Go along z until pos2.z is exceeded
192 | while true do
193 | z = z + 1
194 | pos.z = pos.z + 1
195 | vi = vi + zstride
196 | if z == zrange then
197 | -- Cuboid finished, return nil
198 | return
199 | end
200 | if self[vi - vi_x - vi_y] then
201 | y = 0
202 | nextaction = vi + xrange
203 |
204 | vi = vi - 1
205 | pos.x = pos1.x - 1
206 | return iterfunc()
207 | end
208 | -- Nothing in this xy plane, so increase z again
209 | end
210 | end
211 | return iterfunc
212 | end,
213 | iterAll = function(self)
214 | local previous_vi = nil
215 | local function iterfunc()
216 | local vi, v = next(self, previous_vi)
217 | previous_vi = vi
218 | if not vi then
219 | return
220 | end
221 | local z = math.floor(vi / (0x10000 * 0x10000))
222 | vi = vi - z * 0x10000 * 0x10000
223 | local y = math.floor(vi / 0x10000)
224 | if y == 0 or z == 0 then
225 | -- The index does not refer to a position inside the map
226 | return iterfunc()
227 | end
228 | local x = vi - y * 0x10000 - 0x8000
229 | y = y - 0x8000
230 | z = z - 0x8000
231 | return {x=x, y=y, z=z}, v
232 | end
233 | return iterfunc
234 | end,
235 | serialize = function(self)
236 | local indices = {}
237 | local values = {}
238 | local i = 1
239 | for pos, v in self:iterAll() do
240 | local vi = node_position_key(pos)
241 | -- Convert the double reversible to a string;
242 | -- minetest.serialize does not (yet) do this
243 | indices[i] = ("%.17g"):format(vi)
244 | values[i] = v
245 | end
246 | return minetest.serialize({
247 | version = "MapDataStorage_v1",
248 | indices = "return {" .. table.concat(indices, ",") .. "}",
249 | values = minetest.serialize(values),
250 | })
251 | end,
252 | }
253 | MapDataStorage.deserialize = function(txtdata)
254 | local data = minetest.deserialize(txtdata)
255 | if data.version ~= "MapDataStorage_v1" then
256 | minetest.log("error", "Unknown MapDataStorage version: " ..
257 | data.version)
258 | end
259 | -- I assume that minetest.deserialize correctly deserializes the indices,
260 | -- which are in the %a format
261 | local indices = minetest.deserialize(data.indices)
262 | local values = minetest.deserialize(data.values)
263 | if not indices or not values then
264 | return MapDataStorage()
265 | end
266 | data = MapDataStorage()
267 | for i = 1,#indices do
268 | local vi = indices[i]
269 | local v = values[i]
270 | data:setAtI(vi, v)
271 | end
272 | return data
273 | end
274 | moremesecons.MapDataStorage = MapDataStorage
275 |
276 |
277 | -- Legacy
278 |
279 | -- vector_extras there: https://github.com/HybridDog/vector_extras
280 | -- Creates a MapDataStorage object from old vector_extras generated table
281 | function moremesecons.load_old_data_from_pos(t)
282 | local data = MapDataStorage()
283 | for z, yxv in pairs(t) do
284 | for y, xv in pairs(yxv) do
285 | for x, v in pairs(xv) do
286 | data:setAt({x=x, y=y, z=z}, v)
287 | end
288 | end
289 | end
290 | return data
291 | end
292 |
293 | function moremesecons.load_old_dfp_storage(modstorage, name)
294 | local data = minetest.deserialize(modstorage:get_string(name))
295 | if not data then
296 | return
297 | end
298 | return moremesecons.load_old_data_from_pos(data)
299 | end
300 |
301 | function moremesecons.load_MapDataStorage_legacy(modstorage, name, oldname)
302 | local t_old = moremesecons.load_old_dfp_storage(modstorage, oldname)
303 | local t
304 | if t_old and t_old ~= "" then
305 | t = t_old
306 | modstorage:set_string(name, t:serialize())
307 | modstorage:set_string(oldname, nil)
308 | return t
309 | end
310 | t = modstorage:get_string(name)
311 | if t and t ~= "" then
312 | return MapDataStorage.deserialize(t)
313 | end
314 | return MapDataStorage()
315 | end
316 |
317 |
318 |
319 | --[[
320 | -- This testing code shows an example usage of the MapDataStorage code
321 | local function do_test()
322 | print("Test if iter returns correct positions when a lot is set")
323 | local data = MapDataStorage()
324 | local k = 0
325 | for x = -5, 3 do
326 | for y = -5, 3 do
327 | for z = -5, 3 do
328 | k = k + 1
329 | data:setAt({x=x, y=y, z=z}, k)
330 | end
331 | end
332 | end
333 | local expected_positions = {}
334 | for z = -4, 2 do
335 | for y = -4, 2 do
336 | for x = -4, 2 do
337 | expected_positions[#expected_positions+1] = {x=x, y=y, z=z}
338 | end
339 | end
340 | end
341 | local i = 0
342 | for pos in data:iter({x=-4, y=-4, z=-4}, {x=2, y=2, z=2}) do
343 | i = i + 1
344 | assert(vector.equals(pos, expected_positions[i]))
345 | end
346 |
347 | print("Test if iter works correctly on a corner")
348 | local found = false
349 | for pos in data:iter({x=-8, y=-7, z=-80}, {x=-5, y=-5, z=-5}) do
350 | assert(not found)
351 | found = true
352 | assert(vector.equals(pos, {x=-5, y=-5, z=-5}))
353 | end
354 | assert(found)
355 |
356 | print("Test if iter finds all corners")
357 | local expected_positions = {}
358 | local k = 1
359 | for _, z in ipairs({-9, -6}) do
360 | for _, y in ipairs({-9, -6}) do
361 | for _, x in ipairs({-8, -6}) do
362 | local pos = {x=x, y=y, z=z}
363 | expected_positions[#expected_positions+1] = pos
364 | data:setAt(pos, k)
365 | k = k + 1
366 | end
367 | end
368 | end
369 | local i = 1
370 | for pos, v in data:iter({x=-8, y=-9, z=-9}, {x=-6, y=-6, z=-6}) do
371 | assert(v == i)
372 | assert(vector.equals(pos, expected_positions[i]))
373 | i = i + 1
374 | --~ print("found " .. minetest.pos_to_string(pos))
375 | end
376 | assert(i == 8 + 1, "Not enough or too many corners found")
377 |
378 | --~ data:iterAll()
379 | end
380 | do_test()
381 | --]]
382 |
--------------------------------------------------------------------------------
/moremesecons_utils/mod.conf:
--------------------------------------------------------------------------------
1 | name = moremesecons_utils
2 | description = Various helping functions for moremesecons
3 |
--------------------------------------------------------------------------------
/moremesecons_wireless/init.lua:
--------------------------------------------------------------------------------
1 | local storage = minetest.get_mod_storage()
2 |
3 | -- Names wireless_meta, and jammers were used in old versions of this mod.
4 | -- There is legacy code at the end of this file to migrate the mod storage.
5 | local wireless = minetest.deserialize(storage:get_string("networks")) or {}
6 | local wireless_meta = moremesecons.get_storage_data(storage, "wireless_meta_2")
7 | local jammers = moremesecons.get_storage_data(storage, "jammers_2")
8 |
9 | local function update_mod_storage()
10 | storage:set_string("networks", minetest.serialize(wireless))
11 | end
12 |
13 | local wireless_effector_off
14 | local function remove_wireless(pos)
15 | local wls = moremesecons.get_data_from_pos(wireless_meta, pos)
16 | if not wls then
17 | return
18 | end
19 |
20 | if not wls.owner or wls.owner == "" then
21 | moremesecons.remove_data_from_pos(wireless_meta, pos)
22 | return
23 | end
24 |
25 | if not wireless[wls.owner] or not next(wireless[wls.owner]) then
26 | wireless[wls.owner] = nil
27 | moremesecons.remove_data_from_pos(wireless_meta, pos)
28 | return
29 | end
30 |
31 | if not wls.channel or wls.channel == "" then
32 | moremesecons.remove_data_from_pos(wireless_meta, pos)
33 | return
34 | end
35 |
36 | local network = wireless[wls.owner][wls.channel]
37 |
38 | if network.sources[wls.id] then
39 | wireless_effector_off(pos)
40 | end
41 |
42 | moremesecons.remove_data_from_pos(wireless_meta, pos)
43 |
44 | network.members[wls.id] = nil
45 | if not next(network.members) then
46 | wireless[wls.owner][wls.channel] = nil
47 | if not next(wireless[wls.owner]) then
48 | wireless[wls.owner] = nil
49 | end
50 | end
51 | update_mod_storage()
52 | end
53 |
54 | local function set_owner(pos, owner)
55 | if not owner or owner == "" then
56 | return
57 | end
58 |
59 | remove_wireless(pos)
60 |
61 | local meta = minetest.get_meta(pos)
62 | if meta then
63 | meta:set_string("owner", owner)
64 | end
65 |
66 | local wls = moremesecons.get_data_from_pos(wireless_meta, pos) or {}
67 | wls.owner = owner
68 | moremesecons.set_data_to_pos(wireless_meta, pos, wls)
69 |
70 | if not wireless[owner] then
71 | wireless[owner] = {}
72 | end
73 |
74 | if meta then
75 | meta:set_string("infotext", "Wireless owned by " .. owner .. " on " .. ((wls.channel and wls.channel ~= "") and "channel " .. wls.channel or "undefined channel"))
76 | end
77 | end
78 |
79 | local wireless_receptor_on
80 | local wireless_receptor_off
81 | local wireless_effector_on
82 | local function set_channel(pos, channel)
83 | if not channel or channel == "" then
84 | return
85 | end
86 |
87 | local meta = minetest.get_meta(pos)
88 |
89 | local wls = moremesecons.get_data_from_pos(wireless_meta, pos)
90 | if not wls or wls.owner == "" then
91 | return
92 | end
93 |
94 | if wls.id then
95 | remove_wireless(pos)
96 | end
97 |
98 | if meta then
99 | meta:set_string("channel", channel)
100 | end
101 | wls.channel = channel
102 | moremesecons.set_data_to_pos(wireless_meta, pos, wls)
103 |
104 | if not wireless[wls.owner] then
105 | wireless[wls.owner] = {}
106 | end
107 | if not wireless[wls.owner][channel] then
108 | wireless[wls.owner][channel] = {
109 | members = {},
110 | sources = {}
111 | }
112 | end
113 |
114 | -- Find the first free ID
115 | local id = 1
116 | while wireless[wls.owner][channel].members[id] do
117 | id = id + 1
118 | end
119 | wls.id = id
120 | moremesecons.set_data_to_pos(wireless_meta, pos, wls)
121 |
122 | local network = wireless[wls.owner][channel]
123 |
124 | network.members[id] = pos
125 |
126 | if meta then
127 | meta:set_int("id", id)
128 | end
129 |
130 | update_mod_storage()
131 |
132 | if meta then
133 | meta:set_string("infotext", "Wireless owned by " .. wls.owner .. " on channel " .. channel)
134 | end
135 |
136 | if wls.effector then
137 | wireless_effector_on(pos)
138 | elseif next(network.sources) then
139 | wireless_receptor_on(pos, id, network, false)
140 | else
141 | wireless_receptor_off(pos, id, network, false)
142 | end
143 | end
144 |
145 | local function register_wireless(pos)
146 | local meta = minetest.get_meta(pos)
147 | local owner = meta:get_string("owner")
148 | if owner == "" then
149 | return
150 | end
151 | remove_wireless(pos)
152 |
153 | set_owner(pos, owner)
154 |
155 | local channel = meta:get_string("channel")
156 | if channel ~= "" then
157 | set_channel(pos, channel)
158 | end
159 | end
160 |
161 | local function check_wireless_exists(pos)
162 | local nn = minetest.get_node(pos).name
163 | if nn:sub(1, 30) == "moremesecons_wireless:wireless" then
164 | return true
165 | elseif nn ~= "ignore" then
166 | -- Defer the remove_wireless() call so it doesn't interfere
167 | -- with pairs().
168 | minetest.after(0, remove_wireless, pos)
169 | return false
170 | end
171 | end
172 |
173 | function wireless_receptor_on(pos, id, network, check)
174 | if check == false or check_wireless_exists(pos) then
175 | minetest.swap_node(pos, {name = "moremesecons_wireless:wireless_on"})
176 | if not network.sources[id] then
177 | mesecon.receptor_on(pos)
178 | end
179 | end
180 | end
181 |
182 | function wireless_receptor_off(pos, id, network, check)
183 | if check == false or check_wireless_exists(pos) then
184 | minetest.swap_node(pos, {name = "moremesecons_wireless:wireless_off"})
185 | mesecon.receptor_off(pos)
186 | end
187 | end
188 |
189 | local function activate_network(owner, channel)
190 | local network = wireless[owner][channel]
191 | for i, wl_pos in pairs(network.members) do
192 | wireless_receptor_on(wl_pos, i, network)
193 | end
194 | end
195 |
196 | local function deactivate_network(owner, channel)
197 | local network = wireless[owner][channel]
198 | for i, wl_pos in pairs(network.members) do
199 | wireless_receptor_off(wl_pos, i, network)
200 | end
201 | end
202 |
203 | local is_jammed
204 | function wireless_effector_on(pos)
205 | if is_jammed(pos) then
206 | -- jamming doesn't disallow receiving signals, only sending them
207 | return
208 | end
209 |
210 | local wls = moremesecons.get_data_from_pos(wireless_meta, pos)
211 | if not wls then
212 | return
213 | end
214 |
215 | wls.effector = true
216 |
217 | moremesecons.set_data_to_pos(wireless_meta, pos, wls)
218 |
219 | if wls.owner == "" or not wireless[wls.owner] or wls.channel == "" or not wireless[wls.owner][wls.channel] then
220 | return
221 | end
222 |
223 | local network = wireless[wls.owner][wls.channel]
224 | network.sources[wls.id] = true
225 | activate_network(wls.owner, wls.channel)
226 |
227 | update_mod_storage()
228 | end
229 |
230 | function wireless_effector_off(pos)
231 | local wls = moremesecons.get_data_from_pos(wireless_meta, pos)
232 | if not wls then
233 | return
234 | end
235 |
236 | wls.effector = nil
237 | moremesecons.set_data_to_pos(wireless_meta, pos, wls)
238 |
239 | if wls.owner == "" or not wireless[wls.owner] or wls.channel == "" or not wireless[wls.owner][wls.channel] then
240 | return
241 | end
242 |
243 | local network = wireless[wls.owner][wls.channel]
244 | network.sources[wls.id] = nil
245 | if not next(network.sources) then
246 | deactivate_network(wls.owner, wls.channel)
247 | else
248 | -- There is another source in the network. Turn this wireless into
249 | -- a receptor.
250 | mesecon.receptor_on(pos)
251 | end
252 |
253 | update_mod_storage()
254 | end
255 |
256 | -- This table is required to prevent a message from being sent in loop between wireless nodes
257 | local sending_digilines = {}
258 |
259 | local function on_digiline_receive(pos, node, channel, msg)
260 | if is_jammed(pos) then
261 | return
262 | end
263 |
264 | local wls = moremesecons.get_data_from_pos(wireless_meta, pos)
265 | if not wls then
266 | return
267 | end
268 |
269 | if wls.owner == "" or not wireless[wls.owner] or channel == "" or not wireless[wls.owner][wls.channel] then
270 | return
271 | end
272 |
273 | local pos_hash = minetest.hash_node_position(pos)
274 | if sending_digilines[pos_hash] then
275 | return
276 | end
277 |
278 | sending_digilines[pos_hash] = true
279 | for i, wl_pos in pairs(wireless[wls.owner][wls.channel].members) do
280 | if i ~= wls.id then
281 | digiline:receptor_send(wl_pos, digiline.rules.default, channel, msg)
282 | end
283 | end
284 | sending_digilines[pos_hash] = nil
285 | end
286 |
287 | mesecon.register_node("moremesecons_wireless:wireless", {
288 | paramtype = "light",
289 | paramtype2 = "facedir",
290 | description = "Wireless",
291 | digiline = {
292 | receptor = {},
293 | effector = {
294 | action = on_digiline_receive
295 | },
296 | },
297 | sounds = default.node_sound_stone_defaults(),
298 | on_construct = function(pos)
299 | minetest.get_meta(pos):set_string("formspec", "field[channel;channel;${channel}]")
300 | end,
301 | on_destruct = function(pos)
302 | remove_wireless(pos)
303 | mesecon.receptor_off(pos)
304 | end,
305 | after_place_node = function(pos, placer)
306 | set_owner(pos, placer:get_player_name())
307 | end,
308 | on_receive_fields = function(pos, _, fields, player)
309 | local meta = minetest.get_meta(pos)
310 | local playername = player:get_player_name()
311 |
312 | local owner = meta:get_string("owner")
313 | if not owner or owner == "" then
314 | -- Old wireless
315 | if not minetest.is_protected(pos, playername) then
316 | set_owner(pos, playername)
317 | else
318 | return
319 | end
320 | end
321 |
322 | if playername == owner then
323 | set_channel(pos, fields.channel)
324 | end
325 | end,
326 | }, {
327 | tiles = {"moremesecons_wireless_off.png"},
328 | groups = {cracky=3},
329 | mesecons = {effector = {
330 | action_on = wireless_effector_on
331 | }},
332 | }, {
333 | tiles = {"moremesecons_wireless_on.png"},
334 | groups = {cracky=3, not_in_creative_inventory=1},
335 | mesecons = {effector = {
336 | action_off = wireless_effector_off
337 | }},
338 | })
339 |
340 | minetest.register_alias("moremesecons_wireless:wireless", "moremesecons_wireless:wireless_off")
341 |
342 | minetest.register_craft({
343 | output = "moremesecons_wireless:wireless_off 2",
344 | recipe = {
345 | {"group:mesecon_conductor_craftable", "", "group:mesecon_conductor_craftable"},
346 | {"", "mesecons_torch:mesecon_torch_on", ""},
347 | {"group:mesecon_conductor_craftable", "", "group:mesecon_conductor_craftable"},
348 | }
349 | })
350 |
351 | local function remove_jammer(pos)
352 | moremesecons.remove_data_from_pos(jammers, pos)
353 | end
354 |
355 | local function add_jammer(pos)
356 | remove_jammer(pos)
357 | moremesecons.set_data_to_pos(jammers, pos, true)
358 | end
359 |
360 | function is_jammed(pos)
361 | local JAMMER_MAX_DISTANCE = moremesecons.setting("wireless", "jammer_max_distance", 15, 1)
362 | local JAMMER_MAX_DISTANCE_SQUARE = JAMMER_MAX_DISTANCE^2 -- Cache this result
363 |
364 | for pos_hash, _ in pairs(jammers.tab) do
365 | local j_pos = minetest.get_position_from_hash(pos_hash)
366 | -- Fast comparisons first
367 | if math.abs(pos.x - j_pos.x) <= JAMMER_MAX_DISTANCE and
368 | math.abs(pos.y - j_pos.y) <= JAMMER_MAX_DISTANCE and
369 | math.abs(pos.z - j_pos.z) <= JAMMER_MAX_DISTANCE and
370 | (pos.x - j_pos.x)^2 + (pos.y - j_pos.y)^2 + (pos.z - j_pos.z)^2 <= JAMMER_MAX_DISTANCE_SQUARE then
371 | return true
372 | end
373 | end
374 |
375 | return false
376 | end
377 |
378 | if moremesecons.setting("wireless", "enable_jammer", true) then
379 | mesecon.register_node("moremesecons_wireless:jammer", {
380 | description = "Wireless Jammer",
381 | paramtype = "light",
382 | drawtype = "nodebox",
383 | },{
384 | tiles = {"mesecons_wire_off.png^moremesecons_jammer_top.png", "moremesecons_jammer_bottom.png", "mesecons_wire_off.png^moremesecons_jammer_side_off.png"},
385 | node_box = {
386 | type = "fixed",
387 | fixed = {
388 | -- connection
389 | {-1/16, -0.5, -0.5, 1/16, -7/16, 0.5},
390 | {-0.5, -0.5, -1/16, 0.5, -7/16, 1/16},
391 |
392 | --stabilization
393 | {-1/16, -7/16, -1/16, 1/16, -6/16, 1/16},
394 |
395 | -- fields
396 | {-7/16, -6/16, -7/16, 7/16, -4/16, 7/16},
397 | {-5/16, -4/16, -5/16, 5/16, -3/16, 5/16},
398 | {-3/16, -3/16, -3/16, 3/16, -2/16, 3/16},
399 | {-1/16, -2/16, -1/16, 1/16, -1/16, 1/16},
400 | },
401 | },
402 | groups = {dig_immediate=2},
403 | mesecons = {effector = {
404 | rules = mesecon.rules.flat,
405 | action_on = function(pos)
406 | add_jammer(pos)
407 | minetest.swap_node(pos, {name="moremesecons_wireless:jammer_on"})
408 | end
409 | }}
410 | },{
411 | tiles = {"mesecons_wire_on.png^moremesecons_jammer_top.png", "moremesecons_jammer_bottom.png", "mesecons_wire_on.png^moremesecons_jammer_side_on.png"},
412 | node_box = {
413 | type = "fixed",
414 | fixed = {
415 | -- connection
416 | {-1/16, -0.5, -0.5, 1/16, -7/16, 0.5},
417 | {-0.5, -0.5, -1/16, 0.5, -7/16, 1/16},
418 |
419 | --stabilization
420 | {-1/16, -7/16, -1/16, 1/16, 5/16, 1/16},
421 |
422 | -- fields
423 | {-7/16, -6/16, -7/16, 7/16, -4/16, 7/16},
424 | {-5/16, -3/16, -5/16, 5/16, -1/16, 5/16},
425 | {-3/16, 0, -3/16, 3/16, 2/16, 3/16},
426 | {-1/16, 3/16, -1/16, 1/16, 5/16, 1/16},
427 | },
428 | },
429 | groups = {dig_immediate=2, not_in_creative_inventory=1},
430 | mesecons = {effector = {
431 | rules = mesecon.rules.flat,
432 | action_off = function(pos)
433 | remove_jammer(pos)
434 | minetest.swap_node(pos, {name="moremesecons_wireless:jammer_off"})
435 | end
436 | }},
437 | on_destruct = remove_jammer,
438 | on_construct = add_jammer,
439 | })
440 |
441 | minetest.register_craft({
442 | output = "moremesecons_wireless:jammer_off",
443 | recipe = {
444 | {"moremesecons_wireless:wireless", "mesecons_torch:mesecon_torch_on", "moremesecons_wireless:wireless"}
445 | }
446 | })
447 | end
448 |
449 | if moremesecons.setting("wireless", "enable_lbm", false) then
450 | minetest.register_lbm({
451 | name = "moremesecons_wireless:add_jammer",
452 | nodenames = {"moremesecons_wireless:jammer_on"},
453 | run_at_every_load = true,
454 | action = add_jammer
455 | })
456 |
457 | minetest.register_lbm({
458 | name = "moremesecons_wireless:add_wireless",
459 | nodenames = {"moremesecons_wireless:wireless"},
460 | run_at_every_load = true,
461 | action = register_wireless
462 | })
463 | end
464 |
465 | -- Legacy
466 | if storage:get_string("wireless_meta_2") == "" then
467 | local wireless_meta_1 = minetest.deserialize(storage:get_string("wireless_meta"))
468 | if not wireless_meta_1 then
469 | return
470 | end
471 |
472 | minetest.log("action", "[moremesecons_wireless] Migrating mod storage data...")
473 | local jammers_1 = minetest.deserialize(storage:get_string("jammers"))
474 |
475 | local get = function(t, pos)
476 | -- FIXME: this does not test explicitly for false,
477 | -- but channel is never false
478 | return t[pos.z] and t[pos.z][pos.y] and t[pos.z][pos.y][pos.x]
479 | end
480 |
481 | for z, data_z in pairs(wireless_meta_1.owners) do
482 | for y, data_y in pairs(data_z) do
483 | for x, owner in pairs(data_y) do
484 | local pos = {x = x, y = y, z = z}
485 | set_owner(pos, owner)
486 | set_channel(pos, get(wireless_meta_1.channels, pos))
487 | end
488 | end
489 | end
490 |
491 | for z, data_z in pairs(jammers_1) do
492 | for y, data_y in pairs(data_z) do
493 | for x, jammer in pairs(data_y) do
494 | local pos = {x = x, y = y, z = z}
495 | moremesecons.set_data_to_pos(jammers, pos, jammer)
496 | end
497 | end
498 | end
499 | minetest.log("action", "[moremesecons_wireless] Done!")
500 | end
501 |
--------------------------------------------------------------------------------
/moremesecons_wireless/mod.conf:
--------------------------------------------------------------------------------
1 | name = moremesecons_wireless
2 | depends = mesecons,moremesecons_utils
3 | optional_depends = digilines,craft_guide
4 |
--------------------------------------------------------------------------------
/moremesecons_wireless/textures/moremesecons_jammer_bottom.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/minetest-mods/MoreMesecons/3e93b939f3bae14fb7a8c3f94e8db5d8fc0b2c24/moremesecons_wireless/textures/moremesecons_jammer_bottom.png
--------------------------------------------------------------------------------
/moremesecons_wireless/textures/moremesecons_jammer_side_off.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/minetest-mods/MoreMesecons/3e93b939f3bae14fb7a8c3f94e8db5d8fc0b2c24/moremesecons_wireless/textures/moremesecons_jammer_side_off.png
--------------------------------------------------------------------------------
/moremesecons_wireless/textures/moremesecons_jammer_side_on.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/minetest-mods/MoreMesecons/3e93b939f3bae14fb7a8c3f94e8db5d8fc0b2c24/moremesecons_wireless/textures/moremesecons_jammer_side_on.png
--------------------------------------------------------------------------------
/moremesecons_wireless/textures/moremesecons_jammer_top.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/minetest-mods/MoreMesecons/3e93b939f3bae14fb7a8c3f94e8db5d8fc0b2c24/moremesecons_wireless/textures/moremesecons_jammer_top.png
--------------------------------------------------------------------------------
/moremesecons_wireless/textures/moremesecons_wireless_off.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/minetest-mods/MoreMesecons/3e93b939f3bae14fb7a8c3f94e8db5d8fc0b2c24/moremesecons_wireless/textures/moremesecons_wireless_off.png
--------------------------------------------------------------------------------
/moremesecons_wireless/textures/moremesecons_wireless_on.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/minetest-mods/MoreMesecons/3e93b939f3bae14fb7a8c3f94e8db5d8fc0b2c24/moremesecons_wireless/textures/moremesecons_wireless_on.png
--------------------------------------------------------------------------------
/settingtypes.txt:
--------------------------------------------------------------------------------
1 | [Adjustable Blinky Plant]
2 |
3 | # Minimal interval authorized. Any lower will be set to it.
4 | moremesecons_adjustable_blinky_plant.min_interval (Minimum Interval) float 0.5
5 |
6 | [Adjustable Player Detector]
7 |
8 | moremesecons_adjustable_player_detector.max_radius (Maximum adjustable player detector radius) float 16 0
9 |
10 | [Craftable Commandblock]
11 |
12 | # Space-separated list of authorized commands
13 | # Empty to authorize all
14 | moremesecons_commandblock.authorized_commands (Authorized commands) string tell
15 |
16 | # Maximum distance of the @nearest player
17 | # Any value less than or equal to 0 will be changed to 1 and a NaN value will be changed to the default value
18 | moremesecons_commandblock.nearest_max_distance (Nearest player maximum distance) float 8
19 |
20 | [Entity Detector]
21 |
22 | moremesecons_entity_detector.max_radius (Maximum entity detector radius) float 16 0
23 |
24 | [Signal Jammer]
25 |
26 | # Jammer action range
27 | # Any value less than or equal to 0 will be changed to 1 and a NaN value will be changed to the default value
28 | moremesecons_jammer.max_distance (Jammer action range) float 10
29 |
30 | # Whether to enable the registration LBM.
31 | # The registration LBM will recover the jammer database if the moremesecons_jammer
32 | # mod storage has been removed, and will create that mod storage after an update
33 | # from an older version which did not use it.
34 | moremesecons_jammer.enable_lbm (Enable Registration LBM) bool false
35 |
36 | [Player Killer]
37 |
38 | # Player Killer action range
39 | # Any value less than or equal to 0 will be changed to 1 and a NaN value will be changed to the default value
40 | moremesecons_playerkiller.max_distance (Player Killer action range) float 8
41 |
42 | [Sayer]
43 |
44 | # Whether to use the Speech Dispatcher
45 | # It will work only if:
46 | # * moremesecons_sayer is present in your trusted_mods setting
47 | # * you are playing in singleplayer
48 | # * the speech-dispatcher is installed on your system
49 | # * you are using a POSIX-compliant system and a sh-compatible shell (such as bash, dash, zsh...)
50 | moremesecons_sayer.use_speech_dispatcher (Use the Speech Dispatcher) bool true
51 |
52 | # Sayer range
53 | # Any value less than or equal to 0 will be changed to 1 and a NaN value will be changed to the default value
54 | moremesecons_sayer.max_distance (Range) float 8
55 |
56 | [Teleporter]
57 |
58 | # Maximum Teleporter To Teleporter distance
59 | # Any value less than or equal to 0 will be changed to 1 and a NaN value will be changed to the default value
60 | moremesecons_teleporter.max_t2t_distance (Maximum Teleporter To Teleporter distance) float 50
61 |
62 | # Maximum Player To Teleporter distance
63 | # Any value less than or equal to 0 will be set to 1
64 | moremesecons_teleporter.max_p2t_distance (Maximum Player To Teleporter distance) float 25
65 |
66 | # Whether to enable the registration LBM.
67 | # The registration LBM will recover a teleporter network if the moremesecons_teleporter
68 | # mod storage has been removed, and will create that mod storage after an update
69 | # from an older version which did not use it.
70 | moremesecons_teleporter.enable_lbm (Enable Registration LBM) bool false
71 |
72 | [Wireless]
73 |
74 | # Whether to enable the wireless jammer node
75 | moremesecons_wireless.enable_jammer (Enable wireless jammer) bool true
76 |
77 | # Wireless Jammer action range
78 | # Any value less than or equal to 0 will be changed to 1 and a NaN value will be changed to the default value
79 | moremesecons_wireless.jammer_max_distance (Wireless Jammer action range) float 15
80 |
81 | # Whether to enable the registration LBM.
82 | # The registration LBM will recover a wireless network if the moremesecons_wireless
83 | # mod storage has been removed, and will create that mod storage after an update
84 | # from an older version which did not use it.
85 | moremesecons_wireless.enable_lbm (Enable Registration LBM) bool false
86 |
--------------------------------------------------------------------------------