first commit

This commit is contained in:
Nigel Garnett 2019-07-23 10:28:01 +00:00
commit 37e7b77c31
5841 changed files with 85542 additions and 0 deletions

374
MoreMesecons/LICENSE.txt Normal file
View File

@ -0,0 +1,374 @@
Mozilla Public License Version 2.0
==================================
1. Definitions
--------------
1.1. "Contributor"
means each individual or legal entity that creates, contributes to
the creation of, or owns Covered Software.
1.2. "Contributor Version"
means the combination of the Contributions of others (if any) used
by a Contributor and that particular Contributor's Contribution.
1.3. "Contribution"
means Covered Software of a particular Contributor.
1.4. "Covered Software"
means Source Code Form to which the initial Contributor has attached
the notice in Exhibit A, the Executable Form of such Source Code
Form, and Modifications of such Source Code Form, in each case
including portions thereof.
1.5. "Incompatible With Secondary Licenses"
means
(a) that the initial Contributor has attached the notice described
in Exhibit B to the Covered Software; or
(b) that the Covered Software was made available under the terms of
version 1.1 or earlier of the License, but not also under the
terms of a Secondary License.
1.6. "Executable Form"
means any form of the work other than Source Code Form.
1.7. "Larger Work"
means a work that combines Covered Software with other material, in
a separate file or files, that is not Covered Software.
1.8. "License"
means this document.
1.9. "Licensable"
means having the right to grant, to the maximum extent possible,
whether at the time of the initial grant or subsequently, any and
all of the rights conveyed by this License.
1.10. "Modifications"
means any of the following:
(a) any file in Source Code Form that results from an addition to,
deletion from, or modification of the contents of Covered
Software; or
(b) any new file in Source Code Form that contains any Covered
Software.
1.11. "Patent Claims" of a Contributor
means any patent claim(s), including without limitation, method,
process, and apparatus claims, in any patent Licensable by such
Contributor that would be infringed, but for the grant of the
License, by the making, using, selling, offering for sale, having
made, import, or transfer of either its Contributions or its
Contributor Version.
1.12. "Secondary License"
means either the GNU General Public License, Version 2.0, the GNU
Lesser General Public License, Version 2.1, the GNU Affero General
Public License, Version 3.0, or any later versions of those
licenses.
1.13. "Source Code Form"
means the form of the work preferred for making modifications.
1.14. "You" (or "Your")
means an individual or a legal entity exercising rights under this
License. For legal entities, "You" includes any entity that
controls, is controlled by, or is under common control with You. For
purposes of this definition, "control" means (a) the power, direct
or indirect, to cause the direction or management of such entity,
whether by contract or otherwise, or (b) ownership of more than
fifty percent (50%) of the outstanding shares or beneficial
ownership of such entity.
2. License Grants and Conditions
--------------------------------
2.1. Grants
Each Contributor hereby grants You a world-wide, royalty-free,
non-exclusive license:
(a) under intellectual property rights (other than patent or trademark)
Licensable by such Contributor to use, reproduce, make available,
modify, display, perform, distribute, and otherwise exploit its
Contributions, either on an unmodified basis, with Modifications, or
as part of a Larger Work; and
(b) under Patent Claims of such Contributor to make, use, sell, offer
for sale, have made, import, and otherwise transfer either its
Contributions or its Contributor Version.
2.2. Effective Date
The licenses granted in Section 2.1 with respect to any Contribution
become effective for each Contribution on the date the Contributor first
distributes such Contribution.
2.3. Limitations on Grant Scope
The licenses granted in this Section 2 are the only rights granted under
this License. No additional rights or licenses will be implied from the
distribution or licensing of Covered Software under this License.
Notwithstanding Section 2.1(b) above, no patent license is granted by a
Contributor:
(a) for any code that a Contributor has removed from Covered Software;
or
(b) for infringements caused by: (i) Your and any other third party's
modifications of Covered Software, or (ii) the combination of its
Contributions with other software (except as part of its Contributor
Version); or
(c) under Patent Claims infringed by Covered Software in the absence of
its Contributions.
This License does not grant any rights in the trademarks, service marks,
or logos of any Contributor (except as may be necessary to comply with
the notice requirements in Section 3.4).
2.4. Subsequent Licenses
No Contributor makes additional grants as a result of Your choice to
distribute the Covered Software under a subsequent version of this
License (see Section 10.2) or under the terms of a Secondary License (if
permitted under the terms of Section 3.3).
2.5. Representation
Each Contributor represents that the Contributor believes its
Contributions are its original creation(s) or it has sufficient rights
to grant the rights to its Contributions conveyed by this License.
2.6. Fair Use
This License is not intended to limit any rights You have under
applicable copyright doctrines of fair use, fair dealing, or other
equivalents.
2.7. Conditions
Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted
in Section 2.1.
3. Responsibilities
-------------------
3.1. Distribution of Source Form
All distribution of Covered Software in Source Code Form, including any
Modifications that You create or to which You contribute, must be under
the terms of this License. You must inform recipients that the Source
Code Form of the Covered Software is governed by the terms of this
License, and how they can obtain a copy of this License. You may not
attempt to alter or restrict the recipients' rights in the Source Code
Form.
3.2. Distribution of Executable Form
If You distribute Covered Software in Executable Form then:
(a) such Covered Software must also be made available in Source Code
Form, as described in Section 3.1, and You must inform recipients of
the Executable Form how they can obtain a copy of such Source Code
Form by reasonable means in a timely manner, at a charge no more
than the cost of distribution to the recipient; and
(b) You may distribute such Executable Form under the terms of this
License, or sublicense it under different terms, provided that the
license for the Executable Form does not attempt to limit or alter
the recipients' rights in the Source Code Form under this License.
3.3. Distribution of a Larger Work
You may create and distribute a Larger Work under terms of Your choice,
provided that You also comply with the requirements of this License for
the Covered Software. If the Larger Work is a combination of Covered
Software with a work governed by one or more Secondary Licenses, and the
Covered Software is not Incompatible With Secondary Licenses, this
License permits You to additionally distribute such Covered Software
under the terms of such Secondary License(s), so that the recipient of
the Larger Work may, at their option, further distribute the Covered
Software under the terms of either this License or such Secondary
License(s).
3.4. Notices
You may not remove or alter the substance of any license notices
(including copyright notices, patent notices, disclaimers of warranty,
or limitations of liability) contained within the Source Code Form of
the Covered Software, except that You may alter any license notices to
the extent required to remedy known factual inaccuracies.
3.5. Application of Additional Terms
You may choose to offer, and to charge a fee for, warranty, support,
indemnity or liability obligations to one or more recipients of Covered
Software. However, You may do so only on Your own behalf, and not on
behalf of any Contributor. You must make it absolutely clear that any
such warranty, support, indemnity, or liability obligation is offered by
You alone, and You hereby agree to indemnify every Contributor for any
liability incurred by such Contributor as a result of warranty, support,
indemnity or liability terms You offer. You may include additional
disclaimers of warranty and limitations of liability specific to any
jurisdiction.
4. Inability to Comply Due to Statute or Regulation
---------------------------------------------------
If it is impossible for You to comply with any of the terms of this
License with respect to some or all of the Covered Software due to
statute, judicial order, or regulation then You must: (a) comply with
the terms of this License to the maximum extent possible; and (b)
describe the limitations and the code they affect. Such description must
be placed in a text file included with all distributions of the Covered
Software under this License. Except to the extent prohibited by statute
or regulation, such description must be sufficiently detailed for a
recipient of ordinary skill to be able to understand it.
5. Termination
--------------
5.1. The rights granted under this License will terminate automatically
if You fail to comply with any of its terms. However, if You become
compliant, then the rights granted under this License from a particular
Contributor are reinstated (a) provisionally, unless and until such
Contributor explicitly and finally terminates Your grants, and (b) on an
ongoing basis, if such Contributor fails to notify You of the
non-compliance by some reasonable means prior to 60 days after You have
come back into compliance. Moreover, Your grants from a particular
Contributor are reinstated on an ongoing basis if such Contributor
notifies You of the non-compliance by some reasonable means, this is the
first time You have received notice of non-compliance with this License
from such Contributor, and You become compliant prior to 30 days after
Your receipt of the notice.
5.2. If You initiate litigation against any entity by asserting a patent
infringement claim (excluding declaratory judgment actions,
counter-claims, and cross-claims) alleging that a Contributor Version
directly or indirectly infringes any patent, then the rights granted to
You by any and all Contributors for the Covered Software under Section
2.1 of this License shall terminate.
5.3. In the event of termination under Sections 5.1 or 5.2 above, all
end user license agreements (excluding distributors and resellers) which
have been validly granted by You or Your distributors under this License
prior to termination shall survive termination.
************************************************************************
* *
* 6. Disclaimer of Warranty *
* ------------------------- *
* *
* Covered Software is provided under this License on an "as is" *
* basis, without warranty of any kind, either expressed, implied, or *
* statutory, including, without limitation, warranties that the *
* Covered Software is free of defects, merchantable, fit for a *
* particular purpose or non-infringing. The entire risk as to the *
* quality and performance of the Covered Software is with You. *
* Should any Covered Software prove defective in any respect, You *
* (not any Contributor) assume the cost of any necessary servicing, *
* repair, or correction. This disclaimer of warranty constitutes an *
* essential part of this License. No use of any Covered Software is *
* authorized under this License except under this disclaimer. *
* *
************************************************************************
************************************************************************
* *
* 7. Limitation of Liability *
* -------------------------- *
* *
* Under no circumstances and under no legal theory, whether tort *
* (including negligence), contract, or otherwise, shall any *
* Contributor, or anyone who distributes Covered Software as *
* permitted above, be liable to You for any direct, indirect, *
* special, incidental, or consequential damages of any character *
* including, without limitation, damages for lost profits, loss of *
* goodwill, work stoppage, computer failure or malfunction, or any *
* and all other commercial damages or losses, even if such party *
* shall have been informed of the possibility of such damages. This *
* limitation of liability shall not apply to liability for death or *
* personal injury resulting from such party's negligence to the *
* extent applicable law prohibits such limitation. Some *
* jurisdictions do not allow the exclusion or limitation of *
* incidental or consequential damages, so this exclusion and *
* limitation may not apply to You. *
* *
************************************************************************
8. Litigation
-------------
Any litigation relating to this License may be brought only in the
courts of a jurisdiction where the defendant maintains its principal
place of business and such litigation shall be governed by laws of that
jurisdiction, without reference to its conflict-of-law provisions.
Nothing in this Section shall prevent a party's ability to bring
cross-claims or counter-claims.
9. Miscellaneous
----------------
This License represents the complete agreement concerning the subject
matter hereof. If any provision of this License is held to be
unenforceable, such provision shall be reformed only to the extent
necessary to make it enforceable. Any law or regulation which provides
that the language of a contract shall be construed against the drafter
shall not be used to construe this License against a Contributor.
10. Versions of the License
---------------------------
10.1. New Versions
Mozilla Foundation is the license steward. Except as provided in Section
10.3, no one other than the license steward has the right to modify or
publish new versions of this License. Each version will be given a
distinguishing version number.
10.2. Effect of New Versions
You may distribute the Covered Software under the terms of the version
of the License under which You originally received the Covered Software,
or under the terms of any subsequent version published by the license
steward.
10.3. Modified Versions
If you create software not governed by this License, and you want to
create a new license for such software, you may create and use a
modified version of this License if you rename the license and remove
any references to the name of the license steward (except to note that
such modified license differs from this License).
10.4. Distributing Source Code Form that is Incompatible With Secondary
Licenses
If You choose to distribute Source Code Form that is Incompatible With
Secondary Licenses under the terms of this version of the License, the
notice described in Exhibit B of this License must be attached.
Exhibit A - Source Code Form License Notice
-------------------------------------------
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.
If it is not possible or desirable to put the notice in a particular
file, then You may include the notice in a location (such as a LICENSE
file in a relevant directory) where a recipient would be likely to look
for such a notice.
You may add additional accurate notices of copyright ownership.
Exhibit B - "Incompatible With Secondary Licenses" Notice
---------------------------------------------------------
This Source Code Form is "Incompatible With Secondary Licenses", as
defined by the Mozilla Public License, v. 2.0.

50
MoreMesecons/README.md Normal file
View File

@ -0,0 +1,50 @@
# MoreMesecons
Based on Mesecons by Jeija
By @paly2 and @HybridDog
With the participation of @LeMagnesium (bugfix), @Ataron (textures), @JAPP (texture).
Dependencies: [Mesecons](https://github.com/Jeija/minetest-mod-mesecons/)
Optional dependencies: [vector_extras](https://github.com/HybridDog/vector_extras/) [digilines](https://github.com/minetest-mods/digilines)
MoreMesecons is a mod for minetest which adds some mesecons items.
[Here](http://github.com/minetest-mods/MoreMesecons/wiki)'s the wiki !
## New items
* `Adjustable Blinky plant` : Like a mesecons blinky plant, but... adjustable. Right-click to change the interval.
* `Adjustable Player Detector` : Like a mesecons player detector, but you can change its detection radius by right-click.
* `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).
* `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".
* `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.
* `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")).
* `Igniter` : This node is a lighter that ignites its adjacent flammable nodes (including TNT).
* `Injector Controller` : This node is useful to activate/deactivate a pipeworks filter injector : it sends a blinky signal.
* `Jammer` : If turned on, this node stops mesecons in a radius of 10 nodes.
* `LuaBlock`: This block allows its owner to execute any Lua code in the global environment when turned on. Using it requires the server privilege.
* `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.
* `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.
* `Sayer` : This node sends a message to every players inside a radius of 8 nodes.
* `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.
* `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.
* `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.
* `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.
* `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.
* `Wireless Jammer` : If it receives a mesecons signal, it deactivates all wireless (receptors) in a radius of 15 nodes.
## Settings
You can set the settings by using the Minetest GUI ("Settings" tab -> Advanced settings -> Mods -> MoreMesecons).
## The Sayer and the Speech Dispatcher
[Speech Dispatcher project](http://freecode.com/projects/speech-dispatcher)
The Sayer item is able to speak on your speakers using the speech dispatcher, under these conditions:
1. The moremesecons_sayer mod is present in your trusted_mods setting
2. You are playing in singleplayer.
3. You are using a POSIX-compliant system and a sh-compatible shell (such as bash, dash, zsh...). Microsoft Windows is NOT POSIX-compliant.
4. The speech dispatcher is installed on your system.
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).

67
MoreMesecons/debug.txt Normal file
View File

@ -0,0 +1,67 @@
-------------
Separator
-------------
2017-07-31 12:32:52: [Main]: Automatically selecting world at [/home/www-data/MINETESTX/bin/../worlds/Rainbow]
2017-07-31 12:32:52: ERROR[Main]: mod "mesecons_lightstone" has unsatisfied dependencies: "dye"
2017-07-31 12:32:52: WARNING[Main]: NodeDefManager: Ignoring CONTENT_IGNORE redefinition
2017-07-31 12:32:57: ACTION[Main]: [crops] Loaded!
2017-07-31 12:32:58: WARNING[Main]: [moremesecons_sayer] use_speech_dispatcher = true, but the speech dispatcher can only be used in singleplayer
2017-07-31 12:32:59: ACTION[Main]: .__ __ __
2017-07-31 12:32:59: ACTION[Main]: _____ |__| ____ _____/ |_ ____ _______/ |_
2017-07-31 12:32:59: ACTION[Main]: / \| |/ \_/ __ \ __\/ __ \ / ___/\ __\
2017-07-31 12:32:59: ACTION[Main]: | Y Y \ | | \ ___/| | \ ___/ \___ \ | |
2017-07-31 12:32:59: ACTION[Main]: |__|_| /__|___| /\___ >__| \___ >____ > |__|
2017-07-31 12:32:59: ACTION[Main]: \/ \/ \/ \/ \/
2017-07-31 12:32:59: ACTION[Main]: World at [/home/www-data/MINETESTX/bin/../worlds/Rainbow]
2017-07-31 12:32:59: ACTION[Main]: Server for gameid="rainbow" listening on 0.0.0.0:30005.
2017-07-31 12:33:02: ACTION[Server]: IRC: Connected!
2017-07-31 12:33:02: ACTION[Server]: IRC CHAT: -!- RAINBOW-testing-30005 joined #minetestservers
2017-07-31 12:33:02: ACTION[Server]: IRC CHAT: <NWARGEERG@PLAY-30001> HEEEEELP
2017-07-31 12:33:30: ACTION[Server]: IRC CHAT: *** Nigel joined PLAY-30001
2017-07-31 12:33:59: ACTION[Server]: IRC CHAT: <Nigel@PLAY-30001> whats wrong?
2017-07-31 12:34:27: ACTION[Server]: IRC CHAT: *** 4567u joined PLAY-30001
2017-07-31 12:34:41: ACTION[Server]: IRC CHAT: <NWARGEERG@PLAY-30001> uos the sword
2017-07-31 12:34:45: ACTION[Server]: IRC CHAT: <tspidi@PLAY-30001> ubej evo
2017-07-31 12:34:49: ACTION[Server]: IRC CHAT: *** 4567u left PLAY-30001
2017-07-31 12:34:55: ACTION[Server]: IRC CHAT: <Nigel@PLAY-30001> NWARGEERG... whats wrong?
2017-07-31 12:35:18: ACTION[Server]: IRC CHAT: <CITY2@IRC> *** Henderson1389 left the game (Timed out)
2017-07-31 12:35:21: ACTION[Server]: IRC CHAT: <NWARGEERG@PLAY-30001> I'm trap
2017-07-31 12:35:40: ACTION[Server]: IRC CHAT: *** primezock left PLAY-30001
2017-07-31 12:36:03: ACTION[Server]: IRC CHAT: <BabyDiana@RAINBOW> traps are pretty
2017-07-31 12:36:07: ACTION[Server]: IRC CHAT: *** Roszel566 joined CITY2
2017-07-31 12:36:22: ACTION[Server]: IRC CHAT: <Nigel@PLAY-30001> ok buddy?
2017-07-31 12:36:22: ACTION[Server]: IRC CHAT: *** bi left CITY2
2017-07-31 12:36:53: ACTION[Server]: IRC CHAT: <NWARGEERG@PLAY-30001> thanks
2017-07-31 12:36:54: ACTION[Server]: IRC CHAT: <BabyDiana@RAINBOW> I live by a hospital
2017-07-31 12:37:04: ACTION[Server]: IRC CHAT: <BabyDiana@RAINBOW> And every day I go out walking past its sickly windows
2017-07-31 12:37:13: ACTION[Server]: IRC CHAT: <BabyDiana@RAINBOW> I see people dying there
2017-07-31 12:37:21: ACTION[Server]: IRC CHAT: *** primezock joined PLAY-30001
2017-07-31 12:37:25: ACTION[Server]: IRC CHAT: *** Nigel left PLAY-30001
2017-07-31 12:37:56: ACTION[Server]: IRC CHAT: *** georget joined CITY2
2017-07-31 12:38:03: ACTION[Server]: IRC CHAT: *** Nigel joined PLAY-30001
2017-07-31 12:38:24: ACTION[Server]: IRC CHAT: *** 4567u joined PLAY-30001
2017-07-31 12:38:25: ACTION[Server]: IRC CHAT: *** primezock left PLAY-30001
2017-07-31 12:39:13: ACTION[Server]: IRC CHAT: *** bjorn left CITY2
2017-07-31 12:39:13: ACTION[Server]: IRC CHAT: <PLAY-30001@IRC> *** 4567u left the game (Timed out)
2017-07-31 12:39:18: ACTION[Server]: IRC CHAT: <RAINBOW@IRC> *** Anthony left the game (Timed out)
2017-07-31 12:39:45: ACTION[Server]: IRC CHAT: *** Nigel left PLAY-30001
2017-07-31 12:40:05: ACTION[Server]: IRC CHAT: *** primezock joined PLAY-30001
2017-07-31 12:40:10: ACTION[Server]: IRC CHAT: *** georget left CITY2
2017-07-31 12:40:13: ACTION[Server]: Nigel [10.0.0.2] joins game.
2017-07-31 12:40:13: ACTION[Server]: Nigel joins game. List of players: Nigel
2017-07-31 12:40:14: ACTION[Server]: Showing formspec to Nigel
2017-07-31 12:40:33: ACTION[Server]: IRC CHAT: *** bjorn joined CITY2
2017-07-31 12:40:41: ACTION[Server]: IRC CHAT: *** Anthony joined RAINBOW
2017-07-31 12:40:56: ACTION[Server]: Nigel places node mesecons_noteblock:noteblock at (597,62,324)
2017-07-31 12:41:02: ACTION[Server]: Nigel digs mesecons_noteblock:noteblock at (597,62,324)
2017-07-31 12:41:33: ACTION[Server]: CHAT: <Nigel> Anthony, i have moremesecons working on the test server ;-)
2017-07-31 12:41:50: ACTION[Server]: CHAT: <Nigel> trying for pipeworks now...
2017-07-31 12:42:17: ACTION[Server]: IRC CHAT: <Anthony@RAINBOW> nice, im soting thew missing parts of the towers in fortress rock
2017-07-31 12:42:30: ACTION[Server]: CHAT: <Nigel> cool.
2017-07-31 12:42:37: ACTION[Server]: CHAT: <Nigel> here i go again...
2017-07-31 12:42:39: ACTION[Server]: Nigel leaves game. List of players:
2017-07-31 12:42:46: [Main]: INFO: signal_handler(): Ctrl-C pressed, shutting down.
2017-07-31 12:42:46: ACTION[Main]: IRC: Disconnected.

View File

@ -0,0 +1 @@
Adds more Mesecons items.

1
MoreMesecons/modpack.txt Normal file
View File

@ -0,0 +1 @@
The presence of this file indicates that the current folder is a modpack.

View File

@ -0,0 +1,3 @@
mesecons
moremesecons_utils
craft_guide?

View File

@ -0,0 +1,66 @@
local toggle_timer = function (pos, restart)
local timer = minetest.get_node_timer(pos)
if timer:is_started()
and not restart then
timer:stop()
else
local interval = tonumber(minetest.get_meta(pos):get_string("interval")) or 1
if interval < moremesecons.setting("adjustable_blinky_plant", "min_interval", 0.5) then
interval = moremesecons.setting("adjustable_blinky_plant", "min_interval", 0.5)
end
timer:start(interval)
end
end
local on_timer = function(pos)
if mesecon.flipstate(pos, minetest.get_node(pos)) == "on" then
mesecon.receptor_on(pos)
else
mesecon.receptor_off(pos)
end
toggle_timer(pos, false)
end
mesecon.register_node("moremesecons_adjustable_blinkyplant:adjustable_blinky_plant", {
description="Adjustable Blinky Plant",
drawtype = "plantlike",
inventory_image = "moremesecons_blinky_plant_off.png",
paramtype = "light",
walkable = false,
sounds = default.node_sound_leaves_defaults(),
selection_box = {
type = "fixed",
fixed = {-0.3, -0.5, -0.3, 0.3, -0.5+0.7, 0.3},
},
on_timer = on_timer,
on_construct = function(pos)
local meta = minetest.get_meta(pos)
meta:set_string("interval", "1")
meta:set_string("formspec", "field[interval;interval;${interval}]")
toggle_timer(pos, true)
end,
on_receive_fields = function(pos, _, fields, player)
local interval = tonumber(fields.interval)
if interval
and not minetest.is_protected(pos, player:get_player_name()) then
minetest.get_meta(pos):set_string("interval", interval)
toggle_timer(pos, true)
end
end,
},{
tiles = {"moremesecons_blinky_plant_off.png"},
groups = {dig_immediate=3},
mesecons = {receptor = { state = mesecon.state.off }}
},{
tiles = {"moremesecons_blinky_plant_off.png^moremesecons_blinky_plant_on.png"},
groups = {dig_immediate=3, not_in_creative_inventory=1},
sunlight_propagates = true,
mesecons = {receptor = { state = mesecon.state.on }},
})
minetest.register_craft({
output = "moremesecons_adjustable_blinkyplant:adjustable_blinky_plant_off 1",
recipe = { {"mesecons_blinkyplant:blinky_plant_off"},
{"default:mese_crystal_fragment"},}
})

Binary file not shown.

After

Width:  |  Height:  |  Size: 361 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 237 B

View File

@ -0,0 +1,2 @@
mesecons
craft_guide?

View File

@ -0,0 +1,138 @@
-- Adjustable Player Detector
-- Detects players in a certain radius
-- The radius can be changes by right-click (by default 6)
local function make_formspec(meta)
meta:set_string("formspec", "size[9,5]" ..
"field[0.3, 0;9,2;scanname;Coma-separated list of the names of players to scan for (empty for any):;${scanname}]"..
"field[0.3,1.5;4,2;digiline_channel;Digiline Channel (optional):;${digiline_channel}]"..
"field[0.3,3;4,2;radius;Detection radius:;${radius}]"..
"button_exit[3.5,3.5;2,3;;Save]")
end
local function object_detector_make_formspec(pos)
make_formspec(minetest.get_meta(pos))
end
local function object_detector_on_receive_fields(pos, _, fields, player)
if not fields.scanname
or not fields.digiline_channel
or minetest.is_protected(pos, player:get_player_name()) then
return
end
local meta = minetest.get_meta(pos)
meta:set_string("scanname", fields.scanname)
meta:set_string("digiline_channel", fields.digiline_channel)
local r = tonumber(fields.radius)
if r then
meta:set_int("radius", r)
end
end
-- returns true if player was found, false if not
local object_detector_scan = function (pos)
local meta = minetest.get_meta(pos)
local scanname = meta:get_string("scanname")
local scan_all = scanname == ""
local scan_names = scanname:split(',')
local radius = meta:get_int("radius")
if radius == 0 then
radius = 6
end
for _,obj in pairs(minetest.get_objects_inside_radius(pos, radius)) do
local isname = obj:get_player_name() -- "" is returned if it is not a player; "" ~= nil!
if isname ~= "" then
if scan_all then
return true
end
for _, name in ipairs(scan_names) do
if isname == name then
return true
end
end
end
end
return false
end
-- set player name when receiving a digiline signal on a specific channel
local object_detector_digiline = {
effector = {
action = function (pos, node, channel, msg)
local meta = minetest.get_meta(pos)
local active_channel = meta:get_string("digiline_channel")
if channel ~= active_channel then
return
end
meta:set_string("scanname", msg)
if meta:get_string("formspec") ~= "" then
make_formspec(meta)
end
end,
}
}
minetest.register_node("moremesecons_adjustable_player_detector:player_detector_off", {
tiles = {"default_steel_block.png", "default_steel_block.png", "moremesecons_player_detector_off.png"},
paramtype = "light",
walkable = true,
groups = {cracky=3},
description="Adjustable Player Detector",
mesecons = {receptor = {
state = mesecon.state.off,
rules = mesecon.rules.pplate
}},
on_construct = object_detector_make_formspec,
on_receive_fields = object_detector_on_receive_fields,
sounds = default.node_sound_stone_defaults(),
digiline = object_detector_digiline
})
minetest.register_node("moremesecons_adjustable_player_detector:player_detector_on", {
tiles = {"default_steel_block.png", "default_steel_block.png", "moremesecons_player_detector_on.png"},
paramtype = "light",
walkable = true,
groups = {cracky=3,not_in_creative_inventory=1},
drop = 'moremesecons_adjustable_player_detector:player_detector_off',
mesecons = {receptor = {
state = mesecon.state.on,
rules = mesecon.rules.pplate
}},
on_construct = object_detector_make_formspec,
on_receive_fields = object_detector_on_receive_fields,
sounds = default.node_sound_stone_defaults(),
digiline = object_detector_digiline
})
minetest.register_craft({
output = 'moremesecons_adjustable_player_detector:player_detector_off',
recipe = {
{"mesecons_detector:object_detector_off"},
{"default:mese_crystal_fragment"}
}
})
minetest.register_abm({
nodenames = {"moremesecons_adjustable_player_detector:player_detector_off"},
interval = 1.0,
chance = 1,
action = function(pos)
if object_detector_scan(pos) then
minetest.swap_node(pos, {name = "moremesecons_adjustable_player_detector:player_detector_on"})
mesecon.receptor_on(pos, mesecon.rules.pplate)
end
end,
})
minetest.register_abm({
nodenames = {"moremesecons_adjustable_player_detector:player_detector_on"},
interval = 1.0,
chance = 1,
action = function(pos)
if not object_detector_scan(pos) then
minetest.swap_node(pos, {name = "moremesecons_adjustable_player_detector:player_detector_off"})
mesecon.receptor_off(pos, mesecon.rules.pplate)
end
end,
})

Binary file not shown.

After

Width:  |  Height:  |  Size: 624 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 709 B

View File

@ -0,0 +1,3 @@
mesecons
moremesecons_utils
craft_guide?

View File

@ -0,0 +1,174 @@
local function initialize_data(meta)
local NEAREST_MAX_DISTANCE = moremesecons.setting("commandblock", "nearest_max_distance", 8, 1)
local commands = meta:get_string("commands")
meta:set_string("formspec",
"invsize[9,5;]" ..
"textarea[0.5,0.5;8.5,4;commands;Commands;"..commands.."]" ..
"label[1,3.8;@nearest is replaced by the nearest player name ("..tostring(NEAREST_MAX_DISTANCE).." nodes max for the nearest distance)".."]" ..
"button_exit[3.3,4.5;2,1;submit;Submit]")
local owner = meta:get_string("owner")
if owner == "" then
owner = "not owned"
else
owner = "owned by " .. owner
end
meta:set_string("infotext", "Command Block\n" ..
"(" .. owner .. ")\n" ..
"Commands: "..commands)
end
local function construct(pos)
local meta = minetest.get_meta(pos)
meta:set_string("commands", "tell @nearest Commandblock unconfigured")
meta:set_string("owner", "")
initialize_data(meta)
end
local function after_place(pos, placer)
if placer then
local meta = minetest.get_meta(pos)
meta:set_string("owner", placer:get_player_name())
initialize_data(meta)
end
end
local function receive_fields(pos, _, fields, player)
if not fields.submit then
return
end
local meta = minetest.get_meta(pos)
local owner = meta:get_string("owner")
if owner ~= ""
and player:get_player_name() ~= owner then
return
end
meta:set_string("commands", fields.commands)
initialize_data(meta)
end
local function resolve_commands(commands, pos)
local nearest = nil
local min_distance = math.huge
local players = minetest.get_connected_players()
for index, player in pairs(players) do
local distance = vector.distance(pos, player:getpos())
if distance < min_distance then
min_distance = distance
nearest = player:get_player_name()
end
end
new_commands = commands:gsub("@nearest", nearest)
return new_commands, min_distance, new_commands ~= commands
end
local function commandblock_action_on(pos, node)
local NEAREST_MAX_DISTANCE = moremesecons.setting("commandblock", "nearest_max_distance", 8, 1)
local accepted_commands = {}
do
local commands_str = moremesecons.setting("commandblock", "authorized_commands", "tell")
for command in string.gmatch(commands_str, "([^ ]+)") do
accepted_commands[command] = true
end
end
if node.name ~= "moremesecons_commandblock:commandblock_off" then
return
end
minetest.swap_node(pos, {name = "moremesecons_commandblock:commandblock_on"})
local meta = minetest.get_meta(pos)
local owner = meta:get_string("owner")
if owner == "" then
return
end
local commands, distance, nearest_in_commands = resolve_commands(meta:get_string("commands"), pos)
if distance > NEAREST_MAX_DISTANCE and nearest_in_commands then
minetest.chat_send_player(owner, "The nearest player is too far to use his name in the commands of a craftable command block.")
return
end
for _, command in pairs(commands:split("\n")) do
local pos = command:find(" ")
local cmd, param = command, ""
if pos then
cmd = command:sub(1, pos - 1)
param = command:sub(pos + 1)
end
local cmddef = minetest.chatcommands[cmd]
if not accepted_commands[cmd] and next(accepted_commands) then
minetest.chat_send_player(owner, "You can not execute the command "..cmd.." with a craftable command block ! This event will be reported.")
minetest.log("action", "Player "..owner.." tryed to execute an unauthorized command with a craftable command block.")
return
end
if not cmddef then
minetest.chat_send_player(owner, "The command "..cmd.." does not exist")
return
end
local has_privs, missing_privs = minetest.check_player_privs(owner, cmddef.privs)
if not has_privs then
minetest.chat_send_player(owner, "You don't have permission "
.."to run "..cmd
.." (missing privileges: "
..table.concat(missing_privs, ", ")..")")
return
end
cmddef.func(owner, param)
end
end
local function commandblock_action_off(pos, node)
if node.name == "moremesecons_commandblock:commandblock_on" then
minetest.swap_node(pos, {name = "moremesecons_commandblock:commandblock_off"})
end
end
local function can_dig(pos, player)
local meta = minetest.get_meta(pos)
local owner = meta:get_string("owner")
return owner == "" or owner == player:get_player_name()
end
minetest.register_node("moremesecons_commandblock:commandblock_off", {
description = "Craftable Command Block",
tiles = {"moremesecons_commandblock_off.png"},
groups = {cracky=2, mesecon_effector_off=1},
on_construct = construct,
after_place_node = after_place,
on_receive_fields = receive_fields,
can_dig = can_dig,
sounds = default.node_sound_stone_defaults(),
mesecons = {effector = {
action_on = commandblock_action_on
}}
})
minetest.register_node("moremesecons_commandblock:commandblock_on", {
tiles = {"moremesecons_commandblock_on.png"},
groups = {cracky=2, mesecon_effector_on=1, not_in_creative_inventory=1},
light_source = 10,
drop = "moremesecons_commandblock:commandblock_off",
on_construct = construct,
after_place_node = after_place,
on_receive_fields = receive_fields,
can_dig = can_dig,
sounds = default.node_sound_stone_defaults(),
mesecons = {effector = {
action_off = commandblock_action_off
}}
})
minetest.register_craft({
output = "moremesecons_commandblock:commandblock_off",
recipe = {
{"group:mesecon_conductor_craftable","default:mese_crystal","group:mesecon_conductor_craftable"},
{"default:mese_crystal","group:mesecon_conductor_craftable","default:mese_crystal"},
{"group:mesecon_conductor_craftable","default:mese_crystal","group:mesecon_conductor_craftable"}
}
})

Binary file not shown.

After

Width:  |  Height:  |  Size: 150 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 150 B

View File

@ -0,0 +1,2 @@
mesecons
craft_guide?

View File

@ -0,0 +1,81 @@
local nodebox = {
type = "fixed",
fixed = {{-8/16, -8/16, -8/16, 8/16, -7/16, 8/16 }},
}
local function signalchanger_get_output_rules(node)
local rules = {{x=-1, y=0, z=0}}
for i = 0, node.param2 do
rules = mesecon.rotate_rules_left(rules)
end
return rules
end
local function signalchanger_get_input_rules(node)
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"}}
for i = 0, node.param2 do
rules = mesecon.rotate_rules_left(rules)
end
return rules
end
local update = function(pos, node, link, newstate)
local meta = minetest.get_meta(pos)
meta:set_int(link.name, newstate == "on" and 1 or 0)
local input_on = meta:get_int("input_on") == 1
local input_off = meta:get_int("input_off") == 1
local input_signal = meta:get_int("input_signal") == 1
if input_on then
minetest.swap_node(pos, {name = "moremesecons_conductor_signalchanger:conductor_signalchanger_on", param2 = node.param2})
elseif input_off then
mesecon.receptor_off(pos, signalchanger_get_output_rules(node))
minetest.swap_node(pos, {name = "moremesecons_conductor_signalchanger:conductor_signalchanger_off", param2 = node.param2})
end
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
mesecon.receptor_on(pos, signalchanger_get_output_rules(node))
else
mesecon.receptor_off(pos, signalchanger_get_output_rules(node))
end
end
mesecon.register_node("moremesecons_conductor_signalchanger:conductor_signalchanger", {
description = "Conductor Signal Changer",
inventory_image = "moremesecons_conductor_signalchanger_off.png",
groups = {dig_immediate = 2},
paramtype = "light",
paramtype2 = "facedir",
drawtype = "nodebox",
selection_box = nodebox,
node_box = nodebox,
},{
groups = {dig_immediate = 2},
mesecons = {
receptor = {
rules = signalchanger_get_output_rules
},
effector = {
rules = signalchanger_get_input_rules,
action_change = update
},
},
tiles = {"moremesecons_conductor_signalchanger_off.png"},
},{
groups = {dig_immediate = 2, not_in_creative_inventory = 1},
mesecons = {
receptor = {
rules = signalchanger_get_output_rules,
},
effector = {
rules = signalchanger_get_input_rules,
action_change = update,
},
},
tiles = {"moremesecons_conductor_signalchanger_on.png"},
})
minetest.register_craft({
output = "moremesecons_conductor_signalchanger:conductor_signalchanger_off",
recipe = {{"group:mesecon_conductor_craftable","moremesecons_signalchanger:signalchanger_off"}}
})

Binary file not shown.

After

Width:  |  Height:  |  Size: 161 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 158 B

View File

@ -0,0 +1,2 @@
mesecons
craft_guide?

View File

@ -0,0 +1,95 @@
local function dual_delayer_get_input_rules(node)
local rules = {{x=1, y=0, z=0}}
for i = 0, node.param2 do
rules = mesecon.rotate_rules_left(rules)
end
return rules
end
local function dual_delayer_get_output_rules(node)
local rules = {{x=0, y=0, z=1}, {x=0, y=0, z=-1}}
for i = 0, node.param2 do
rules = mesecon.rotate_rules_left(rules)
end
return rules
end
local dual_delayer_activate = function(pos, node)
mesecon.receptor_on(pos, {dual_delayer_get_output_rules(node)[1]}) -- Turn on the port 1
minetest.swap_node(pos, {name = "moremesecons_dual_delayer:dual_delayer_10", param2 = node.param2})
minetest.after(0.4, function(pos, node)
mesecon.receptor_on(pos, {dual_delayer_get_output_rules(node)[2]}) -- Turn on the port 2
minetest.swap_node(pos, {name = "moremesecons_dual_delayer:dual_delayer_11", param2 = node.param2})
end, pos, node)
end
local dual_delayer_deactivate = function(pos, node, link)
mesecon.receptor_off(pos, {dual_delayer_get_output_rules(node)[2]}) -- Turn off the port 2
minetest.swap_node(pos, {name = "moremesecons_dual_delayer:dual_delayer_10", param2 = node.param2})
minetest.after(0.4, function(pos, node)
mesecon.receptor_off(pos, {dual_delayer_get_output_rules(node)[1]}) -- Turn off the port 1
minetest.swap_node(pos, {name = "moremesecons_dual_delayer:dual_delayer_00", param2 = node.param2})
end, pos, node)
end
for n,i in pairs({{0,0},{1,0},{1,1}}) do
local i1,i2 = unpack(i)
local groups = {dig_immediate = 2}
if n ~= 1 then
groups.not_in_creative_inventory = 1
end
local top_texture = "^moremesecons_dual_delayer_overlay.png^[makealpha:255,126,126"
if i1 == i2 then
if i1 == 0 then
top_texture = "mesecons_wire_off.png"..top_texture
else
top_texture = "mesecons_wire_on.png"..top_texture
end
else
local pre = "mesecons_wire_off.png^[lowpart:50:mesecons_wire_on.png^[transformR"
if i1 == 0 then
pre = pre.. 90
else
pre = pre.. 270
end
top_texture = pre..top_texture
end
minetest.register_node("moremesecons_dual_delayer:dual_delayer_"..i1 ..i2, {
description = "Dual Delayer",
drop = "moremesecons_dual_delayer:dual_delayer_00",
inventory_image = top_texture,
wield_image = top_texture,
paramtype = "light",
paramtype2 = "facedir",
drawtype = "nodebox",
node_box = {
type = "fixed",
fixed = {{-6/16, -8/16, -8/16, 6/16, -7/16, 1/16 },
{-8/16, -8/16, 1/16, -6/16, -7/16, -1/16},
{8/16, -8/16, -1/16, 6/16, -7/16, 1/16}}
},
groups = groups,
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"},
mesecons = {
receptor = {
state = mesecon.state.off,
rules = dual_delayer_get_output_rules
},
effector = {
rules = dual_delayer_get_input_rules,
action_on = dual_delayer_activate,
action_off = dual_delayer_deactivate
}
}
})
end
minetest.register_craft({
type = "shapeless",
output = "moremesecons_dual_delayer:dual_delayer_00 2",
recipe = {"mesecons_delayer:delayer_off_1", "mesecons_delayer:delayer_off_1"}
})

Binary file not shown.

After

Width:  |  Height:  |  Size: 129 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 91 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 189 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 77 B

View File

@ -0,0 +1,2 @@
mesecons
craft_guide?

View File

@ -0,0 +1,141 @@
-- Entity detector
-- Detects entitys in a certain radius
-- The radius can be changes by right-click (by default 6)
local function make_formspec(meta)
meta:set_string("formspec", "size[9,5]" ..
"field[0.3, 0;9,2;scanname;Coma-separated list of the names (itemstring) of entities to scan for (empty for any):;${scanname}]"..
"field[0.3,1.5;4,2;digiline_channel;Digiline Channel (optional):;${digiline_channel}]"..
"field[0.3,3;2,2;radius;Detection radius:;${radius}]"..
"button_exit[3.5,3.5;2,3;;Save]")
end
local function object_detector_make_formspec(pos)
make_formspec(minetest.get_meta(pos))
end
local function object_detector_on_receive_fields(pos, _, fields, player)
if not fields.scanname
or not fields.digiline_channel
or minetest.is_protected(pos, player:get_player_name()) then
return
end
local meta = minetest.get_meta(pos)
meta:set_string("scanname", fields.scanname)
meta:set_string("digiline_channel", fields.digiline_channel)
local r = tonumber(fields.radius)
if r then
meta:set_int("radius", r)
end
end
-- returns true if entity was found, false if not
local object_detector_scan = function (pos)
local meta = minetest.get_meta(pos)
local scanname = meta:get_string("scanname")
local scan_all = scanname == ""
local scan_names = scanname:split(',')
local radius = meta:get_int("radius")
if radius == 0 then
radius = 6
end
for _,obj in pairs(minetest.get_objects_inside_radius(pos, radius)) do
if not obj:is_player() then
local luaentity = obj:get_luaentity()
local isname = luaentity.name
if isname then
if scan_all then
return true
end
for _, name in ipairs(scan_names) do
if isname == name or (isname == "__builtin:item" and luaentity.itemstring == name) then
return true
end
end
end
end
end
return false
end
-- set entity name when receiving a digiline signal on a specific channel
local object_detector_digiline = {
effector = {
action = function (pos, node, channel, msg)
local meta = minetest.get_meta(pos)
local active_channel = meta:get_string("digiline_channel")
if channel ~= active_channel then
return
end
meta:set_string("scanname", msg)
if meta:get_string("formspec") ~= "" then
make_formspec(meta)
end
end,
}
}
minetest.register_node("moremesecons_entity_detector:entity_detector_off", {
tiles = {"default_steel_block.png", "default_steel_block.png", "moremesecons_entity_detector_off.png"},
paramtype = "light",
walkable = true,
groups = {cracky=3},
description="Entity Detector",
mesecons = {receptor = {
state = mesecon.state.off,
rules = mesecon.rules.pplate
}},
on_construct = object_detector_make_formspec,
on_receive_fields = object_detector_on_receive_fields,
sounds = default.node_sound_stone_defaults(),
digiline = object_detector_digiline
})
minetest.register_node("moremesecons_entity_detector:entity_detector_on", {
tiles = {"default_steel_block.png", "default_steel_block.png", "moremesecons_entity_detector_on.png"},
paramtype = "light",
walkable = true,
groups = {cracky=3,not_in_creative_inventory=1},
drop = 'moremesecons_entity_detector:entity_detector_off',
mesecons = {receptor = {
state = mesecon.state.on,
rules = mesecon.rules.pplate
}},
on_construct = object_detector_make_formspec,
on_receive_fields = object_detector_on_receive_fields,
sounds = default.node_sound_stone_defaults(),
digiline = object_detector_digiline
})
minetest.register_craft({
output = 'moremesecons_entity_detector:entity_detector_off',
recipe = {
{"default:mese_crystal_fragment"},
{"mesecons_detector:object_detector_off"}
}
})
minetest.register_abm({
nodenames = {"moremesecons_entity_detector:entity_detector_off"},
interval = 1.0,
chance = 1,
action = function(pos)
if object_detector_scan(pos) then
minetest.swap_node(pos, {name = "moremesecons_entity_detector:entity_detector_on"})
mesecon.receptor_on(pos, mesecon.rules.pplate)
end
end,
})
minetest.register_abm({
nodenames = {"moremesecons_entity_detector:entity_detector_on"},
interval = 1.0,
chance = 1,
action = function(pos)
if not object_detector_scan(pos) then
minetest.swap_node(pos, {name = "moremesecons_entity_detector:entity_detector_off"})
mesecon.receptor_off(pos, mesecon.rules.pplate)
end
end,
})

Binary file not shown.

After

Width:  |  Height:  |  Size: 554 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 549 B

View File

@ -0,0 +1,3 @@
mesecons
fire
craft_guide?

View File

@ -0,0 +1,48 @@
local function add_back_igniter(pos)
local name = minetest.get_node(pos).name
if name == "moremesecons_igniter:igniter" then
-- this should not happen
minetest.log("error", "[moremesecons_igniter] igniter is already back")
return
end
if name == "ignore" then
-- in case of unloaded chunk
minetest.get_voxel_manip():read_from_map(pos, pos)
name = minetest.get_node(pos).name
end
if name == "air"
or name == "fire:basic_flame" then
minetest.set_node(pos, {name="moremesecons_igniter:igniter"})
else
-- drop it as item if something took place there in the 0.8 seconds
pos.y = pos.y+1
minetest.add_item(pos, "moremesecons_igniter:igniter")
pos.y = pos.y-1
end
end
local function igniter_on(pos)
minetest.set_node(pos, {name="fire:basic_flame"})
minetest.after(0.8, add_back_igniter, pos)
end
minetest.register_node("moremesecons_igniter:igniter", {
description = "Igniter",
paramtype = "light",
tiles = {"moremesecons_igniter.png"},
groups = {cracky=3},
mesecons = {
effector = {
action_on = igniter_on
}}
})
minetest.register_craft({
output = "moremesecons_igniter:igniter",
recipe = { {"default:torch"},
{"default:mese_crystal_fragment"},}
})

Binary file not shown.

After

Width:  |  Height:  |  Size: 696 B

View File

@ -0,0 +1,3 @@
mesecons
mesecons_torch
default

View File

@ -0,0 +1,104 @@
local function induction_transmitter_get_input_rules(node)
-- All horizontal rules, except the output
local rules = {
{x=-1,y=0,z=0},
{x=1,y=0,z=0},
{x=0,y=0,z=-1},
{x=0,y=0,z=1}
}
for i, r in ipairs(rules) do
if vector.equals(r, minetest.facedir_to_dir(node.param2)) then
table.remove(rules, i)
end
end
return rules
end
local function induction_transmitter_get_output_rules(node)
return {vector.multiply(minetest.facedir_to_dir(node.param2), 2)}
end
local function induction_transmitter_get_virtual_output_rules(node)
return {minetest.facedir_to_dir(node.param2)}
end
local function act(pos, node, state)
minetest.swap_node(pos, {name = "moremesecons_induction_transmitter:induction_transmitter_"..state, param2 = node.param2})
local dir = minetest.facedir_to_dir(node.param2)
local target_pos = vector.add(pos, vector.multiply(dir, 2))
local target_node = minetest.get_node(target_pos)
if mesecon.is_effector(target_node.name) then
-- Switch on an aside node, so it sends a signal to the target node
local aside_rule = mesecon.effector_get_rules(target_node)[1]
if not aside_rule then
return
end
mesecon["receptor_"..state](vector.add(target_pos, aside_rule), {vector.multiply(aside_rule, -1)})
elseif mesecon.is_conductor(target_node.name) then
-- Switch on the conductor itself
mesecon["receptor_"..state](target_pos, mesecon.conductor_get_rules(target_node))
end
end
mesecon.register_node("moremesecons_induction_transmitter:induction_transmitter", {
description = "Induction Transmitter",
drawtype = "nodebox",
paramtype = "light",
paramtype2 = "facedir",
node_box = {
type = "fixed",
fixed = {
{-0.5, -0.5, 0.125, 0.5, 0.5, 0.5},
{-0.375, -0.375, -0.1875, 0.375, 0.375, 0.125},
{-0.25, -0.25, -0.5, 0.25, 0.25, -0.1875},
}
},
selection_box = {
type = "fixed",
fixed = {
{-0.5, -0.5, 0.125, 0.5, 0.5, 0.5},
{-0.375, -0.375, -0.1875, 0.375, 0.375, 0.125},
{-0.25, -0.25, -0.5, 0.25, 0.25, -0.1875},
},
},
}, {
tiles = {"default_mese_block.png"},
groups = {cracky = 3},
mesecons = {
receptor = {
state = mesecon.state.off,
rules = induction_transmitter_get_output_rules
},
effector = {
rules = induction_transmitter_get_input_rules,
action_on = function(pos, node)
act(pos, node, "on")
end
}
}
}, {
light_source = 5,
tiles = {"default_mese_block.png^[brighten"},
groups = {cracky = 3, not_in_creative_inventory = 1},
mesecons = {
receptor = {
state = mesecon.state.on,
rules = induction_transmitter_get_output_rules
},
effector = {
rules = induction_transmitter_get_input_rules,
action_off = function(pos, node)
act(pos, node, "off")
end
}
}
})
minetest.register_craft({
output = "moremesecons_induction_transmitter:induction_transmitter_off",
recipe = {
{"default:mese_crystal_fragment", "mesecons_torch:mesecon_torch_on", "default:mese_crystal_fragment"},
{"", "default:mese_crystal_fragment", ""}
}
})

View File

@ -0,0 +1,2 @@
mesecons
craft_guide?

View File

@ -0,0 +1,84 @@
local injector_controller_get_output_rules = function(node)
local rules = {{x = 0, y = 0, z = 1}}
for i = 0, node.param2 do
rules = mesecon.rotate_rules_left(rules)
end
return rules
end
local injector_controller_get_input_rules = function(node)
local rules = {{x = 0, y = 0, z = -1},
{x = 1, y = 0, z = 0},
{x = -1, y = 0, z = 0}}
for i = 0, node.param2 do
rules = mesecon.rotate_rules_left(rules)
end
return rules
end
local start_timer = function(pos)
local timer = minetest.get_node_timer(pos)
timer:start(1)
end
local stop_timer = function(pos, node)
local timer = minetest.get_node_timer(pos)
timer:stop()
mesecon.receptor_off(pos, injector_controller_get_output_rules(node))
minetest.swap_node(pos, {name="moremesecons_injector_controller:injector_controller_off", param2=node.param2})
end
local on_timer = function(pos)
local node = minetest.get_node(pos)
if(mesecon.flipstate(pos, node) == "on") then
mesecon.receptor_on(pos, injector_controller_get_output_rules(node))
else
mesecon.receptor_off(pos, injector_controller_get_output_rules(node))
end
start_timer(pos)
end
mesecon.register_node("moremesecons_injector_controller:injector_controller", {
description="Injector Controller",
drawtype = "nodebox",
inventory_image = "moremesecons_injector_controller_off.png",
paramtype = "light",
paramtype2 = "facedir",
node_box = {
type = "fixed",
fixed = {{-8/16, -8/16, -8/16, 8/16, -7/16, 8/16 }},
},
on_timer = on_timer,
},{
tiles = {"moremesecons_injector_controller_off.png", "moremesecons_injector_controller_side.png", "moremesecons_injector_controller_side.png"},
groups = {dig_immediate=2},
mesecons = {
receptor = {
state = mesecon.state.off,
rules = injector_controller_get_output_rules
},
effector = {
rules = injector_controller_get_input_rules,
action_on = start_timer,
action_off = stop_timer,
}
}
},{
tiles = {"moremesecons_injector_controller_on.png", "moremesecons_injector_controller_side.png", "moremesecons_injector_controller_side.png"},
groups = {dig_immediate=2, not_in_creative_inventory=1},
mesecons = {
receptor = {
state = mesecon.state.on,
rules = injector_controller_get_output_rules
},
effector = {
rules = injector_controller_get_input_rules,
action_off = stop_timer,
action_on = start_timer,
}
}
})
minetest.register_craft({
output = "moremesecons_injector_controller:injector_controller_off",
recipe = {{"mesecons_blinkyplant:blinky_plant_off","mesecons_gates:and_off"}}
})

Binary file not shown.

After

Width:  |  Height:  |  Size: 127 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 127 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 B

View File

@ -0,0 +1,3 @@
mesecons
moremesecons_utils
craft_guide?

View File

@ -0,0 +1,143 @@
-- see wireless jammer
local get = vector.get_data_from_pos
local set = vector.set_data_to_pos
local remove = vector.remove_data_from_pos
local storage = minetest.get_mod_storage()
local jammers = minetest.deserialize(storage:get_string("jammers")) or {}
local function update_mod_storage()
storage:set_string("jammers", minetest.serialize(jammers))
end
local function add_jammer(pos)
if get(jammers, pos.z,pos.y,pos.x) then
return
end
set(jammers, pos.z,pos.y,pos.x, true)
update_mod_storage()
end
local function remove_jammer(pos)
remove(jammers, pos.z,pos.y,pos.x)
update_mod_storage()
end
local function is_jammed(pos)
local JAMMER_MAX_DISTANCE = moremesecons.setting("jammer", "max_distance", 10, 1)
local pz,py,px = vector.unpack(pos)
for z,yxs in pairs(jammers) do
if math.abs(pz-z) <= JAMMER_MAX_DISTANCE then
for y,xs in pairs(yxs) do
if math.abs(py-y) <= JAMMER_MAX_DISTANCE then
for x in pairs(xs) do
if math.abs(px-x) <= JAMMER_MAX_DISTANCE
and (px-x)^2+(py-y)^2+(pz-z)^2 <= JAMMER_MAX_DISTANCE^2 then
return true
end
end
end
end
end
end
return false
end
minetest.after(0, function() -- After loading all mods, override some functions
local jammed
local actual_node_get = mesecon.get_node_force
local function temp_node_get(pos, ...)
local node = actual_node_get(pos, ...)
if jammed == nil
and node then
jammed = is_jammed(pos)
end
return node
end
local actual_is_conductor_off = mesecon.is_conductor_off
local function temp_is_conductor_off(...)
if jammed then
-- go to the next elseif, there's is_effector
return
end
local v = actual_is_conductor_off(...)
if v then
-- it continues to the next frontier
jammed = nil
end
return v
end
local actual_is_effector = mesecon.is_effector
local function temp_is_effector(...)
local abort_here = jammed
-- the last elseif before continuing, jammed needs to be nil then
jammed = nil
if abort_here then
return
end
return actual_is_effector(...)
end
local actual_turnon = mesecon.turnon
function mesecon.turnon(...)
--set those to the temporary functions
mesecon.get_node_force = temp_node_get
mesecon.is_conductor_off = temp_is_conductor_off
mesecon.is_effector = temp_is_effector
actual_turnon(...)
mesecon.get_node_force = actual_node_get
mesecon.is_conductor_off = actual_is_conductor_off
mesecon.is_effector = actual_is_effector
-- safety
jammed = nil
end
end)
mesecon.register_node("moremesecons_jammer:jammer", {
description = "Mesecons Jammer",
paramtype = "light",
},{
tiles = {"moremesecons_jammer_off.png"},
groups = {dig_immediate=2},
mesecons = {effector = {
action_on = function(pos)
add_jammer(pos)
minetest.sound_play("moremesecons_jammer", {pos = pos})
minetest.swap_node(pos, {name="moremesecons_jammer:jammer_on"})
end
}},
},{
tiles = {"moremesecons_jammer_on.png"},
groups = {dig_immediate=2, not_in_creative_inventory=1},
mesecons = {effector = {
action_off = function(pos)
remove_jammer(pos)
minetest.swap_node(pos, {name="moremesecons_jammer:jammer_off"})
end
}},
on_destruct = remove_jammer,
on_construct = add_jammer,
})
minetest.register_craft({
output = "moremesecons_jammer:jammer_off",
recipe = {{"group:mesecon_conductor_craftable", "default:mese", "group:mesecon_conductor_craftable"},
{"", "moremesecons_wireless:jammer_off", ""}}
})
if moremesecons.setting("jammer", "enable_lbm", false) then
minetest.register_lbm({
name = "moremesecons_jammer:add_jammer",
nodenames = {"moremesecons_jammer:jammer_on"},
run_at_every_load = true,
action = add_jammer
})
end

Binary file not shown.

After

Width:  |  Height:  |  Size: 100 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 112 B

View File

@ -0,0 +1,2 @@
mesecons
moremesecons_utils

View File

@ -0,0 +1,145 @@
local md5 = dofile(minetest.get_modpath(minetest.get_current_modname()).."/md5_lua/md5.lua")
local storage = minetest.get_mod_storage()
local hash_table = minetest.deserialize(storage:get_string("hash_table")) or {}
local function set_md5(pos, code)
vector.set_data_to_pos(hash_table, pos.z,pos.y,pos.x, md5.sum(code))
storage:set_string("hash_table", minetest.serialize(hash_table))
end
local function check_md5(pos, code)
local stored_sum = vector.get_data_from_pos(hash_table, pos.z,pos.y,pos.x)
if not stored_sum then
-- Legacy
set_md5(pos, code)
return true
end
if md5.sum(code) ~= stored_sum then
return false
end
return true
end
local function make_formspec(meta, pos)
local code = meta:get_string("code")
local errmsg = minetest.formspec_escape(meta:get_string("errmsg"))
meta:set_string("formspec",
"size[10,8;]" ..
"textarea[0.5,0.5;10,7;code;Code;"..code.."]" ..
"label[0.1,7;"..errmsg.."]" ..
"button_exit[4,7.5;2,1;submit;Submit]")
end
minetest.register_node("moremesecons_luablock:luablock", {
description = "Lua Block",
tiles = {"moremesecons_luablock.png"},
groups = {cracky = 2},
on_place = function(itemstack, placer, pointed_thing)
local under = pointed_thing.under
local node = minetest.get_node(under)
local udef = minetest.registered_nodes[node.name]
if udef and udef.on_rightclick and
not (placer and placer:get_player_control().sneak) then
return udef.on_rightclick(under, node, placer, itemstack,
pointed_thing) or itemstack
end
local pos
if minetest.registered_items[minetest.get_node(under).name].buildable_to then
pos = under
else
pos = pointed_thing.above
end
local name = placer:get_player_name()
if minetest.is_protected(pos, name) and
not minetest.check_player_privs(name, {protection_bypass = true}) then
minetest.record_protection_violation(pos, name)
return itemstack
end
if not minetest.check_player_privs(name, {server = true}) then
minetest.chat_send_player(name, "You can't use a LuaBlock without the server privilege.")
return itemstack
end
local node_def = minetest.registered_nodes[minetest.get_node(pos).name]
if not node_def or not node_def.buildable_to then
return itemstack
end
minetest.set_node(pos, {name = "moremesecons_luablock:luablock"})
local meta = minetest.get_meta(pos)
meta:set_string("owner", name)
meta:set_string("infotext", "LuaBlock owned by " .. name)
make_formspec(meta, pos)
if not (creative and creative.is_enabled_for
and creative.is_enabled_for(placer:get_player_name())) then
itemstack:take_item()
end
return itemstack
end,
on_receive_fields = function(pos, form_name, fields, sender)
if not fields.submit then
return
end
local name = sender:get_player_name()
local meta = minetest.get_meta(pos)
if name ~= meta:get_string("owner") then
minetest.chat_send_player(name, "You don't own this LuaBlock.")
return
end
if not minetest.check_player_privs(name, {server = true}) then
minetest.chat_send_player(name, "You can't use a LuaBlock without the server privilege.")
return
end
meta:set_string("code", fields.code)
set_md5(pos, fields.code)
make_formspec(meta, pos)
end,
can_dig = function(pos, player)
local meta = minetest.get_meta(pos)
return meta:get_string("owner") == player:get_player_name()
end,
mesecons = {effector = {
action_on = function(npos, node)
local meta = minetest.get_meta(npos)
local code = meta:get_string("code")
if code == "" then
return
end
if not check_md5(npos, code) then
minetest.log("warning", "[moremesecons_luablock] Code of LuaBlock at pos "..minetest.pos_to_string(npos).." does not match with its md5 checksum!")
return
end
-- We do absolutely no check there.
-- There is no limitation in the number of instruction the LuaBlock can execute
-- or the usage it can make of loops.
-- It is executed in the global namespace.
-- Remember: *The LuaBlock is highly dangerous and should be manipulated cautiously!*
local func, err = loadstring(code)
if not func then
meta:set_string("errmsg", err)
make_formspec(meta, pos)
return
end
-- Set the "pos" global
local old_pos = pos -- In case there's already an existing "pos" global
pos = table.copy(npos)
local good, err = pcall(func)
pos = old_pos
if not good then -- Runtime error
meta:set_string("errmsg", err)
make_formspec(meta, pos)
return
end
meta:set_string("errmsg", "")
make_formspec(meta, pos)
end
}}
})

View File

@ -0,0 +1,34 @@
language: python
sudo: false
env:
- LUA="lua=5.1"
- LUA="lua=5.2"
- LUA="lua=5.3"
- LUA="luajit=2.0"
- LUA="luajit=2.1"
before_install:
- pip install hererocks
- hererocks lua_install -r^ --$LUA
- export PATH=$PATH:$PWD/lua_install/bin # Add directory with all installed binaries to PATH
install:
- luarocks install busted
- luarocks install luacov
- luarocks install luacov-coveralls
script:
- busted --verbose --coverage
after_success:
- luacov-coveralls --exclude $TRAVIS_BUILD_DIR/lua_install
branches:
except:
- gh-pages
notifications:
email:
on_success: change
on_failure: always

View File

@ -0,0 +1,5 @@
# 1.1.0
* Fixes error with long strings in Lua 5.1 (@pgimeno)
* Adds incremental mode (@pgimeno)

View File

@ -0,0 +1,20 @@
Copyright (c) 2013 Enrique García Cota + Adam Baldwin + hanzao + Equi 4 Software
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@ -0,0 +1,55 @@
md5.lua [![Build Status](https://travis-ci.org/kikito/md5.lua.svg)](https://travis-ci.org/kikito/md5.lua)
=========================================================================================================
This pure-Lua module computes md5 in Lua 5.1, Lua 5.2 and LuaJIT, using native bit-manipulation libraries when available, and falling back to table-based manipulation of integers in 5.1.
It implements md5.sum and md5.sumhex like the [kernel project md5 package](http://www.keplerproject.org/md5/), but it's done completely in Lua, with no dependencies on other libs or C files.
Usage
=====
Simple example:
local md5 = require 'md5'
local md5_as_data = md5.sum(message) -- returns raw bytes
local md5_as_hex = md5.sumhexa(message) -- returns a hex string
local md5_as_hex2 = md5.tohex(md5_as_data) -- returns the same string as md5_as_hex
Incremental example (for computing md5 of streams, or big files which have to be loaded in chunks - new since 1.1.0):
local m = md5.new()
m:update('some bytes')
m:update('some more bytes')
m:update('etc')
return md5.tohex(m:finish())
Credits
=======
This is a cleanup of an implementation by Adam Baldwin - https://gist.github.com/evilpacket/3647908
Which in turn was a mix of the bitwise lib, http://luaforge.net/projects/bit/ by hanzhao (`abrash_han - at - hotmail.com`),
and http://equi4.com/md5/md5calc.lua, by Equi 4 Software.
Lua 5.2 and LuaJIT compatibility by [Positive07](https://github.com/kikito/md5.lua/pull/2)
A very important fix and the incremental variant by [pgimeno](https://github.com/kikito/md5.lua/pull/10)
License
=======
This library, as well as all the previous ones in which is based, is released under the MIT license (See license file for details).
Specs
=====
The specs for this library are implemented with [busted](http://ovinelabs.com/busted/). In order to run them, install busted and then:
cd path/to/where/the/spec/folder/is
busted

View File

@ -0,0 +1,396 @@
local md5 = {
_VERSION = "md5.lua 1.1.0",
_DESCRIPTION = "MD5 computation in Lua (5.1-3, LuaJIT)",
_URL = "https://github.com/kikito/md5.lua",
_LICENSE = [[
MIT LICENSE
Copyright (c) 2013 Enrique García Cota + Adam Baldwin + hanzao + Equi 4 Software
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
]]
}
-- bit lib implementions
local char, byte, format, rep, sub =
string.char, string.byte, string.format, string.rep, string.sub
local bit_or, bit_and, bit_not, bit_xor, bit_rshift, bit_lshift
local ok, bit = pcall(require, 'bit')
if ok then
bit_or, bit_and, bit_not, bit_xor, bit_rshift, bit_lshift = bit.bor, bit.band, bit.bnot, bit.bxor, bit.rshift, bit.lshift
else
ok, bit = pcall(require, 'bit32')
if ok then
bit_not = bit.bnot
local tobit = function(n)
return n <= 0x7fffffff and n or -(bit_not(n) + 1)
end
local normalize = function(f)
return function(a,b) return tobit(f(tobit(a), tobit(b))) end
end
bit_or, bit_and, bit_xor = normalize(bit.bor), normalize(bit.band), normalize(bit.bxor)
bit_rshift, bit_lshift = normalize(bit.rshift), normalize(bit.lshift)
else
local function tbl2number(tbl)
local result = 0
local power = 1
for i = 1, #tbl do
result = result + tbl[i] * power
power = power * 2
end
return result
end
local function expand(t1, t2)
local big, small = t1, t2
if(#big < #small) then
big, small = small, big
end
-- expand small
for i = #small + 1, #big do
small[i] = 0
end
end
local to_bits -- needs to be declared before bit_not
bit_not = function(n)
local tbl = to_bits(n)
local size = math.max(#tbl, 32)
for i = 1, size do
if(tbl[i] == 1) then
tbl[i] = 0
else
tbl[i] = 1
end
end
return tbl2number(tbl)
end
-- defined as local above
to_bits = function (n)
if(n < 0) then
-- negative
return to_bits(bit_not(math.abs(n)) + 1)
end
-- to bits table
local tbl = {}
local cnt = 1
local last
while n > 0 do
last = n % 2
tbl[cnt] = last
n = (n-last)/2
cnt = cnt + 1
end
return tbl
end
bit_or = function(m, n)
local tbl_m = to_bits(m)
local tbl_n = to_bits(n)
expand(tbl_m, tbl_n)
local tbl = {}
for i = 1, #tbl_m do
if(tbl_m[i]== 0 and tbl_n[i] == 0) then
tbl[i] = 0
else
tbl[i] = 1
end
end
return tbl2number(tbl)
end
bit_and = function(m, n)
local tbl_m = to_bits(m)
local tbl_n = to_bits(n)
expand(tbl_m, tbl_n)
local tbl = {}
for i = 1, #tbl_m do
if(tbl_m[i]== 0 or tbl_n[i] == 0) then
tbl[i] = 0
else
tbl[i] = 1
end
end
return tbl2number(tbl)
end
bit_xor = function(m, n)
local tbl_m = to_bits(m)
local tbl_n = to_bits(n)
expand(tbl_m, tbl_n)
local tbl = {}
for i = 1, #tbl_m do
if(tbl_m[i] ~= tbl_n[i]) then
tbl[i] = 1
else
tbl[i] = 0
end
end
return tbl2number(tbl)
end
bit_rshift = function(n, bits)
local high_bit = 0
if(n < 0) then
-- negative
n = bit_not(math.abs(n)) + 1
high_bit = 0x80000000
end
local floor = math.floor
for i=1, bits do
n = n/2
n = bit_or(floor(n), high_bit)
end
return floor(n)
end
bit_lshift = function(n, bits)
if(n < 0) then
-- negative
n = bit_not(math.abs(n)) + 1
end
for i=1, bits do
n = n*2
end
return bit_and(n, 0xFFFFFFFF)
end
end
end
-- convert little-endian 32-bit int to a 4-char string
local function lei2str(i)
local f=function (s) return char( bit_and( bit_rshift(i, s), 255)) end
return f(0)..f(8)..f(16)..f(24)
end
-- convert raw string to big-endian int
local function str2bei(s)
local v=0
for i=1, #s do
v = v * 256 + byte(s, i)
end
return v
end
-- convert raw string to little-endian int
local function str2lei(s)
local v=0
for i = #s,1,-1 do
v = v*256 + byte(s, i)
end
return v
end
-- cut up a string in little-endian ints of given size
local function cut_le_str(s,...)
local o, r = 1, {}
local args = {...}
for i=1, #args do
table.insert(r, str2lei(sub(s, o, o + args[i] - 1)))
o = o + args[i]
end
return r
end
local swap = function (w) return str2bei(lei2str(w)) end
-- An MD5 mplementation in Lua, requires bitlib (hacked to use LuaBit from above, ugh)
-- 10/02/2001 jcw@equi4.com
local CONSTS = {
0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee,
0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,
0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,
0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa,
0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8,
0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed,
0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a,
0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c,
0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05,
0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,
0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039,
0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,
0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391,
0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476
}
local f=function (x,y,z) return bit_or(bit_and(x,y),bit_and(-x-1,z)) end
local g=function (x,y,z) return bit_or(bit_and(x,z),bit_and(y,-z-1)) end
local h=function (x,y,z) return bit_xor(x,bit_xor(y,z)) end
local i=function (x,y,z) return bit_xor(y,bit_or(x,-z-1)) end
local z=function (ff,a,b,c,d,x,s,ac)
a=bit_and(a+ff(b,c,d)+x+ac,0xFFFFFFFF)
-- be *very* careful that left shift does not cause rounding!
return bit_or(bit_lshift(bit_and(a,bit_rshift(0xFFFFFFFF,s)),s),bit_rshift(a,32-s))+b
end
local function transform(A,B,C,D,X)
local a,b,c,d=A,B,C,D
local t=CONSTS
a=z(f,a,b,c,d,X[ 0], 7,t[ 1])
d=z(f,d,a,b,c,X[ 1],12,t[ 2])
c=z(f,c,d,a,b,X[ 2],17,t[ 3])
b=z(f,b,c,d,a,X[ 3],22,t[ 4])
a=z(f,a,b,c,d,X[ 4], 7,t[ 5])
d=z(f,d,a,b,c,X[ 5],12,t[ 6])
c=z(f,c,d,a,b,X[ 6],17,t[ 7])
b=z(f,b,c,d,a,X[ 7],22,t[ 8])
a=z(f,a,b,c,d,X[ 8], 7,t[ 9])
d=z(f,d,a,b,c,X[ 9],12,t[10])
c=z(f,c,d,a,b,X[10],17,t[11])
b=z(f,b,c,d,a,X[11],22,t[12])
a=z(f,a,b,c,d,X[12], 7,t[13])
d=z(f,d,a,b,c,X[13],12,t[14])
c=z(f,c,d,a,b,X[14],17,t[15])
b=z(f,b,c,d,a,X[15],22,t[16])
a=z(g,a,b,c,d,X[ 1], 5,t[17])
d=z(g,d,a,b,c,X[ 6], 9,t[18])
c=z(g,c,d,a,b,X[11],14,t[19])
b=z(g,b,c,d,a,X[ 0],20,t[20])
a=z(g,a,b,c,d,X[ 5], 5,t[21])
d=z(g,d,a,b,c,X[10], 9,t[22])
c=z(g,c,d,a,b,X[15],14,t[23])
b=z(g,b,c,d,a,X[ 4],20,t[24])
a=z(g,a,b,c,d,X[ 9], 5,t[25])
d=z(g,d,a,b,c,X[14], 9,t[26])
c=z(g,c,d,a,b,X[ 3],14,t[27])
b=z(g,b,c,d,a,X[ 8],20,t[28])
a=z(g,a,b,c,d,X[13], 5,t[29])
d=z(g,d,a,b,c,X[ 2], 9,t[30])
c=z(g,c,d,a,b,X[ 7],14,t[31])
b=z(g,b,c,d,a,X[12],20,t[32])
a=z(h,a,b,c,d,X[ 5], 4,t[33])
d=z(h,d,a,b,c,X[ 8],11,t[34])
c=z(h,c,d,a,b,X[11],16,t[35])
b=z(h,b,c,d,a,X[14],23,t[36])
a=z(h,a,b,c,d,X[ 1], 4,t[37])
d=z(h,d,a,b,c,X[ 4],11,t[38])
c=z(h,c,d,a,b,X[ 7],16,t[39])
b=z(h,b,c,d,a,X[10],23,t[40])
a=z(h,a,b,c,d,X[13], 4,t[41])
d=z(h,d,a,b,c,X[ 0],11,t[42])
c=z(h,c,d,a,b,X[ 3],16,t[43])
b=z(h,b,c,d,a,X[ 6],23,t[44])
a=z(h,a,b,c,d,X[ 9], 4,t[45])
d=z(h,d,a,b,c,X[12],11,t[46])
c=z(h,c,d,a,b,X[15],16,t[47])
b=z(h,b,c,d,a,X[ 2],23,t[48])
a=z(i,a,b,c,d,X[ 0], 6,t[49])
d=z(i,d,a,b,c,X[ 7],10,t[50])
c=z(i,c,d,a,b,X[14],15,t[51])
b=z(i,b,c,d,a,X[ 5],21,t[52])
a=z(i,a,b,c,d,X[12], 6,t[53])
d=z(i,d,a,b,c,X[ 3],10,t[54])
c=z(i,c,d,a,b,X[10],15,t[55])
b=z(i,b,c,d,a,X[ 1],21,t[56])
a=z(i,a,b,c,d,X[ 8], 6,t[57])
d=z(i,d,a,b,c,X[15],10,t[58])
c=z(i,c,d,a,b,X[ 6],15,t[59])
b=z(i,b,c,d,a,X[13],21,t[60])
a=z(i,a,b,c,d,X[ 4], 6,t[61])
d=z(i,d,a,b,c,X[11],10,t[62])
c=z(i,c,d,a,b,X[ 2],15,t[63])
b=z(i,b,c,d,a,X[ 9],21,t[64])
return bit_and(A+a,0xFFFFFFFF),bit_and(B+b,0xFFFFFFFF),
bit_and(C+c,0xFFFFFFFF),bit_and(D+d,0xFFFFFFFF)
end
----------------------------------------------------------------
local function md5_update(self, s)
self.pos = self.pos + #s
s = self.buf .. s
for ii = 1, #s - 63, 64 do
local X = cut_le_str(sub(s,ii,ii+63),4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4)
assert(#X == 16)
X[0] = table.remove(X,1) -- zero based!
self.a,self.b,self.c,self.d = transform(self.a,self.b,self.c,self.d,X)
end
self.buf = sub(s, math.floor(#s/64)*64 + 1, #s)
return self
end
local function md5_finish(self)
local msgLen = self.pos
local padLen = 56 - msgLen % 64
if msgLen % 64 > 56 then padLen = padLen + 64 end
if padLen == 0 then padLen = 64 end
local s = char(128) .. rep(char(0),padLen-1) .. lei2str(bit_and(8*msgLen, 0xFFFFFFFF)) .. lei2str(math.floor(msgLen/0x20000000))
md5_update(self, s)
assert(self.pos % 64 == 0)
return lei2str(self.a) .. lei2str(self.b) .. lei2str(self.c) .. lei2str(self.d)
end
----------------------------------------------------------------
function md5.new()
return { a = CONSTS[65], b = CONSTS[66], c = CONSTS[67], d = CONSTS[68],
pos = 0,
buf = '',
update = md5_update,
finish = md5_finish }
end
function md5.tohex(s)
return format("%08x%08x%08x%08x", str2bei(sub(s, 1, 4)), str2bei(sub(s, 5, 8)), str2bei(sub(s, 9, 12)), str2bei(sub(s, 13, 16)))
end
function md5.sum(s)
return md5.new():update(s):finish()
end
function md5.sumhexa(s)
return md5.tohex(md5.sum(s))
end
return md5

View File

@ -0,0 +1,21 @@
package = "md5"
version = "1.0-0"
source = {
url = "https://github.com/kikito/md5.lua/archive/v1.0.0.tar.gz",
dir = "md5.lua-1.0.0"
}
description = {
summary = "MD5 sum in pure Lua, with no C and no external dependencies",
detailed = "This pure-Lua module computes md5 in Lua 5.1, Lua 5.2 and LuaJIT, using native bit-manipulation libraries when available, and falling back to table-based manipulation of integers in 5.1",
homepage = "https://github.com/kikito/md5.lua",
license = "MIT"
}
dependencies = {
"lua >= 5.1"
}
build = {
type = "builtin",
modules = {
md5 = "md5.lua"
}
}

View File

@ -0,0 +1,21 @@
package = "md5"
version = "1.0-1"
source = {
url = "https://github.com/kikito/md5.lua/archive/v1.0.1.tar.gz",
dir = "md5.lua-1.0.1"
}
description = {
summary = "MD5 sum in pure Lua, with no C and no external dependencies",
detailed = "This pure-Lua module computes md5 in Lua 5.1, Lua 5.2 and LuaJIT, using native bit-manipulation libraries when available, and falling back to table-based manipulation of integers in 5.1",
homepage = "https://github.com/kikito/md5.lua",
license = "MIT"
}
dependencies = {
"lua >= 5.1"
}
build = {
type = "builtin",
modules = {
md5 = "md5.lua"
}
}

View File

@ -0,0 +1,21 @@
package = "md5"
version = "1.0-2"
source = {
url = "https://github.com/kikito/md5.lua/archive/v1.0.2.tar.gz",
dir = "md5.lua-1.0.2"
}
description = {
summary = "MD5 sum in pure Lua, with no C and no external dependencies",
detailed = "This pure-Lua module computes md5 in Lua 5.1, Lua 5.2 and LuaJIT, using native bit-manipulation libraries when available, and falling back to table-based manipulation of integers in 5.1",
homepage = "https://github.com/kikito/md5.lua",
license = "MIT"
}
dependencies = {
"lua >= 5.1"
}
build = {
type = "builtin",
modules = {
md5 = "md5.lua"
}
}

View File

@ -0,0 +1,21 @@
package = "md5"
version = "1.1-0"
source = {
url = "https://github.com/kikito/md5.lua/archive/v1.1.0.tar.gz",
dir = "md5.lua-1.1.0"
}
description = {
summary = "MD5 sum in pure Lua, with no C and no external dependencies",
detailed = "This pure-Lua module computes md5 in Lua 5.1, Lua 5.2 and LuaJIT, using native bit-manipulation libraries when available, and falling back to table-based manipulation of integers in 5.1",
homepage = "https://github.com/kikito/md5.lua",
license = "MIT"
}
dependencies = {
"lua >= 5.1"
}
build = {
type = "builtin",
modules = {
md5 = "md5.lua"
}
}

View File

@ -0,0 +1,40 @@
local md5 = require('md5')
local function hex2bin(hex)
local result, _ = hex:gsub('..', function(hexval)
return string.char(tonumber(hexval, 16))
end)
return result
end
describe('md5', function()
describe('md5.sumhexa', function()
it('works', function()
assert.equal(md5.sumhexa("asdf"), '912ec803b2ce49e4a541068d495ab570')
assert.equal(md5.sumhexa('The quick brown fox jumps over the lazy dog'), '9e107d9d372bb6826bd81d3542a419d6')
assert.equal(md5.sumhexa('The quick brown fox jumps over the lazy dog.'), 'e4d909c290d0fb1ca068ffaddf22cbd0')
assert.equal(md5.sumhexa(''), 'd41d8cd98f00b204e9800998ecf8427e')
assert.equal(md5.sumhexa(('1'):rep(824)), 'a126fd3611ab8d9b7e8a3384e2fa78a0')
assert.equal(md5.sumhexa(('1'):rep(1528)), '3750b6a29d923b633e05d6ae76895664')
local state = md5.new()
state:update('Hello')
state:update(', World!')
assert.equal(md5.tohex(state:finish()), '65a8e27d8879283831b664bd8b7f0ad4')
end)
end)
describe('md5.sum', function()
it('works', function()
assert.equal(md5.sum("asdf"), hex2bin '912ec803b2ce49e4a541068d495ab570')
assert.equal(md5.sum('The quick brown fox jumps over the lazy dog'), hex2bin '9e107d9d372bb6826bd81d3542a419d6')
assert.equal(md5.sum('The quick brown fox jumps over the lazy dog.'), hex2bin 'e4d909c290d0fb1ca068ffaddf22cbd0')
assert.equal(md5.sum(''), hex2bin 'd41d8cd98f00b204e9800998ecf8427e')
assert.equal(md5.sum(('1'):rep(824)), hex2bin 'a126fd3611ab8d9b7e8a3384e2fa78a0')
assert.equal(md5.sum(('1'):rep(1528)), hex2bin '3750b6a29d923b633e05d6ae76895664')
local state = md5.new()
state:update('Hello')
state:update(', World!')
assert.equal(state:finish(), hex2bin '65a8e27d8879283831b664bd8b7f0ad4')
end)
end)
end)

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

View File

@ -0,0 +1,2 @@
mesecons
moremesecons_utils

View File

@ -0,0 +1,358 @@
--[[
vector_extras there: https://github.com/HybridDog/vector_extras
]]
local templates = {MoreMesecons = {
logic = [[-- AND
port.a = pin.b and pin.c
-- OR
port.a = pin.b or pin.c
-- NOT
port.a = not pin.b
-- NAND
port.a = not (pin.b and pin.c)
-- NOR
port.a = not (pin.b or pin.c)
-- XOR
port.a = pin.b ~= pin.c
-- XNOR / NXOR
port.a = pin.b == pin.c]],
digilinesth = [[digiline_send(channel, msg)
if event.type == "digiline" then
print(event.channel)
print(event.msg)
end]],
clock = [[number_of_oscillations = 0 -- 0 for infinity
interval = 1
input_port = "A"
output_port = "C"
if event.type == "on" and event.pin.name == input_port and not mem.running then
if not mem.counter then
mem.counter = 0
end
mem.running = true
port[string.lower(output_port)] = true
interrupt(interval)
mem.counter = mem.counter + 1
elseif event.type == "off" and event.pin.name == input_port and mem.running and number_of_oscillations == 0 then
mem.running = false
mem.counter = 0
elseif event.type == "interrupt" then
if not port[string.lower(output_port)] and mem.running then
port[string.lower(output_port)] = true
interrupt(interval)
mem.counter = mem.counter + 1
else
port[string.lower(output_port)] = false
if mem.counter < number_of_oscillations or number_of_oscillations == 0 and mem.running then
interrupt(interval)
else
mem.running = false
mem.counter = 0
end
end
end]],
counter = [[counter_limit = 5
output_time = 0.5
input_port = "A"
output_port = "C"
if event.type == "on" and event.pin.name == input_port then
if not mem.counter then
mem.counter = 0
end
mem.counter = mem.counter + 1
if mem.counter >= counter_limit then
port[string.lower(output_port)] = true
interrupt(output_time)
mem.counter = 0
end
elseif event.type == "interrupt" then
port[string.lower(output_port)] = false
end]]
}}
local file_path = minetest.get_worldpath().."/MoreMesecons_lctt"
-- load templates from a compressed file
local templates_file = io.open(file_path, "rb")
if templates_file then
local templates_raw = templates_file:read("*all")
io.close(templates_file)
if templates_raw
and templates_raw ~= "" then
for name,t in pairs(minetest.deserialize(minetest.decompress(templates_raw))) do
templates[name] = t
end
end
end
-- the save function
local function save_to_file()
local templates_file = io.open(file_path, "w")
if not templates_file then
minetest.log("error", "[MoreMesecons] Could not open file for saving!")
return
end
local player_templates = table.copy(templates)
player_templates.MoreMesecons = nil
templates_file:write(minetest.compress(minetest.serialize(player_templates)))
io.close(templates_file)
end
-- save doesn't save more than every 10s to disallow spamming
local saving
local function save()
if saving then
return
end
saving = true
minetest.after(16, function()
save_to_file()
saving = false
end)
end
minetest.register_on_shutdown(function()
if saving then
save_to_file()
end
end)
-- used for the dropdown formspec element
local function fill_formspec_dropdown_list(t, selected)
local it,num = {},1
for i in pairs(t) do
it[num] = i
num = num+1
end
num = num-1
table.sort(it)
local txt = ""
local selected_id
for i = 1,num do
local t = it[i]
if not selected_id
and t == selected then
selected_id = i
end
txt = txt..t -- add available indices
if i ~= num then
txt = txt..","
end
end
return txt..";"..(selected_id or 1).."]"
--spec = string.sub(spec, 1, -2)
end
local pdata = {}
local function get_selection_formspec(pname, selected_template)
-- templates might be removed by someone while changing sth in formspec
local pl_templates = templates[pname]
if not pl_templates then
pname = next(templates)
pl_templates = templates[pname]
end
local template_code = pl_templates[selected_template]
if not template_code then
selected_template = next(pl_templates)
template_code = pl_templates[selected_template]
end
local spec = "size[10,10]"..
-- show available players, field player_name, current player name is the selected one
"dropdown[0,0;5;player_name;"..
fill_formspec_dropdown_list(templates, pname)..
-- show templates of pname
"dropdown[5,0;5;template_name;"..
fill_formspec_dropdown_list(pl_templates, selected_template)..
-- show selected template
"textarea[0,1;10.5,8.5;template_code;template code:;"..minetest.formspec_escape(template_code).."]"..
-- save name
"field[5,9.5;5,0;save_name;savename;"..selected_template.."]"..
"button[0,10;2,0;button;set]"..
"button[2,10;2,0;button;add]"..
"button[5,10;2,0;button;save]"
return spec
end
-- tests if the node is a luacontroller
local function is_luacontroller(pos)
if not pos then
return false
end
return string.match(minetest.get_node(pos).name, "mesecons_luacontroller:luacontroller%d%d%d%d")
end
-- do not localize the function directly here to support possible overwritten luacontrollers
local luac_def = minetest.registered_nodes["mesecons_luacontroller:luacontroller0000"]
local function set_luacontroller_code(pos, code, sender)
luac_def.on_receive_fields(pos, nil, {code=code, program=""}, sender)
end
minetest.register_tool("moremesecons_luacontroller_tool:lctt", {
description = "luacontroller template tool",
inventory_image = "moremesecons_luacontroller_tool.png",
on_use = function(_, player, pt)
if not player
or not pt then
return
end
local pname = player:get_player_name()
local pos = pt.under
if not is_luacontroller(pos) then
minetest.chat_send_player(pname, "You can use the luacontroller template tool only on luacontroller nodes.")
return
end
pdata[pname] = pdata[pname] or {
pos = pos,
player_name = pname,
template_name = next(templates[pname] or templates[next(templates)]),
}
minetest.show_formspec(pname, "moremesecons:luacontroller_tool", get_selection_formspec(pdata[pname].player_name, pdata[pname].template_name))
end,
})
--[[ Luacontroller reset_meta function, by Jeija
local function reset_meta(pos, code, errmsg)
local meta = minetest.get_meta(pos)
meta:set_string("code", code)
code = minetest.formspec_escape(code or "")
errmsg = minetest.formspec_escape(errmsg or "")
meta:set_string("formspec", "size[10,8]"..
"background[-0.2,-0.25;10.4,8.75;jeija_luac_background.png]"..
"textarea[0.2,0.6;10.2,5;code;;"..code.."]"..
"image_button[3.75,6;2.5,1;jeija_luac_runbutton.png;program;]"..
"image_button_exit[9.72,-0.25;0.425,0.4;jeija_close_window.png;exit;]"..
"label[0.1,5;"..errmsg.."]")
meta:set_int("heat", 0)
meta:set_int("luac_id", math.random(1, 65535))
end--]]
-- used to avoid possibly crashes
local function get_code_or_nil(pname, player_name, template_name)
local player_templates = templates[player_name]
if not player_templates then
minetest.chat_send_player(pname, "error: "..player_name.." doesn't have templates now")
return
end
local code = player_templates[template_name]
if not code then
minetest.chat_send_player(pname, "error: "..template_name.." doesn't exist now")
return
end
return code
end
minetest.register_on_player_receive_fields(function(player, formname, fields)
if formname ~= "moremesecons:luacontroller_tool"
or fields.quit
or not player then
return
end
--minetest.chat_send_all(dump(fields))
local pname = player:get_player_name()
if fields.player_name
and fields.player_name ~= pdata[pname].player_name then
-- show available templates of that player
minetest.show_formspec(pname, "moremesecons:luacontroller_tool",
get_selection_formspec(fields.player_name, pdata[pname].template_name)
)
pdata[pname].player_name = fields.player_name
return
end
if fields.template_name
and fields.template_name ~= pdata[pname].template_name then
-- show selected template of that player
minetest.show_formspec(pname, "moremesecons:luacontroller_tool",
get_selection_formspec(pdata[pname].player_name, fields.template_name)
)
pdata[pname].template_name = fields.template_name
return
end
local pos = pdata[pname].pos
if not is_luacontroller(pos) then
-- this can happen
return
end
local meta = minetest.get_meta(pos)
if fields.button == "set" then
-- replace the code of the luacontroller with the template
local code = get_code_or_nil(pname, fields.player_name, fields.template_name)
if code then
set_luacontroller_code(pos, code, player)
minetest.chat_send_player(pname, "code set to template at "..minetest.pos_to_string(pos))
end
return
end
if fields.button == "add" then
-- add the template to the end of the code of the luacontroller
local code = get_code_or_nil(pname, fields.player_name, fields.template_name)
if code then
set_luacontroller_code(pos, meta:get_string("code").."\r"..code, player)
minetest.chat_send_player(pname, "code added to luacontroller at "..minetest.pos_to_string(pos))
end
return
end
if fields.button == "save" then
-- save the template, when you try to change others' templates, yours become changed
local savename = fields.template_name
if fields.save_name
and fields.save_name ~= ""
and fields.save_name ~= savename then
savename = minetest.formspec_escape(fields.save_name)
end
local code = fields.template_code
if not code then
minetest.chat_send_player(pname, "error: template code missing")
return
end
templates[pname] = templates[pname] or {}
if code == "" then
templates[pname][savename] = nil
if not next(templates[pname]) then
templates[pname] = nil
end
minetest.chat_send_player(pname, "template removed")
save()
return
end
code = minetest.formspec_escape(code)
if templates[pname][savename] == code then
minetest.chat_send_player(pname, "template not saved because it didn't change")
return
end
templates[pname][savename] = code
save()
minetest.chat_send_player(pname, "template "..pname.."/"..savename.." saved")
return
end
end)

Binary file not shown.

After

Width:  |  Height:  |  Size: 290 B

View File

@ -0,0 +1,4 @@
mesecons
mesecons_materials
moremesecons_utils
craft_guide?

View File

@ -0,0 +1,62 @@
local kill_nearest_player = function(pos)
local MAX_DISTANCE = moremesecons.setting("playerkiller", "max_distance", 8, 1)
-- Search the nearest player
local nearest
local min_distance = MAX_DISTANCE
for index, player in pairs(minetest.get_connected_players()) do
local distance = vector.distance(pos, player:getpos())
if distance < min_distance then
min_distance = distance
nearest = player
end
end
if not nearest then
-- no nearby player
return
end
local owner = minetest.get_meta(pos):get_string("owner")
if not owner then
-- maybe some mod placed it
return
end
if owner == nearest:get_player_name() then
-- don't kill the owner !
return
end
-- And kill him
nearest:set_hp(0)
minetest.log("action", "Player "..owner.." kills player "..nearest.." using a MoreMesecons Player Killer.")
end
minetest.register_craft({
output = "moremesecons_playerkiller:playerkiller",
recipe = { {"","default:mese",""},
{"default:mese","mesecons_detector:object_detector_off","default:mese"},
{"","default:mese",""}}
})
minetest.register_node("moremesecons_playerkiller:playerkiller", {
description = "Player Killer",
tiles = {"moremesecons_playerkiller_top.png", "moremesecons_playerkiller_top.png", "moremesecons_playerkiller_side.png"},
paramtype = "light",
walkable = true,
groups = {cracky=3},
mesecons = {effector = {
state = mesecon.state.off,
action_on = kill_nearest_player
}},
after_place_node = function(pos, placer)
if not placer then
return
end
local meta = minetest.get_meta(pos)
meta:set_string("owner", placer:get_player_name())
meta:set_string("infotext", "PlayerKiller owned by " .. meta:get_string("owner"))
end,
sounds = default.node_sound_stone_defaults(),
})

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

View File

@ -0,0 +1,2 @@
mesecons
craft_guide?

View File

@ -0,0 +1,81 @@
local nodebox = {
type = "fixed",
fixed = {{-8/16, -8/16, -8/16, 8/16, -7/16, 8/16 }},
}
local function signalchanger_get_output_rules(node)
local rules = {{x=-1, y=0, z=0},
{x=1, y=0, z=0}}
for i = 0, node.param2 do
rules = mesecon.rotate_rules_left(rules)
end
return rules
end
local function signalchanger_get_input_rules(node)
local rules = {{x=0, y=0, z=-1, name="input_on"}, {x=0, y=0, z=1, name="input_off"}}
for i = 0, node.param2 do
rules = mesecon.rotate_rules_left(rules)
end
return rules
end
local update = function(pos, node, link, newstate)
local meta = minetest.get_meta(pos)
meta:set_int(link.name, newstate == "on" and 1 or 0)
local input_on = meta:get_int("input_on") == 1
local input_off = meta:get_int("input_off") == 1
if input_on then
mesecon.receptor_on(pos, {signalchanger_get_output_rules(node)[1]})
mesecon.receptor_off(pos, {signalchanger_get_output_rules(node)[2]})
minetest.swap_node(pos, {name = "moremesecons_signalchanger:signalchanger_on", param2 = node.param2})
elseif input_off then
mesecon.receptor_off(pos, {signalchanger_get_output_rules(node)[1]})
mesecon.receptor_on(pos, {signalchanger_get_output_rules(node)[2]})
minetest.swap_node(pos, {name = "moremesecons_signalchanger:signalchanger_off", param2 = node.param2})
end
end
mesecon.register_node("moremesecons_signalchanger:signalchanger", {
description = "Signal Changer",
inventory_image = "moremesecons_signalchanger_off.png",
groups = {dig_immediate = 2},
paramtype = "light",
paramtype2 = "facedir",
drawtype = "nodebox",
selection_box = nodebox,
node_box = nodebox,
},{
groups = {dig_immediate = 2},
mesecons = {
receptor = {
rules = signalchanger_get_output_rules
},
effector = {
rules = signalchanger_get_input_rules,
action_change = update
},
},
tiles = {"moremesecons_signalchanger_off.png"},
on_construct = function(pos)
local node = minetest.get_node(pos)
mesecon.receptor_on(pos, {signalchanger_get_output_rules(node)[2]})
end
},{
groups = {dig_immediate = 2, not_in_creative_inventory = 1},
mesecons = {
receptor = {
rules = signalchanger_get_output_rules,
},
effector = {
rules = signalchanger_get_input_rules,
action_change = update,
},
},
tiles = {"moremesecons_signalchanger_on.png"},
})
minetest.register_craft({
output = "moremesecons_signalchanger:signalchanger_off",
recipe = {{"group:mesecon_conductor_craftable","moremesecons_switchtorch:switchtorch_off","group:mesecon_conductor_craftable"}}
})

Binary file not shown.

After

Width:  |  Height:  |  Size: 158 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 159 B

View File

@ -0,0 +1,2 @@
mesecons
craft_guide?

View File

@ -0,0 +1,129 @@
local rotate_torch_rules = function (rules, param2)
if param2 == 5 then
return mesecon.rotate_rules_right(rules)
elseif param2 == 2 then
return mesecon.rotate_rules_right(mesecon.rotate_rules_right(rules)) --180 degrees
elseif param2 == 4 then
return mesecon.rotate_rules_left(rules)
elseif param2 == 1 then
return mesecon.rotate_rules_down(rules)
elseif param2 == 0 then
return mesecon.rotate_rules_up(rules)
else
return rules
end
end
local output_rules = {
{x = 1, y = 0, z = 0},
{x = 0, y = 0, z = 1},
{x = 0, y = 0, z =-1},
{x = 0, y = 1, z = 0},
{x = 0, y =-1, z = 0}
}
local torch_get_output_rules = function(node)
return rotate_torch_rules(output_rules, node.param2)
end
local input_rules = {
{x = -2, y = 0, z = 0},
{x = -1, y = 1, z = 0}
}
local torch_get_input_rules = function(node)
return rotate_torch_rules(input_rules, node.param2)
end
minetest.register_craft({
output = "moremesecons_switchtorch:switchtorch_off 4",
recipe = {
{"group:stick"},
{"group:mesecon_conductor_craftable"},
}
})
local torch_selectionbox =
{
type = "wallmounted",
wall_top = {-0.1, 0.5-0.6, -0.1, 0.1, 0.5, 0.1},
wall_bottom = {-0.1, -0.5, -0.1, 0.1, -0.5+0.6, 0.1},
wall_side = {-0.5, -0.1, -0.1, -0.5+0.6, 0.1, 0.1},
}
minetest.register_node("moremesecons_switchtorch:switchtorch_off", {
description = "Switch Torch",
inventory_image = "moremesecons_switchtorch_on.png",
wield_image = "moremesecons_switchtorch_on.png",
drawtype = "torchlike",
tiles = {"moremesecons_switchtorch_off.png", "moremesecons_switchtorch_off_ceiling.png", "moremesecons_switchtorch_off_side.png"},
paramtype = "light",
walkable = false,
paramtype2 = "wallmounted",
selection_box = torch_selectionbox,
groups = {dig_immediate = 3},
mesecons = {receptor = {
state = mesecon.state.off,
rules = torch_get_output_rules
}},
on_construct = function(pos)-- For EndPower
minetest.get_meta(pos):set_int("EndPower", 1) -- 1 for true, 0 for false
end
})
minetest.register_node("moremesecons_switchtorch:switchtorch_on", {
drawtype = "torchlike",
tiles = {"moremesecons_switchtorch_on.png", "moremesecons_switchtorch_on_ceiling.png", "moremesecons_switchtorch_on_side.png"},
paramtype = "light",
sunlight_propagates = true,
walkable = false,
paramtype2 = "wallmounted",
selection_box = torch_selectionbox,
groups = {dig_immediate=3, not_in_creative_inventory = 1},
drop = "moremesecons_switchtorch:switchtorch_off",
light_source = LIGHT_MAX-5,
mesecons = {receptor = {
state = mesecon.state.on,
rules = torch_get_output_rules
}},
})
minetest.register_abm({
nodenames = {"moremesecons_switchtorch:switchtorch_off","moremesecons_switchtorch:switchtorch_on"},
interval = 1,
chance = 1,
action = function(pos, node)
local is_powered = false
for _, rule in ipairs(torch_get_input_rules(node)) do
local src = vector.add(pos, rule)
if mesecon.is_power_on(src) then
is_powered = true
break
end
end
local meta = minetest.get_meta(pos)
if meta:get_int("EndPower") == 0 == is_powered then
return
end
if not is_powered then
meta:set_int("EndPower", 1)
return
end
if node.name == "moremesecons_switchtorch:switchtorch_on" then
minetest.swap_node(pos, {name = "moremesecons_switchtorch:switchtorch_off", param2 = node.param2})
mesecon.receptor_off(pos, torch_get_output_rules(node))
elseif node.name == "moremesecons_switchtorch:switchtorch_off" then
minetest.swap_node(pos, {name = "moremesecons_switchtorch:switchtorch_on", param2 = node.param2})
mesecon.receptor_on(pos, torch_get_output_rules(node))
end
meta:set_int("EndPower", 0)
end
})
-- Param2 Table (Block Attached To)
-- 5 = z-1
-- 3 = x-1
-- 4 = z+1
-- 2 = x+1
-- 0 = y+1
-- 1 = y-1

Binary file not shown.

After

Width:  |  Height:  |  Size: 119 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 111 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 110 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 116 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 118 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 B

View File

@ -0,0 +1,3 @@
mesecons
moremesecons_utils
craft_guide?

View File

@ -0,0 +1,108 @@
local storage = minetest.get_mod_storage()
local teleporters = minetest.deserialize(storage:get_string("teleporters")) or {}
local teleporters_rids = minetest.deserialize(storage:get_string("teleporters_rids")) or {}
local jammers = minetest.deserialize(storage:get_string("jammers")) or {}
local function update_mod_storage()
storage:set_string("teleporters", minetest.serialize(teleporters))
storage:set_string("teleporters_rids", minetest.serialize(teleporters_rids))
end
local function register(pos)
if not vector.get_data_from_pos(teleporters_rids, pos.z,pos.y,pos.x) then
table.insert(teleporters, pos)
vector.set_data_to_pos(teleporters_rids, pos.z,pos.y,pos.x, #teleporters)
update_mod_storage()
end
end
local function teleport_nearest(pos)
local MAX_TELEPORTATION_DISTANCE = moremesecons.setting("teleporter", "max_t2t_distance", 50, 1)
local MAX_PLAYER_DISTANCE = moremesecons.setting("teleporter", "max_p2t_distance", 25, 1)
-- Search for the nearest player
local nearest = nil
local min_distance = MAX_PLAYER_DISTANCE
local players = minetest.get_connected_players()
for index, player in pairs(players) do
local distance = vector.distance(pos, player:getpos())
if distance <= min_distance then
min_distance = distance
nearest = player
end
end
if not nearest then
-- If there is no nearest player (maybe too far away...)
return
end
-- Search for the corresponding teleporter and teleport
if not minetest.registered_nodes["moremesecons_teleporter:teleporter"] then return end
local newpos = {}
local min_distance = MAX_TELEPORTATION_DISTANCE
for i = 1, #teleporters do
if minetest.get_node(teleporters[i]).name == "moremesecons_teleporter:teleporter" then
local tel_pos
if teleporters[i].y == pos.y and teleporters[i].x == pos.x and teleporters[i].z ~= pos.z then
tel_pos = {x=teleporters[i].x, y=teleporters[i].y+1, z=teleporters[i].z}
elseif teleporters[i].z == pos.z and teleporters[i].x == pos.x and teleporters[i].y ~= pos.y then
tel_pos = {x=teleporters[i].x, y=teleporters[i].y+1, z=teleporters[i].z}
elseif teleporters[i].z == pos.z and teleporters[i].y == pos.y and teleporters[i].x ~= pos.x then
tel_pos = {x=teleporters[i].x, y=teleporters[i].y+1, z=teleporters[i].z}
end
if tel_pos then
local distance = vector.distance(tel_pos, pos)
if distance <= min_distance then
min_distance = distance
newpos = tel_pos
end
end
end
end
if not newpos.x then
newpos = {x=pos.x, y=pos.y+1, z=pos.z} -- If newpos doesn't exist, teleport on the current teleporter
end
nearest:moveto(newpos)
minetest.log("action", "Player "..nearest:get_player_name().." was teleported using a MoreMesecons Teleporter.")
end
minetest.register_craft({
output = "moremesecons_teleporter:teleporter 2",
recipe = {{"default:diamond","group:stick","default:mese"}}
})
minetest.register_node("moremesecons_teleporter:teleporter", {
tiles = {"moremesecons_teleporter.png"},
paramtype = "light",
walkable = true,
groups = {cracky=3},
description="Teleporter",
mesecons = {effector = {
state = mesecon.state.off,
action_on = teleport_nearest
}},
sounds = default.node_sound_stone_defaults(),
on_construct = register,
on_destruct = function(pos)
local RID = vector.get_data_from_pos(teleporters_rids, pos.z,pos.y,pos.x)
if RID then
table.remove(teleporters, RID)
vector.remove_data_from_pos(teleporters_rids, pos.z,pos.y,pos.x)
update_mod_storage()
end
end,
})
if moremesecons.setting("teleporter", "enable_lbm", false) then
minetest.register_lbm({
name = "moremesecons_teleporter:add_teleporter",
nodenames = {"moremesecons_teleporter:teleporter"},
run_at_every_load = true,
action = register
})
end

Binary file not shown.

After

Width:  |  Height:  |  Size: 513 B

View File

@ -0,0 +1,2 @@
mesecons
craft_guide?

View File

@ -0,0 +1,127 @@
local timegate_get_output_rules = function(node)
local rules = {{x = 0, y = 0, z = 1}}
for i = 0, node.param2 do
rules = mesecon.rotate_rules_left(rules)
end
return rules
end
local timegate_get_input_rules = function(node)
local rules = {{x = 0, y = 0, z = -1}}
for i = 0, node.param2 do
rules = mesecon.rotate_rules_left(rules)
end
return rules
end
-- Functions that are called after the delay time
local function timegate_activate(pos, node)
-- using a meta string allows writing the time in hexadecimals
local time = tonumber(minetest.get_meta(pos):get_string("time"))
if not time then
return
end
node.name = "moremesecons_timegate:timegate_on"
minetest.swap_node(pos, node)
mesecon.receptor_on(pos)
minetest.after(time, function(pos, node)
mesecon.receptor_off(pos)
node.name = "moremesecons_timegate:timegate_off"
minetest.swap_node(pos, node)
end, pos, node)
end
boxes = {{ -6/16, -8/16, -6/16, 6/16, -7/16, 6/16 }, -- the main slab
{ -2/16, -7/16, -4/16, 2/16, -26/64, -3/16 }, -- the jeweled "on" indicator
{ -3/16, -7/16, -3/16, 3/16, -26/64, -2/16 },
{ -4/16, -7/16, -2/16, 4/16, -26/64, 2/16 },
{ -3/16, -7/16, 2/16, 3/16, -26/64, 3/16 },
{ -2/16, -7/16, 3/16, 2/16, -26/64, 4/16 },
{ -6/16, -7/16, -6/16, -4/16, -27/64, -4/16 }, -- the timer indicator
{ -8/16, -8/16, -1/16, -6/16, -7/16, 1/16 }, -- the two wire stubs
{ 6/16, -8/16, -1/16, 8/16, -7/16, 1/16 }}
mesecon.register_node("moremesecons_timegate:timegate", {
description = "Time Gate",
drawtype = "nodebox",
inventory_image = "moremesecons_timegate_off.png",
wield_image = "moremesecons_timegate_off.png",
walkable = true,
selection_box = {
type = "fixed",
fixed = { -8/16, -8/16, -8/16, 8/16, -6/16, 8/16 },
},
node_box = {
type = "fixed",
fixed = boxes
},
paramtype = "light",
paramtype2 = "facedir",
sunlight_propagates = true,
is_ground_content = true,
sounds = default.node_sound_stone_defaults(),
on_construct = function(pos)
minetest.get_meta(pos):set_string("formspec", "field[time;time;${time}]")
end,
on_receive_fields = function(pos, _, fields, player)
if fields.time
and not minetest.is_protected(pos, player:get_player_name()) then
minetest.get_meta(pos):set_string("time", fields.time)
end
end
},{
tiles = {
"moremesecons_timegate_off.png",
"moremesecons_timegate_bottom.png",
"moremesecons_timegate_ends_off.png",
"moremesecons_timegate_ends_off.png",
"moremesecons_timegate_sides_off.png",
"moremesecons_timegate_sides_off.png"
},
groups = {bendy=2,snappy=1,dig_immediate=2},
mesecons = {
receptor =
{
state = mesecon.state.off,
rules = timegate_get_output_rules
},
effector =
{
rules = timegate_get_input_rules,
action_on = timegate_activate
}
},
},{
tiles = {
"moremesecons_timegate_on.png",
"moremesecons_timegate_bottom.png",
"moremesecons_timegate_ends_on.png",
"moremesecons_timegate_ends_on.png",
"moremesecons_timegate_sides_on.png",
"moremesecons_timegate_sides_on.png"
},
groups = {bendy=2,snappy=1,dig_immediate=2, not_in_creative_inventory=1},
mesecons = {
receptor = {
state = mesecon.state.on,
rules = timegate_get_output_rules
},
effector = {
rules = timegate_get_input_rules,
}
},
})
minetest.register_craft({
output = "moremesecons_timegate:timegate_off 2",
recipe = {
{"group:mesecon_conductor_craftable", "mesecons_delayer:delayer_off_1", "group:mesecon_conductor_craftable"},
{"group:wood","group:wood", "group:wood"},
}
})
minetest.register_alias("moremesecons_temporarygate:temporarygate_off", "moremesecons_timegate:timegate_off")
minetest.register_alias("moremesecons_temporarygate:temporarygate_on", "moremesecons_timegate:timegate_on")

Binary file not shown.

After

Width:  |  Height:  |  Size: 261 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 170 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 171 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 361 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 364 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 164 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 169 B

View File

@ -0,0 +1 @@
vector_extras?

View File

@ -0,0 +1,80 @@
moremesecons = {}
function moremesecons.setting(modname, settingname, default, min)
local setting = "moremesecons_" .. modname .. "." .. settingname
if type(default) == "boolean" then
local ret = minetest.settings:get_bool(setting)
if ret == nil then
ret = default
end
return ret
elseif type(default) == "string" then
return minetest.settings:get(setting) or default
elseif type(default) == "number" then
local ret = tonumber(minetest.settings:get(setting)) or default
if not ret then
minetest.log("warning", "[moremesecons_"..modname.."]: setting '"..setting.."' must be a number. Set to default value ("..tostring(default)..").")
ret = default
elseif ret ~= ret then -- NaN
minetest.log("warning", "[moremesecons_"..modname.."]: setting '"..setting.."' is NaN. Set to default value ("..tostring(default)..").")
ret = default
end
if min and ret < min then
minetest.log("warning", "[moremesecons_"..modname.."]: setting '"..setting.."' is under minimum value "..tostring(min)..". Set to minimum value ("..tostring(min)..").")
ret = min
end
return ret
end
end
-- Vector helpers
-- All the following functions are from the vector_extras mod (https://github.com/HybridDog/vector_extras).
-- If you enable that mod, its functions will be used instead of the ones defined below
if not vector.get_data_from_pos then
function vector.get_data_from_pos(tab, z,y,x)
local data = tab[z]
if data then
data = data[y]
if data then
return data[x]
end
end
end
end
if not vector.set_data_to_pos then
function vector.set_data_to_pos(tab, z,y,x, data)
if tab[z] then
if tab[z][y] then
tab[z][y][x] = data
return
end
tab[z][y] = {[x] = data}
return
end
tab[z] = {[y] = {[x] = data}}
end
end
if not vector.remove_data_from_pos then
function vector.remove_data_from_pos(tab, z,y,x)
if vector.get_data_from_pos(tab, z,y,x) == nil then
return
end
tab[z][y][x] = nil
if not next(tab[z][y]) then
tab[z][y] = nil
end
if not next(tab[z]) then
tab[z] = nil
end
end
end
if not vector.unpack then
function vector.unpack(pos)
return pos.z, pos.y, pos.x
end
end

View File

@ -0,0 +1,4 @@
mesecons
moremesecons_utils
digilines?
craft_guide?

View File

@ -0,0 +1,419 @@
local storage = minetest.get_mod_storage()
local wireless = minetest.deserialize(storage:get_string("wireless")) or {}
local wireless_meta = minetest.deserialize(storage:get_string("wireless_meta")) or {owners = {}, channels = {}, ids = {}}
local jammers = minetest.deserialize(storage:get_string("jammers")) or {}
local function update_mod_storage()
storage:set_string("wireless", minetest.serialize(wireless))
storage:set_string("wireless_meta", minetest.serialize(wireless_meta))
storage:set_string("jammers", minetest.serialize(jammers))
end
-- localize these functions with small names because they work fairly fast
local get = vector.get_data_from_pos
local set = vector.set_data_to_pos
local remove = vector.remove_data_from_pos
local function remove_wireless(pos)
local owner = get(wireless_meta.owners, pos.z,pos.y,pos.x)
if not owner or owner == "" then
return
end
remove(wireless_meta.owners, pos.z,pos.y,pos.x)
if not wireless[owner] or not next(wireless[owner]) then
wireless[owner] = nil
return
end
local channel = get(wireless_meta.channels, pos.z,pos.y,pos.x)
if not channel or channel == "" then
return
end
table.remove(wireless[owner][channel], get(wireless_meta.ids, pos.z,pos.y,pos.x))
if #wireless[owner][channel] == 0 then
wireless[owner][channel] = nil
if not next(wireless[owner]) then
wireless[owner] = nil
end
end
remove(wireless_meta.channels, pos.z,pos.y,pos.x)
remove(wireless_meta.ids, pos.z,pos.y,pos.x)
end
local set_channel
local function set_owner(pos, owner)
if not owner or owner == "" then
return
end
local meta = minetest.get_meta(pos)
meta:set_string("owner", owner)
set(wireless_meta.owners, pos.z,pos.y,pos.x, owner)
if not wireless[owner] then
wireless[owner] = {}
end
local channel = get(wireless_meta.channels, pos.z,pos.y,pos.x)
if channel and channel ~= "" then
if not wireless[owner][channel] then
wireless[owner][channel] = {}
end
set_channel(pos, channel)
end
meta:set_string("infotext", "Wireless owned by " .. owner .. " on " .. ((channel and channel ~= "") and "channel " .. channel or "undefined channel"))
end
function set_channel(pos, channel)
if not channel or channel == "" then
return
end
local meta = minetest.get_meta(pos)
local owner = get(wireless_meta.owners, pos.z,pos.y,pos.x)
if not owner or owner == "" then
return
end
local old_channel = get(wireless_meta.channels, pos.z,pos.y,pos.x)
if old_channel and old_channel ~= "" and old_channel ~= channel then
remove_wireless(pos)
set_owner(pos, owner)
end
meta:set_string("channel", channel)
set(wireless_meta.channels, pos.z,pos.y,pos.x, channel)
if not wireless[owner] then
wireless[owner] = {}
end
if not wireless[owner][channel] then
wireless[owner][channel] = {}
end
local id = get(wireless_meta.ids, pos.z,pos.y,pos.x)
if id then
wireless[owner][channel][id] = pos
else
table.insert(wireless[owner][channel], pos)
meta:set_int("id", #wireless[owner][channel])
set(wireless_meta.ids, pos.z,pos.y,pos.x, #wireless[owner][channel])
end
meta:set_string("infotext", "Wireless owned by " .. owner .. " on channel " .. channel)
end
local function register_wireless(pos)
local meta = minetest.get_meta(pos)
local owner = meta:get_string("owner")
if owner == "" then
return
end
set_owner(pos, owner)
local channel = meta:get_string("channel")
if channel ~= "" then
set_channel(pos, channel)
end
update_mod_storage()
end
local is_jammed
local function wireless_activate(pos)
if is_jammed(pos) then
-- jamming doesn't disallow receiving signals, only sending them
return
end
local channel = get(wireless_meta.channels, pos.z,pos.y,pos.x)
local owner = get(wireless_meta.owners, pos.z,pos.y,pos.x)
local id = get(wireless_meta.ids, pos.z,pos.y,pos.x)
if owner == "" or not wireless[owner] or channel == "" or not wireless[owner][channel] then
return
end
minetest.swap_node(pos, {name = "moremesecons_wireless:wireless_on"})
for i, wl_pos in ipairs(wireless[owner][channel]) do
if i ~= id then
minetest.swap_node(wl_pos, {name = "moremesecons_wireless:wireless_on"})
mesecon.receptor_on(wl_pos)
end
end
end
local function wireless_deactivate(pos)
if is_jammed(pos) then
return
end
local channel = get(wireless_meta.channels, pos.z,pos.y,pos.x)
local owner = get(wireless_meta.owners, pos.z,pos.y,pos.x)
local id = get(wireless_meta.ids, pos.z,pos.y,pos.x)
if owner == "" or not wireless[owner] or channel == "" or not wireless[owner][channel] then
return
end
minetest.swap_node(pos, {name = "moremesecons_wireless:wireless_off"})
for i, wl_pos in ipairs(wireless[owner][channel]) do
if i ~= id then
minetest.swap_node(wl_pos, {name = "moremesecons_wireless:wireless_off"})
mesecon.receptor_off(wl_pos)
end
end
end
local function on_digiline_receive(pos, node, channel, msg)
local setchan = minetest.get_meta(pos):get_string("channel") -- Note : the digiline channel is the same as the wireless channel. TODO: Making two different channels and a more complex formspec ?
if channel ~= setchan or is_jammed(pos) or setchan == "" then
return
end
local channel = get(wireless_meta.channels, pos.z,pos.y,pos.x)
local owner = get(wireless_meta.owners, pos.z,pos.y,pos.x)
local id = get(wireless_meta.ids, pos.z,pos.y,pos.x)
if owner == "" or not wireless[owner] or channel == "" or not wireless[owner][channel] then
return
end
for i, wl_pos in ipairs(wireless[owner][channel]) do
if i ~= id then
digiline:receptor_send(wl_pos, digiline.rules.default, channel, msg)
end
end
end
mesecon.register_node("moremesecons_wireless:wireless", {
paramtype = "light",
paramtype2 = "facedir",
description = "Wireless",
digiline = {
receptor = {},
effector = {
action = on_digiline_receive
},
},
sounds = default.node_sound_stone_defaults(),
on_construct = function(pos)
minetest.get_meta(pos):set_string("formspec", "field[channel;channel;${channel}]")
end,
on_destruct = function(pos)
remove_wireless(pos)
update_mod_storage()
mesecon.receptor_off(pos)
end,
after_place_node = function(pos, placer)
local placername = placer:get_player_name()
set_owner(pos, placer:get_player_name())
update_mod_storage()
end,
on_receive_fields = function(pos, _, fields, player)
local meta = minetest.get_meta(pos)
local playername = player:get_player_name()
local owner = meta:get_string("owner")
if not owner or owner == "" then
-- Old wireless
if not minetest.is_protected(pos, playername) then
set_owner(pos, playername)
update_mod_storage()
else
return
end
end
if playername == owner then
set_channel(pos, fields.channel)
update_mod_storage()
end
end,
}, {
tiles = {"moremesecons_wireless_off.png"},
groups = {cracky=3},
mesecons = {effector = {
action_on = wireless_activate,
}},
}, {
tiles = {"moremesecons_wireless_on.png"},
groups = {cracky=3, not_in_creative_inventory=1},
mesecons = {effector = {
action_off = wireless_deactivate
}},
})
minetest.register_alias("moremesecons_wireless:wireless", "moremesecons_wireless:wireless_off")
local jammers = {}
local function add_jammer(pos)
if get(jammers, pos.z,pos.y,pos.x) then
return
end
set(jammers, pos.z,pos.y,pos.x, true)
update_mod_storage()
end
local function remove_jammer(pos)
remove(jammers, pos.z,pos.y,pos.x)
update_mod_storage()
end
-- looks big, but should work fast
function is_jammed(pos)
local JAMMER_MAX_DISTANCE = moremesecons.setting("wireless", "jammer_max_distance", 15, 1)
local pz,py,px = vector.unpack(pos)
for z,yxs in pairs(jammers) do
if math.abs(pz-z) <= JAMMER_MAX_DISTANCE then
for y,xs in pairs(yxs) do
if math.abs(py-y) <= JAMMER_MAX_DISTANCE then
for x in pairs(xs) do
if math.abs(px-x) <= JAMMER_MAX_DISTANCE
and (px-x)^2+(py-y)^2+(pz-z)^2 <= JAMMER_MAX_DISTANCE^2 then
return true
end
end
end
end
end
end
return false
end
mesecon.register_node("moremesecons_wireless:jammer", {
description = "Wireless Jammer",
paramtype = "light",
drawtype = "nodebox",
},{
tiles = {"mesecons_wire_off.png^moremesecons_jammer_top.png", "moremesecons_jammer_bottom.png", "mesecons_wire_off.png^moremesecons_jammer_side_off.png"},
node_box = {
type = "fixed",
fixed = {
-- connection
{-1/16, -0.5, -0.5, 1/16, -7/16, 0.5},
{-0.5, -0.5, -1/16, 0.5, -7/16, 1/16},
--stabilization
{-1/16, -7/16, -1/16, 1/16, -6/16, 1/16},
-- fields
{-7/16, -6/16, -7/16, 7/16, -4/16, 7/16},
{-5/16, -4/16, -5/16, 5/16, -3/16, 5/16},
{-3/16, -3/16, -3/16, 3/16, -2/16, 3/16},
{-1/16, -2/16, -1/16, 1/16, -1/16, 1/16},
},
},
groups = {dig_immediate=2},
mesecons = {effector = {
rules = mesecon.rules.flat,
action_on = function(pos)
add_jammer(pos)
minetest.swap_node(pos, {name="moremesecons_wireless:jammer_on"})
end
}}
},{
tiles = {"mesecons_wire_on.png^moremesecons_jammer_top.png", "moremesecons_jammer_bottom.png", "mesecons_wire_on.png^moremesecons_jammer_side_on.png"},
node_box = {
type = "fixed",
fixed = {
-- connection
{-1/16, -0.5, -0.5, 1/16, -7/16, 0.5},
{-0.5, -0.5, -1/16, 0.5, -7/16, 1/16},
--stabilization
{-1/16, -7/16, -1/16, 1/16, 5/16, 1/16},
-- fields
{-7/16, -6/16, -7/16, 7/16, -4/16, 7/16},
{-5/16, -3/16, -5/16, 5/16, -1/16, 5/16},
{-3/16, 0, -3/16, 3/16, 2/16, 3/16},
{-1/16, 3/16, -1/16, 1/16, 5/16, 1/16},
},
},
groups = {dig_immediate=2, not_in_creative_inventory=1},
mesecons = {effector = {
rules = mesecon.rules.flat,
action_off = function(pos)
remove_jammer(pos)
minetest.swap_node(pos, {name="moremesecons_wireless:jammer_off"})
end
}},
on_destruct = remove_jammer,
on_construct = add_jammer,
})
minetest.register_craft({
output = "moremesecons_wireless:jammer_off",
recipe = {
{"moremesecons_wireless:wireless", "mesecons_torch:mesecon_torch_on", "moremesecons_wireless:wireless"}
}
})
minetest.register_craft({
output = "moremesecons_wireless:wireless_off 2",
recipe = {
{"group:mesecon_conductor_craftable", "", "group:mesecon_conductor_craftable"},
{"", "mesecons_torch:mesecon_torch_on", ""},
{"group:mesecon_conductor_craftable", "", "group:mesecon_conductor_craftable"},
}
})
if moremesecons.setting("wireless", "enable_lbm", false) then
minetest.register_lbm({
name = "moremesecons_wireless:add_jammer",
nodenames = {"moremesecons_wireless:jammer_on"},
run_at_every_load = true,
action = add_jammer
})
minetest.register_lbm({
name = "moremesecons_wireless:add_wireless",
nodenames = {"moremesecons_wireless:wireless"},
run_at_every_load = true,
action = register_wireless
})
end
-- Legacy
if storage and storage:get_string("wireless_rids") and storage:get_string("wireless_rids") ~= "" then
-- Upgrade mod storage!
local wireless_rids = minetest.deserialize(storage:get_string("wireless_rids"))
local old_wireless = table.copy(wireless)
wireless = {}
minetest.after(0, function(old_wireless)
-- After loading all mods, try to guess owners based on the areas mod database.
-- That won't work for all wireless. Owners of remaining wireless will be set
-- to the first player using their formspec.
if not areas then
return
end
for RID, pos in ipairs(old_wireless) do
local numerous_owners = false
local owner
for _, area in pairs(areas:getAreasAtPos(pos)) do
if owner and area.owner ~= owner then
numerous_owners = true
break
end
owner = area.owner
end
if not numerous_owners and owner then
set_owner(pos, owner)
set_channel(pos, minetest.get_meta(pos):get_string("channel"))
end
end
end, old_wireless)
-- Remove wireless_rids from storage
storage:from_table({
jammers = jammers,
wireless_meta = wireless_meta,
wireless = wireless
})
end

Binary file not shown.

After

Width:  |  Height:  |  Size: 170 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 138 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 163 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 160 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Some files were not shown because too many files have changed in this diff Show More