Compare commits

25 Commits

Author SHA1 Message Date
3c9055c723 Fix crash when doors.registered_doors isn't available 2024-10-17 11:14:04 +02:00
b46c589a38 Support doors and trapdoors from mods (#683)
* Support doors and trapdoors from mods

Removed hardcoded door names and instead now use the API of the door mod to meseconify all doors and trapdoors that have been registered after the mods are finished loading.

* indentation as described by sfan5
2024-10-16 00:27:20 +02:00
ac83dead50 mesecons_doors: Don't modify doors that are already mesecon-enabled 2024-10-08 20:30:26 +02:00
ff87cf3162 Add smoke test with engine using Docker 2024-08-26 22:03:10 +02:00
096df65cc6 Update modpack.conf 2024-08-26 22:03:10 +02:00
f718816cea Modernize readme 2024-08-16 16:45:33 +02:00
9ff3ab1007 MineClonia compat (#677) 2024-08-16 16:15:10 +02:00
368b294c70 Fix mesecons displayed as unknown(??) mod in the profiler (#679) 2024-08-16 11:37:44 +02:00
fe57adec26 Permit number type for 'distance' in digiline message again
fixes #680
2024-08-15 15:10:32 +02:00
DS
d52eac5a4a Add documentation for Microcontroller (#603) 2024-08-01 18:03:30 +02:00
e2c8a81e7b Move textures to correct dependency issue between delayer and gates (#676) 2024-08-01 18:02:20 +02:00
e71cdb6f08 Add French translation (#675) 2024-08-01 17:19:49 +02:00
0c7bb316c7 Check for digiline message field type (#670) 2024-07-02 12:32:19 +02:00
0a4651c33c Changes to torch and delayer appearance (#669)
* plantlike, x-shaped torch
* removed separate LEDs for luacontroller since already contained in base mod it depends on
* changed delayer textures to be more consistent with other gates
* Reduced the amount of textures needed for pistons with texture modifiers. Will continue to work fine with all existing texturepacks. No change in graphics.
* use luacontroller_LED instead of microcontroller_LED to prevent breaking the digistuff mod which inherits it. I hope no mods inherit microcontroller LED.
2024-06-08 13:43:47 +02:00
a82bac7b5b [mesecons_doors] Improve code quality and fix Voxelgarden support (#671)
now trapdoors are also overridden using their own function, and both
`meseconify_door` and `meseconify_trapdoor` are now ran inside loops
In the future, this could help refactor this mod entirely to not list doors
manually but parse through the `doors.registered_*` variables,
ensuring that every door works.

As a nice bonus, Voxelgarden support is fixed, and potentially so is
support for other games with exotic implementations of the doors mod. No
longer are we assuming that the existence of doors.get means that all
the trapdoors exist too; now, if the meseconify function doesn't find
their definition, it just returns without crashing.
2024-05-20 20:21:52 +02:00
cffbc33e6d Remove NaN values (#667)
NaN can cause problems (and errors) if the receiving node doesn't check for it, this PR makes it so NaN values are removed from digiline messages.
2024-03-14 19:54:19 +01:00
59780437f2 Fix 1-tick pulses causing delayers to get stuck in the on state (#663) 2024-01-22 18:29:02 +01:00
50a4bd6170 node_detector now accepts a comma-seperated list of nodes like object_detector 2024-01-13 11:05:49 +01:00
7418d5cb61 Reduce redundancy in minetest.registered_nodes lookups 2023-12-27 11:21:05 +01:00
6b42419828 Pistons can no longer push beds 2023-12-17 20:27:49 +01:00
8e30ee4113 Update mesecons_delayer.de.tr (#649)
This is a casual game, no need for formal voice.
2023-08-26 11:36:20 +02:00
b318aadd0a Translate Mesecons to German (#636) 2023-08-05 12:57:46 +02:00
fef402e88a Add string.split function (#500) 2023-06-18 21:43:53 +03:00
DS
f98ea14023 MVPS: make stoppers non-replaceable even if they are buildable_to (#545) 2023-06-18 21:21:32 +03:00
7f8758f17b Pressure plates: check for entity contact (#632) 2023-06-18 21:05:35 +03:00
128 changed files with 797 additions and 233 deletions

View File

@ -1,10 +1,10 @@
on: [push, pull_request]
name: Check & Release
name: "Check"
jobs:
lint:
runs-on: ubuntu-latest
name: "Luacheck"
steps:
- uses: actions/checkout@main
- name: apt
@ -14,9 +14,9 @@ jobs:
- name: luacheck run
run: $HOME/.luarocks/bin/luacheck ./
test:
mineunit:
runs-on: ubuntu-latest
name: "Mineunit tests"
steps:
- uses: actions/checkout@main
- name: apt

26
.github/workflows/test.yml vendored Normal file
View File

@ -0,0 +1,26 @@
on: [push, pull_request]
name: "Test"
jobs:
test:
name: "Smoke Test ${{ matrix.cfg.image }}"
runs-on: ubuntu-latest
timeout-minutes: 5
strategy:
matrix:
cfg:
- { image: 'registry.gitlab.com/minetest/minetest/server:5.0.1', mtg: false }
- { image: 'ghcr.io/minetest/minetest:5.9.0', mtg: true }
steps:
- uses: actions/checkout@main
- uses: actions/checkout@main
with:
repository: 'minetest/minetest_game'
path: ./.test/minetest_game
if: ${{ matrix.cfg.mtg }}
- name: Run tests
run: ./.test/run.sh
env:
DOCKER_IMAGE: "${{ matrix.cfg.image }}"

View File

@ -27,6 +27,8 @@ read_globals = {
"table.insert_all",
"vector",
"VoxelArea",
"mcl_dyes",
"mcl_sounds",
}
globals = {"mesecon"}

3
.test/minetest.conf Normal file
View File

@ -0,0 +1,3 @@
mg_name = singlenode
mesecon.internal_test = true
random_mod_load_order = true

31
.test/run.sh Executable file
View File

@ -0,0 +1,31 @@
#!/bin/bash
tempdir=$(mktemp -d)
confpath=$tempdir/minetest.conf
worldpath=$tempdir/world
trap 'rm -rf "$tempdir" || :' EXIT
[ -f mesecons/mod.conf ] || { echo "Must be run in modpack root folder." >&2; exit 1; }
command -v docker >/dev/null || { echo "Docker is not installed." >&2; exit 1; }
mtg=.test/minetest_game
[ -d $mtg ] || echo "A source checkout of minetest_game was not found. This can fail if your docker image does not ship a game." >&2
mkdir "$worldpath"
cp -v .test/minetest.conf "$confpath"
chmod -R 777 "$tempdir"
args=(
-v "$confpath":/etc/minetest/minetest.conf
-v "$tempdir":/var/lib/minetest/.minetest
-v "$PWD":/var/lib/minetest/.minetest/world/worldmods/mesecons
)
[ -d $mtg ] && args+=(
-v "$(realpath $mtg)":/var/lib/minetest/.minetest/games/minetest_game
)
args+=("$DOCKER_IMAGE")
[ -d $mtg ] && args+=(--gameid minetest)
docker run --rm -i "${args[@]}"
ls -la "$worldpath"
test -f "$worldpath/mesecon_actionqueue" || exit 1
exit 0

View File

@ -12,6 +12,7 @@ MESECONS by Jeija and contributors
Mezzee-what?
------------
[Mesecons](https://mesecons.net/)! They're yellow, they're conductive, and they'll add a whole new dimension to Minetest's gameplay.
Mesecons is a mod for [Minetest](https://www.minetest.net/) that implements a ton of items related to digital circuitry, such as wires, buttons, lights, and even programmable controllers. Among other things, there are also pistons, solar panels, pressure plates, and note blocks.
@ -20,15 +21,18 @@ Mesecons has a similar goal to Redstone in Minecraft, but works in its own way,
OK, I want in.
--------------
Go get it!
[DOWNLOAD IT NOW](https://github.com/minetest-mods/mesecons/archive/master.zip)
[![ContentDB](https://content.minetest.net/packages/Jeija/mesecons/shields/downloads/)](https://content.minetest.net/packages/Jeija/mesecons/)
Now go ahead and install it like any other Minetest mod. Don't know how? Check out [the wonderful page about it](https://wiki.minetest.net/Mods) over at the official Minetest Wiki. For your convenience, here's a quick summary:
Install it directly from your client by searching it in the Online Content tab.
**Or** if you've downloaded a ZIP file check out [this page](https://wiki.minetest.net/Mods) over at the official Minetest Wiki. For your convenience, here's a quick summary:
1. If Mesecons is still in a ZIP file, extract the folder inside to somewhere on the computer.
2. Make sure that when you open the folder, you can directly find `README.md` in the listing. If you just see another folder, move that folder up one level and delete the old one.
3. Open up the Minetest mods folder - usually `/mods/`. If you see the `minetest` or folder inside of that, that is your mod folder instead.
3. Open up the Minetest mods folder - called `mods`.
4. Copy the Mesecons folder into the mods folder.
Don't like some parts of Mesecons? Open up the Mesecons folder and delete the subfolder containing the mod you don't want. If you didn't want movestones, for example, all you have to do is delete the `mesecons_movestones` folder and they will no longer be available.
@ -37,21 +41,21 @@ There are no dependencies - it will work right after installing!
How do I use this thing?
------------------------
How about a [quick overview video](https://www.youtube.com/watch?v=6kmeQj6iW5k)?
Or maybe a [comprehensive reference](http://mesecons.net/items.html) is your style?
Or maybe a [comprehensive reference](https://mesecons.net/items.html) is your style?
An overview for the very newest of new beginners? How does [this one](http://uberi.mesecons.net/projects/MeseconsBasics/index.html) look?
An overview for the very newest of new beginners? How does [this one](https://uberi.mesecons.net/projects/MeseconsBasics/index.html) look?
There is also a [wiki page](https://wiki.minetest.net/Mods/Mesecons) dedicated to this mod.
Want to get more into building? Why not check out the [Mesecons Laboratory](http://uberi.mesecons.net/), a website dedicated to advanced Mesecons builders?
Want to get more into building? Why not check out the [Mesecons Laboratory](https://uberi.mesecons.net/), a website dedicated to advanced Mesecons builders?
Want to contribute to Mesecons itself? Check out the [source code](https://github.com/minetest-mods/mesecons)!
Who wrote it anyways?
---------------------
These awesome people made Mesecons possible!
These awesome people made Mesecons possible! (as of 2016)
| Contributor | Contribution |
| --------------- | -------------------------------- |
@ -72,8 +76,11 @@ These awesome people made Mesecons possible!
There are also a whole bunch of other people helping with everything from code to testing and feedback. Mesecons would also not be possible without their help!
Check out the [entire contributor list](https://github.com/minetest-mods/mesecons/graphs/contributors) on GitHub.
Alright, how can I use it?
--------------------------
All textures in this project are licensed under the CC-BY-SA 3.0 (Creative Commons Attribution-ShareAlike 3.0 Generic).
That means you can distribute and remix them as much as you want to, under the condition that you give credit to the authors and the project, and that if you remix and release them, they must be under the same or similar license to this one.

View File

@ -42,6 +42,7 @@
},
"Logic" : {
"Luacontroller" : "mesecons_luacontroller/doc/luacontroller",
"Microcontroller" : "mesecons_microcontroller/doc/microcontroler",
"FPGA" : "mesecons_fpga/doc/fpga",
"FPGA Programmer" : "mesecons_fpga/doc/programmer",
"Torch" : "mesecons_torch/doc/torch",

View File

@ -70,7 +70,17 @@ end
-- However, even that does not work in some cases, that's why we delay the time the globalsteps
-- start to be execute by 4 seconds
local m_time = 0
local resumetime = mesecon.setting("resumetime", 4)
local function globalstep_func(dtime)
-- don't even try if server has not been running for XY seconds; resumetime = time to wait
-- after starting the server before processing the ActionQueue, don't set this too low
if m_time < resumetime then
m_time = m_time + dtime
return
end
local actions = queue.actions
-- split into two categories:
-- actions_now: actions to execute now
@ -112,23 +122,7 @@ local function globalstep_func(dtime)
end
end
-- delay the time the globalsteps start to be execute by 4 seconds
do
local m_time = 0
local resumetime = mesecon.setting("resumetime", 4)
local globalstep_func_index = #minetest.registered_globalsteps + 1
minetest.register_globalstep(function(dtime)
m_time = m_time + dtime
-- don't even try if server has not been running for XY seconds; resumetime = time to wait
-- after starting the server before processing the ActionQueue, don't set this too low
if m_time < resumetime then
return
end
-- replace this globalstep function
minetest.registered_globalsteps[globalstep_func_index] = globalstep_func
end)
end
minetest.register_globalstep(globalstep_func)
function queue:execute(action)
-- ignore if action queue function name doesn't exist,

View File

@ -123,3 +123,11 @@ dofile(minetest.get_modpath("mesecons").."/legacy.lua");
--Services like turnoff receptor on dignode and so on
dofile(minetest.get_modpath("mesecons").."/services.lua");
-- Automated test run
if mesecon.setting("internal_test", false) then
-- currently does nothing, we only fail if some error happens right on startup
minetest.after(5, function()
minetest.request_shutdown()
end)
end

View File

@ -51,27 +51,18 @@ mesecon.fifo_queue = dofile(minetest.get_modpath("mesecons").."/fifo_queue.lua")
-- General
function mesecon.get_effector(nodename)
if minetest.registered_nodes[nodename]
and minetest.registered_nodes[nodename].mesecons
and minetest.registered_nodes[nodename].mesecons.effector then
return minetest.registered_nodes[nodename].mesecons.effector
end
local def = minetest.registered_nodes[nodename]
return def and def.mesecons and def.mesecons.effector
end
function mesecon.get_receptor(nodename)
if minetest.registered_nodes[nodename]
and minetest.registered_nodes[nodename].mesecons
and minetest.registered_nodes[nodename].mesecons.receptor then
return minetest.registered_nodes[nodename].mesecons.receptor
end
local def = minetest.registered_nodes[nodename]
return def and def.mesecons and def.mesecons.receptor
end
function mesecon.get_conductor(nodename)
if minetest.registered_nodes[nodename]
and minetest.registered_nodes[nodename].mesecons
and minetest.registered_nodes[nodename].mesecons.conductor then
return minetest.registered_nodes[nodename].mesecons.conductor
end
local def = minetest.registered_nodes[nodename]
return def and def.mesecons and def.mesecons.conductor
end
function mesecon.get_any_outputrules(node)

View File

@ -0,0 +1,3 @@
# textdomain: mesecons
Mesecons=Mesecons

View File

@ -0,0 +1,4 @@
# textdomain: mesecons
### oldwires.lua ###
Mesecons=Mesecons

View File

Before

Width:  |  Height:  |  Size: 844 B

After

Width:  |  Height:  |  Size: 844 B

View File

Before

Width:  |  Height:  |  Size: 838 B

After

Width:  |  Height:  |  Size: 838 B

View File

Before

Width:  |  Height:  |  Size: 851 B

After

Width:  |  Height:  |  Size: 851 B

View File

Before

Width:  |  Height:  |  Size: 846 B

After

Width:  |  Height:  |  Size: 846 B

View File

@ -0,0 +1,2 @@
# textdomain: mesecons_blinkyplant
Blinky Plant=Blinkpflanze

View File

@ -0,0 +1,4 @@
# textdomain: mesecons_blinkyplant
### init.lua ###
Blinky Plant=Plante clignotante

View File

@ -0,0 +1,2 @@
# textdomain: mesecons_button
Button=Taster

View File

@ -0,0 +1,4 @@
# textdomain: mesecons_button
### init.lua ###
Button=Bouton

View File

@ -0,0 +1,5 @@
# textdomain: mesecons_commandblock
Say <text> as the server=<Text> als Server sagen
Say <text> to <name> privately=<Text> an <Name> privat senden
Set health of <name> to <value> hitpoints=Gesundheit von <Name> auf <Wert> Trefferpunkte setzen
Command Block=Befehlsblock

View File

@ -0,0 +1,7 @@
# textdomain: mesecons_commandblock
### init.lua ###
Say <text> as the server=Dire <text> au serveur
Say <text> to <name> privately=Dire <text> à <name> en privé
Set health of <name> to <value> hitpoints=Définir la vie de <name> sur <value> cœurs
Command Block=Bloc de commandes

View File

@ -27,20 +27,6 @@ local delaytime = { 0.1, 0.3, 0.5, 1.0 }
for i = 1, 4 do
local 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 }
}
-- Delayer definition defaults
local def = {
drawtype = "nodebox",
@ -48,11 +34,14 @@ local def = {
walkable = true,
selection_box = {
type = "fixed",
fixed = { -8/16, -8/16, -8/16, 8/16, -6/16, 8/16 },
fixed = { -8/16, -8/16, -8/16, 8/16, -7/16, 8/16 },
},
node_box = {
type = "fixed",
fixed = boxes
fixed = {
{ -8/16, -8/16, -8/16, 8/16, -7/16, 8/16 }, -- bottom slab
{ -6/16, -7/16, -6/16, 6/16, -6/16, 6/16 }
},
},
paramtype = "light",
paramtype2 = "facedir",
@ -62,6 +51,8 @@ local def = {
sounds = mesecon.node_sound.stone,
on_blast = mesecon.on_blastnode,
drop = "mesecons_delayer:delayer_off_1",
delayer_onstate = "mesecons_delayer:delayer_on_"..tostring(i),
delayer_offstate = "mesecons_delayer:delayer_off_"..tostring(i),
}
-- Deactivated delayer definition defaults
@ -72,16 +63,17 @@ end
local off_state = {
description = S("Delayer"),
inventory_image = "jeija_gate_off.png^jeija_delayer.png",
wield_image = "jeija_gate_off.png^jeija_delayer.png",
tiles = {
"mesecons_delayer_off_"..tostring(i)..".png",
"mesecons_delayer_bottom.png",
"mesecons_delayer_ends_off.png",
"mesecons_delayer_ends_off.png",
"mesecons_delayer_sides_off.png",
"mesecons_delayer_sides_off.png"
"jeija_microcontroller_bottom.png^jeija_gate_output_off.png^jeija_gate_off.png^"..
"jeija_delayer.png^mesecons_delayer_"..tostring(i)..".png",
"jeija_microcontroller_bottom.png^jeija_gate_output_off.png",
"jeija_gate_side.png^jeija_gate_side_output_off.png",
"jeija_gate_side.png",
"jeija_gate_side.png",
"jeija_gate_side.png",
},
inventory_image = "mesecons_delayer_off_1.png",
wield_image = "mesecons_delayer_off_1.png",
groups = off_groups,
on_punch = function(pos, node, puncher)
if minetest.is_protected(pos, puncher and puncher:get_player_name() or "") then
@ -93,7 +85,6 @@ local off_state = {
param2 = node.param2
})
end,
delayer_onstate = "mesecons_delayer:delayer_on_"..tostring(i),
mesecons = {
receptor =
{
@ -103,6 +94,7 @@ local off_state = {
effector =
{
rules = delayer_get_input_rules,
action_off = delayer_deactivate,
action_on = delayer_activate
}
},
@ -115,13 +107,16 @@ minetest.register_node("mesecons_delayer:delayer_off_"..tostring(i), off_state)
-- Activated delayer definition defaults
local on_state = {
description = S("You hacker you"),
inventory_image = "jeija_gate_on.png^jeija_delayer.png",
wield_image = "jeija_gate_on.png^jeija_delayer.png",
tiles = {
"mesecons_delayer_on_"..tostring(i)..".png",
"mesecons_delayer_bottom.png",
"mesecons_delayer_ends_on.png",
"mesecons_delayer_ends_on.png",
"mesecons_delayer_sides_on.png",
"mesecons_delayer_sides_on.png"
"jeija_microcontroller_bottom.png^jeija_gate_output_on.png^jeija_gate_on.png^"..
"jeija_delayer.png^mesecons_delayer_"..tostring(i)..".png",
"jeija_microcontroller_bottom.png^jeija_gate_output_on.png",
"jeija_gate_side.png^jeija_gate_side_output_on.png",
"jeija_gate_side.png",
"jeija_gate_side.png",
"jeija_gate_side.png",
},
groups = {bendy = 2, snappy = 1, dig_immediate = 2, not_in_creative_inventory = 1},
on_punch = function(pos, node, puncher)
@ -134,7 +129,6 @@ local on_state = {
param2 = node.param2
})
end,
delayer_offstate = "mesecons_delayer:delayer_off_"..tostring(i),
mesecons = {
receptor =
{
@ -144,7 +138,8 @@ local on_state = {
effector =
{
rules = delayer_get_input_rules,
action_off = delayer_deactivate
action_off = delayer_deactivate,
action_on = delayer_activate
}
},
}

View File

@ -0,0 +1,3 @@
# textdomain: mesecons_delayer
Delayer=Verzögerer
You hacker you=Du Hacker, Du

View File

@ -0,0 +1,5 @@
# textdomain: mesecons_delayer
### init.lua ###
Delayer=Retardateur
You hacker you=Vous êtes un pirate informatique

Binary file not shown.

After

Width:  |  Height:  |  Size: 149 B

View File

Before

Width:  |  Height:  |  Size: 84 B

After

Width:  |  Height:  |  Size: 84 B

View File

Before

Width:  |  Height:  |  Size: 84 B

After

Width:  |  Height:  |  Size: 84 B

View File

Before

Width:  |  Height:  |  Size: 98 B

After

Width:  |  Height:  |  Size: 98 B

View File

Before

Width:  |  Height:  |  Size: 99 B

After

Width:  |  Height:  |  Size: 99 B

View File

Before

Width:  |  Height:  |  Size: 136 B

After

Width:  |  Height:  |  Size: 136 B

View File

Before

Width:  |  Height:  |  Size: 109 B

After

Width:  |  Height:  |  Size: 109 B

View File

Before

Width:  |  Height:  |  Size: 110 B

After

Width:  |  Height:  |  Size: 110 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 338 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 337 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 339 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 334 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 221 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 176 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 187 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 448 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 449 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 448 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 446 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 541 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 541 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 541 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 538 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 173 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 181 B

View File

@ -4,6 +4,16 @@ local side_texture = mesecon.texture.steel_block or "mesecons_detector_side.png"
local GET_COMMAND = "GET"
local function comma_list_to_table(comma_list)
local tbl = {}
for _, str in ipairs(string.split(comma_list:gsub("%s", ""), ",")) do
tbl[str] = true
end
return tbl
end
-- Object detector
-- Detects players in a certain radius
-- The radius can be specified in mesecons/settings.lua
@ -35,10 +45,7 @@ local function object_detector_scan(pos)
if next(objs) == nil then return false end
local scanname = minetest.get_meta(pos):get_string("scanname")
local scan_for = {}
for _, str in pairs(string.split(scanname:gsub(" ", ""), ",")) do
scan_for[str] = true
end
local scan_for = comma_list_to_table(scanname)
local every_player = scanname == ""
for _, obj in pairs(objs) do
@ -188,8 +195,9 @@ local function node_detector_scan(pos)
vector.subtract(pos, vector.multiply(minetest.facedir_to_dir(node.param2), distance + 1))
).name
local scanname = meta:get_string("scanname")
local scan_for = comma_list_to_table(scanname)
return (frontname == scanname) or
return (scan_for[frontname]) or
(frontname ~= "air" and frontname ~= "ignore" and scanname == "")
end
@ -215,10 +223,10 @@ local node_detector_digiline = {
if type(msg) == "table" then
if msg.distance or msg.scanname then
if msg.distance then
if type(msg.distance) == "number" or type(msg.distance) == "string" then
meta:set_string("distance", msg.distance)
end
if msg.scanname then
if type(msg.scanname) == "string" then
meta:set_string("scanname", msg.scanname)
end
node_detector_make_formspec(pos)
@ -232,7 +240,7 @@ local node_detector_digiline = {
else
if msg == GET_COMMAND then
node_detector_send_node_name(pos, node, channel, meta)
else
elseif type(msg) == "string" then
meta:set_string("scanname", msg)
node_detector_make_formspec(pos)
end

View File

@ -0,0 +1,3 @@
# textdomain: mesecons_detector
Player Detector=Spielerdetektor
Node Detector=Blockdetektor

View File

@ -0,0 +1,5 @@
# textdomain: mesecons_detector
### init.lua ###
Player Detector=Détecteur de joueur
Node Detector=Détecteur de bloc

View File

@ -22,6 +22,11 @@ end
local function meseconify_door(name)
if minetest.registered_items[name .. "_b_1"] then
-- old style double-node doors
if minetest.registered_items[name .. "_b_1"].mesecons then
minetest.log("info", "[mesecons_doors] Not touching door " .. name)
return
end
local function toggle_state1 (pos)
on_rightclick(pos, 1, name.."_t_1", name.."_b_2", name.."_t_2", {1,2,3,0})
end
@ -47,6 +52,10 @@ local function meseconify_door(name)
})
elseif minetest.registered_items[name .. "_a"] then
-- new style mesh node based doors
if minetest.registered_items[name .. "_a"].mesecons then
minetest.log("info", "[mesecons_doors] Not touching door " .. name)
return
end
local override = {
mesecons = {effector = {
action_on = function(pos)
@ -73,68 +82,66 @@ local function meseconify_door(name)
end
end
meseconify_door("doors:door_wood")
meseconify_door("doors:door_steel")
meseconify_door("doors:door_glass")
meseconify_door("doors:door_obsidian_glass")
meseconify_door("xpanes:door_steel_bar")
-- Trapdoor
local function trapdoor_switch(pos, node)
local state = minetest.get_meta(pos):get_int("state")
local function trapdoor_switch(name)
return function(pos, node)
local state = minetest.get_meta(pos):get_int("state")
if state == 1 then
minetest.sound_play("doors_door_close", { pos = pos, gain = 0.3, max_hear_distance = 10 }, true)
minetest.set_node(pos, {name=name, param2 = node.param2})
else
minetest.sound_play("doors_door_open", { pos = pos, gain = 0.3, max_hear_distance = 10 }, true)
minetest.set_node(pos, {name=name.."_open", param2 = node.param2})
end
minetest.get_meta(pos):set_int("state", state == 1 and 0 or 1)
end
end
if state == 1 then
minetest.sound_play("doors_door_close", { pos = pos, gain = 0.3, max_hear_distance = 10 }, true)
minetest.set_node(pos, {name="doors:trapdoor", param2 = node.param2})
local function meseconify_trapdoor(name)
local override
if doors and doors.get then
override = {
mesecons = {effector = {
action_on = function(pos)
local door = doors.get(pos)
if door then
door:open()
end
end,
action_off = function(pos)
local door = doors.get(pos)
if door then
door:close()
end
end,
}},
}
else
minetest.sound_play("doors_door_open", { pos = pos, gain = 0.3, max_hear_distance = 10 }, true)
minetest.set_node(pos, {name="doors:trapdoor_open", param2 = node.param2})
override = {
mesecons = {effector = {
action_on = trapdoor_switch(name),
action_off = trapdoor_switch(name)
}},
}
end
minetest.get_meta(pos):set_int("state", state == 1 and 0 or 1)
if minetest.registered_items[name] then
minetest.override_item(name, override)
minetest.override_item(name.."_open", override)
end
end
if doors and doors.get then
local override = {
mesecons = {effector = {
action_on = function(pos)
local door = doors.get(pos)
if door then
door:open()
end
end,
action_off = function(pos)
local door = doors.get(pos)
if door then
door:close()
end
end,
}},
}
minetest.override_item("doors:trapdoor", override)
minetest.override_item("doors:trapdoor_open", override)
minetest.override_item("doors:trapdoor_steel", override)
minetest.override_item("doors:trapdoor_steel_open", override)
if minetest.registered_items["xpanes:trapdoor_steel_bar"] then
minetest.override_item("xpanes:trapdoor_steel_bar", override)
minetest.override_item("xpanes:trapdoor_steel_bar_open", override)
minetest.register_on_mods_loaded(function()
if doors.registered_doors ~= nil then -- registered_doors is not always available
for k,_ in pairs(doors.registered_doors) do
if k:find("_a$") then
meseconify_door(k:sub(1,-3))
end
end
for k,_ in pairs(doors.registered_trapdoors) do
if not k:find("_open$") then
meseconify_trapdoor(k)
end
end
end
else
if minetest.registered_nodes["doors:trapdoor"] then
minetest.override_item("doors:trapdoor", {
mesecons = {effector = {
action_on = trapdoor_switch,
action_off = trapdoor_switch
}},
})
minetest.override_item("doors:trapdoor_open", {
mesecons = {effector = {
action_on = trapdoor_switch,
action_off = trapdoor_switch
}},
})
end
end
end)

View File

@ -0,0 +1,8 @@
# textdomain: mesecons_extrawires
Insulated Mesecon Corner=Isolierte Meseconecke
Insulated Mesecon Crossover=Isolierter Meseconübergang
You hacker you!=Sie Hacker!
Insulated Mesecon Double Corner=Isolierte Mesecondoppelecke
Mese Wire=Mesedraht
Insulated Mesecon T-junction=Isolierte Mesecongabelung
Vertical Mesecon=Vertikaler Mesecon

View File

@ -0,0 +1,20 @@
# textdomain: mesecons_extrawires
### corner.lua ###
Insulated Mesecon Corner=Coin de Mesecon isolé
### crossover.lua ###
Insulated Mesecon Crossover=Croisement de Mesecon isolé
You hacker you!=Vous êtes un pirate informatique !
### doublecorner.lua ###
Insulated Mesecon Double Corner=Double coin de Mesecon isolé
### mesewire.lua ###
Mese Wire=Câble de Mesecon
### tjunction.lua ###
Insulated Mesecon T-junction=Croisement en T de Mesecon isolé
### vertical.lua ###
Vertical Mesecon=Mesecon vertical

View File

@ -40,35 +40,39 @@ local bottom_rules = {
{x=0, y=2, z=0} -- receive power from pressure plate / detector / ... 2 nodes above
}
local function is_vertical_conductor(nodename)
local def = minetest.registered_nodes[nodename]
return def and def.is_vertical_conductor
end
local vertical_updatepos = function (pos)
local node = minetest.get_node(pos)
if minetest.registered_nodes[node.name]
and minetest.registered_nodes[node.name].is_vertical_conductor then
local node_above = minetest.get_node(vector.add(pos, vertical_rules[1]))
local node_below = minetest.get_node(vector.add(pos, vertical_rules[2]))
local above = minetest.registered_nodes[node_above.name]
and minetest.registered_nodes[node_above.name].is_vertical_conductor
local below = minetest.registered_nodes[node_below.name]
and minetest.registered_nodes[node_below.name].is_vertical_conductor
mesecon.on_dignode(pos, node)
-- Always place offstate conductor and let mesecon.on_placenode take care
local newname = "mesecons_extrawires:vertical_"
if above and below then -- above and below: vertical mesecon
newname = newname .. "off"
elseif above and not below then -- above only: bottom
newname = newname .. "bottom_off"
elseif not above and below then -- below only: top
newname = newname .. "top_off"
else -- no vertical wire above, no vertical wire below: use bottom
newname = newname .. "bottom_off"
end
minetest.set_node(pos, {name = newname})
mesecon.on_placenode(pos, {name = newname})
if not is_vertical_conductor(node.name) then
return
end
local node_above = minetest.get_node(vector.add(pos, vertical_rules[1]))
local node_below = minetest.get_node(vector.add(pos, vertical_rules[2]))
local above = is_vertical_conductor(node_above.name)
local below = is_vertical_conductor(node_below.name)
mesecon.on_dignode(pos, node)
-- Always place offstate conductor and let mesecon.on_placenode take care
local newname = "mesecons_extrawires:vertical_"
if above and below then -- above and below: vertical mesecon
newname = newname .. "off"
elseif above and not below then -- above only: bottom
newname = newname .. "bottom_off"
elseif not above and below then -- below only: top
newname = newname .. "top_off"
else -- no vertical wire above, no vertical wire below: use bottom
newname = newname .. "bottom_off"
end
minetest.set_node(pos, {name = newname})
mesecon.on_placenode(pos, {name = newname})
end
local vertical_update = function (pos)

View File

@ -20,10 +20,10 @@ plg.register_nodes = function(template)
-- build top texture string
local texture = "jeija_fpga_top.png"
if a == 1 then texture = texture .. "^jeija_microcontroller_LED_A.png" end
if b == 1 then texture = texture .. "^jeija_microcontroller_LED_B.png" end
if c == 1 then texture = texture .. "^jeija_microcontroller_LED_C.png" end
if d == 1 then texture = texture .. "^jeija_microcontroller_LED_D.png" end
if a == 1 then texture = texture .. "^jeija_luacontroller_LED_A.png" end
if b == 1 then texture = texture .. "^jeija_luacontroller_LED_B.png" end
if c == 1 then texture = texture .. "^jeija_luacontroller_LED_C.png" end
if d == 1 then texture = texture .. "^jeija_luacontroller_LED_D.png" end
ndef.tiles[1] = texture
ndef.inventory_image = texture

View File

@ -0,0 +1,3 @@
# textdomain: mesecons_fpga
FPGA=FPGA
FPGA Programmer=FPGA-Programmierer

View File

@ -0,0 +1,7 @@
# textdomain: mesecons_fpga
### init.lua ###
FPGA=Circuit logique programmable (FPGA)
### tool.lua ###
FPGA Programmer=Programmateur de circuit logique

View File

@ -0,0 +1,43 @@
--Aliases
minetest.register_alias("mesecons_gamecompat:chest", "mcl_chests:chest")
minetest.register_alias("mesecons_gamecompat:chest_locked", "mcl_chests:chest")
minetest.register_alias("mesecons_gamecompat:coalblock", "mcl_core:coalblock")
minetest.register_alias("mesecons_gamecompat:cobble", "mcl_core:cobble")
minetest.register_alias("mesecons_gamecompat:glass", "mcl_core:glass")
minetest.register_alias("mesecons_gamecompat:lava_source", "mcl_core:lava_source")
minetest.register_alias("mesecons_gamecompat:mese", "mesecons:redstoneblock")
minetest.register_alias("mesecons_gamecompat:mese_crystal", "mesecoms:redstone")
minetest.register_alias("mesecons_gamecompat:mese_crystal_fragment", "mesecons:redstone")
minetest.register_alias("mesecons_gamecompat:obsidian_glass", "mcl_core:glass")
minetest.register_alias("mesecons_gamecompat:stone", "mcl_core:stone")
minetest.register_alias("mesecons_gamecompat:steel_ingot", "mcl_core:iron_ingot")
minetest.register_alias("mesecons_gamecompat:steelblock", "mcl_core:steelblock")
minetest.register_alias("mesecons_gamecompat:torch", "mcl_torches:torch")
if minetest.get_modpath("mcl_dyes") then
for color, def in ipairs(mcl_dyes.colors) do
minetest.register_alias("mesecons_gamecompat:dye_" .. def.mcl2, "mcl_dyes:" .. color)
end
end
-- Sounds
mesecon.node_sound.default = mcl_sounds.node_sound_defaults()
mesecon.node_sound.glass = mcl_sounds.node_sound_glass_defaults()
mesecon.node_sound.leaves = mcl_sounds.node_sound_leaves_defaults()
mesecon.node_sound.stone = mcl_sounds.node_sound_stone_defaults()
mesecon.node_sound.wood = mcl_sounds.node_sound_wood_defaults()
if minetest.get_modpath("mcl_fire") then
mesecon.sound_name.fire = "fire_fire"
end
if minetest.get_modpath("mcl_tnt") then
mesecon.sound_name.explode = "tnt_explode"
end
-- Textures
mesecon.texture.steel_block = "default_steel_block.png"

View File

@ -59,6 +59,10 @@ if minetest.get_modpath("mesecons_mvps") then
"doors:hidden",
"doors:trapdoor_steel",
"doors:trapdoor_steel_open",
"beds:bed_bottom",
"beds:bed_top",
"beds:fancy_bed_bottom",
"beds:fancy_bed_top",
"xpanes:door_steel_bar_a",
"xpanes:door_steel_bar_b",
"xpanes:door_steel_bar_c",

View File

@ -13,3 +13,8 @@ if minetest.get_modpath("default") then
minetest.log("info", "Mesecons: detected Minetest Game for game compatibility")
dofile(minetest.get_modpath("mesecons_gamecompat").."/compat_mtg.lua")
end
if minetest.get_modpath("mcl_core") then
minetest.log("info", "Mesecons: detected MineClonia Game for game compatibility")
dofile(minetest.get_modpath("mesecons_gamecompat").."/compat_mcl.lua")
end

View File

@ -1,3 +1,3 @@
name = mesecons_gamecompat
depends = mesecons
optional_depends = fire, default, dye, mesecons_mvps, tnt
optional_depends = fire, default, dye, mesecons_mvps, tnt, mcl_fire, mcl_core, mcl_dye, mcl_tnt

View File

@ -0,0 +1,2 @@
# textdomain: mesecons_hydroturbine
Water Turbine=Wasserturbine

View File

@ -0,0 +1,4 @@
# textdomain: mesecons_hydroturbine
### init.lua ###
Water Turbine=Détecteur de courant

View File

@ -0,0 +1,2 @@
# textdomain: mesecons_insulated
Straight Insulated Mesecon=Isolierte Mesecongerade

View File

@ -0,0 +1,4 @@
# textdomain: mesecons_insulated
### init.lua ###
Straight Insulated Mesecon=Mesecon isolé droit

View File

@ -0,0 +1,2 @@
# textdomain: mesecons_lamp
Mesecon Lamp=Meseconlampe

View File

@ -0,0 +1,4 @@
# textdomain: mesecons_lamp
### init.lua ###
Mesecon Lamp=Lampe de Mesecon

View File

@ -0,0 +1,13 @@
# textdomain: mesecons_lightstone
Red Lightstone=Roter Leuchtstein
Green Lightstone=Grüner Leuchtstein
Blue Lightstone=Blauer Leuchtstein
Grey Lightstone=Grauer Leuchtstein
Dark Grey Lightstone=Dunkelgrauer Leuchtstein
Yellow Lightstone=Gelber Leuchtstein
Orange Lightstone=Orange Leuchtstein
White Lightstone=Weißer Leuchtstein
Pink Lightstone=Rosa Leuchtstein
Magenta Lightstone=Magenta Leuchtstein
Cyan Lightstone=Türkiser Leuchtstein
Violet Lightstone=Violetter Leuchtstein

View File

@ -0,0 +1,15 @@
# textdomain: mesecons_lightstone
### init.lua ###
Red Lightstone=Pierre lumineuse rouge
Green Lightstone=Pierre lumineuse verte
Blue Lightstone=Pierre lumineuse bleue
Grey Lightstone=Pierre lumineuse grise
Dark Grey Lightstone=Pierre lumineuse gris foncée
Yellow Lightstone=Pierre lumineuse jaune
Orange Lightstone=Pierre lumineuse orange
White Lightstone=Pierre lumineuse blanche
Pink Lightstone=Pierre lumineuse rose
Magenta Lightstone=Pierre lumineuse magenta
Cyan Lightstone=Pierre lumineuse bleu clair
Violet Lightstone=Pierre lumineuse violette

View File

@ -238,6 +238,16 @@ local function safe_string_find(...)
return string.find(...)
end
-- do not allow pattern matching in string.split (see string.find for details)
local function safe_string_split(...)
if select(5, ...) then
debug.sethook() -- Clear hook
error("string.split: 'sep_is_pattern' (fifth parameter) may not be used in a Luacontroller")
end
return string.split(...)
end
local function remove_functions(x)
local tp = type(x)
if tp == "function" then
@ -378,7 +388,10 @@ local function clean_and_weigh_digiline_message(msg, back_references)
return msg, #msg + 25
elseif t == "number" then
-- Numbers are passed by value so need not be touched, and cost 8 bytes
-- as all numbers in Lua are doubles.
-- as all numbers in Lua are doubles. NaN values are removed.
if msg ~= msg then
return nil, 0
end
return msg, 8
elseif t == "boolean" then
-- Booleans are passed by value so need not be touched, and cost 1
@ -507,6 +520,7 @@ local function create_environment(pos, mem, event, itbl, send_warning)
reverse = string.reverse,
sub = string.sub,
find = safe_string_find,
split = safe_string_split,
},
math = {
abs = math.abs,

View File

@ -0,0 +1,2 @@
# textdomain: mesecons_luacontroller
Luacontroller=Luacontroller

View File

@ -0,0 +1,4 @@
# textdomain: mesecons_luacontroller
### init.lua ###
Luacontroller=Programmateur LUA

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

View File

@ -0,0 +1,4 @@
# textdomain: mesecons_materials
Glue=Klebstoff
Fiber=Faser
Silicon=Silizium

View File

@ -0,0 +1,6 @@
# textdomain: mesecons_materials
### init.lua ###
Glue=Colle
Fiber=Fibre
Silicon=Silicone

View File

@ -0,0 +1,64 @@
<!-- Generate `description.html` from this by using `$ md2html -o description.html description.md`. -->
<p>The Microcontroller is a semi-advanced programmable component with a persistent
256 bit EEPROM memory.</p>
<p>Warning: This device is largely considered deprecated and might contain bugs. It
is recommended to use a Luacontroller instead.</p>
<p>Detailed documentation can be found below:</p>
<ul>
<li>The Microcontroller's code is executed whenever any of the following events
happens:<ul>
<li>The Microcontroller is programmed. In this case the EEPROM and ports are all
reset to <code>0</code> before.</li>
<li>An incoming signal changes its state.</li>
<li>An <code>after</code> event happens (see command <code>after</code> below).</li>
</ul>
</li>
<li>There are 4 I/O ports (ABCD) and 256 EEPROM bits (1 to 256).</li>
<li>The code consists of a sequence of commands.</li>
<li>Everything after <code>:</code> is a comment.</li>
<li>Strings are enclosed in <code>&quot;</code>s.</li>
<li>Spaces and tabs outside of strings are ignored.</li>
<li>Basic command syntax:<pre><code> command_name`(`param1`,` param2`,` ...`)`
</code></pre>
</li>
<li>Commands:<ul>
<li><code>if(condition) commands [&gt; else_commands];</code>:
Evaluates the given condition and takes the corresponding branch.
The else branch is optional (as indicated by the <code>[</code> and <code>]</code>). The <code>&gt;</code> is part
of the syntax and indicates the start of the else branch. The <code>;</code> marks the
end of the if command.</li>
<li><code>on(port1, port2, ...)</code>:
Sets the given ports to <code>1</code>.</li>
<li><code>off(port1, port2, ...)</code>:
Sets the given ports to <code>0</code>.</li>
<li><code>print(&quot;string&quot; or codition, ...)</code>:
Evaluates the conditions and prints the concatenation of all params to stdout
(only useful in singleplayer).</li>
<li><code>after(time, &quot;more commands&quot;)</code>:
Executes the commands in the string after the given time in seconds.
There can only be one waiting <code>after</code> event at once.
Warning: This is not reliable, ie. <code>minetest.after</code> is used.</li>
<li><code>sbi(port_or_eeprom, condition)</code>:
Evaluates the condition and sets the port or EEPROM bit to the resulting value.
Note: EEPROM indices don't use <code>#</code> here, ie. it's <code>sbi(1, #2)</code>, not <code>sbi(#1, #2)</code>.</li>
</ul>
</li>
<li>Conditions (sorted by descending precedence; they are all evaluated from left
to right):<ul>
<li><code>0</code>, <code>1</code>: constant</li>
<li><code>A</code>, ..., <code>D</code>: value of a port. Takes writes that already happened during the
current execution into account.</li>
<li><code>#1</code>, ..., <code>#256</code>: value of an EEPROM bit. Takes writes that already happened
during the current execution into account.</li>
<li><code>!condition</code>: negation (can only be applied once, ie. not <code>!!1</code>)</li>
<li><code>condition1 = condition2</code>: XNOR (equality)</li>
<li><code>condition1 op condition2</code> where <code>op</code> is one of:<ul>
<li><code>&amp;</code>: AND</li>
<li><code>|</code>: OR</li>
<li><code>~</code>: XOR (inequality)</li>
</ul>
</li>
<li>Note: Explicit precedence using parentheses is not supported.</li>
</ul>
</li>
</ul>

View File

@ -0,0 +1,59 @@
<!-- Generate `description.html` from this by using `$ md2html -o description.html description.md`. -->
The Microcontroller is a semi-advanced programmable component with a persistent
256 bit EEPROM memory.
Warning: This device is largely considered deprecated and might contain bugs. It
is recommended to use a Luacontroller instead.
Detailed documentation can be found below:
* The Microcontroller's code is executed whenever any of the following events
happens:
* The Microcontroller is programmed. In this case the EEPROM and ports are all
reset to `0` before.
* An incoming signal changes its state.
* An `after` event happens (see command `after` below).
* There are 4 I/O ports (ABCD) and 256 EEPROM bits (1 to 256).
* The code consists of a sequence of commands.
* Everything after `:` is a comment.
* Strings are enclosed in `"`s.
* Spaces and tabs outside of strings are ignored.
* Basic command syntax:
```
command_name`(`param1`,` param2`,` ...`)`
```
* Commands:
* `if(condition) commands [> else_commands];`:
Evaluates the given condition and takes the corresponding branch.
The else branch is optional (as indicated by the `[` and `]`). The `>` is part
of the syntax and indicates the start of the else branch. The `;` marks the
end of the if command.
* `on(port1, port2, ...)`:
Sets the given ports to `1`.
* `off(port1, port2, ...)`:
Sets the given ports to `0`.
* `print("string" or codition, ...)`:
Evaluates the conditions and prints the concatenation of all params to stdout
(only useful in singleplayer).
* `after(time, "more commands")`:
Executes the commands in the string after the given time in seconds.
There can only be one waiting `after` event at once.
Warning: This is not reliable, ie. `minetest.after` is used.
* `sbi(port_or_eeprom, condition)`:
Evaluates the condition and sets the port or EEPROM bit to the resulting value.
Note: EEPROM indices don't use `#` here, ie. it's `sbi(1, #2)`, not `sbi(#1, #2)`.
* Conditions (sorted by descending precedence; they are all evaluated from left
to right):
* `0`, `1`: constant
* `A`, ..., `D`: value of a port. Takes writes that already happened during the
current execution into account.
* `#1`, ..., `#256`: value of an EEPROM bit. Takes writes that already happened
during the current execution into account.
* `!condition`: negation (can only be applied once, ie. not `!!1`)
* `condition1 = condition2`: XNOR (equality)
* `condition1 op condition2` where `op` is one of:
* `&`: AND
* `|`: OR
* `~`: XOR (inequality)
* Note: Explicit precedence using parentheses is not supported.

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

View File

@ -12,16 +12,16 @@ for d = 0, 1 do
local nodename = "mesecons_microcontroller:microcontroller"..tostring(d)..tostring(c)..tostring(b)..tostring(a)
local top = "jeija_microcontroller_top.png"
if tostring(a) == "1" then
top = top.."^jeija_microcontroller_LED_A.png"
top = top.."^jeija_luacontroller_LED_A.png"
end
if tostring(b) == "1" then
top = top.."^jeija_microcontroller_LED_B.png"
top = top.."^jeija_luacontroller_LED_B.png"
end
if tostring(c) == "1" then
top = top.."^jeija_microcontroller_LED_C.png"
top = top.."^jeija_luacontroller_LED_C.png"
end
if tostring(d) == "1" then
top = top.."^jeija_microcontroller_LED_D.png"
top = top.."^jeija_luacontroller_LED_D.png"
end
local groups
if tostring(d)..tostring(c)..tostring(b)..tostring(a) ~= "0000" then
@ -122,7 +122,7 @@ minetest.register_node(nodename, {
elseif fields.bnand then
fields.code = "sbi(C, !A|!B) :A and B are inputs, C is output"
elseif fields.btflop then
fields.code = "if(A)sbi(1,1);if(!A&#1)sbi(B,!B)sbi(1,0); if(C)off(B,1); :A is input, B is output (Q), C is reset, toggles with falling edge"
fields.code = "if(A)sbi(1,1);if(!A&#1)sbi(B,!B)sbi(1,0); if(C)off(B); :A is input, B is output (Q), C is reset, toggles with falling edge"
elseif fields.brsflop then
fields.code = "if(A)on(C);if(B)off(C); :A is S (Set), B is R (Reset), C is output (R dominates)"
end

View File

@ -0,0 +1,2 @@
# textdomain: mesecons_microcontroller
Microcontroller=Mikrocontroller

View File

@ -0,0 +1,4 @@
# textdomain: mesecons_microcontroller
### init.lua ###
Microcontroller=Micro-controlleur

View File

@ -0,0 +1,7 @@
# textdomain: mesecons_movestones
### init.lua ###
Movestone=Pierre mouvante
Sticky Movestone=Pierre collante mouvante
Vertical Movestone=Pierre mouvante verticalement
Vertical Sticky Movestone=Pierre collante mouvante verticalement

View File

@ -0,0 +1,5 @@
# textdomain: mesecons_movestones
Movestone=Laufstein
Sticky Movestone=Klebriger Laufstein
Vertical Movestone=Vertikaler Laufstein
Vertical Sticky Movestone=Vertikaler klebriger Laufstein

View File

@ -53,11 +53,16 @@ end
-- tests if the node can be pushed into, e.g. air, water, grass
local function node_replaceable(name)
if minetest.registered_nodes[name] then
return minetest.registered_nodes[name].buildable_to or false
local nodedef = minetest.registered_nodes[name]
-- everything that can be an mvps stopper (unknown nodes and nodes in the
-- mvps_stoppers table) must not be replacable
-- Note: ignore (a stopper) is buildable_to, but we do not want to push into it
if not nodedef or mesecon.mvps_stoppers[name] then
return false
end
return false
return nodedef.buildable_to or false
end
function mesecon.mvps_get_stack(pos, dir, maximum, all_pull_sticky)
@ -76,9 +81,9 @@ function mesecon.mvps_get_stack(pos, dir, maximum, all_pull_sticky)
if #nodes > maximum then return nil end
-- add connected nodes to frontiers
if minetest.registered_nodes[nn.name]
and minetest.registered_nodes[nn.name].mvps_sticky then
local connected = minetest.registered_nodes[nn.name].mvps_sticky(np, nn)
local nndef = minetest.registered_nodes[nn.name]
if nndef and nndef.mvps_sticky then
local connected = nndef.mvps_sticky(np, nn)
for _, cp in ipairs(connected) do
frontiers:add(cp)
end
@ -91,10 +96,9 @@ function mesecon.mvps_get_stack(pos, dir, maximum, all_pull_sticky)
for _, r in ipairs(mesecon.rules.alldirs) do
local adjpos = vector.add(np, r)
local adjnode = minetest.get_node(adjpos)
if minetest.registered_nodes[adjnode.name]
and minetest.registered_nodes[adjnode.name].mvps_sticky then
local sticksto = minetest.registered_nodes[adjnode.name]
.mvps_sticky(adjpos, adjnode)
local adjdef = minetest.registered_nodes[adjnode.name]
if adjdef and adjdef.mvps_sticky then
local sticksto = adjdef.mvps_sticky(adjpos, adjnode)
-- connects to this position?
for _, link in ipairs(sticksto) do

View File

@ -0,0 +1,2 @@
# textdomain: mesecons_noteblock
Noteblock=Notenblock

View File

@ -0,0 +1,4 @@
# textdomain: mesecons_noteblock
### init.lua ###
Noteblock=Bloc de musique

View File

@ -270,9 +270,9 @@ minetest.register_node("mesecons_pistons:piston_normal_off", {
description = S("Piston"),
tiles = {
"mesecons_piston_top.png",
"mesecons_piston_bottom.png",
"mesecons_piston_left.png",
"mesecons_piston_right.png",
"mesecons_piston_top.png^[transform2",
"mesecons_piston_top.png^[transform3",
"mesecons_piston_top.png^[transform1",
"mesecons_piston_back.png",
"mesecons_piston_pusher_front.png"
},
@ -296,9 +296,9 @@ minetest.register_node("mesecons_pistons:piston_normal_on", {
drawtype = "nodebox",
tiles = {
"mesecons_piston_top.png",
"mesecons_piston_bottom.png",
"mesecons_piston_left.png",
"mesecons_piston_right.png",
"mesecons_piston_top.png^[transform2",
"mesecons_piston_top.png^[transform3",
"mesecons_piston_top.png^[transform1",
"mesecons_piston_back.png",
"mesecons_piston_on_front.png"
},
@ -325,9 +325,9 @@ minetest.register_node("mesecons_pistons:piston_pusher_normal", {
drawtype = "nodebox",
tiles = {
"mesecons_piston_pusher_top.png",
"mesecons_piston_pusher_bottom.png",
"mesecons_piston_pusher_left.png",
"mesecons_piston_pusher_right.png",
"mesecons_piston_pusher_top.png^[transform2",
"mesecons_piston_pusher_top.png^[transform3",
"mesecons_piston_pusher_top.png^[transform1",
"mesecons_piston_pusher_back.png",
"mesecons_piston_pusher_front.png"
},
@ -349,9 +349,9 @@ minetest.register_node("mesecons_pistons:piston_sticky_off", {
description = S("Sticky Piston"),
tiles = {
"mesecons_piston_top.png",
"mesecons_piston_bottom.png",
"mesecons_piston_left.png",
"mesecons_piston_right.png",
"mesecons_piston_top.png^[transform2",
"mesecons_piston_top.png^[transform3",
"mesecons_piston_top.png^[transform1",
"mesecons_piston_back.png",
"mesecons_piston_pusher_front_sticky.png"
},
@ -375,9 +375,9 @@ minetest.register_node("mesecons_pistons:piston_sticky_on", {
drawtype = "nodebox",
tiles = {
"mesecons_piston_top.png",
"mesecons_piston_bottom.png",
"mesecons_piston_left.png",
"mesecons_piston_right.png",
"mesecons_piston_top.png^[transform2",
"mesecons_piston_top.png^[transform3",
"mesecons_piston_top.png^[transform1",
"mesecons_piston_back.png",
"mesecons_piston_on_front.png"
},
@ -404,9 +404,9 @@ minetest.register_node("mesecons_pistons:piston_pusher_sticky", {
drawtype = "nodebox",
tiles = {
"mesecons_piston_pusher_top.png",
"mesecons_piston_pusher_bottom.png",
"mesecons_piston_pusher_left.png",
"mesecons_piston_pusher_right.png",
"mesecons_piston_pusher_top.png^[transform2",
"mesecons_piston_pusher_top.png^[transform3",
"mesecons_piston_pusher_top.png^[transform1",
"mesecons_piston_pusher_back.png",
"mesecons_piston_pusher_front_sticky.png"
},

View File

@ -0,0 +1,7 @@
# textdomain: mesecons_pistons
Piston=Kolben
Activated Piston Base=Aktivierter Kolbenkörper
Piston Pusher=Kolbenschieber
Sticky Piston=Haftender Kolben
Activated Sticky Piston Base=Aktivierter haftender Kolbenkörper
Sticky Piston Pusher=Haftender Kolbenschieber

View File

@ -0,0 +1,9 @@
# textdomain: mesecons_pistons
### init.lua ###
Piston=Piston
Activated Piston Base=Base de piston activé
Piston Pusher=Bras de piston
Sticky Piston=Piston collant
Activated Sticky Piston Base=Base de piston collant activé
Sticky Piston Pusher=Bras de piston collant

Binary file not shown.

Before

Width:  |  Height:  |  Size: 738 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 740 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 720 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 733 B

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