mirror of
https://github.com/minetest-mods/mesecons.git
synced 2025-06-29 14:20:25 +02:00
Compare commits
30 Commits
v2022-04-0
...
detector_b
Author | SHA1 | Date | |
---|---|---|---|
32e1cc63f2 | |||
cffbc33e6d | |||
59780437f2 | |||
50a4bd6170 | |||
7418d5cb61 | |||
6b42419828 | |||
8e30ee4113 | |||
b318aadd0a | |||
fef402e88a | |||
f98ea14023 | |||
7f8758f17b | |||
54de66b3e1 | |||
6890624f3d | |||
2589b391e5 | |||
edcdc6817e | |||
60240ba268 | |||
c10ce2dbc5 | |||
2ede29df9c | |||
a780298cfc | |||
bd07fb0c79 | |||
121082859f | |||
68171b3d8d | |||
da57a6214a | |||
c4f9336a26 | |||
0a4a88b1b9 | |||
58305f52bc | |||
27c3c515b4 | |||
960b7c4915 | |||
dfa43d6c0c | |||
f4070d3e64 |
26
.github/workflows/check-release.yml
vendored
26
.github/workflows/check-release.yml
vendored
@ -13,3 +13,29 @@ jobs:
|
|||||||
run: luarocks install --local luacheck
|
run: luarocks install --local luacheck
|
||||||
- name: luacheck run
|
- name: luacheck run
|
||||||
run: $HOME/.luarocks/bin/luacheck ./
|
run: $HOME/.luarocks/bin/luacheck ./
|
||||||
|
|
||||||
|
test:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@main
|
||||||
|
- name: apt
|
||||||
|
run: sudo apt-get install -y luarocks
|
||||||
|
- name: busted install
|
||||||
|
run: luarocks install --local busted
|
||||||
|
- name: luacov install
|
||||||
|
run: luarocks install --local luacov
|
||||||
|
- name: mineunit install
|
||||||
|
run: luarocks install --server=https://luarocks.org/dev --local mineunit
|
||||||
|
- name: run mesecons tests
|
||||||
|
working-directory: ./mesecons/
|
||||||
|
run: $HOME/.luarocks/bin/mineunit -q
|
||||||
|
- name: run mesecons_mvps tests
|
||||||
|
working-directory: ./mesecons_mvps/
|
||||||
|
run: $HOME/.luarocks/bin/mineunit -q
|
||||||
|
- name: run mesecons_fpga tests
|
||||||
|
working-directory: ./mesecons_fpga/
|
||||||
|
run: $HOME/.luarocks/bin/mineunit -q
|
||||||
|
- name: run mesecons_luacontroller tests
|
||||||
|
working-directory: ./mesecons_luacontroller/
|
||||||
|
run: $HOME/.luarocks/bin/mineunit -q
|
||||||
|
23
.luacheckrc
23
.luacheckrc
@ -34,3 +34,26 @@ globals = {"mesecon"}
|
|||||||
files["mesecons/actionqueue.lua"] = {
|
files["mesecons/actionqueue.lua"] = {
|
||||||
globals = {"minetest.registered_globalsteps"},
|
globals = {"minetest.registered_globalsteps"},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
-- Test-specific stuff follows.
|
||||||
|
|
||||||
|
local test_conf = {
|
||||||
|
read_globals = {
|
||||||
|
"assert",
|
||||||
|
"fixture",
|
||||||
|
"mineunit",
|
||||||
|
"Player",
|
||||||
|
"sourcefile",
|
||||||
|
"world",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
files["*/spec/*.lua"] = test_conf
|
||||||
|
files[".test_fixtures/*.lua"] = test_conf
|
||||||
|
|
||||||
|
files[".test_fixtures/screwdriver.lua"] = {
|
||||||
|
globals = {"screwdriver"},
|
||||||
|
}
|
||||||
|
|
||||||
|
files[".test_fixtures/mesecons_fpga.lua"] = {
|
||||||
|
globals = {"minetest.register_on_player_receive_fields"},
|
||||||
|
}
|
||||||
|
156
.test_fixtures/mesecons.lua
Normal file
156
.test_fixtures/mesecons.lua
Normal file
@ -0,0 +1,156 @@
|
|||||||
|
mineunit("core")
|
||||||
|
mineunit("server")
|
||||||
|
mineunit("voxelmanip")
|
||||||
|
|
||||||
|
mineunit:set_current_modname("mesecons")
|
||||||
|
mineunit:set_modpath("mesecons", "../mesecons")
|
||||||
|
sourcefile("../mesecons/init")
|
||||||
|
|
||||||
|
-- Utility node: this conductor is used to test the connectivity and state of adjacent wires.
|
||||||
|
do
|
||||||
|
local off_spec = {conductor = {
|
||||||
|
state = mesecon.state.off,
|
||||||
|
rules = mesecon.rules.alldirs,
|
||||||
|
onstate = "mesecons:test_conductor_on",
|
||||||
|
}}
|
||||||
|
local on_spec = {conductor = {
|
||||||
|
state = mesecon.state.on,
|
||||||
|
rules = mesecon.rules.alldirs,
|
||||||
|
offstate = "mesecons:test_conductor_off",
|
||||||
|
}}
|
||||||
|
mesecon.register_node("mesecons:test_conductor", {
|
||||||
|
description = "Test Conductor",
|
||||||
|
}, {mesecons = off_spec}, {mesecons = on_spec})
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Utility node: this receptor is used to test power sources.
|
||||||
|
do
|
||||||
|
local off_spec = {receptor = {
|
||||||
|
state = mesecon.state.off,
|
||||||
|
rules = mesecon.rules.alldirs,
|
||||||
|
}}
|
||||||
|
local on_spec = {receptor = {
|
||||||
|
state = mesecon.state.on,
|
||||||
|
rules = mesecon.rules.alldirs,
|
||||||
|
}}
|
||||||
|
mesecon.register_node("mesecons:test_receptor", {
|
||||||
|
description = "Test Receptor",
|
||||||
|
}, {mesecons = off_spec}, {mesecons = on_spec})
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Utility node: this effector is used to test circuit outputs.
|
||||||
|
do
|
||||||
|
-- This is a list of actions in the form {<kind>, <pos>},
|
||||||
|
-- where <kind> is "on", "off", or "overheat".
|
||||||
|
mesecon._test_effector_events = {}
|
||||||
|
local function action_on(pos, node)
|
||||||
|
table.insert(mesecon._test_effector_events, {"on", pos})
|
||||||
|
node.param2 = node.param2 % 64 + 128 -- Turn on bit 7
|
||||||
|
minetest.swap_node(pos, node)
|
||||||
|
end
|
||||||
|
local function action_off(pos, node)
|
||||||
|
table.insert(mesecon._test_effector_events, {"off", pos})
|
||||||
|
node.param2 = node.param2 % 64 -- Turn off bit 7
|
||||||
|
minetest.swap_node(pos, node)
|
||||||
|
end
|
||||||
|
local function action_change(pos, node, rule_name, new_state)
|
||||||
|
if mesecon.do_overheat(pos) then
|
||||||
|
table.insert(mesecon._test_effector_events, {"overheat", pos})
|
||||||
|
minetest.remove_node(pos)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
-- Set the value of a bit in param2 according to the rule name and new state.
|
||||||
|
local bit = tonumber(rule_name.name, 2)
|
||||||
|
local bits_above = node.param2 - node.param2 % (bit * 2)
|
||||||
|
local bits_below = node.param2 % bit
|
||||||
|
local bits_flipped = new_state == mesecon.state.on and bit or 0
|
||||||
|
node.param2 = bits_above + bits_flipped + bits_below
|
||||||
|
minetest.swap_node(pos, node)
|
||||||
|
end
|
||||||
|
minetest.register_node("mesecons:test_effector", {
|
||||||
|
description = "Test Effector",
|
||||||
|
mesecons = {effector = {
|
||||||
|
action_on = action_on,
|
||||||
|
action_off = action_off,
|
||||||
|
action_change = action_change,
|
||||||
|
rules = {
|
||||||
|
{x = 1, y = 0, z = 0, name = "000001"},
|
||||||
|
{x = -1, y = 0, z = 0, name = "000010"},
|
||||||
|
{x = 0, y = 1, z = 0, name = "000100"},
|
||||||
|
{x = 0, y = -1, z = 0, name = "001000"},
|
||||||
|
{x = 0, y = 0, z = 1, name = "010000"},
|
||||||
|
{x = 0, y = 0, z = -1, name = "100000"},
|
||||||
|
}
|
||||||
|
}},
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Utility node: this conductor is used to test rotation.
|
||||||
|
do
|
||||||
|
local get_rules = mesecon.horiz_rules_getter({{x = 1, y = 0, z = 0}, {x = -1, y = 0, z = 0}})
|
||||||
|
local off_spec = {conductor = {
|
||||||
|
state = mesecon.state.off,
|
||||||
|
rules = get_rules,
|
||||||
|
onstate = "mesecons:test_conductor_rot_on",
|
||||||
|
}}
|
||||||
|
local on_spec = {conductor = {
|
||||||
|
state = mesecon.state.on,
|
||||||
|
rules = get_rules,
|
||||||
|
offstate = "mesecons:test_conductor_rot_off",
|
||||||
|
}}
|
||||||
|
mesecon.register_node("mesecons:test_conductor_rot", {
|
||||||
|
description = "Rotatable Test Conductor",
|
||||||
|
on_rotate = mesecon.on_rotate_horiz,
|
||||||
|
}, {mesecons = off_spec}, {mesecons = on_spec})
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Utility node: this is used to test multiple conductors within a single node.
|
||||||
|
do
|
||||||
|
local mesecons_spec = {conductor = {
|
||||||
|
rules = {
|
||||||
|
{{x = 1, y = 0, z = 0}, {x = 0, y = -1, z = 0}},
|
||||||
|
{{x = 0, y = 1, z = 0}, {x = 0, y = 0, z = -1}},
|
||||||
|
{{x = 0, y = 0, z = 1}, {x = -1, y = 0, z = 0}},
|
||||||
|
},
|
||||||
|
states = {
|
||||||
|
"mesecons:test_multiconductor_off", "mesecons:test_multiconductor_001",
|
||||||
|
"mesecons:test_multiconductor_010", "mesecons:test_multiconductor_011",
|
||||||
|
"mesecons:test_multiconductor_100", "mesecons:test_multiconductor_101",
|
||||||
|
"mesecons:test_multiconductor_110", "mesecons:test_multiconductor_on",
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
for _, state in ipairs(mesecons_spec.conductor.states) do
|
||||||
|
minetest.register_node(state, {
|
||||||
|
description = "Test Multiconductor",
|
||||||
|
mesecons = mesecons_spec,
|
||||||
|
})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
mesecon._test_autoconnects = {}
|
||||||
|
mesecon.register_autoconnect_hook("test", function(pos, node)
|
||||||
|
table.insert(mesecon._test_autoconnects, {pos, node})
|
||||||
|
end)
|
||||||
|
|
||||||
|
function mesecon._test_dig(pos)
|
||||||
|
local node = minetest.get_node(pos)
|
||||||
|
minetest.remove_node(pos)
|
||||||
|
mesecon.on_dignode(pos, node)
|
||||||
|
end
|
||||||
|
|
||||||
|
function mesecon._test_place(pos, node)
|
||||||
|
world.set_node(pos, node)
|
||||||
|
mesecon.on_placenode(pos, minetest.get_node(pos))
|
||||||
|
end
|
||||||
|
|
||||||
|
function mesecon._test_reset()
|
||||||
|
-- First let circuits settle by simulating many globalsteps.
|
||||||
|
for i = 1, 10 do
|
||||||
|
mineunit:execute_globalstep(60)
|
||||||
|
end
|
||||||
|
mesecon.queue.actions = {}
|
||||||
|
mesecon._test_effector_events = {}
|
||||||
|
mesecon._test_autoconnects = {}
|
||||||
|
end
|
||||||
|
|
||||||
|
mineunit:execute_globalstep(mesecon.setting("resumetime", 4) + 1)
|
59
.test_fixtures/mesecons_fpga.lua
Normal file
59
.test_fixtures/mesecons_fpga.lua
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
mineunit("player")
|
||||||
|
|
||||||
|
fixture("mesecons")
|
||||||
|
fixture("mesecons_gamecompat")
|
||||||
|
|
||||||
|
local registered_on_player_receive_fields = {}
|
||||||
|
local old_register_on_player_receive_fields = minetest.register_on_player_receive_fields
|
||||||
|
function minetest.register_on_player_receive_fields(func)
|
||||||
|
old_register_on_player_receive_fields(func)
|
||||||
|
table.insert(registered_on_player_receive_fields, func)
|
||||||
|
end
|
||||||
|
|
||||||
|
mineunit:set_current_modname("mesecons_fpga")
|
||||||
|
mineunit:set_modpath("mesecons_fpga", "../mesecons_fpga")
|
||||||
|
sourcefile("../mesecons_fpga/init")
|
||||||
|
|
||||||
|
local fpga_user = Player("mesecons_fpga_user")
|
||||||
|
|
||||||
|
function mesecon._test_program_fpga(pos, program)
|
||||||
|
local node = minetest.get_node(pos)
|
||||||
|
assert.equal("mesecons_fpga:fpga", node.name:sub(1, 18))
|
||||||
|
|
||||||
|
local fields = {program = true}
|
||||||
|
for i, instr in ipairs(program) do
|
||||||
|
-- Translate the instruction into formspec fields.
|
||||||
|
local op1, act, op2, dst
|
||||||
|
if #instr == 3 then
|
||||||
|
act, op2, dst = unpack(instr)
|
||||||
|
else
|
||||||
|
assert.equal(4, #instr)
|
||||||
|
op1, act, op2, dst = unpack(instr)
|
||||||
|
end
|
||||||
|
fields[i .. "op1"] = op1
|
||||||
|
fields[i .. "act"] = (" "):rep(4 - #act) .. act
|
||||||
|
fields[i .. "op2"] = op2
|
||||||
|
fields[i .. "dst"] = dst
|
||||||
|
end
|
||||||
|
|
||||||
|
minetest.registered_nodes[node.name].on_rightclick(pos, node, fpga_user)
|
||||||
|
|
||||||
|
for _, func in ipairs(registered_on_player_receive_fields) do
|
||||||
|
if func(fpga_user, "mesecons:fpga", fields) then
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function mesecon._test_copy_fpga_program(pos)
|
||||||
|
fpga_user:get_inventory():set_stack("main", 1, "mesecons_fpga:programmer")
|
||||||
|
local pt = {type = "node", under = vector.new(pos), above = vector.offset(pos, 0, 1, 0)}
|
||||||
|
fpga_user:do_place(pt)
|
||||||
|
return fpga_user:get_wielded_item()
|
||||||
|
end
|
||||||
|
|
||||||
|
function mesecon._test_paste_fpga_program(pos, tool)
|
||||||
|
fpga_user:get_inventory():set_stack("main", 1, tool)
|
||||||
|
local pt = {type = "node", under = vector.new(pos), above = vector.offset(pos, 0, 1, 0)}
|
||||||
|
fpga_user:do_use(pt)
|
||||||
|
end
|
5
.test_fixtures/mesecons_gamecompat.lua
Normal file
5
.test_fixtures/mesecons_gamecompat.lua
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
fixture("mesecons")
|
||||||
|
|
||||||
|
mineunit:set_current_modname("mesecons_gamecompat")
|
||||||
|
mineunit:set_modpath("mesecons_gamecompat", "../mesecons_gamecompat")
|
||||||
|
sourcefile("../mesecons_gamecompat/init")
|
12
.test_fixtures/mesecons_luacontroller.lua
Normal file
12
.test_fixtures/mesecons_luacontroller.lua
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
fixture("mesecons")
|
||||||
|
fixture("mesecons_gamecompat")
|
||||||
|
|
||||||
|
mineunit:set_current_modname("mesecons_luacontroller")
|
||||||
|
mineunit:set_modpath("mesecons_luacontroller", "../mesecons_luacontroller")
|
||||||
|
sourcefile("../mesecons_luacontroller/init")
|
||||||
|
|
||||||
|
function mesecon._test_program_luac(pos, code)
|
||||||
|
local node = minetest.get_node(pos)
|
||||||
|
assert.equal("mesecons_luacontroller:luacontroller", node.name:sub(1, 36))
|
||||||
|
return minetest.registered_nodes[node.name].mesecons.luacontroller.set_program(pos, code)
|
||||||
|
end
|
45
.test_fixtures/mesecons_mvps.lua
Normal file
45
.test_fixtures/mesecons_mvps.lua
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
mineunit("protection")
|
||||||
|
|
||||||
|
fixture("mesecons")
|
||||||
|
|
||||||
|
mineunit:set_current_modname("mesecons_mvps")
|
||||||
|
mineunit:set_modpath("mesecons_mvps", "../mesecons_mvps")
|
||||||
|
sourcefile("../mesecons_mvps/init")
|
||||||
|
|
||||||
|
minetest.register_node("mesecons_mvps:test_stopper", {
|
||||||
|
description = "Test Stopper",
|
||||||
|
})
|
||||||
|
mesecon.register_mvps_stopper("mesecons_mvps:test_stopper")
|
||||||
|
|
||||||
|
minetest.register_node("mesecons_mvps:test_stopper_cond", {
|
||||||
|
description = "Test Stopper (Conditional)",
|
||||||
|
})
|
||||||
|
mesecon.register_mvps_stopper("mesecons_mvps:test_stopper_cond", function(node)
|
||||||
|
return node.param2 == 0
|
||||||
|
end)
|
||||||
|
|
||||||
|
minetest.register_node("mesecons_mvps:test_sticky", {
|
||||||
|
description = "Test Sticky",
|
||||||
|
mvps_sticky = function(pos)
|
||||||
|
local connected = {}
|
||||||
|
for i, rule in ipairs(mesecon.rules.alldirs) do
|
||||||
|
connected[i] = vector.add(pos, rule)
|
||||||
|
end
|
||||||
|
return connected
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
|
||||||
|
mesecon._test_moves = {}
|
||||||
|
minetest.register_node("mesecons_mvps:test_on_move", {
|
||||||
|
description = "Test Moveable",
|
||||||
|
mesecon = {
|
||||||
|
on_mvps_move = function(pos, node, oldpos, meta)
|
||||||
|
table.insert(mesecon._test_moves, {pos, node, oldpos, meta})
|
||||||
|
end
|
||||||
|
},
|
||||||
|
})
|
||||||
|
local old_reset = mesecon._test_reset
|
||||||
|
function mesecon._test_reset()
|
||||||
|
mesecon._test_moves = {}
|
||||||
|
old_reset()
|
||||||
|
end
|
6
.test_fixtures/screwdriver.lua
Normal file
6
.test_fixtures/screwdriver.lua
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
mineunit:set_current_modname("screwdriver")
|
||||||
|
|
||||||
|
screwdriver = {}
|
||||||
|
|
||||||
|
screwdriver.ROTATE_FACE = 1
|
||||||
|
screwdriver.ROTATE_AXIS = 2
|
@ -1,6 +1,12 @@
|
|||||||
The LGPLv3 applies to all code in this project.
|
The LGPLv3 applies to all code in this project.
|
||||||
The CC-BY-SA-3.0 license applies to textures and any other content in this project which is not source code.
|
The CC-BY-SA-3.0 license applies to textures and any other content in this project which is not source code.
|
||||||
|
|
||||||
|
The file mesecons_detector/textures/mesecons_detector_side.png is an unmodified copy of
|
||||||
|
"default_steel_block.png" by Jean-Patrick Guerrero <https://github.com/kilbith>, which can be found at
|
||||||
|
<https://github.com/minetest/minetest_game/blob/9528c0f8b93d6934930e99c3c116df275fb0e4bc/mods/default/textures/default_steel_block.png>.
|
||||||
|
"default_steel_block.png" is licensed under a CC BY-SA 3.0 license. This license can be found later in this document, and can also be found at
|
||||||
|
<https://creativecommons.org/licenses/by-sa/3.0/>. The artwork is reportedly copyright (C) 2010-2018 kilbith.
|
||||||
|
|
||||||
=================================================================
|
=================================================================
|
||||||
|
|
||||||
GNU LESSER GENERAL PUBLIC LICENSE
|
GNU LESSER GENERAL PUBLIC LICENSE
|
||||||
|
@ -99,7 +99,6 @@ mesecon.queue:add_function("receptor_off", function (pos, rules)
|
|||||||
local rulenames = mesecon.rules_link_rule_all(pos, rule)
|
local rulenames = mesecon.rules_link_rule_all(pos, rule)
|
||||||
for _, rulename in ipairs(rulenames) do
|
for _, rulename in ipairs(rulenames) do
|
||||||
mesecon.vm_begin()
|
mesecon.vm_begin()
|
||||||
mesecon.changesignal(np, minetest.get_node(np), rulename, mesecon.state.off, 2)
|
|
||||||
|
|
||||||
-- Turnoff returns true if turnoff process was successful, no onstate receptor
|
-- Turnoff returns true if turnoff process was successful, no onstate receptor
|
||||||
-- was found along the way. Commit changes that were made in voxelmanip. If turnoff
|
-- was found along the way. Commit changes that were made in voxelmanip. If turnoff
|
||||||
@ -118,8 +117,6 @@ function mesecon.receptor_off(pos, rules)
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
print("[OK] Mesecons")
|
|
||||||
|
|
||||||
-- Deprecated stuff
|
-- Deprecated stuff
|
||||||
-- To be removed in future releases
|
-- To be removed in future releases
|
||||||
dofile(minetest.get_modpath("mesecons").."/legacy.lua");
|
dofile(minetest.get_modpath("mesecons").."/legacy.lua");
|
||||||
|
@ -46,31 +46,23 @@
|
|||||||
-- mesecon.rotate_rules_down(rules)
|
-- mesecon.rotate_rules_down(rules)
|
||||||
-- These functions return rules that have been rotated in the specific direction
|
-- These functions return rules that have been rotated in the specific direction
|
||||||
|
|
||||||
local fifo_queue = dofile(minetest.get_modpath("mesecons").."/fifo_queue.lua")
|
-- See fifo_queue.lua for documentation.
|
||||||
|
mesecon.fifo_queue = dofile(minetest.get_modpath("mesecons").."/fifo_queue.lua")
|
||||||
|
|
||||||
-- General
|
-- General
|
||||||
function mesecon.get_effector(nodename)
|
function mesecon.get_effector(nodename)
|
||||||
if minetest.registered_nodes[nodename]
|
local def = minetest.registered_nodes[nodename]
|
||||||
and minetest.registered_nodes[nodename].mesecons
|
return def and def.mesecons and def.mesecons.effector
|
||||||
and minetest.registered_nodes[nodename].mesecons.effector then
|
|
||||||
return minetest.registered_nodes[nodename].mesecons.effector
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function mesecon.get_receptor(nodename)
|
function mesecon.get_receptor(nodename)
|
||||||
if minetest.registered_nodes[nodename]
|
local def = minetest.registered_nodes[nodename]
|
||||||
and minetest.registered_nodes[nodename].mesecons
|
return def and def.mesecons and def.mesecons.receptor
|
||||||
and minetest.registered_nodes[nodename].mesecons.receptor then
|
|
||||||
return minetest.registered_nodes[nodename].mesecons.receptor
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function mesecon.get_conductor(nodename)
|
function mesecon.get_conductor(nodename)
|
||||||
if minetest.registered_nodes[nodename]
|
local def = minetest.registered_nodes[nodename]
|
||||||
and minetest.registered_nodes[nodename].mesecons
|
return def and def.mesecons and def.mesecons.conductor
|
||||||
and minetest.registered_nodes[nodename].mesecons.conductor then
|
|
||||||
return minetest.registered_nodes[nodename].mesecons.conductor
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function mesecon.get_any_outputrules(node)
|
function mesecon.get_any_outputrules(node)
|
||||||
@ -421,7 +413,7 @@ end
|
|||||||
function mesecon.turnon(pos, link)
|
function mesecon.turnon(pos, link)
|
||||||
find_light_update_conductors()
|
find_light_update_conductors()
|
||||||
|
|
||||||
local frontiers = fifo_queue.new()
|
local frontiers = mesecon.fifo_queue.new()
|
||||||
frontiers:add({pos = pos, link = link})
|
frontiers:add({pos = pos, link = link})
|
||||||
local pos_can_be_skipped = {}
|
local pos_can_be_skipped = {}
|
||||||
|
|
||||||
@ -484,7 +476,7 @@ end
|
|||||||
function mesecon.turnoff(pos, link)
|
function mesecon.turnoff(pos, link)
|
||||||
find_light_update_conductors()
|
find_light_update_conductors()
|
||||||
|
|
||||||
local frontiers = fifo_queue.new()
|
local frontiers = mesecon.fifo_queue.new()
|
||||||
frontiers:add({pos = pos, link = link})
|
frontiers:add({pos = pos, link = link})
|
||||||
local signals = {}
|
local signals = {}
|
||||||
local pos_can_be_skipped = {}
|
local pos_can_be_skipped = {}
|
||||||
@ -541,9 +533,12 @@ function mesecon.turnoff(pos, link)
|
|||||||
end
|
end
|
||||||
|
|
||||||
for _, sig in ipairs(signals) do
|
for _, sig in ipairs(signals) do
|
||||||
mesecon.changesignal(sig.pos, sig.node, sig.link, mesecon.state.off, sig.depth)
|
-- If sig.depth is 1, it has not yet been checked that the power source is actually off.
|
||||||
if mesecon.is_effector_on(sig.node.name) and not mesecon.is_powered(sig.pos) then
|
if sig.depth > 1 or not mesecon.is_powered(sig.pos, sig.link) then
|
||||||
mesecon.deactivate(sig.pos, sig.node, sig.link, sig.depth)
|
mesecon.changesignal(sig.pos, sig.node, sig.link, mesecon.state.off, sig.depth)
|
||||||
|
if mesecon.is_effector_on(sig.node.name) and not mesecon.is_powered(sig.pos) then
|
||||||
|
mesecon.deactivate(sig.pos, sig.node, sig.link, sig.depth)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
3
mesecons/locale/mesecons.de.tr
Normal file
3
mesecons/locale/mesecons.de.tr
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
# textdomain: mesecons
|
||||||
|
|
||||||
|
Mesecons=Mesecons
|
4
mesecons/locale/mesecons.eo.tr
Normal file
4
mesecons/locale/mesecons.eo.tr
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
# textdomain: mesecons
|
||||||
|
|
||||||
|
### oldwires.lua ###
|
||||||
|
Mesecons=Mesekonduktilo
|
4
mesecons/locale/template.txt
Normal file
4
mesecons/locale/template.txt
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
# textdomain: mesecons
|
||||||
|
|
||||||
|
### oldwires.lua ###
|
||||||
|
Mesecons=
|
@ -1,3 +1,5 @@
|
|||||||
|
local S = minetest.get_translator(minetest.get_current_modname())
|
||||||
|
|
||||||
minetest.register_node("mesecons:mesecon_off", {
|
minetest.register_node("mesecons:mesecon_off", {
|
||||||
drawtype = "raillike",
|
drawtype = "raillike",
|
||||||
tiles = {"jeija_mesecon_off.png", "jeija_mesecon_curved_off.png", "jeija_mesecon_t_junction_off.png", "jeija_mesecon_crossing_off.png"},
|
tiles = {"jeija_mesecon_off.png", "jeija_mesecon_curved_off.png", "jeija_mesecon_t_junction_off.png", "jeija_mesecon_crossing_off.png"},
|
||||||
@ -11,7 +13,7 @@ minetest.register_node("mesecons:mesecon_off", {
|
|||||||
fixed = {-0.5, -0.5, -0.5, 0.5, -0.45, 0.5},
|
fixed = {-0.5, -0.5, -0.5, 0.5, -0.45, 0.5},
|
||||||
},
|
},
|
||||||
groups = {dig_immediate=3, mesecon=1, mesecon_conductor_craftable=1},
|
groups = {dig_immediate=3, mesecon=1, mesecon_conductor_craftable=1},
|
||||||
description="Mesecons",
|
description= S("Mesecons"),
|
||||||
mesecons = {conductor={
|
mesecons = {conductor={
|
||||||
state = mesecon.state.off,
|
state = mesecon.state.off,
|
||||||
onstate = "mesecons:mesecon_on"
|
onstate = "mesecons:mesecon_on"
|
||||||
|
@ -64,6 +64,8 @@ local rules_buttonlike = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
local function rules_from_dir(ruleset, dir)
|
local function rules_from_dir(ruleset, dir)
|
||||||
|
if not dir then return {} end
|
||||||
|
|
||||||
if dir.x == 1 then return ruleset.xp end
|
if dir.x == 1 then return ruleset.xp end
|
||||||
if dir.y == 1 then return ruleset.yp end
|
if dir.y == 1 then return ruleset.yp end
|
||||||
if dir.z == 1 then return ruleset.zp end
|
if dir.z == 1 then return ruleset.zp end
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
mesecon.on_placenode = function(pos, node)
|
mesecon.on_placenode = function(pos, node)
|
||||||
mesecon.execute_autoconnect_hooks_now(pos, node)
|
mesecon.execute_autoconnect_hooks_now(pos, node)
|
||||||
|
node = minetest.get_node(pos) -- Update the node in case it was just changed.
|
||||||
|
|
||||||
-- Receptors: Send on signal when active
|
-- Receptors: Send on signal when active
|
||||||
if mesecon.is_receptor_on(node.name) then
|
if mesecon.is_receptor_on(node.name) then
|
||||||
@ -11,18 +12,20 @@ mesecon.on_placenode = function(pos, node)
|
|||||||
-- Conductors: Send turnon signal when powered or replace by respective offstate conductor
|
-- Conductors: Send turnon signal when powered or replace by respective offstate conductor
|
||||||
-- if placed conductor is an onstate one
|
-- if placed conductor is an onstate one
|
||||||
if mesecon.is_conductor(node.name) then
|
if mesecon.is_conductor(node.name) then
|
||||||
|
local conductor = mesecon.get_conductor(node.name)
|
||||||
|
if conductor.state ~= mesecon.state.off then
|
||||||
|
-- Turn the conductor off.
|
||||||
|
node.name = conductor.offstate or conductor.states[1]
|
||||||
|
minetest.swap_node(pos, node)
|
||||||
|
end
|
||||||
local sources = mesecon.is_powered(pos)
|
local sources = mesecon.is_powered(pos)
|
||||||
if sources then
|
if sources then
|
||||||
-- also call receptor_on if itself is powered already, so that neighboring
|
mesecon.vm_begin()
|
||||||
-- conductors will be activated (when pushing an on-conductor with a piston)
|
|
||||||
for _, s in ipairs(sources) do
|
for _, s in ipairs(sources) do
|
||||||
local rule = vector.subtract(s, pos)
|
local rule = vector.subtract(s, pos)
|
||||||
mesecon.turnon(pos, rule)
|
mesecon.turnon(pos, rule)
|
||||||
end
|
end
|
||||||
--mesecon.receptor_on (pos, mesecon.conductor_get_rules(node))
|
mesecon.vm_commit()
|
||||||
elseif mesecon.is_conductor_on(node) then
|
|
||||||
node.name = mesecon.get_conductor_off(node)
|
|
||||||
minetest.swap_node(pos, node)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
62
mesecons/spec/action_spec.lua
Normal file
62
mesecons/spec/action_spec.lua
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
require("mineunit")
|
||||||
|
|
||||||
|
fixture("mesecons")
|
||||||
|
|
||||||
|
describe("action queue", function()
|
||||||
|
local layout = {
|
||||||
|
{{x = 1, y = 0, z = 0}, "mesecons:test_receptor_off"},
|
||||||
|
{{x = 0, y = 0, z = 0}, "mesecons:test_conductor_off"},
|
||||||
|
{{x = -1, y = 0, z = 0}, "mesecons:test_conductor_off"},
|
||||||
|
{{x = 0, y = 1, z = 0}, "mesecons:test_effector"},
|
||||||
|
{{x = -1, y = 1, z = 0}, "mesecons:test_effector"},
|
||||||
|
}
|
||||||
|
|
||||||
|
before_each(function()
|
||||||
|
world.layout(layout)
|
||||||
|
end)
|
||||||
|
|
||||||
|
after_each(function()
|
||||||
|
mesecon._test_reset()
|
||||||
|
world.clear()
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("executes in order", function()
|
||||||
|
world.set_node(layout[1][1], "mesecons:test_receptor_on")
|
||||||
|
mesecon.receptor_on(layout[1][1], mesecon.rules.alldirs)
|
||||||
|
mineunit:execute_globalstep() -- Execute receptor_on action
|
||||||
|
mineunit:execute_globalstep() -- Execute activate/change actions
|
||||||
|
assert.equal(2, #mesecon._test_effector_events)
|
||||||
|
assert.same({"on", layout[4][1]}, mesecon._test_effector_events[1])
|
||||||
|
assert.same({"on", layout[5][1]}, mesecon._test_effector_events[2])
|
||||||
|
|
||||||
|
world.set_node(layout[1][1], "mesecons:test_receptor_off")
|
||||||
|
mesecon.receptor_off(layout[1][1], mesecon.rules.alldirs)
|
||||||
|
mineunit:execute_globalstep() -- Execute receptor_off action
|
||||||
|
mineunit:execute_globalstep() -- Execute deactivate/change actions
|
||||||
|
assert.equal(4, #mesecon._test_effector_events)
|
||||||
|
assert.same({"off", layout[4][1]}, mesecon._test_effector_events[3])
|
||||||
|
assert.same({"off", layout[5][1]}, mesecon._test_effector_events[4])
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("discards outdated/overwritten node events", function()
|
||||||
|
world.set_node(layout[1][1], "mesecons:test_receptor_on")
|
||||||
|
mesecon.receptor_on(layout[1][1], mesecon.rules.alldirs)
|
||||||
|
world.set_node(layout[1][1], "mesecons:test_receptor_off")
|
||||||
|
mesecon.receptor_off(layout[1][1], mesecon.rules.alldirs)
|
||||||
|
mineunit:execute_globalstep() -- Execute receptor_off action
|
||||||
|
mineunit:execute_globalstep() -- Execute deactivate/change actions
|
||||||
|
assert.equal(0, #mesecon._test_effector_events)
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("delays actions", function()
|
||||||
|
world.set_node(layout[1][1], "mesecons:test_receptor_on")
|
||||||
|
mesecon.queue:add_action(layout[1][1], "receptor_on", {mesecon.rules.alldirs}, 1, nil)
|
||||||
|
mineunit:execute_globalstep(0.1)
|
||||||
|
mineunit:execute_globalstep(1)
|
||||||
|
assert.equal(0, #mesecon._test_effector_events)
|
||||||
|
mineunit:execute_globalstep() -- Execute receptor_on action
|
||||||
|
assert.equal(0, #mesecon._test_effector_events)
|
||||||
|
mineunit:execute_globalstep() -- Execute activate/change actions
|
||||||
|
assert.equal(2, #mesecon._test_effector_events)
|
||||||
|
end)
|
||||||
|
end)
|
1
mesecons/spec/mineunit.conf
Normal file
1
mesecons/spec/mineunit.conf
Normal file
@ -0,0 +1 @@
|
|||||||
|
fixture_paths = {"../.test_fixtures"}
|
192
mesecons/spec/service_spec.lua
Normal file
192
mesecons/spec/service_spec.lua
Normal file
@ -0,0 +1,192 @@
|
|||||||
|
require("mineunit")
|
||||||
|
|
||||||
|
fixture("mesecons")
|
||||||
|
fixture("screwdriver")
|
||||||
|
|
||||||
|
describe("placement/digging service", function()
|
||||||
|
local layout = {
|
||||||
|
{{x = 1, y = 0, z = 0}, "mesecons:test_receptor_on"},
|
||||||
|
{{x = 0, y = 0, z = 0}, "mesecons:test_conductor_on"},
|
||||||
|
{{x = -1, y = 0, z = 0}, "mesecons:test_conductor_on"},
|
||||||
|
{{x = 0, y = 1, z = 0}, "mesecons:test_effector"},
|
||||||
|
{{x = -2, y = 0, z = 0}, "mesecons:test_effector"},
|
||||||
|
{{x = 2, y = 0, z = 0}, "mesecons:test_effector"},
|
||||||
|
}
|
||||||
|
|
||||||
|
before_each(function()
|
||||||
|
world.layout(layout)
|
||||||
|
end)
|
||||||
|
|
||||||
|
after_each(function()
|
||||||
|
mesecon._test_reset()
|
||||||
|
world.clear()
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("updates components when a receptor changes", function()
|
||||||
|
-- Dig then replace a receptor and check that the connected effectors changed.
|
||||||
|
|
||||||
|
mesecon._test_dig(layout[1][1])
|
||||||
|
mineunit:execute_globalstep() -- Execute receptor_off action
|
||||||
|
assert.equal("mesecons:test_conductor_off", world.get_node(layout[2][1]).name)
|
||||||
|
mineunit:execute_globalstep() -- Execute deactivate/change actions
|
||||||
|
assert.equal(3, #mesecon._test_effector_events)
|
||||||
|
|
||||||
|
mesecon._test_place(layout[1][1], "mesecons:test_receptor_on")
|
||||||
|
mineunit:execute_globalstep() -- Execute receptor_on action
|
||||||
|
assert.equal("mesecons:test_conductor_on", world.get_node(layout[2][1]).name)
|
||||||
|
mineunit:execute_globalstep() -- Execute activate/change action
|
||||||
|
assert.equal(6, #mesecon._test_effector_events)
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("updates components when a conductor changes", function()
|
||||||
|
-- Dig then replace a powered conductor and check that the connected effectors changed.
|
||||||
|
|
||||||
|
mesecon._test_dig(layout[2][1])
|
||||||
|
mineunit:execute_globalstep() -- Execute receptor_off action
|
||||||
|
assert.equal("mesecons:test_conductor_off", world.get_node(layout[3][1]).name)
|
||||||
|
mineunit:execute_globalstep() -- Execute deactivate/change actions
|
||||||
|
assert.equal(2, #mesecon._test_effector_events)
|
||||||
|
|
||||||
|
mesecon._test_place(layout[2][1], "mesecons:test_conductor_off")
|
||||||
|
assert.equal("mesecons:test_conductor_on", world.get_node(layout[2][1]).name)
|
||||||
|
assert.equal("mesecons:test_conductor_on", world.get_node(layout[3][1]).name)
|
||||||
|
mineunit:execute_globalstep() -- Execute activate/change actions
|
||||||
|
assert.equal(4, #mesecon._test_effector_events)
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("updates effectors on placement", function()
|
||||||
|
local pos = {x = 0, y = 0, z = 1}
|
||||||
|
mesecon._test_place(pos, "mesecons:test_effector")
|
||||||
|
mineunit:execute_globalstep() -- Execute activate/change actions
|
||||||
|
assert.equal(tonumber("10100000", 2), world.get_node(pos).param2)
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("updates multiconductors on placement", function()
|
||||||
|
local pos = {x = 0, y = 0, z = 1}
|
||||||
|
mesecon._test_place(pos, "mesecons:test_multiconductor_off")
|
||||||
|
assert.equal("mesecons:test_multiconductor_010", world.get_node(pos).name)
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("turns off conductors on placement", function()
|
||||||
|
local pos = {x = 3, y = 0, z = 0}
|
||||||
|
mesecon._test_place(pos, "mesecons:test_conductor_on")
|
||||||
|
assert.equal("mesecons:test_conductor_off", world.get_node(pos).name)
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("turns off multiconductors on placement", function()
|
||||||
|
local pos = {x = 3, y = 0, z = 0}
|
||||||
|
mesecon._test_place(pos, "mesecons:test_multiconductor_on")
|
||||||
|
assert.equal("mesecons:test_multiconductor_off", world.get_node(pos).name)
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("triggers autoconnect hooks", function()
|
||||||
|
mesecon._test_dig(layout[2][1])
|
||||||
|
mineunit:execute_globalstep() -- Execute delayed hook
|
||||||
|
assert.equal(1, #mesecon._test_autoconnects)
|
||||||
|
|
||||||
|
mesecon._test_place(layout[2][1], layout[2][2])
|
||||||
|
assert.equal(2, #mesecon._test_autoconnects)
|
||||||
|
end)
|
||||||
|
end)
|
||||||
|
|
||||||
|
describe("overheating service", function()
|
||||||
|
local layout = {
|
||||||
|
{{x = 0, y = 0, z = 0}, "mesecons:test_receptor_off"},
|
||||||
|
{{x = 1, y = 0, z = 0}, "mesecons:test_effector"},
|
||||||
|
{{x = 2, y = 0, z = 0}, "mesecons:test_receptor_on"},
|
||||||
|
}
|
||||||
|
|
||||||
|
before_each(function()
|
||||||
|
world.layout(layout)
|
||||||
|
end)
|
||||||
|
|
||||||
|
after_each(function()
|
||||||
|
mesecon._test_reset()
|
||||||
|
world.clear()
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("tracks heat", function()
|
||||||
|
mesecon.do_overheat(layout[2][1])
|
||||||
|
assert.equal(1, mesecon.get_heat(layout[2][1]))
|
||||||
|
mesecon.do_cooldown(layout[2][1])
|
||||||
|
assert.equal(0, mesecon.get_heat(layout[2][1]))
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("cools over time", function()
|
||||||
|
mesecon.do_overheat(layout[2][1])
|
||||||
|
assert.equal(1, mesecon.get_heat(layout[2][1]))
|
||||||
|
mineunit:execute_globalstep(60)
|
||||||
|
mineunit:execute_globalstep(60)
|
||||||
|
mineunit:execute_globalstep(60)
|
||||||
|
assert.equal(0, mesecon.get_heat(layout[2][1]))
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("tracks movement", function()
|
||||||
|
local oldpos = layout[2][1]
|
||||||
|
local pos = vector.offset(oldpos, 0, 1, 0)
|
||||||
|
mesecon.do_overheat(oldpos)
|
||||||
|
mesecon.move_hot_nodes({{pos = pos, oldpos = oldpos}})
|
||||||
|
assert.equal(0, mesecon.get_heat(oldpos))
|
||||||
|
assert.equal(1, mesecon.get_heat(pos))
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("causes overheating", function()
|
||||||
|
-- Switch the first receptor on and off until it overheats/breaks a receptor.
|
||||||
|
repeat
|
||||||
|
if mesecon.flipstate(layout[1][1], minetest.get_node(layout[1][1])) == "on" then
|
||||||
|
mesecon.receptor_on(layout[1][1], mesecon.rules.alldirs)
|
||||||
|
else
|
||||||
|
mesecon.receptor_off(layout[1][1], mesecon.rules.alldirs)
|
||||||
|
end
|
||||||
|
mineunit:execute_globalstep(0) -- Execute receptor_on/receptor_off/activate/deactivate/change actions
|
||||||
|
until minetest.get_node(layout[2][1]).name ~= "mesecons:test_effector"
|
||||||
|
assert.same({"overheat", layout[2][1]}, mesecon._test_effector_events[#mesecon._test_effector_events])
|
||||||
|
assert.equal(0, mesecon.get_heat(layout[2][1]))
|
||||||
|
end)
|
||||||
|
end)
|
||||||
|
|
||||||
|
describe("screwdriver service", function()
|
||||||
|
local layout = {
|
||||||
|
{{x = 0, y = 0, z = 0}, "mesecons:test_conductor_rot_on"},
|
||||||
|
{{x = 1, y = 0, z = 0}, "mesecons:test_receptor_on"},
|
||||||
|
{{x = -1, y = 0, z = 0}, "mesecons:test_conductor_on"},
|
||||||
|
{{x = 0, y = 0, z = 1}, "mesecons:test_receptor_on"},
|
||||||
|
{{x = 0, y = 0, z = -1}, "mesecons:test_conductor_off"},
|
||||||
|
}
|
||||||
|
|
||||||
|
local function rotate(new_param2)
|
||||||
|
local pos = layout[1][1]
|
||||||
|
local node = world.get_node(pos)
|
||||||
|
local on_rotate = minetest.registered_nodes[node.name].on_rotate
|
||||||
|
on_rotate(pos, node, nil, screwdriver.ROTATE_FACE, new_param2)
|
||||||
|
end
|
||||||
|
|
||||||
|
before_each(function()
|
||||||
|
world.layout(layout)
|
||||||
|
end)
|
||||||
|
|
||||||
|
after_each(function()
|
||||||
|
mesecon._test_reset()
|
||||||
|
world.clear()
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("updates conductors", function()
|
||||||
|
-- Rotate a conductor and see that the circuit state changes.
|
||||||
|
rotate(1)
|
||||||
|
mineunit:execute_globalstep() -- Execute receptor_off action
|
||||||
|
assert.equal("mesecons:test_conductor_off", world.get_node(layout[3][1]).name)
|
||||||
|
assert.equal("mesecons:test_conductor_on", world.get_node(layout[5][1]).name)
|
||||||
|
rotate(2)
|
||||||
|
mineunit:execute_globalstep() -- Execute receptor_off action
|
||||||
|
assert.equal("mesecons:test_conductor_on", world.get_node(layout[3][1]).name)
|
||||||
|
assert.equal("mesecons:test_conductor_off", world.get_node(layout[5][1]).name)
|
||||||
|
rotate(3)
|
||||||
|
mineunit:execute_globalstep() -- Execute receptor_off action
|
||||||
|
assert.equal("mesecons:test_conductor_off", world.get_node(layout[3][1]).name)
|
||||||
|
assert.equal("mesecons:test_conductor_on", world.get_node(layout[5][1]).name)
|
||||||
|
rotate(0)
|
||||||
|
mineunit:execute_globalstep() -- Execute receptor_off action
|
||||||
|
assert.equal("mesecons:test_conductor_on", world.get_node(layout[3][1]).name)
|
||||||
|
assert.equal("mesecons:test_conductor_off", world.get_node(layout[5][1]).name)
|
||||||
|
end)
|
||||||
|
end)
|
147
mesecons/spec/state_spec.lua
Normal file
147
mesecons/spec/state_spec.lua
Normal file
@ -0,0 +1,147 @@
|
|||||||
|
require("mineunit")
|
||||||
|
|
||||||
|
fixture("mesecons")
|
||||||
|
|
||||||
|
describe("state", function()
|
||||||
|
local layout = {
|
||||||
|
{{x = 1, y = 0, z = 0}, "mesecons:test_receptor_off"},
|
||||||
|
{{x = 0, y = 1, z = 0}, "mesecons:test_receptor_off"},
|
||||||
|
{{x = 0, y = 0, z = 0}, "mesecons:test_conductor_off"},
|
||||||
|
{{x = -1, y = 0, z = 0}, "mesecons:test_effector"},
|
||||||
|
{{x = 2, y = 0, z = 0}, "mesecons:test_effector"},
|
||||||
|
{{x = 0, y = -1, z = 0}, "mesecons:test_effector"},
|
||||||
|
}
|
||||||
|
|
||||||
|
before_each(function()
|
||||||
|
world.layout(layout)
|
||||||
|
end)
|
||||||
|
|
||||||
|
after_each(function()
|
||||||
|
mesecon._test_reset()
|
||||||
|
world.clear()
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("turns on", function()
|
||||||
|
world.set_node(layout[1][1], "mesecons:test_receptor_on")
|
||||||
|
mesecon.receptor_on(layout[1][1], mesecon.rules.alldirs)
|
||||||
|
mineunit:execute_globalstep() -- Execute receptor_on action
|
||||||
|
mineunit:execute_globalstep() -- Execute activate/change actions
|
||||||
|
assert.equal("mesecons:test_conductor_on", world.get_node(layout[3][1]).name)
|
||||||
|
assert.equal(tonumber("10000001", 2), world.get_node(layout[4][1]).param2)
|
||||||
|
assert.equal(tonumber("10000010", 2), world.get_node(layout[5][1]).param2)
|
||||||
|
assert.equal(tonumber("10000100", 2), world.get_node(layout[6][1]).param2)
|
||||||
|
|
||||||
|
world.set_node(layout[2][1], "mesecons:test_receptor_on")
|
||||||
|
mesecon.receptor_on(layout[2][1], mesecon.rules.alldirs)
|
||||||
|
mineunit:execute_globalstep() -- Execute receptor_on action
|
||||||
|
mineunit:execute_globalstep() -- Execute activate/change actions
|
||||||
|
assert.equal("mesecons:test_conductor_on", world.get_node(layout[3][1]).name)
|
||||||
|
assert.equal(tonumber("10000001", 2), world.get_node(layout[4][1]).param2)
|
||||||
|
assert.equal(tonumber("10000010", 2), world.get_node(layout[5][1]).param2)
|
||||||
|
assert.equal(tonumber("10000100", 2), world.get_node(layout[6][1]).param2)
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("turns off", function()
|
||||||
|
world.set_node(layout[1][1], "mesecons:test_receptor_on")
|
||||||
|
world.set_node(layout[2][1], "mesecons:test_receptor_on")
|
||||||
|
mesecon.receptor_on(layout[1][1], mesecon.rules.alldirs)
|
||||||
|
mesecon.receptor_on(layout[2][1], mesecon.rules.alldirs)
|
||||||
|
mineunit:execute_globalstep() -- Execute receptor_on actions
|
||||||
|
|
||||||
|
world.set_node(layout[1][1], "mesecons:test_receptor_off")
|
||||||
|
mesecon.receptor_off(layout[1][1], mesecon.rules.alldirs)
|
||||||
|
mineunit:execute_globalstep() -- Execute receptor_off and activate/change actions
|
||||||
|
mineunit:execute_globalstep() -- Execute deactivate/change actions
|
||||||
|
assert.equal("mesecons:test_conductor_on", world.get_node(layout[3][1]).name)
|
||||||
|
assert.equal(tonumber("10000001", 2), world.get_node(layout[4][1]).param2)
|
||||||
|
assert.equal(tonumber("00000000", 2), world.get_node(layout[5][1]).param2)
|
||||||
|
assert.equal(tonumber("10000100", 2), world.get_node(layout[6][1]).param2)
|
||||||
|
|
||||||
|
world.set_node(layout[2][1], "mesecons:test_receptor_off")
|
||||||
|
mesecon.receptor_off(layout[2][1], mesecon.rules.alldirs)
|
||||||
|
mineunit:execute_globalstep() -- Execute receptor_off action
|
||||||
|
mineunit:execute_globalstep() -- Execute deactivate/change actions
|
||||||
|
assert.equal("mesecons:test_conductor_off", world.get_node(layout[3][1]).name)
|
||||||
|
assert.equal(tonumber("00000000", 2), world.get_node(layout[4][1]).param2)
|
||||||
|
assert.equal(tonumber("00000000", 2), world.get_node(layout[5][1]).param2)
|
||||||
|
assert.equal(tonumber("00000000", 2), world.get_node(layout[6][1]).param2)
|
||||||
|
end)
|
||||||
|
end)
|
||||||
|
|
||||||
|
describe("rotation", function()
|
||||||
|
local layout = {
|
||||||
|
{{x = 0, y = 0, z = 0}, "mesecons:test_receptor_off"},
|
||||||
|
{{x = 1, y = 0, z = 0}, {name = "mesecons:test_conductor_rot_off", param2 = 0}},
|
||||||
|
{{x = 0, y = 0, z = 1}, {name = "mesecons:test_conductor_rot_off", param2 = 1}},
|
||||||
|
{{x = -1, y = 0, z = 0}, {name = "mesecons:test_conductor_rot_off", param2 = 2}},
|
||||||
|
{{x = 0, y = 0, z = -1}, {name = "mesecons:test_conductor_rot_off", param2 = 3}},
|
||||||
|
}
|
||||||
|
|
||||||
|
before_each(function()
|
||||||
|
for _, entry in ipairs(layout) do
|
||||||
|
world.set_node(entry[1], entry[2])
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
after_each(function()
|
||||||
|
mesecon._test_reset()
|
||||||
|
world.clear()
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("works", function()
|
||||||
|
world.set_node(layout[1][1], "mesecons:test_receptor_on")
|
||||||
|
mesecon.receptor_on(layout[1][1], mesecon.rules.alldirs)
|
||||||
|
mineunit:execute_globalstep() -- Execute receptor_on action
|
||||||
|
assert.equal("mesecons:test_conductor_rot_on", world.get_node(layout[2][1]).name)
|
||||||
|
assert.equal("mesecons:test_conductor_rot_on", world.get_node(layout[3][1]).name)
|
||||||
|
assert.equal("mesecons:test_conductor_rot_on", world.get_node(layout[4][1]).name)
|
||||||
|
assert.equal("mesecons:test_conductor_rot_on", world.get_node(layout[5][1]).name)
|
||||||
|
end)
|
||||||
|
end)
|
||||||
|
|
||||||
|
describe("multiconductor", function()
|
||||||
|
local layout = {
|
||||||
|
{{x = 1, y = 0, z = 0}, "mesecons:test_receptor_off"},
|
||||||
|
{{x = 0, y = 1, z = 0}, "mesecons:test_receptor_off"},
|
||||||
|
{{x = 0, y = 0, z = 1}, "mesecons:test_receptor_off"},
|
||||||
|
{{x = 0, y = 0, z = 0}, "mesecons:test_multiconductor_off"},
|
||||||
|
}
|
||||||
|
|
||||||
|
before_each(function()
|
||||||
|
world.layout(layout)
|
||||||
|
end)
|
||||||
|
|
||||||
|
after_each(function()
|
||||||
|
world.clear()
|
||||||
|
mesecon._test_reset()
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("separates its subparts", function()
|
||||||
|
world.set_node(layout[1][1], "mesecons:test_receptor_on")
|
||||||
|
mesecon.receptor_on(layout[1][1], mesecon.rules.alldirs)
|
||||||
|
mineunit:execute_globalstep() -- Execute receptor_on action
|
||||||
|
assert.equal("mesecons:test_multiconductor_001", world.get_node(layout[4][1]).name)
|
||||||
|
|
||||||
|
world.set_node(layout[2][1], "mesecons:test_receptor_on")
|
||||||
|
mesecon.receptor_on(layout[2][1], mesecon.rules.alldirs)
|
||||||
|
mineunit:execute_globalstep() -- Execute receptor_on action
|
||||||
|
assert.equal("mesecons:test_multiconductor_011", world.get_node(layout[4][1]).name)
|
||||||
|
|
||||||
|
world.set_node(layout[3][1], "mesecons:test_receptor_on")
|
||||||
|
mesecon.receptor_on(layout[3][1], mesecon.rules.alldirs)
|
||||||
|
mineunit:execute_globalstep() -- Execute receptor_on action
|
||||||
|
assert.equal("mesecons:test_multiconductor_on", world.get_node(layout[4][1]).name)
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("loops through itself", function()
|
||||||
|
-- Make a loop.
|
||||||
|
world.set_node({x = 0, y = -1, z = 0}, "mesecons:test_conductor_off")
|
||||||
|
world.set_node({x = -1, y = -1, z = 0}, "mesecons:test_conductor_off")
|
||||||
|
world.set_node({x = -1, y = 0, z = 0}, "mesecons:test_conductor_off")
|
||||||
|
|
||||||
|
world.set_node(layout[1][1], "mesecons:test_receptor_on")
|
||||||
|
mesecon.receptor_on(layout[1][1], mesecon.rules.alldirs)
|
||||||
|
mineunit:execute_globalstep() -- Execute receptor_on action
|
||||||
|
assert.equal("mesecons:test_multiconductor_101", world.get_node(layout[4][1]).name)
|
||||||
|
end)
|
||||||
|
end)
|
@ -6,6 +6,24 @@ function mesecon.move_node(pos, newpos)
|
|||||||
minetest.get_meta(pos):from_table(meta)
|
minetest.get_meta(pos):from_table(meta)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- An on_rotate callback for mesecons components.
|
||||||
|
function mesecon.on_rotate(pos, node, _, _, new_param2)
|
||||||
|
local new_node = {name = node.name, param1 = node.param1, param2 = new_param2}
|
||||||
|
minetest.swap_node(pos, new_node)
|
||||||
|
mesecon.on_dignode(pos, node)
|
||||||
|
mesecon.on_placenode(pos, new_node)
|
||||||
|
minetest.check_for_falling(pos)
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
-- An on_rotate callback for components which stay horizontal.
|
||||||
|
function mesecon.on_rotate_horiz(pos, node, user, mode, new_param2)
|
||||||
|
if not minetest.global_exists("screwdriver") or mode ~= screwdriver.ROTATE_FACE then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
return mesecon.on_rotate(pos, node, user, mode, new_param2)
|
||||||
|
end
|
||||||
|
|
||||||
-- Rules rotation Functions:
|
-- Rules rotation Functions:
|
||||||
function mesecon.rotate_rules_right(rules)
|
function mesecon.rotate_rules_right(rules)
|
||||||
local nr = {}
|
local nr = {}
|
||||||
@ -54,7 +72,28 @@ function mesecon.rotate_rules_up(rules)
|
|||||||
end
|
end
|
||||||
return nr
|
return nr
|
||||||
end
|
end
|
||||||
--
|
|
||||||
|
-- Returns a rules getter function that returns different rules depending on the node's horizontal rotation.
|
||||||
|
-- If param2 % 4 == 0, then the rules returned by the getter are a copy of base_rules.
|
||||||
|
function mesecon.horiz_rules_getter(base_rules)
|
||||||
|
local rotations = {mesecon.tablecopy(base_rules)}
|
||||||
|
for i = 2, 4 do
|
||||||
|
local right_rules = rotations[i - 1]
|
||||||
|
if not right_rules[1] or right_rules[1].x then
|
||||||
|
-- flat rules
|
||||||
|
rotations[i] = mesecon.rotate_rules_left(right_rules)
|
||||||
|
else
|
||||||
|
-- not flat
|
||||||
|
rotations[i] = {}
|
||||||
|
for j, rules in ipairs(right_rules) do
|
||||||
|
rotations[i][j] = mesecon.rotate_rules_left(rules)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return function(node)
|
||||||
|
return rotations[node.param2 % 4 + 1]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
function mesecon.flattenrules(allrules)
|
function mesecon.flattenrules(allrules)
|
||||||
--[[
|
--[[
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
-- The BLINKY_PLANT
|
-- The BLINKY_PLANT
|
||||||
|
|
||||||
|
local S = minetest.get_translator(minetest.get_current_modname())
|
||||||
|
|
||||||
local toggle_timer = function (pos)
|
local toggle_timer = function (pos)
|
||||||
local timer = minetest.get_node_timer(pos)
|
local timer = minetest.get_node_timer(pos)
|
||||||
if timer:is_started() then
|
if timer:is_started() then
|
||||||
@ -20,13 +22,13 @@ local on_timer = function (pos)
|
|||||||
end
|
end
|
||||||
|
|
||||||
mesecon.register_node("mesecons_blinkyplant:blinky_plant", {
|
mesecon.register_node("mesecons_blinkyplant:blinky_plant", {
|
||||||
description="Blinky Plant",
|
description= S("Blinky Plant"),
|
||||||
drawtype = "plantlike",
|
drawtype = "plantlike",
|
||||||
inventory_image = "jeija_blinky_plant_off.png",
|
inventory_image = "jeija_blinky_plant_off.png",
|
||||||
paramtype = "light",
|
paramtype = "light",
|
||||||
is_ground_content = false,
|
is_ground_content = false,
|
||||||
walkable = false,
|
walkable = false,
|
||||||
sounds = default.node_sound_leaves_defaults(),
|
sounds = mesecon.node_sound.leaves,
|
||||||
selection_box = {
|
selection_box = {
|
||||||
type = "fixed",
|
type = "fixed",
|
||||||
fixed = {-0.3, -0.5, -0.3, 0.3, -0.5+0.7, 0.3},
|
fixed = {-0.3, -0.5, -0.3, 0.3, -0.5+0.7, 0.3},
|
||||||
|
2
mesecons_blinkyplant/locale/mesecons_blinkyplant.de.tr
Normal file
2
mesecons_blinkyplant/locale/mesecons_blinkyplant.de.tr
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
# textdomain: mesecons_blinkyplant
|
||||||
|
Blinky Plant=Blinkpflanze
|
4
mesecons_blinkyplant/locale/mesecons_blinkyplant.eo.tr
Normal file
4
mesecons_blinkyplant/locale/mesecons_blinkyplant.eo.tr
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
# textdomain: mesecons_blinkyplant
|
||||||
|
|
||||||
|
### init.lua ###
|
||||||
|
Blinky Plant=Palpebruma Planto
|
4
mesecons_blinkyplant/locale/template.txt
Normal file
4
mesecons_blinkyplant/locale/template.txt
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
# textdomain: mesecons_blinkyplant
|
||||||
|
|
||||||
|
### init.lua ###
|
||||||
|
Blinky Plant=
|
@ -1,2 +1,2 @@
|
|||||||
name = mesecons_blinkyplant
|
name = mesecons_blinkyplant
|
||||||
depends = default, mesecons
|
depends = mesecons, mesecons_gamecompat
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
-- WALL BUTTON
|
-- WALL BUTTON
|
||||||
-- A button that when pressed emits power for 1 second
|
-- A button that when pressed emits power for 1 second
|
||||||
-- and then turns off again
|
-- and then turns off again
|
||||||
|
local S = minetest.get_translator(minetest.get_current_modname())
|
||||||
|
|
||||||
mesecon.button_turnoff = function (pos)
|
mesecon.button_turnoff = function (pos)
|
||||||
local node = minetest.get_node(pos)
|
local node = minetest.get_node(pos)
|
||||||
@ -45,14 +46,14 @@ minetest.register_node("mesecons_button:button_off", {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
groups = {dig_immediate=2, mesecon_needs_receiver = 1},
|
groups = {dig_immediate=2, mesecon_needs_receiver = 1},
|
||||||
description = "Button",
|
description = S("Button"),
|
||||||
on_rightclick = function (pos, node)
|
on_rightclick = function (pos, node)
|
||||||
minetest.swap_node(pos, {name = "mesecons_button:button_on", param2=node.param2})
|
minetest.swap_node(pos, {name = "mesecons_button:button_on", param2=node.param2})
|
||||||
mesecon.receptor_on(pos, mesecon.rules.buttonlike_get(node))
|
mesecon.receptor_on(pos, mesecon.rules.buttonlike_get(node))
|
||||||
minetest.sound_play("mesecons_button_push", { pos = pos }, true)
|
minetest.sound_play("mesecons_button_push", { pos = pos }, true)
|
||||||
minetest.get_node_timer(pos):start(1)
|
minetest.get_node_timer(pos):start(1)
|
||||||
end,
|
end,
|
||||||
sounds = default.node_sound_stone_defaults(),
|
sounds = mesecon.node_sound.stone,
|
||||||
mesecons = {receptor = {
|
mesecons = {receptor = {
|
||||||
state = mesecon.state.off,
|
state = mesecon.state.off,
|
||||||
rules = mesecon.rules.buttonlike_get
|
rules = mesecon.rules.buttonlike_get
|
||||||
@ -92,8 +93,8 @@ minetest.register_node("mesecons_button:button_on", {
|
|||||||
},
|
},
|
||||||
groups = {dig_immediate=2, not_in_creative_inventory=1, mesecon_needs_receiver = 1},
|
groups = {dig_immediate=2, not_in_creative_inventory=1, mesecon_needs_receiver = 1},
|
||||||
drop = 'mesecons_button:button_off',
|
drop = 'mesecons_button:button_off',
|
||||||
description = "Button",
|
description = S("Button"),
|
||||||
sounds = default.node_sound_stone_defaults(),
|
sounds = mesecon.node_sound.stone,
|
||||||
mesecons = {receptor = {
|
mesecons = {receptor = {
|
||||||
state = mesecon.state.on,
|
state = mesecon.state.on,
|
||||||
rules = mesecon.rules.buttonlike_get
|
rules = mesecon.rules.buttonlike_get
|
||||||
@ -105,6 +106,6 @@ minetest.register_node("mesecons_button:button_on", {
|
|||||||
minetest.register_craft({
|
minetest.register_craft({
|
||||||
output = "mesecons_button:button_off 2",
|
output = "mesecons_button:button_off 2",
|
||||||
recipe = {
|
recipe = {
|
||||||
{"group:mesecon_conductor_craftable","default:stone"},
|
{"group:mesecon_conductor_craftable","mesecons_gamecompat:stone"},
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
2
mesecons_button/locale/mesecons_button.de.tr
Normal file
2
mesecons_button/locale/mesecons_button.de.tr
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
# textdomain: mesecons_button
|
||||||
|
Button=Taster
|
4
mesecons_button/locale/mesecons_button.eo.tr
Normal file
4
mesecons_button/locale/mesecons_button.eo.tr
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
# textdomain: mesecons_button
|
||||||
|
|
||||||
|
### init.lua ###
|
||||||
|
Button=Butono
|
4
mesecons_button/locale/template.txt
Normal file
4
mesecons_button/locale/template.txt
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
# textdomain: mesecons_button
|
||||||
|
|
||||||
|
### init.lua ###
|
||||||
|
Button=
|
@ -1,2 +1,2 @@
|
|||||||
name = mesecons_button
|
name = mesecons_button
|
||||||
depends = default, mesecons, mesecons_receiver
|
depends = mesecons, mesecons_gamecompat, mesecons_receiver
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
|
local S = minetest.get_translator(minetest.get_current_modname())
|
||||||
|
|
||||||
minetest.register_chatcommand("say", {
|
minetest.register_chatcommand("say", {
|
||||||
params = "<text>",
|
params = "<text>",
|
||||||
description = "Say <text> as the server",
|
description = S("Say <text> as the server"),
|
||||||
privs = {server=true},
|
privs = {server=true},
|
||||||
func = function(name, param)
|
func = function(name, param)
|
||||||
minetest.chat_send_all(name .. ": " .. param)
|
minetest.chat_send_all(name .. ": " .. param)
|
||||||
@ -9,7 +11,7 @@ minetest.register_chatcommand("say", {
|
|||||||
|
|
||||||
minetest.register_chatcommand("tell", {
|
minetest.register_chatcommand("tell", {
|
||||||
params = "<name> <text>",
|
params = "<name> <text>",
|
||||||
description = "Say <text> to <name> privately",
|
description = S("Say <text> to <name> privately"),
|
||||||
privs = {shout=true},
|
privs = {shout=true},
|
||||||
func = function(name, param)
|
func = function(name, param)
|
||||||
local found, _, target, message = param:find("^([^%s]+)%s+(.*)$")
|
local found, _, target, message = param:find("^([^%s]+)%s+(.*)$")
|
||||||
@ -26,7 +28,7 @@ minetest.register_chatcommand("tell", {
|
|||||||
|
|
||||||
minetest.register_chatcommand("hp", {
|
minetest.register_chatcommand("hp", {
|
||||||
params = "<name> <value>",
|
params = "<name> <value>",
|
||||||
description = "Set health of <name> to <value> hitpoints",
|
description = S("Set health of <name> to <value> hitpoints"),
|
||||||
privs = {ban=true},
|
privs = {ban=true},
|
||||||
func = function(name, param)
|
func = function(name, param)
|
||||||
local found, _, target, value = param:find("^([^%s]+)%s+(%d+)$")
|
local found, _, target, value = param:find("^([^%s]+)%s+(%d+)$")
|
||||||
@ -180,7 +182,7 @@ local function can_dig(pos, player)
|
|||||||
end
|
end
|
||||||
|
|
||||||
minetest.register_node("mesecons_commandblock:commandblock_off", {
|
minetest.register_node("mesecons_commandblock:commandblock_off", {
|
||||||
description = "Command Block",
|
description = S("Command Block"),
|
||||||
tiles = {"jeija_commandblock_off.png"},
|
tiles = {"jeija_commandblock_off.png"},
|
||||||
inventory_image = minetest.inventorycube("jeija_commandblock_off.png"),
|
inventory_image = minetest.inventorycube("jeija_commandblock_off.png"),
|
||||||
is_ground_content = false,
|
is_ground_content = false,
|
||||||
@ -189,7 +191,7 @@ minetest.register_node("mesecons_commandblock:commandblock_off", {
|
|||||||
after_place_node = after_place,
|
after_place_node = after_place,
|
||||||
on_receive_fields = receive_fields,
|
on_receive_fields = receive_fields,
|
||||||
can_dig = can_dig,
|
can_dig = can_dig,
|
||||||
sounds = default.node_sound_stone_defaults(),
|
sounds = mesecon.node_sound.stone,
|
||||||
mesecons = {effector = {
|
mesecons = {effector = {
|
||||||
action_on = commandblock_action_on
|
action_on = commandblock_action_on
|
||||||
}},
|
}},
|
||||||
@ -206,7 +208,7 @@ minetest.register_node("mesecons_commandblock:commandblock_on", {
|
|||||||
after_place_node = after_place,
|
after_place_node = after_place,
|
||||||
on_receive_fields = receive_fields,
|
on_receive_fields = receive_fields,
|
||||||
can_dig = can_dig,
|
can_dig = can_dig,
|
||||||
sounds = default.node_sound_stone_defaults(),
|
sounds = mesecon.node_sound.stone,
|
||||||
mesecons = {effector = {
|
mesecons = {effector = {
|
||||||
action_off = commandblock_action_off
|
action_off = commandblock_action_off
|
||||||
}},
|
}},
|
||||||
|
5
mesecons_commandblock/locale/mesecons_commandblock.de.tr
Normal file
5
mesecons_commandblock/locale/mesecons_commandblock.de.tr
Normal 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
|
7
mesecons_commandblock/locale/mesecons_commandblock.eo.tr
Normal file
7
mesecons_commandblock/locale/mesecons_commandblock.eo.tr
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
# textdomain: mesecons_commandblock
|
||||||
|
|
||||||
|
### init.lua ###
|
||||||
|
Say <text> as the server=Diru <teksto> kiel la servilo
|
||||||
|
Say <text> to <name> privately=Diru <teksto> al <nomo> private
|
||||||
|
Set health of <name> to <value> hitpoints=Agordu sanon de <nomo> al <valoro>
|
||||||
|
Command Block=Komando-Bloko
|
7
mesecons_commandblock/locale/template.txt
Normal file
7
mesecons_commandblock/locale/template.txt
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
# textdomain: mesecons_commandblock
|
||||||
|
|
||||||
|
### init.lua ###
|
||||||
|
Say <text> as the server=
|
||||||
|
Say <text> to <name> privately=
|
||||||
|
Set health of <name> to <value> hitpoints=
|
||||||
|
Command Block=
|
@ -1,2 +1,2 @@
|
|||||||
name = mesecons_commandblock
|
name = mesecons_commandblock
|
||||||
depends = default, mesecons
|
depends = mesecons, mesecons_gamecompat
|
||||||
|
@ -1,19 +1,9 @@
|
|||||||
-- Function that get the input/output rules of the delayer
|
local S = minetest.get_translator(minetest.get_current_modname())
|
||||||
local delayer_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 delayer_get_input_rules = function(node)
|
-- Function that get the input/output rules of the delayer
|
||||||
local rules = {{x = 0, y = 0, z = -1}}
|
local delayer_get_output_rules = mesecon.horiz_rules_getter({{x = 1, y = 0, z = 0}})
|
||||||
for i = 0, node.param2 do
|
|
||||||
rules = mesecon.rotate_rules_left(rules)
|
local delayer_get_input_rules = mesecon.horiz_rules_getter({{x = -1, y = 0, z = 0}})
|
||||||
end
|
|
||||||
return rules
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Functions that are called after the delay time
|
-- Functions that are called after the delay time
|
||||||
|
|
||||||
@ -69,9 +59,11 @@ local def = {
|
|||||||
sunlight_propagates = true,
|
sunlight_propagates = true,
|
||||||
is_ground_content = false,
|
is_ground_content = false,
|
||||||
delayer_time = delaytime[i],
|
delayer_time = delaytime[i],
|
||||||
sounds = default.node_sound_stone_defaults(),
|
sounds = mesecon.node_sound.stone,
|
||||||
on_blast = mesecon.on_blastnode,
|
on_blast = mesecon.on_blastnode,
|
||||||
drop = "mesecons_delayer:delayer_off_1",
|
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
|
-- Deactivated delayer definition defaults
|
||||||
@ -81,7 +73,7 @@ if i > 1 then
|
|||||||
end
|
end
|
||||||
|
|
||||||
local off_state = {
|
local off_state = {
|
||||||
description = "Delayer",
|
description = S("Delayer"),
|
||||||
tiles = {
|
tiles = {
|
||||||
"mesecons_delayer_off_"..tostring(i)..".png",
|
"mesecons_delayer_off_"..tostring(i)..".png",
|
||||||
"mesecons_delayer_bottom.png",
|
"mesecons_delayer_bottom.png",
|
||||||
@ -103,7 +95,6 @@ local off_state = {
|
|||||||
param2 = node.param2
|
param2 = node.param2
|
||||||
})
|
})
|
||||||
end,
|
end,
|
||||||
delayer_onstate = "mesecons_delayer:delayer_on_"..tostring(i),
|
|
||||||
mesecons = {
|
mesecons = {
|
||||||
receptor =
|
receptor =
|
||||||
{
|
{
|
||||||
@ -113,6 +104,7 @@ local off_state = {
|
|||||||
effector =
|
effector =
|
||||||
{
|
{
|
||||||
rules = delayer_get_input_rules,
|
rules = delayer_get_input_rules,
|
||||||
|
action_off = delayer_deactivate,
|
||||||
action_on = delayer_activate
|
action_on = delayer_activate
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -124,7 +116,7 @@ minetest.register_node("mesecons_delayer:delayer_off_"..tostring(i), off_state)
|
|||||||
|
|
||||||
-- Activated delayer definition defaults
|
-- Activated delayer definition defaults
|
||||||
local on_state = {
|
local on_state = {
|
||||||
description = "You hacker you",
|
description = S("You hacker you"),
|
||||||
tiles = {
|
tiles = {
|
||||||
"mesecons_delayer_on_"..tostring(i)..".png",
|
"mesecons_delayer_on_"..tostring(i)..".png",
|
||||||
"mesecons_delayer_bottom.png",
|
"mesecons_delayer_bottom.png",
|
||||||
@ -144,7 +136,6 @@ local on_state = {
|
|||||||
param2 = node.param2
|
param2 = node.param2
|
||||||
})
|
})
|
||||||
end,
|
end,
|
||||||
delayer_offstate = "mesecons_delayer:delayer_off_"..tostring(i),
|
|
||||||
mesecons = {
|
mesecons = {
|
||||||
receptor =
|
receptor =
|
||||||
{
|
{
|
||||||
@ -154,7 +145,8 @@ local on_state = {
|
|||||||
effector =
|
effector =
|
||||||
{
|
{
|
||||||
rules = delayer_get_input_rules,
|
rules = delayer_get_input_rules,
|
||||||
action_off = delayer_deactivate
|
action_off = delayer_deactivate,
|
||||||
|
action_on = delayer_activate
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -169,6 +161,6 @@ minetest.register_craft({
|
|||||||
output = "mesecons_delayer:delayer_off_1",
|
output = "mesecons_delayer:delayer_off_1",
|
||||||
recipe = {
|
recipe = {
|
||||||
{"mesecons_torch:mesecon_torch_on", "group:mesecon_conductor_craftable", "mesecons_torch:mesecon_torch_on"},
|
{"mesecons_torch:mesecon_torch_on", "group:mesecon_conductor_craftable", "mesecons_torch:mesecon_torch_on"},
|
||||||
{"default:cobble","default:cobble", "default:cobble"},
|
{"mesecons_gamecompat:cobble","mesecons_gamecompat:cobble", "mesecons_gamecompat:cobble"},
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
3
mesecons_delayer/locale/mesecons_delayer.de.tr
Normal file
3
mesecons_delayer/locale/mesecons_delayer.de.tr
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
# textdomain: mesecons_delayer
|
||||||
|
Delayer=Verzögerer
|
||||||
|
You hacker you=Du Hacker, Du
|
5
mesecons_delayer/locale/mesecons_delayer.eo.tr
Normal file
5
mesecons_delayer/locale/mesecons_delayer.eo.tr
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
# textdomain: mesecons_delayer
|
||||||
|
|
||||||
|
### init.lua ###
|
||||||
|
Delayer=Prokrasto
|
||||||
|
You hacker you=Vi hakisto
|
5
mesecons_delayer/locale/template.txt
Normal file
5
mesecons_delayer/locale/template.txt
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
# textdomain: mesecons_delayer
|
||||||
|
|
||||||
|
### init.lua ###
|
||||||
|
Delayer=
|
||||||
|
You hacker you=
|
@ -1,2 +1,2 @@
|
|||||||
name = mesecons_delayer
|
name = mesecons_delayer
|
||||||
depends = default, mesecons
|
depends = mesecons, mesecons_gamecompat
|
||||||
|
@ -1,5 +1,19 @@
|
|||||||
|
local S = minetest.get_translator(minetest.get_current_modname())
|
||||||
|
|
||||||
|
local side_texture = mesecon.texture.steel_block or "mesecons_detector_side.png"
|
||||||
|
|
||||||
local GET_COMMAND = "GET"
|
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
|
-- Object detector
|
||||||
-- Detects players in a certain radius
|
-- Detects players in a certain radius
|
||||||
-- The radius can be specified in mesecons/settings.lua
|
-- The radius can be specified in mesecons/settings.lua
|
||||||
@ -31,10 +45,7 @@ local function object_detector_scan(pos)
|
|||||||
if next(objs) == nil then return false end
|
if next(objs) == nil then return false end
|
||||||
|
|
||||||
local scanname = minetest.get_meta(pos):get_string("scanname")
|
local scanname = minetest.get_meta(pos):get_string("scanname")
|
||||||
local scan_for = {}
|
local scan_for = comma_list_to_table(scanname)
|
||||||
for _, str in pairs(string.split(scanname:gsub(" ", ""), ",")) do
|
|
||||||
scan_for[str] = true
|
|
||||||
end
|
|
||||||
|
|
||||||
local every_player = scanname == ""
|
local every_player = scanname == ""
|
||||||
for _, obj in pairs(objs) do
|
for _, obj in pairs(objs) do
|
||||||
@ -64,25 +75,25 @@ local object_detector_digiline = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
minetest.register_node("mesecons_detector:object_detector_off", {
|
minetest.register_node("mesecons_detector:object_detector_off", {
|
||||||
tiles = {"default_steel_block.png", "default_steel_block.png", "jeija_object_detector_off.png", "jeija_object_detector_off.png", "jeija_object_detector_off.png", "jeija_object_detector_off.png"},
|
tiles = {side_texture, side_texture, "jeija_object_detector_off.png", "jeija_object_detector_off.png", "jeija_object_detector_off.png", "jeija_object_detector_off.png"},
|
||||||
paramtype = "light",
|
paramtype = "light",
|
||||||
is_ground_content = false,
|
is_ground_content = false,
|
||||||
walkable = true,
|
walkable = true,
|
||||||
groups = {cracky=3},
|
groups = {cracky=3},
|
||||||
description="Player Detector",
|
description= S("Player Detector"),
|
||||||
mesecons = {receptor = {
|
mesecons = {receptor = {
|
||||||
state = mesecon.state.off,
|
state = mesecon.state.off,
|
||||||
rules = mesecon.rules.pplate
|
rules = mesecon.rules.pplate
|
||||||
}},
|
}},
|
||||||
on_construct = object_detector_make_formspec,
|
on_construct = object_detector_make_formspec,
|
||||||
on_receive_fields = object_detector_on_receive_fields,
|
on_receive_fields = object_detector_on_receive_fields,
|
||||||
sounds = default.node_sound_stone_defaults(),
|
sounds = mesecon.node_sound.stone,
|
||||||
digiline = object_detector_digiline,
|
digiline = object_detector_digiline,
|
||||||
on_blast = mesecon.on_blastnode,
|
on_blast = mesecon.on_blastnode,
|
||||||
})
|
})
|
||||||
|
|
||||||
minetest.register_node("mesecons_detector:object_detector_on", {
|
minetest.register_node("mesecons_detector:object_detector_on", {
|
||||||
tiles = {"default_steel_block.png", "default_steel_block.png", "jeija_object_detector_on.png", "jeija_object_detector_on.png", "jeija_object_detector_on.png", "jeija_object_detector_on.png"},
|
tiles = {side_texture, side_texture, "jeija_object_detector_on.png", "jeija_object_detector_on.png", "jeija_object_detector_on.png", "jeija_object_detector_on.png"},
|
||||||
paramtype = "light",
|
paramtype = "light",
|
||||||
is_ground_content = false,
|
is_ground_content = false,
|
||||||
walkable = true,
|
walkable = true,
|
||||||
@ -94,7 +105,7 @@ minetest.register_node("mesecons_detector:object_detector_on", {
|
|||||||
}},
|
}},
|
||||||
on_construct = object_detector_make_formspec,
|
on_construct = object_detector_make_formspec,
|
||||||
on_receive_fields = object_detector_on_receive_fields,
|
on_receive_fields = object_detector_on_receive_fields,
|
||||||
sounds = default.node_sound_stone_defaults(),
|
sounds = mesecon.node_sound.stone,
|
||||||
digiline = object_detector_digiline,
|
digiline = object_detector_digiline,
|
||||||
on_blast = mesecon.on_blastnode,
|
on_blast = mesecon.on_blastnode,
|
||||||
})
|
})
|
||||||
@ -102,18 +113,18 @@ minetest.register_node("mesecons_detector:object_detector_on", {
|
|||||||
minetest.register_craft({
|
minetest.register_craft({
|
||||||
output = 'mesecons_detector:object_detector_off',
|
output = 'mesecons_detector:object_detector_off',
|
||||||
recipe = {
|
recipe = {
|
||||||
{"default:steel_ingot", "default:steel_ingot", "default:steel_ingot"},
|
{"mesecons_gamecompat:steel_ingot", "mesecons_gamecompat:steel_ingot", "mesecons_gamecompat:steel_ingot"},
|
||||||
{"default:steel_ingot", "mesecons_luacontroller:luacontroller0000", "default:steel_ingot"},
|
{"mesecons_gamecompat:steel_ingot", "mesecons_luacontroller:luacontroller0000", "mesecons_gamecompat:steel_ingot"},
|
||||||
{"default:steel_ingot", "group:mesecon_conductor_craftable", "default:steel_ingot"},
|
{"mesecons_gamecompat:steel_ingot", "group:mesecon_conductor_craftable", "mesecons_gamecompat:steel_ingot"},
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
minetest.register_craft({
|
minetest.register_craft({
|
||||||
output = 'mesecons_detector:object_detector_off',
|
output = 'mesecons_detector:object_detector_off',
|
||||||
recipe = {
|
recipe = {
|
||||||
{"default:steel_ingot", "default:steel_ingot", "default:steel_ingot"},
|
{"mesecons_gamecompat:steel_ingot", "mesecons_gamecompat:steel_ingot", "mesecons_gamecompat:steel_ingot"},
|
||||||
{"default:steel_ingot", "mesecons_microcontroller:microcontroller0000", "default:steel_ingot"},
|
{"mesecons_gamecompat:steel_ingot", "mesecons_microcontroller:microcontroller0000", "mesecons_gamecompat:steel_ingot"},
|
||||||
{"default:steel_ingot", "group:mesecon_conductor_craftable", "default:steel_ingot"},
|
{"mesecons_gamecompat:steel_ingot", "group:mesecon_conductor_craftable", "mesecons_gamecompat:steel_ingot"},
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -146,6 +157,23 @@ minetest.register_abm({
|
|||||||
-- Node detector
|
-- Node detector
|
||||||
-- Detects the node in front of it
|
-- Detects the node in front of it
|
||||||
|
|
||||||
|
local blacklist = {
|
||||||
|
air = true,
|
||||||
|
ignore = true,
|
||||||
|
}
|
||||||
|
|
||||||
|
function mesecon.node_detector_blacklist_add(node)
|
||||||
|
blacklist[node] = true
|
||||||
|
end
|
||||||
|
|
||||||
|
function mesecon.node_detector_blacklist_remove(node)
|
||||||
|
blacklist[node] = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
function mesecon.node_detector_on_blacklist(node)
|
||||||
|
return blacklist[node] == true
|
||||||
|
end
|
||||||
|
|
||||||
local function node_detector_make_formspec(pos)
|
local function node_detector_make_formspec(pos)
|
||||||
local meta = minetest.get_meta(pos)
|
local meta = minetest.get_meta(pos)
|
||||||
if meta:get_string("distance") == "" then meta:set_string("distance", "0") end
|
if meta:get_string("distance") == "" then meta:set_string("distance", "0") end
|
||||||
@ -184,9 +212,10 @@ local function node_detector_scan(pos)
|
|||||||
vector.subtract(pos, vector.multiply(minetest.facedir_to_dir(node.param2), distance + 1))
|
vector.subtract(pos, vector.multiply(minetest.facedir_to_dir(node.param2), distance + 1))
|
||||||
).name
|
).name
|
||||||
local scanname = meta:get_string("scanname")
|
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 == "")
|
(blacklist[frontname] ~= true and scanname == "")
|
||||||
end
|
end
|
||||||
|
|
||||||
local function node_detector_send_node_name(pos, node, channel, meta)
|
local function node_detector_send_node_name(pos, node, channel, meta)
|
||||||
@ -239,25 +268,25 @@ local node_detector_digiline = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
minetest.register_node("mesecons_detector:node_detector_off", {
|
minetest.register_node("mesecons_detector:node_detector_off", {
|
||||||
tiles = {"default_steel_block.png", "default_steel_block.png", "default_steel_block.png", "default_steel_block.png", "default_steel_block.png", "jeija_node_detector_off.png"},
|
tiles = {side_texture, side_texture, side_texture, side_texture, side_texture, "jeija_node_detector_off.png"},
|
||||||
paramtype = "light",
|
paramtype = "light",
|
||||||
paramtype2 = "facedir",
|
paramtype2 = "facedir",
|
||||||
is_ground_content = false,
|
is_ground_content = false,
|
||||||
walkable = true,
|
walkable = true,
|
||||||
groups = {cracky=3},
|
groups = {cracky=3},
|
||||||
description="Node Detector",
|
description = S("Node Detector"),
|
||||||
mesecons = {receptor = {
|
mesecons = {receptor = {
|
||||||
state = mesecon.state.off
|
state = mesecon.state.off
|
||||||
}},
|
}},
|
||||||
on_construct = node_detector_make_formspec,
|
on_construct = node_detector_make_formspec,
|
||||||
on_receive_fields = node_detector_on_receive_fields,
|
on_receive_fields = node_detector_on_receive_fields,
|
||||||
sounds = default.node_sound_stone_defaults(),
|
sounds = mesecon.node_sound.stone,
|
||||||
digiline = node_detector_digiline,
|
digiline = node_detector_digiline,
|
||||||
on_blast = mesecon.on_blastnode,
|
on_blast = mesecon.on_blastnode,
|
||||||
})
|
})
|
||||||
|
|
||||||
minetest.register_node("mesecons_detector:node_detector_on", {
|
minetest.register_node("mesecons_detector:node_detector_on", {
|
||||||
tiles = {"default_steel_block.png", "default_steel_block.png", "default_steel_block.png", "default_steel_block.png", "default_steel_block.png", "jeija_node_detector_on.png"},
|
tiles = {side_texture, side_texture, side_texture, side_texture, side_texture, "jeija_node_detector_on.png"},
|
||||||
paramtype = "light",
|
paramtype = "light",
|
||||||
paramtype2 = "facedir",
|
paramtype2 = "facedir",
|
||||||
is_ground_content = false,
|
is_ground_content = false,
|
||||||
@ -269,7 +298,7 @@ minetest.register_node("mesecons_detector:node_detector_on", {
|
|||||||
}},
|
}},
|
||||||
on_construct = node_detector_make_formspec,
|
on_construct = node_detector_make_formspec,
|
||||||
on_receive_fields = node_detector_on_receive_fields,
|
on_receive_fields = node_detector_on_receive_fields,
|
||||||
sounds = default.node_sound_stone_defaults(),
|
sounds = mesecon.node_sound.stone,
|
||||||
digiline = node_detector_digiline,
|
digiline = node_detector_digiline,
|
||||||
on_blast = mesecon.on_blastnode,
|
on_blast = mesecon.on_blastnode,
|
||||||
})
|
})
|
||||||
@ -277,18 +306,18 @@ minetest.register_node("mesecons_detector:node_detector_on", {
|
|||||||
minetest.register_craft({
|
minetest.register_craft({
|
||||||
output = 'mesecons_detector:node_detector_off',
|
output = 'mesecons_detector:node_detector_off',
|
||||||
recipe = {
|
recipe = {
|
||||||
{"default:steel_ingot", "group:mesecon_conductor_craftable", "default:steel_ingot"},
|
{"mesecons_gamecompat:steel_ingot", "group:mesecon_conductor_craftable", "mesecons_gamecompat:steel_ingot"},
|
||||||
{"default:steel_ingot", "mesecons_luacontroller:luacontroller0000", "default:steel_ingot"},
|
{"mesecons_gamecompat:steel_ingot", "mesecons_luacontroller:luacontroller0000", "mesecons_gamecompat:steel_ingot"},
|
||||||
{"default:steel_ingot", "default:steel_ingot", "default:steel_ingot"},
|
{"mesecons_gamecompat:steel_ingot", "mesecons_gamecompat:steel_ingot", "mesecons_gamecompat:steel_ingot"},
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
minetest.register_craft({
|
minetest.register_craft({
|
||||||
output = 'mesecons_detector:node_detector_off',
|
output = 'mesecons_detector:node_detector_off',
|
||||||
recipe = {
|
recipe = {
|
||||||
{"default:steel_ingot", "group:mesecon_conductor_craftable", "default:steel_ingot"},
|
{"mesecons_gamecompat:steel_ingot", "group:mesecon_conductor_craftable", "mesecons_gamecompat:steel_ingot"},
|
||||||
{"default:steel_ingot", "mesecons_microcontroller:microcontroller0000", "default:steel_ingot"},
|
{"mesecons_gamecompat:steel_ingot", "mesecons_microcontroller:microcontroller0000", "mesecons_gamecompat:steel_ingot"},
|
||||||
{"default:steel_ingot", "default:steel_ingot", "default:steel_ingot"},
|
{"mesecons_gamecompat:steel_ingot", "mesecons_gamecompat:steel_ingot", "mesecons_gamecompat:steel_ingot"},
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
3
mesecons_detector/locale/mesecons_detector.de.tr
Normal file
3
mesecons_detector/locale/mesecons_detector.de.tr
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
# textdomain: mesecons_detector
|
||||||
|
Player Detector=Spielerdetektor
|
||||||
|
Node Detector=Blockdetektor
|
5
mesecons_detector/locale/mesecons_detector.eo.tr
Normal file
5
mesecons_detector/locale/mesecons_detector.eo.tr
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
# textdomain: mesecons_detector
|
||||||
|
|
||||||
|
### init.lua ###
|
||||||
|
Player Detector=Ludanta Detektilo
|
||||||
|
Node Detector=Noda Detektilo
|
5
mesecons_detector/locale/template.txt
Normal file
5
mesecons_detector/locale/template.txt
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
# textdomain: mesecons_detector
|
||||||
|
|
||||||
|
### init.lua ###
|
||||||
|
Player Detector=
|
||||||
|
Node Detector=
|
@ -1,2 +1,2 @@
|
|||||||
name = mesecons_detector
|
name = mesecons_detector
|
||||||
depends = default, mesecons, mesecons_materials
|
depends = mesecons, mesecons_gamecompat, mesecons_materials
|
||||||
|
BIN
mesecons_detector/textures/mesecons_detector_side.png
Normal file
BIN
mesecons_detector/textures/mesecons_detector_side.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 350 B |
@ -1,21 +1,14 @@
|
|||||||
local screwdriver_exists = minetest.global_exists("screwdriver")
|
local S = minetest.get_translator(minetest.get_current_modname())
|
||||||
|
|
||||||
local corner_selectionbox = {
|
local corner_selectionbox = {
|
||||||
type = "fixed",
|
type = "fixed",
|
||||||
fixed = { -16/32, -16/32, -16/32, 5/32, -12/32, 5/32 },
|
fixed = { -16/32, -16/32, -16/32, 5/32, -12/32, 5/32 },
|
||||||
}
|
}
|
||||||
|
|
||||||
local corner_get_rules = function (node)
|
local corner_get_rules = mesecon.horiz_rules_getter({
|
||||||
local rules =
|
{x = 0, y = 0, z = -1},
|
||||||
{{x = 1, y = 0, z = 0},
|
{x = -1, y = 0, z = 0},
|
||||||
{x = 0, y = 0, z = -1}}
|
})
|
||||||
|
|
||||||
for i = 0, node.param2 do
|
|
||||||
rules = mesecon.rotate_rules_left(rules)
|
|
||||||
end
|
|
||||||
|
|
||||||
return rules
|
|
||||||
end
|
|
||||||
|
|
||||||
minetest.register_node("mesecons_extrawires:corner_on", {
|
minetest.register_node("mesecons_extrawires:corner_on", {
|
||||||
drawtype = "mesh",
|
drawtype = "mesh",
|
||||||
@ -32,7 +25,7 @@ minetest.register_node("mesecons_extrawires:corner_on", {
|
|||||||
selection_box = corner_selectionbox,
|
selection_box = corner_selectionbox,
|
||||||
groups = {dig_immediate = 3, not_in_creative_inventory = 1},
|
groups = {dig_immediate = 3, not_in_creative_inventory = 1},
|
||||||
drop = "mesecons_extrawires:corner_off",
|
drop = "mesecons_extrawires:corner_off",
|
||||||
sounds = default.node_sound_defaults(),
|
sounds = mesecon.node_sound.default,
|
||||||
mesecons = {conductor =
|
mesecons = {conductor =
|
||||||
{
|
{
|
||||||
state = mesecon.state.on,
|
state = mesecon.state.on,
|
||||||
@ -40,12 +33,12 @@ minetest.register_node("mesecons_extrawires:corner_on", {
|
|||||||
offstate = "mesecons_extrawires:corner_off"
|
offstate = "mesecons_extrawires:corner_off"
|
||||||
}},
|
}},
|
||||||
on_blast = mesecon.on_blastnode,
|
on_blast = mesecon.on_blastnode,
|
||||||
on_rotate = screwdriver_exists and screwdriver.rotate_simple,
|
on_rotate = mesecon.on_rotate_horiz,
|
||||||
})
|
})
|
||||||
|
|
||||||
minetest.register_node("mesecons_extrawires:corner_off", {
|
minetest.register_node("mesecons_extrawires:corner_off", {
|
||||||
drawtype = "mesh",
|
drawtype = "mesh",
|
||||||
description = "Insulated Mesecon Corner",
|
description = S("Insulated Mesecon Corner"),
|
||||||
mesh = "mesecons_extrawires_corner.obj",
|
mesh = "mesecons_extrawires_corner.obj",
|
||||||
tiles = {
|
tiles = {
|
||||||
{ name = "jeija_insulated_wire_sides_off.png", backface_culling = true },
|
{ name = "jeija_insulated_wire_sides_off.png", backface_culling = true },
|
||||||
@ -58,7 +51,7 @@ minetest.register_node("mesecons_extrawires:corner_off", {
|
|||||||
sunlight_propagates = true,
|
sunlight_propagates = true,
|
||||||
selection_box = corner_selectionbox,
|
selection_box = corner_selectionbox,
|
||||||
groups = {dig_immediate = 3},
|
groups = {dig_immediate = 3},
|
||||||
sounds = default.node_sound_defaults(),
|
sounds = mesecon.node_sound.default,
|
||||||
mesecons = {conductor =
|
mesecons = {conductor =
|
||||||
{
|
{
|
||||||
state = mesecon.state.off,
|
state = mesecon.state.off,
|
||||||
@ -66,7 +59,7 @@ minetest.register_node("mesecons_extrawires:corner_off", {
|
|||||||
onstate = "mesecons_extrawires:corner_on"
|
onstate = "mesecons_extrawires:corner_on"
|
||||||
}},
|
}},
|
||||||
on_blast = mesecon.on_blastnode,
|
on_blast = mesecon.on_blastnode,
|
||||||
on_rotate = screwdriver_exists and screwdriver.rotate_simple,
|
on_rotate = mesecon.on_rotate_horiz,
|
||||||
})
|
})
|
||||||
|
|
||||||
minetest.register_craft({
|
minetest.register_craft({
|
||||||
@ -76,3 +69,9 @@ minetest.register_craft({
|
|||||||
{"", "mesecons_insulated:insulated_off"},
|
{"", "mesecons_insulated:insulated_off"},
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
minetest.register_craft({
|
||||||
|
output = "mesecons_insulated:insulated_off",
|
||||||
|
type = "shapeless",
|
||||||
|
recipe = {"mesecons_extrawires:corner_off"}
|
||||||
|
})
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
local S = minetest.get_translator(minetest.get_current_modname())
|
||||||
|
|
||||||
local crossover_rules = {
|
local crossover_rules = {
|
||||||
{--first wire
|
{--first wire
|
||||||
{x=-1,y=0,z=0},
|
{x=-1,y=0,z=0},
|
||||||
@ -17,7 +19,7 @@ local crossover_states = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
minetest.register_node("mesecons_extrawires:crossover_off", {
|
minetest.register_node("mesecons_extrawires:crossover_off", {
|
||||||
description = "Insulated Mesecon Crossover",
|
description = S("Insulated Mesecon Crossover"),
|
||||||
drawtype = "mesh",
|
drawtype = "mesh",
|
||||||
mesh = "mesecons_extrawires_crossover.b3d",
|
mesh = "mesecons_extrawires_crossover.b3d",
|
||||||
tiles = {
|
tiles = {
|
||||||
@ -32,7 +34,7 @@ minetest.register_node("mesecons_extrawires:crossover_off", {
|
|||||||
stack_max = 99,
|
stack_max = 99,
|
||||||
selection_box = {type="fixed", fixed={-16/32, -16/32, -16/32, 16/32, -5/32, 16/32}},
|
selection_box = {type="fixed", fixed={-16/32, -16/32, -16/32, 16/32, -5/32, 16/32}},
|
||||||
groups = {dig_immediate=3, mesecon=3},
|
groups = {dig_immediate=3, mesecon=3},
|
||||||
sounds = default.node_sound_defaults(),
|
sounds = mesecon.node_sound.default,
|
||||||
mesecons = {
|
mesecons = {
|
||||||
conductor = {
|
conductor = {
|
||||||
states = crossover_states,
|
states = crossover_states,
|
||||||
@ -43,7 +45,7 @@ minetest.register_node("mesecons_extrawires:crossover_off", {
|
|||||||
})
|
})
|
||||||
|
|
||||||
minetest.register_node("mesecons_extrawires:crossover_01", {
|
minetest.register_node("mesecons_extrawires:crossover_01", {
|
||||||
description = "You hacker you!",
|
description = S("You hacker you!"),
|
||||||
drop = "mesecons_extrawires:crossover_off",
|
drop = "mesecons_extrawires:crossover_off",
|
||||||
drawtype = "mesh",
|
drawtype = "mesh",
|
||||||
mesh = "mesecons_extrawires_crossover.b3d",
|
mesh = "mesecons_extrawires_crossover.b3d",
|
||||||
@ -59,7 +61,7 @@ minetest.register_node("mesecons_extrawires:crossover_01", {
|
|||||||
stack_max = 99,
|
stack_max = 99,
|
||||||
selection_box = {type="fixed", fixed={-16/32, -16/32, -16/32, 16/32, -5/32, 16/32}},
|
selection_box = {type="fixed", fixed={-16/32, -16/32, -16/32, 16/32, -5/32, 16/32}},
|
||||||
groups = {dig_immediate=3, mesecon=3, not_in_creative_inventory=1},
|
groups = {dig_immediate=3, mesecon=3, not_in_creative_inventory=1},
|
||||||
sounds = default.node_sound_defaults(),
|
sounds = mesecon.node_sound.default,
|
||||||
mesecons = {
|
mesecons = {
|
||||||
conductor = {
|
conductor = {
|
||||||
states = crossover_states,
|
states = crossover_states,
|
||||||
@ -70,7 +72,7 @@ minetest.register_node("mesecons_extrawires:crossover_01", {
|
|||||||
})
|
})
|
||||||
|
|
||||||
minetest.register_node("mesecons_extrawires:crossover_10", {
|
minetest.register_node("mesecons_extrawires:crossover_10", {
|
||||||
description = "You hacker you!",
|
description = S("You hacker you!"),
|
||||||
drop = "mesecons_extrawires:crossover_off",
|
drop = "mesecons_extrawires:crossover_off",
|
||||||
drawtype = "mesh",
|
drawtype = "mesh",
|
||||||
mesh = "mesecons_extrawires_crossover.b3d",
|
mesh = "mesecons_extrawires_crossover.b3d",
|
||||||
@ -86,7 +88,7 @@ minetest.register_node("mesecons_extrawires:crossover_10", {
|
|||||||
stack_max = 99,
|
stack_max = 99,
|
||||||
selection_box = {type="fixed", fixed={-16/32, -16/32, -16/32, 16/32, -5/32, 16/32}},
|
selection_box = {type="fixed", fixed={-16/32, -16/32, -16/32, 16/32, -5/32, 16/32}},
|
||||||
groups = {dig_immediate=3, mesecon=3, not_in_creative_inventory=1},
|
groups = {dig_immediate=3, mesecon=3, not_in_creative_inventory=1},
|
||||||
sounds = default.node_sound_defaults(),
|
sounds = mesecon.node_sound.default,
|
||||||
mesecons = {
|
mesecons = {
|
||||||
conductor = {
|
conductor = {
|
||||||
states = crossover_states,
|
states = crossover_states,
|
||||||
@ -97,7 +99,7 @@ minetest.register_node("mesecons_extrawires:crossover_10", {
|
|||||||
})
|
})
|
||||||
|
|
||||||
minetest.register_node("mesecons_extrawires:crossover_on", {
|
minetest.register_node("mesecons_extrawires:crossover_on", {
|
||||||
description = "You hacker you!",
|
description = S("You hacker you!"),
|
||||||
drop = "mesecons_extrawires:crossover_off",
|
drop = "mesecons_extrawires:crossover_off",
|
||||||
drawtype = "mesh",
|
drawtype = "mesh",
|
||||||
mesh = "mesecons_extrawires_crossover.b3d",
|
mesh = "mesecons_extrawires_crossover.b3d",
|
||||||
@ -113,7 +115,7 @@ minetest.register_node("mesecons_extrawires:crossover_on", {
|
|||||||
stack_max = 99,
|
stack_max = 99,
|
||||||
selection_box = {type="fixed", fixed={-16/32, -16/32, -16/32, 16/32, -5/32, 16/32}},
|
selection_box = {type="fixed", fixed={-16/32, -16/32, -16/32, 16/32, -5/32, 16/32}},
|
||||||
groups = {dig_immediate=3, mesecon=3, not_in_creative_inventory=1},
|
groups = {dig_immediate=3, mesecon=3, not_in_creative_inventory=1},
|
||||||
sounds = default.node_sound_defaults(),
|
sounds = mesecon.node_sound.default,
|
||||||
mesecons = {
|
mesecons = {
|
||||||
conductor = {
|
conductor = {
|
||||||
states = crossover_states,
|
states = crossover_states,
|
||||||
|
@ -1,12 +1,11 @@
|
|||||||
local rotate
|
local S = minetest.get_translator(minetest.get_current_modname())
|
||||||
if minetest.global_exists("screwdriver") then rotate = screwdriver.rotate_simple end
|
|
||||||
|
|
||||||
local doublecorner_selectionbox = {
|
local doublecorner_selectionbox = {
|
||||||
type = "fixed",
|
type = "fixed",
|
||||||
fixed = { -8/16, -8/16, -8/16, 8/16, -6/16, 8/16 },
|
fixed = { -8/16, -8/16, -8/16, 8/16, -6/16, 8/16 },
|
||||||
}
|
}
|
||||||
|
|
||||||
local rules = {
|
local doublecorner_get_rules = mesecon.horiz_rules_getter({
|
||||||
{
|
{
|
||||||
{ x = 1, y = 0, z = 0 },
|
{ x = 1, y = 0, z = 0 },
|
||||||
{ x = 0, y = 0, z = 1 },
|
{ x = 0, y = 0, z = 1 },
|
||||||
@ -15,19 +14,7 @@ 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 },
|
||||||
},
|
},
|
||||||
}
|
})
|
||||||
|
|
||||||
local doublecorner_rules = {}
|
|
||||||
for k = 1, 4 do
|
|
||||||
doublecorner_rules[k] = table.copy(rules)
|
|
||||||
for i, r in ipairs(rules) do
|
|
||||||
rules[i] = mesecon.rotate_rules_left(r)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local function doublecorner_get_rules(node)
|
|
||||||
return doublecorner_rules[node.param2 % 4 + 1]
|
|
||||||
end
|
|
||||||
|
|
||||||
local doublecorner_states = {
|
local doublecorner_states = {
|
||||||
"mesecons_extrawires:doublecorner_00",
|
"mesecons_extrawires:doublecorner_00",
|
||||||
@ -46,7 +33,7 @@ for k, state in ipairs(doublecorner_states) do
|
|||||||
minetest.register_node(state, {
|
minetest.register_node(state, {
|
||||||
drawtype = "mesh",
|
drawtype = "mesh",
|
||||||
mesh = "mesecons_extrawires_doublecorner.obj",
|
mesh = "mesecons_extrawires_doublecorner.obj",
|
||||||
description = "Insulated Mesecon Double Corner",
|
description = S("Insulated Mesecon Double Corner"),
|
||||||
tiles = {
|
tiles = {
|
||||||
{ name = "jeija_insulated_wire_sides_" .. w1 .. ".png", backface_culling = true },
|
{ name = "jeija_insulated_wire_sides_" .. w1 .. ".png", backface_culling = true },
|
||||||
{ name = "jeija_insulated_wire_ends_" .. w1 .. ".png", backface_culling = true },
|
{ name = "jeija_insulated_wire_ends_" .. w1 .. ".png", backface_culling = true },
|
||||||
@ -61,7 +48,7 @@ for k, state in ipairs(doublecorner_states) do
|
|||||||
selection_box = doublecorner_selectionbox,
|
selection_box = doublecorner_selectionbox,
|
||||||
groups = groups,
|
groups = groups,
|
||||||
drop = doublecorner_states[1],
|
drop = doublecorner_states[1],
|
||||||
sounds = default.node_sound_defaults(),
|
sounds = mesecon.node_sound.default,
|
||||||
mesecons = {
|
mesecons = {
|
||||||
conductor = {
|
conductor = {
|
||||||
states = doublecorner_states,
|
states = doublecorner_states,
|
||||||
@ -69,7 +56,7 @@ for k, state in ipairs(doublecorner_states) do
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
on_blast = mesecon.on_blastnode,
|
on_blast = mesecon.on_blastnode,
|
||||||
on_rotate = rotate,
|
on_rotate = mesecon.on_rotate_horiz,
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
|
8
mesecons_extrawires/locale/mesecons_extrawires.de.tr
Normal file
8
mesecons_extrawires/locale/mesecons_extrawires.de.tr
Normal 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
|
20
mesecons_extrawires/locale/mesecons_extrawires.eo.tr
Normal file
20
mesecons_extrawires/locale/mesecons_extrawires.eo.tr
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
# textdomain: mesecons_extrawires
|
||||||
|
|
||||||
|
### corner.lua ###
|
||||||
|
Insulated Mesecon Corner=Izolita Mesekonduktila Angulo
|
||||||
|
|
||||||
|
### crossover.lua ###
|
||||||
|
Insulated Mesecon Crossover=Izolita Mesekonduktila Interkruciĝo
|
||||||
|
You hacker you!=Vi hakisto
|
||||||
|
|
||||||
|
### doublecorner.lua ###
|
||||||
|
Insulated Mesecon Double Corner=Izolita Mesekonduktila Duobla Angulo
|
||||||
|
|
||||||
|
### mesewire.lua ###
|
||||||
|
Mese Wire=Mesea Drato
|
||||||
|
|
||||||
|
### tjunction.lua ###
|
||||||
|
Insulated Mesecon T-junction=Izolita Mesekonduktila T-Kruciĝo
|
||||||
|
|
||||||
|
### vertical.lua ###
|
||||||
|
Vertical Mesecon=Vertikala Mesekonduktilo
|
20
mesecons_extrawires/locale/template.txt
Normal file
20
mesecons_extrawires/locale/template.txt
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
# textdomain: mesecons_extrawires
|
||||||
|
|
||||||
|
### corner.lua ###
|
||||||
|
Insulated Mesecon Corner=
|
||||||
|
|
||||||
|
### crossover.lua ###
|
||||||
|
Insulated Mesecon Crossover=
|
||||||
|
You hacker you!=
|
||||||
|
|
||||||
|
### doublecorner.lua ###
|
||||||
|
Insulated Mesecon Double Corner=
|
||||||
|
|
||||||
|
### mesewire.lua ###
|
||||||
|
Mese Wire=
|
||||||
|
|
||||||
|
### tjunction.lua ###
|
||||||
|
Insulated Mesecon T-junction=
|
||||||
|
|
||||||
|
### vertical.lua ###
|
||||||
|
Vertical Mesecon=
|
@ -1,3 +1,22 @@
|
|||||||
|
local S = minetest.get_translator(minetest.get_current_modname())
|
||||||
|
|
||||||
|
local mese_nodename = minetest.registered_aliases["mesecons_gamecompat:mese"]
|
||||||
|
if mese_nodename then
|
||||||
|
-- Convert placeholders.
|
||||||
|
minetest.register_alias("mesecons_extrawires:mese", mese_nodename)
|
||||||
|
else
|
||||||
|
-- Register placeholder.
|
||||||
|
mese_nodename = "mesecons_extrawires:mese"
|
||||||
|
minetest.register_node("mesecons_extrawires:mese", {
|
||||||
|
description = S("Mese Wire"),
|
||||||
|
tiles = {"mesecons_wire_off.png"},
|
||||||
|
paramtype = "light",
|
||||||
|
light_source = 3,
|
||||||
|
groups = {cracky = 1},
|
||||||
|
sounds = mesecon.node_sound.stone,
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
local mesewire_rules =
|
local mesewire_rules =
|
||||||
{
|
{
|
||||||
{x = 1, y = 0, z = 0},
|
{x = 1, y = 0, z = 0},
|
||||||
@ -8,7 +27,7 @@ local mesewire_rules =
|
|||||||
{x = 0, y = 0, z =-1},
|
{x = 0, y = 0, z =-1},
|
||||||
}
|
}
|
||||||
|
|
||||||
minetest.override_item("default:mese", {
|
minetest.override_item(mese_nodename, {
|
||||||
mesecons = {conductor = {
|
mesecons = {conductor = {
|
||||||
state = mesecon.state.off,
|
state = mesecon.state.off,
|
||||||
onstate = "mesecons_extrawires:mese_powered",
|
onstate = "mesecons_extrawires:mese_powered",
|
||||||
@ -18,15 +37,17 @@ minetest.override_item("default:mese", {
|
|||||||
|
|
||||||
-- Copy node definition of powered mese from normal mese
|
-- Copy node definition of powered mese from normal mese
|
||||||
-- and brighten texture tiles to indicate mese is powered
|
-- and brighten texture tiles to indicate mese is powered
|
||||||
local powered_def = mesecon.merge_tables(minetest.registered_nodes["default:mese"], {
|
local unpowered_def = minetest.registered_nodes[mese_nodename]
|
||||||
drop = "default:mese",
|
local powered_def = mesecon.merge_tables(unpowered_def, {
|
||||||
light_source = 5,
|
drop = mese_nodename,
|
||||||
|
paramtype = "light",
|
||||||
|
light_source = math.min(unpowered_def.light_source + 2, minetest.LIGHT_MAX),
|
||||||
mesecons = {conductor = {
|
mesecons = {conductor = {
|
||||||
state = mesecon.state.on,
|
state = mesecon.state.on,
|
||||||
offstate = "default:mese",
|
offstate = mese_nodename,
|
||||||
rules = mesewire_rules
|
rules = mesewire_rules
|
||||||
}},
|
}},
|
||||||
groups = {cracky = 1, not_in_creative_inventory = 1},
|
groups = mesecon.merge_tables(unpowered_def.groups or {}, {not_in_creative_inventory = 1}),
|
||||||
on_blast = mesecon.on_blastnode,
|
on_blast = mesecon.on_blastnode,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -1,3 +1,2 @@
|
|||||||
name = mesecons_extrawires
|
name = mesecons_extrawires
|
||||||
depends = default, mesecons
|
depends = mesecons, mesecons_gamecompat
|
||||||
optional_depends = screwdriver
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
local screwdriver_exists = minetest.global_exists("screwdriver")
|
local S = minetest.get_translator(minetest.get_current_modname())
|
||||||
|
|
||||||
local tjunction_nodebox = {
|
local tjunction_nodebox = {
|
||||||
type = "fixed",
|
type = "fixed",
|
||||||
@ -12,18 +12,11 @@ local tjunction_selectionbox = {
|
|||||||
fixed = { -16/32, -16/32, -16/32, 16/32, -12/32, 7/32 },
|
fixed = { -16/32, -16/32, -16/32, 16/32, -12/32, 7/32 },
|
||||||
}
|
}
|
||||||
|
|
||||||
local tjunction_get_rules = function (node)
|
local tjunction_get_rules = mesecon.horiz_rules_getter({
|
||||||
local rules =
|
{x = 1, y = 0, z = 0},
|
||||||
{{x = 0, y = 0, z = 1},
|
{x = 0, y = 0, z = -1},
|
||||||
{x = 1, y = 0, z = 0},
|
{x = -1, y = 0, z = 0},
|
||||||
{x = 0, y = 0, z = -1}}
|
})
|
||||||
|
|
||||||
for i = 0, node.param2 do
|
|
||||||
rules = mesecon.rotate_rules_left(rules)
|
|
||||||
end
|
|
||||||
|
|
||||||
return rules
|
|
||||||
end
|
|
||||||
|
|
||||||
minetest.register_node("mesecons_extrawires:tjunction_on", {
|
minetest.register_node("mesecons_extrawires:tjunction_on", {
|
||||||
drawtype = "nodebox",
|
drawtype = "nodebox",
|
||||||
@ -44,7 +37,7 @@ minetest.register_node("mesecons_extrawires:tjunction_on", {
|
|||||||
node_box = tjunction_nodebox,
|
node_box = tjunction_nodebox,
|
||||||
groups = {dig_immediate = 3, not_in_creative_inventory = 1},
|
groups = {dig_immediate = 3, not_in_creative_inventory = 1},
|
||||||
drop = "mesecons_extrawires:tjunction_off",
|
drop = "mesecons_extrawires:tjunction_off",
|
||||||
sounds = default.node_sound_defaults(),
|
sounds = mesecon.node_sound.default,
|
||||||
mesecons = {conductor =
|
mesecons = {conductor =
|
||||||
{
|
{
|
||||||
state = mesecon.state.on,
|
state = mesecon.state.on,
|
||||||
@ -52,12 +45,12 @@ minetest.register_node("mesecons_extrawires:tjunction_on", {
|
|||||||
offstate = "mesecons_extrawires:tjunction_off"
|
offstate = "mesecons_extrawires:tjunction_off"
|
||||||
}},
|
}},
|
||||||
on_blast = mesecon.on_blastnode,
|
on_blast = mesecon.on_blastnode,
|
||||||
on_rotate = screwdriver_exists and screwdriver.rotate_simple,
|
on_rotate = mesecon.on_rotate_horiz,
|
||||||
})
|
})
|
||||||
|
|
||||||
minetest.register_node("mesecons_extrawires:tjunction_off", {
|
minetest.register_node("mesecons_extrawires:tjunction_off", {
|
||||||
drawtype = "nodebox",
|
drawtype = "nodebox",
|
||||||
description = "Insulated Mesecon T-junction",
|
description = S("Insulated Mesecon T-junction"),
|
||||||
tiles = {
|
tiles = {
|
||||||
"jeija_insulated_wire_tjunction_tb_off.png",
|
"jeija_insulated_wire_tjunction_tb_off.png",
|
||||||
"jeija_insulated_wire_tjunction_tb_off.png^[transformR180",
|
"jeija_insulated_wire_tjunction_tb_off.png^[transformR180",
|
||||||
@ -74,7 +67,7 @@ minetest.register_node("mesecons_extrawires:tjunction_off", {
|
|||||||
selection_box = tjunction_selectionbox,
|
selection_box = tjunction_selectionbox,
|
||||||
node_box = tjunction_nodebox,
|
node_box = tjunction_nodebox,
|
||||||
groups = {dig_immediate = 3},
|
groups = {dig_immediate = 3},
|
||||||
sounds = default.node_sound_defaults(),
|
sounds = mesecon.node_sound.default,
|
||||||
mesecons = {conductor =
|
mesecons = {conductor =
|
||||||
{
|
{
|
||||||
state = mesecon.state.off,
|
state = mesecon.state.off,
|
||||||
@ -82,7 +75,7 @@ minetest.register_node("mesecons_extrawires:tjunction_off", {
|
|||||||
onstate = "mesecons_extrawires:tjunction_on"
|
onstate = "mesecons_extrawires:tjunction_on"
|
||||||
}},
|
}},
|
||||||
on_blast = mesecon.on_blastnode,
|
on_blast = mesecon.on_blastnode,
|
||||||
on_rotate = screwdriver_exists and screwdriver.rotate_simple,
|
on_rotate = mesecon.on_rotate_horiz,
|
||||||
})
|
})
|
||||||
|
|
||||||
minetest.register_craft({
|
minetest.register_craft({
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
local S = minetest.get_translator(minetest.get_current_modname())
|
||||||
|
|
||||||
local vertical_box = {
|
local vertical_box = {
|
||||||
type = "fixed",
|
type = "fixed",
|
||||||
fixed = {-1/16, -8/16, -1/16, 1/16, 8/16, 1/16}
|
fixed = {-1/16, -8/16, -1/16, 1/16, 8/16, 1/16}
|
||||||
@ -38,35 +40,39 @@ local bottom_rules = {
|
|||||||
{x=0, y=2, z=0} -- receive power from pressure plate / detector / ... 2 nodes above
|
{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 vertical_updatepos = function (pos)
|
||||||
local node = minetest.get_node(pos)
|
local node = minetest.get_node(pos)
|
||||||
if minetest.registered_nodes[node.name]
|
if not is_vertical_conductor(node.name) then
|
||||||
and minetest.registered_nodes[node.name].is_vertical_conductor then
|
return
|
||||||
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})
|
|
||||||
end
|
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
|
end
|
||||||
|
|
||||||
local vertical_update = function (pos)
|
local vertical_update = function (pos)
|
||||||
@ -77,7 +83,7 @@ end
|
|||||||
|
|
||||||
-- Vertical wire
|
-- Vertical wire
|
||||||
mesecon.register_node("mesecons_extrawires:vertical", {
|
mesecon.register_node("mesecons_extrawires:vertical", {
|
||||||
description = "Vertical Mesecon",
|
description = S("Vertical Mesecon"),
|
||||||
drawtype = "nodebox",
|
drawtype = "nodebox",
|
||||||
walkable = false,
|
walkable = false,
|
||||||
paramtype = "light",
|
paramtype = "light",
|
||||||
@ -89,7 +95,7 @@ mesecon.register_node("mesecons_extrawires:vertical", {
|
|||||||
drop = "mesecons_extrawires:vertical_off",
|
drop = "mesecons_extrawires:vertical_off",
|
||||||
after_place_node = vertical_update,
|
after_place_node = vertical_update,
|
||||||
after_dig_node = vertical_update,
|
after_dig_node = vertical_update,
|
||||||
sounds = default.node_sound_defaults(),
|
sounds = mesecon.node_sound.default,
|
||||||
},{
|
},{
|
||||||
tiles = {"mesecons_wire_off.png"},
|
tiles = {"mesecons_wire_off.png"},
|
||||||
groups = {dig_immediate=3},
|
groups = {dig_immediate=3},
|
||||||
@ -110,7 +116,7 @@ mesecon.register_node("mesecons_extrawires:vertical", {
|
|||||||
|
|
||||||
-- Vertical wire top
|
-- Vertical wire top
|
||||||
mesecon.register_node("mesecons_extrawires:vertical_top", {
|
mesecon.register_node("mesecons_extrawires:vertical_top", {
|
||||||
description = "Vertical mesecon",
|
description = S("Vertical Mesecon"),
|
||||||
drawtype = "nodebox",
|
drawtype = "nodebox",
|
||||||
walkable = false,
|
walkable = false,
|
||||||
paramtype = "light",
|
paramtype = "light",
|
||||||
@ -123,7 +129,7 @@ mesecon.register_node("mesecons_extrawires:vertical_top", {
|
|||||||
drop = "mesecons_extrawires:vertical_off",
|
drop = "mesecons_extrawires:vertical_off",
|
||||||
after_place_node = vertical_update,
|
after_place_node = vertical_update,
|
||||||
after_dig_node = vertical_update,
|
after_dig_node = vertical_update,
|
||||||
sounds = default.node_sound_defaults(),
|
sounds = mesecon.node_sound.default,
|
||||||
},{
|
},{
|
||||||
tiles = {"mesecons_wire_off.png"},
|
tiles = {"mesecons_wire_off.png"},
|
||||||
mesecons = {conductor = {
|
mesecons = {conductor = {
|
||||||
@ -142,7 +148,7 @@ mesecon.register_node("mesecons_extrawires:vertical_top", {
|
|||||||
|
|
||||||
-- Vertical wire bottom
|
-- Vertical wire bottom
|
||||||
mesecon.register_node("mesecons_extrawires:vertical_bottom", {
|
mesecon.register_node("mesecons_extrawires:vertical_bottom", {
|
||||||
description = "Vertical mesecon",
|
description = S("Vertical Mesecon"),
|
||||||
drawtype = "nodebox",
|
drawtype = "nodebox",
|
||||||
walkable = false,
|
walkable = false,
|
||||||
paramtype = "light",
|
paramtype = "light",
|
||||||
@ -155,7 +161,7 @@ mesecon.register_node("mesecons_extrawires:vertical_bottom", {
|
|||||||
drop = "mesecons_extrawires:vertical_off",
|
drop = "mesecons_extrawires:vertical_off",
|
||||||
after_place_node = vertical_update,
|
after_place_node = vertical_update,
|
||||||
after_dig_node = vertical_update,
|
after_dig_node = vertical_update,
|
||||||
sounds = default.node_sound_defaults(),
|
sounds = mesecon.node_sound.default,
|
||||||
},{
|
},{
|
||||||
tiles = {"mesecons_wire_off.png"},
|
tiles = {"mesecons_wire_off.png"},
|
||||||
mesecons = {conductor = {
|
mesecons = {conductor = {
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
local S = minetest.get_translator(minetest.get_current_modname())
|
||||||
|
|
||||||
local plg = {}
|
local plg = {}
|
||||||
plg.rules = {}
|
plg.rules = {}
|
||||||
-- per-player formspec positions
|
-- per-player formspec positions
|
||||||
@ -59,7 +61,7 @@ plg.register_nodes = function(template)
|
|||||||
end
|
end
|
||||||
|
|
||||||
plg.register_nodes({
|
plg.register_nodes({
|
||||||
description = "FPGA",
|
description = S("FPGA"),
|
||||||
drawtype = "nodebox",
|
drawtype = "nodebox",
|
||||||
tiles = {
|
tiles = {
|
||||||
"", -- replaced later
|
"", -- replaced later
|
||||||
@ -109,7 +111,7 @@ plg.register_nodes({
|
|||||||
local is = lcore.deserialize(meta:get_string("instr"))
|
local is = lcore.deserialize(meta:get_string("instr"))
|
||||||
minetest.show_formspec(name, "mesecons:fpga", plg.to_formspec_string(is, nil))
|
minetest.show_formspec(name, "mesecons:fpga", plg.to_formspec_string(is, nil))
|
||||||
end,
|
end,
|
||||||
sounds = default.node_sound_stone_defaults(),
|
sounds = mesecon.node_sound.stone,
|
||||||
mesecons = {
|
mesecons = {
|
||||||
effector = {
|
effector = {
|
||||||
rules = {}, -- replaced later
|
rules = {}, -- replaced later
|
||||||
|
3
mesecons_fpga/locale/mesecons_fpga.de.tr
Normal file
3
mesecons_fpga/locale/mesecons_fpga.de.tr
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
# textdomain: mesecons_fpga
|
||||||
|
FPGA=FPGA
|
||||||
|
FPGA Programmer=FPGA-Programmierer
|
7
mesecons_fpga/locale/mesecons_fpga.eo.tr
Normal file
7
mesecons_fpga/locale/mesecons_fpga.eo.tr
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
# textdomain: mesecons_fpga
|
||||||
|
|
||||||
|
### init.lua ###
|
||||||
|
FPGA=FPGA
|
||||||
|
|
||||||
|
### tool.lua ###
|
||||||
|
FPGA Programmer=FPGA Programilo
|
7
mesecons_fpga/locale/template.txt
Normal file
7
mesecons_fpga/locale/template.txt
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
# textdomain: mesecons_fpga
|
||||||
|
|
||||||
|
### init.lua ###
|
||||||
|
FPGA=
|
||||||
|
|
||||||
|
### tool.lua ###
|
||||||
|
FPGA Programmer=
|
@ -1,3 +1,3 @@
|
|||||||
name = mesecons_fpga
|
name = mesecons_fpga
|
||||||
depends = default, mesecons
|
depends = mesecons, mesecons_gamecompat
|
||||||
optional_depends = screwdriver
|
optional_depends = screwdriver
|
||||||
|
106
mesecons_fpga/spec/helper_spec.lua
Normal file
106
mesecons_fpga/spec/helper_spec.lua
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
require("mineunit")
|
||||||
|
|
||||||
|
fixture("mesecons_fpga")
|
||||||
|
fixture("screwdriver")
|
||||||
|
|
||||||
|
local pos = {x = 0, y = 0, z = 0}
|
||||||
|
local pos_a = {x = -1, y = 0, z = 0}
|
||||||
|
local pos_b = {x = 0, y = 0, z = 1}
|
||||||
|
local pos_c = {x = 1, y = 0, z = 0}
|
||||||
|
local pos_d = {x = 0, y = 0, z = -1}
|
||||||
|
|
||||||
|
describe("FPGA rotation", function()
|
||||||
|
before_each(function()
|
||||||
|
world.set_node(pos, "mesecons_fpga:fpga0000")
|
||||||
|
end)
|
||||||
|
|
||||||
|
after_each(function()
|
||||||
|
mesecon._test_reset()
|
||||||
|
world.clear()
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("rotates I/O operands clockwise", function()
|
||||||
|
mesecon._test_program_fpga(pos, {{"A", "OR", "B", "C"}})
|
||||||
|
|
||||||
|
local node = world.get_node(pos)
|
||||||
|
minetest.registered_nodes[node.name].on_rotate(pos, node, nil, screwdriver.ROTATE_FACE)
|
||||||
|
|
||||||
|
mesecon._test_place(pos_b, "mesecons:test_receptor_on")
|
||||||
|
mineunit:execute_globalstep() -- Execute receptor_on action
|
||||||
|
mineunit:execute_globalstep() -- Execute activate/change actions
|
||||||
|
assert.equal("mesecons_fpga:fpga1000", world.get_node(pos).name)
|
||||||
|
|
||||||
|
mesecon._test_dig(pos_b)
|
||||||
|
mesecon._test_place(pos_c, "mesecons:test_receptor_on")
|
||||||
|
mineunit:execute_globalstep() -- Execute receptor_on/receptor_off actions
|
||||||
|
mineunit:execute_globalstep() -- Execute activate/deactivate/change actions
|
||||||
|
assert.equal("mesecons_fpga:fpga1000", world.get_node(pos).name)
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("rotates I/O operands counterclockwise", function()
|
||||||
|
mesecon._test_program_fpga(pos, {{"A", "OR", "B", "C"}})
|
||||||
|
|
||||||
|
local node = world.get_node(pos)
|
||||||
|
minetest.registered_nodes[node.name].on_rotate(pos, node, nil, screwdriver.ROTATE_AXIS)
|
||||||
|
|
||||||
|
mesecon._test_place(pos_d, "mesecons:test_receptor_on")
|
||||||
|
mineunit:execute_globalstep() -- Execute receptor_on action
|
||||||
|
mineunit:execute_globalstep() -- Execute activate/change actions
|
||||||
|
assert.equal("mesecons_fpga:fpga0010", world.get_node(pos).name)
|
||||||
|
|
||||||
|
mesecon._test_dig(pos_d)
|
||||||
|
mesecon._test_place(pos_a, "mesecons:test_receptor_on")
|
||||||
|
mineunit:execute_globalstep() -- Execute receptor_on/receptor_off actions
|
||||||
|
mineunit:execute_globalstep() -- Execute activate/deactivate/change actions
|
||||||
|
assert.equal("mesecons_fpga:fpga0010", world.get_node(pos).name)
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("updates ports", function()
|
||||||
|
mesecon._test_program_fpga(pos, {{"NOT", "A", "B"}})
|
||||||
|
assert.equal("mesecons_fpga:fpga0010", world.get_node(pos).name)
|
||||||
|
|
||||||
|
local node = world.get_node(pos)
|
||||||
|
minetest.registered_nodes[node.name].on_rotate(pos, node, nil, screwdriver.ROTATE_AXIS)
|
||||||
|
assert.equal("mesecons_fpga:fpga0001", world.get_node(pos).name)
|
||||||
|
end)
|
||||||
|
end)
|
||||||
|
|
||||||
|
describe("FPGA programmer", function()
|
||||||
|
local pos2 = {x = 10, y = 0, z = 0}
|
||||||
|
|
||||||
|
before_each(function()
|
||||||
|
world.set_node(pos, "mesecons_fpga:fpga0000")
|
||||||
|
world.set_node(pos2, "mesecons_fpga:fpga0000")
|
||||||
|
end)
|
||||||
|
|
||||||
|
after_each(function()
|
||||||
|
mesecon._test_reset()
|
||||||
|
world.clear()
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("transfers instructions", function()
|
||||||
|
mesecon._test_program_fpga(pos2, {{"NOT", "A", "B"}})
|
||||||
|
mesecon._test_paste_fpga_program(pos, mesecon._test_copy_fpga_program(pos2))
|
||||||
|
assert.equal("mesecons_fpga:fpga0010", world.get_node(pos).name)
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("does not copy from new FPGAs", function()
|
||||||
|
mesecon._test_program_fpga(pos, {{"NOT", "A", "B"}})
|
||||||
|
mesecon._test_paste_fpga_program(pos, mesecon._test_copy_fpga_program(pos2))
|
||||||
|
assert.equal("mesecons_fpga:fpga0010", world.get_node(pos).name)
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("does not copy from cleared FPGAs", function()
|
||||||
|
mesecon._test_program_fpga(pos, {{"NOT", "A", "B"}})
|
||||||
|
mesecon._test_program_fpga(pos2, {{"=", "A", "B"}})
|
||||||
|
mesecon._test_program_fpga(pos2, {})
|
||||||
|
mesecon._test_paste_fpga_program(pos, mesecon._test_copy_fpga_program(pos2))
|
||||||
|
assert.equal("mesecons_fpga:fpga0010", world.get_node(pos).name)
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("does not copy from non-FPGA nodes", function()
|
||||||
|
mesecon._test_program_fpga(pos, {{"NOT", "A", "B"}})
|
||||||
|
mesecon._test_paste_fpga_program(pos, mesecon._test_copy_fpga_program(vector.add(pos2, 1)))
|
||||||
|
assert.equal("mesecons_fpga:fpga0010", world.get_node(pos).name)
|
||||||
|
end)
|
||||||
|
end)
|
235
mesecons_fpga/spec/logic_spec.lua
Normal file
235
mesecons_fpga/spec/logic_spec.lua
Normal file
@ -0,0 +1,235 @@
|
|||||||
|
require("mineunit")
|
||||||
|
|
||||||
|
fixture("mesecons_fpga")
|
||||||
|
|
||||||
|
describe("FPGA logic", function()
|
||||||
|
local pos = {x = 0, y = 0, z = 0}
|
||||||
|
local pos_a = {x = -1, y = 0, z = 0}
|
||||||
|
local pos_b = {x = 0, y = 0, z = 1}
|
||||||
|
local pos_c = {x = 1, y = 0, z = 0}
|
||||||
|
local pos_d = {x = 0, y = 0, z = -1}
|
||||||
|
|
||||||
|
local fpga_set = false
|
||||||
|
|
||||||
|
local function set_fpga()
|
||||||
|
if not fpga_set then
|
||||||
|
world.set_node(pos, "mesecons_fpga:fpga0000")
|
||||||
|
fpga_set = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
before_each(set_fpga)
|
||||||
|
|
||||||
|
local function reset_world()
|
||||||
|
if fpga_set then
|
||||||
|
mesecon._test_reset()
|
||||||
|
world.clear()
|
||||||
|
fpga_set = false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
after_each(reset_world)
|
||||||
|
|
||||||
|
local function test_program(inputs, outputs, program)
|
||||||
|
set_fpga()
|
||||||
|
|
||||||
|
mesecon._test_program_fpga(pos, program)
|
||||||
|
|
||||||
|
if inputs.a then mesecon._test_place(pos_a, "mesecons:test_receptor_on") end
|
||||||
|
if inputs.b then mesecon._test_place(pos_b, "mesecons:test_receptor_on") end
|
||||||
|
if inputs.c then mesecon._test_place(pos_c, "mesecons:test_receptor_on") end
|
||||||
|
if inputs.d then mesecon._test_place(pos_d, "mesecons:test_receptor_on") end
|
||||||
|
mineunit:execute_globalstep() -- Execute receptor_on actions
|
||||||
|
mineunit:execute_globalstep() -- Execute activate/change actions
|
||||||
|
|
||||||
|
local expected_name = "mesecons_fpga:fpga"
|
||||||
|
.. (outputs.d and 1 or 0) .. (outputs.c and 1 or 0)
|
||||||
|
.. (outputs.b and 1 or 0) .. (outputs.a and 1 or 0)
|
||||||
|
assert.equal(expected_name, world.get_node(pos).name)
|
||||||
|
|
||||||
|
reset_world()
|
||||||
|
end
|
||||||
|
|
||||||
|
it("operator and", function()
|
||||||
|
local prog = {{"A", "AND", "B", "C"}}
|
||||||
|
test_program({}, {}, prog)
|
||||||
|
test_program({a = true}, {}, prog)
|
||||||
|
test_program({b = true}, {}, prog)
|
||||||
|
test_program({a = true, b = true}, {c = true}, prog)
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("operator or", function()
|
||||||
|
local prog = {{"A", "OR", "B", "C"}}
|
||||||
|
test_program({}, {}, prog)
|
||||||
|
test_program({a = true}, {c = true}, prog)
|
||||||
|
test_program({b = true}, {c = true}, prog)
|
||||||
|
test_program({a = true, b = true}, {c = true}, prog)
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("operator not", function()
|
||||||
|
local prog = {{"NOT", "A", "B"}}
|
||||||
|
test_program({}, {b = true}, prog)
|
||||||
|
test_program({a = true}, {}, prog)
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("operator xor", function()
|
||||||
|
local prog = {{"A", "XOR", "B", "C"}}
|
||||||
|
test_program({}, {}, prog)
|
||||||
|
test_program({a = true}, {c = true}, prog)
|
||||||
|
test_program({b = true}, {c = true}, prog)
|
||||||
|
test_program({a = true, b = true}, {}, prog)
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("operator nand", function()
|
||||||
|
local prog = {{"A", "NAND", "B", "C"}}
|
||||||
|
test_program({}, {c = true}, prog)
|
||||||
|
test_program({a = true}, {c = true}, prog)
|
||||||
|
test_program({b = true}, {c = true}, prog)
|
||||||
|
test_program({a = true, b = true}, {}, prog)
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("operator buf", function()
|
||||||
|
local prog = {{"=", "A", "B"}}
|
||||||
|
test_program({}, {}, prog)
|
||||||
|
test_program({a = true}, {b = true}, prog)
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("operator xnor", function()
|
||||||
|
local prog = {{"A", "XNOR", "B", "C"}}
|
||||||
|
test_program({}, {c = true}, prog)
|
||||||
|
test_program({a = true}, {}, prog)
|
||||||
|
test_program({b = true}, {}, prog)
|
||||||
|
test_program({a = true, b = true}, {c = true}, prog)
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("operator nor", function()
|
||||||
|
local prog = {{"A", "NOR", "B", "C"}}
|
||||||
|
test_program({}, {c = true}, prog)
|
||||||
|
test_program({a = true}, {}, prog)
|
||||||
|
test_program({b = true}, {}, prog)
|
||||||
|
test_program({a = true, b = true}, {}, prog)
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("rejects duplicate operands", function()
|
||||||
|
test_program({a = true}, {}, {{"A", "OR", "A", "B"}})
|
||||||
|
test_program({a = true}, {}, {{"=", "A", "0"}, {"0", "OR", "0", "B"}})
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("rejects unassigned memory operands", function()
|
||||||
|
test_program({a = true}, {}, {{"A", "OR", "0", "B"}})
|
||||||
|
test_program({a = true}, {}, {{"0", "OR", "A", "B"}})
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("rejects double memory assignment", function()
|
||||||
|
test_program({a = true}, {}, {{"=", "A", "0"}, {"=", "A", "0"}, {"=", "0", "B"}})
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("rejects assignment to memory operand", function()
|
||||||
|
test_program({a = true}, {}, {{"=", "A", "0"}, {"A", "OR", "0", "0"}, {"=", "0", "B"}})
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("allows double port assignment", function()
|
||||||
|
test_program({a = true}, {b = true}, {{"NOT", "A", "B"}, {"=", "A", "B"}})
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("allows assignment to port operand", function()
|
||||||
|
test_program({a = true}, {b = true}, {{"A", "OR", "B", "B"}})
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("preserves initial pin states", function()
|
||||||
|
test_program({a = true}, {b = true}, {{"=", "A", "B"}, {"=", "B", "C"}})
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("rejects binary operations with single operands", function()
|
||||||
|
test_program({a = true}, {}, {{"=", "A", "B"}, {" ", "OR", "A", "C"}})
|
||||||
|
test_program({a = true}, {}, {{"=", "A", "B"}, {"A", "OR", " ", "C"}})
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("rejects unary operations with first operands", function()
|
||||||
|
test_program({a = true}, {}, {{"=", "A", "B"}, {"A", "=", " ", "C"}})
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("rejects operations without destinations", function()
|
||||||
|
test_program({a = true}, {}, {{"=", "A", "B"}, {"=", "A", " "}})
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("allows blank statements", function()
|
||||||
|
test_program({a = true}, {b = true, c = true}, {
|
||||||
|
{" ", " ", " ", " "},
|
||||||
|
{"=", "A", "B"},
|
||||||
|
{" ", " ", " ", " "},
|
||||||
|
{" ", " ", " ", " "},
|
||||||
|
{"=", "A", "C"},
|
||||||
|
})
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("transmits output signals to adjacent nodes", function()
|
||||||
|
mesecon._test_program_fpga(pos, {
|
||||||
|
{"=", "A", "B"},
|
||||||
|
{"=", "A", "C"},
|
||||||
|
{"NOT", "A", "D"},
|
||||||
|
})
|
||||||
|
mesecon._test_place(pos_b, "mesecons:test_effector")
|
||||||
|
mesecon._test_place(pos_c, "mesecons:test_effector")
|
||||||
|
mesecon._test_place(pos_d, "mesecons:test_effector")
|
||||||
|
mineunit:execute_globalstep() -- Execute receptor_on actions
|
||||||
|
mineunit:execute_globalstep() -- Execute activate/change actions
|
||||||
|
|
||||||
|
-- Makes an object from the last three effector events in the list for use with assert.same.
|
||||||
|
-- This is necessary to ignore the ordering of events.
|
||||||
|
local function event_tester(list)
|
||||||
|
local o = {list[#list - 2], list[#list - 1], list[#list - 0]}
|
||||||
|
table.sort(o, function(a, b)
|
||||||
|
local fmt = "%s %d %d %d"
|
||||||
|
return fmt:format(a[1], a[2].x, a[2].y, a[2].z) < fmt:format(b[1], b[2].x, b[2].y, b[2].z)
|
||||||
|
end)
|
||||||
|
return o
|
||||||
|
end
|
||||||
|
|
||||||
|
mesecon._test_place(pos_a, "mesecons:test_receptor_on")
|
||||||
|
mineunit:execute_globalstep() -- Execute receptor_on action
|
||||||
|
mineunit:execute_globalstep() -- Execute activate/change actions
|
||||||
|
mineunit:execute_globalstep() -- Execute receptor_on/receptor_off actions
|
||||||
|
mineunit:execute_globalstep() -- Execute activate/deactivate/change actions
|
||||||
|
assert.equal("mesecons_fpga:fpga0110", world.get_node(pos).name)
|
||||||
|
assert.same(event_tester({{"on", pos_b}, {"on", pos_c}, {"off", pos_d}}), event_tester(mesecon._test_effector_events))
|
||||||
|
|
||||||
|
mesecon._test_dig(pos_a)
|
||||||
|
mineunit:execute_globalstep() -- Execute receptor_off action
|
||||||
|
mineunit:execute_globalstep() -- Execute deactivate/change actions
|
||||||
|
mineunit:execute_globalstep() -- Execute receptor_on/receptor_off actions
|
||||||
|
mineunit:execute_globalstep() -- Execute activate/deactivate/change actions
|
||||||
|
assert.equal("mesecons_fpga:fpga1000", world.get_node(pos).name)
|
||||||
|
assert.same(event_tester({{"off", pos_b}, {"off", pos_c}, {"on", pos_d}}), event_tester(mesecon._test_effector_events))
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("considers past outputs in determining inputs", function()
|
||||||
|
-- Memory cell: Turning on A turns on C; turning on B turns off C.
|
||||||
|
mesecon._test_program_fpga(pos, {
|
||||||
|
{"A", "OR", "C", "0"},
|
||||||
|
{"B", "OR", "D", "1"},
|
||||||
|
{"NOT", "A", "2"},
|
||||||
|
{"NOT", "B", "3"},
|
||||||
|
{"0", "AND", "3", "C"},
|
||||||
|
{"1", "AND", "2", "D"},
|
||||||
|
})
|
||||||
|
|
||||||
|
mesecon._test_place(pos_a, "mesecons:test_receptor_on")
|
||||||
|
mineunit:execute_globalstep() -- Execute receptor_on actions
|
||||||
|
mineunit:execute_globalstep() -- Execute activate/change actions
|
||||||
|
assert.equal("mesecons_fpga:fpga0100", world.get_node(pos).name)
|
||||||
|
|
||||||
|
mesecon._test_dig(pos_a)
|
||||||
|
mineunit:execute_globalstep() -- Execute receptor_off actions
|
||||||
|
mineunit:execute_globalstep() -- Execute deactivate/change actions
|
||||||
|
assert.equal("mesecons_fpga:fpga0100", world.get_node(pos).name)
|
||||||
|
|
||||||
|
mesecon._test_place(pos_b, "mesecons:test_receptor_on")
|
||||||
|
mineunit:execute_globalstep() -- Execute receptor_on actions
|
||||||
|
mineunit:execute_globalstep() -- Execute activate/change actions
|
||||||
|
assert.equal("mesecons_fpga:fpga1000", world.get_node(pos).name)
|
||||||
|
|
||||||
|
mesecon._test_dig(pos_b)
|
||||||
|
mineunit:execute_globalstep() -- Execute receptor_off actions
|
||||||
|
mineunit:execute_globalstep() -- Execute deactivate/change actions
|
||||||
|
assert.equal("mesecons_fpga:fpga1000", world.get_node(pos).name)
|
||||||
|
end)
|
||||||
|
end)
|
1
mesecons_fpga/spec/mineunit.conf
Normal file
1
mesecons_fpga/spec/mineunit.conf
Normal file
@ -0,0 +1 @@
|
|||||||
|
fixture_paths = {"../.test_fixtures"}
|
@ -1,8 +1,10 @@
|
|||||||
|
local S = minetest.get_translator(minetest.get_current_modname())
|
||||||
|
|
||||||
return function(plg)
|
return function(plg)
|
||||||
|
|
||||||
|
|
||||||
minetest.register_tool("mesecons_fpga:programmer", {
|
minetest.register_tool("mesecons_fpga:programmer", {
|
||||||
description = "FPGA Programmer",
|
description = S("FPGA Programmer"),
|
||||||
inventory_image = "jeija_fpga_programmer.png",
|
inventory_image = "jeija_fpga_programmer.png",
|
||||||
stack_max = 1,
|
stack_max = 1,
|
||||||
on_place = function(itemstack, placer, pointed_thing)
|
on_place = function(itemstack, placer, pointed_thing)
|
||||||
@ -21,7 +23,7 @@ minetest.register_tool("mesecons_fpga:programmer", {
|
|||||||
minetest.sound_play("mesecons_fpga_fail", { pos = placer:get_pos(), gain = 0.1, max_hear_distance = 4 }, true)
|
minetest.sound_play("mesecons_fpga_fail", { pos = placer:get_pos(), gain = 0.1, max_hear_distance = 4 }, true)
|
||||||
return itemstack
|
return itemstack
|
||||||
end
|
end
|
||||||
itemstack:set_metadata(meta:get_string("instr"))
|
itemstack:get_meta():set_string("", meta:get_string("instr"))
|
||||||
minetest.chat_send_player(placer:get_player_name(), "FPGA gate configuration was successfully copied!")
|
minetest.chat_send_player(placer:get_player_name(), "FPGA gate configuration was successfully copied!")
|
||||||
minetest.sound_play("mesecons_fpga_copy", { pos = placer:get_pos(), gain = 0.1, max_hear_distance = 4 }, true)
|
minetest.sound_play("mesecons_fpga_copy", { pos = placer:get_pos(), gain = 0.1, max_hear_distance = 4 }, true)
|
||||||
|
|
||||||
@ -42,7 +44,7 @@ minetest.register_tool("mesecons_fpga:programmer", {
|
|||||||
return itemstack
|
return itemstack
|
||||||
end
|
end
|
||||||
|
|
||||||
local imeta = itemstack:get_metadata()
|
local imeta = itemstack:get_meta():get_string("")
|
||||||
if imeta == "" then
|
if imeta == "" then
|
||||||
minetest.chat_send_player(player_name, "Use shift+right-click to copy a gate configuration first.")
|
minetest.chat_send_player(player_name, "Use shift+right-click to copy a gate configuration first.")
|
||||||
minetest.sound_play("mesecons_fpga_fail", { pos = user:get_pos(), gain = 0.1, max_hear_distance = 4 }, true)
|
minetest.sound_play("mesecons_fpga_fail", { pos = user:get_pos(), gain = 0.1, max_hear_distance = 4 }, true)
|
||||||
|
75
mesecons_gamecompat/compat_mtg.lua
Normal file
75
mesecons_gamecompat/compat_mtg.lua
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
--Aliases
|
||||||
|
|
||||||
|
minetest.register_alias("mesecons_gamecompat:chest", "default:chest")
|
||||||
|
minetest.register_alias("mesecons_gamecompat:chest_locked", "default:chest_locked")
|
||||||
|
minetest.register_alias("mesecons_gamecompat:coalblock", "default:coalblock")
|
||||||
|
minetest.register_alias("mesecons_gamecompat:cobble", "default:cobble")
|
||||||
|
minetest.register_alias("mesecons_gamecompat:glass", "default:glass")
|
||||||
|
minetest.register_alias("mesecons_gamecompat:lava_source", "default:lava_source")
|
||||||
|
minetest.register_alias("mesecons_gamecompat:mese", "default:mese")
|
||||||
|
minetest.register_alias("mesecons_gamecompat:mese_crystal", "default:mese_crystal")
|
||||||
|
minetest.register_alias("mesecons_gamecompat:mese_crystal_fragment", "default:mese_crystal_fragment")
|
||||||
|
minetest.register_alias("mesecons_gamecompat:obsidian_glass", "default:obsidian_glass")
|
||||||
|
minetest.register_alias("mesecons_gamecompat:stone", "default:stone")
|
||||||
|
minetest.register_alias("mesecons_gamecompat:steel_ingot", "default:steel_ingot")
|
||||||
|
minetest.register_alias("mesecons_gamecompat:steelblock", "default:steelblock")
|
||||||
|
minetest.register_alias("mesecons_gamecompat:torch", "default:torch")
|
||||||
|
|
||||||
|
if minetest.get_modpath("dye") then
|
||||||
|
for _, color in ipairs(mesecon.dye_colors) do
|
||||||
|
minetest.register_alias("mesecons_gamecompat:dye_" .. color, "dye:" .. color)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Sounds
|
||||||
|
|
||||||
|
mesecon.node_sound.default = default.node_sound_defaults()
|
||||||
|
mesecon.node_sound.glass = default.node_sound_glass_defaults()
|
||||||
|
mesecon.node_sound.leaves = default.node_sound_leaves_defaults()
|
||||||
|
mesecon.node_sound.stone = default.node_sound_stone_defaults()
|
||||||
|
mesecon.node_sound.wood = default.node_sound_wood_defaults()
|
||||||
|
|
||||||
|
if minetest.get_modpath("fire") then
|
||||||
|
mesecon.sound_name.fire = "fire_fire"
|
||||||
|
end
|
||||||
|
|
||||||
|
if minetest.get_modpath("tnt") then
|
||||||
|
mesecon.sound_name.explode = "tnt_explode"
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Textures
|
||||||
|
|
||||||
|
mesecon.texture.steel_block = "default_steel_block.png"
|
||||||
|
|
||||||
|
-- MVPS stoppers
|
||||||
|
|
||||||
|
if minetest.get_modpath("mesecons_mvps") then
|
||||||
|
-- All of the locked and internal nodes in Minetest Game
|
||||||
|
for _, name in ipairs({
|
||||||
|
"default:chest_locked",
|
||||||
|
"default:chest_locked_open",
|
||||||
|
"doors:door_steel_b_1", -- old style doors
|
||||||
|
"doors:door_steel_b_2", --
|
||||||
|
"doors:door_steel_t_1", --
|
||||||
|
"doors:door_steel_t_2", --
|
||||||
|
"doors:door_steel_a", -- new style doors
|
||||||
|
"doors:door_steel_b", --
|
||||||
|
"doors:door_steel_c", --
|
||||||
|
"doors:door_steel_d", --
|
||||||
|
"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",
|
||||||
|
"xpanes:door_steel_bar_d",
|
||||||
|
"xpanes:trapdoor_steel_bar",
|
||||||
|
"xpanes:trapdoor_steel_bar_open",
|
||||||
|
}) do
|
||||||
|
mesecon.register_mvps_stopper(name)
|
||||||
|
end
|
||||||
|
end
|
15
mesecons_gamecompat/init.lua
Normal file
15
mesecons_gamecompat/init.lua
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
mesecon.node_sound = {}
|
||||||
|
|
||||||
|
mesecon.sound_name = {}
|
||||||
|
|
||||||
|
mesecon.texture = {}
|
||||||
|
|
||||||
|
mesecon.dye_colors = {
|
||||||
|
"red", "green", "blue", "grey", "dark_grey", "yellow",
|
||||||
|
"orange", "white", "pink", "magenta", "cyan", "violet",
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
3
mesecons_gamecompat/mod.conf
Normal file
3
mesecons_gamecompat/mod.conf
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
name = mesecons_gamecompat
|
||||||
|
depends = mesecons
|
||||||
|
optional_depends = fire, default, dye, mesecons_mvps, tnt
|
@ -11,39 +11,30 @@ local nodebox = {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
local function gate_rotate_rules(node, rules)
|
local gate_get_output_rules = mesecon.horiz_rules_getter({{x = 1, y = 0, z = 0}})
|
||||||
for rotations = 0, node.param2 - 1 do
|
|
||||||
rules = mesecon.rotate_rules_left(rules)
|
|
||||||
end
|
|
||||||
return rules
|
|
||||||
end
|
|
||||||
|
|
||||||
local function gate_get_output_rules(node)
|
local gate_get_input_rules_oneinput = mesecon.horiz_rules_getter({{x =-1, y = 0, z = 0}})
|
||||||
return gate_rotate_rules(node, {{x=1, y=0, z=0}})
|
|
||||||
end
|
|
||||||
|
|
||||||
local function gate_get_input_rules_oneinput(node)
|
local gate_get_input_rules_twoinputs = mesecon.horiz_rules_getter({
|
||||||
return gate_rotate_rules(node, {{x=-1, y=0, z=0}})
|
{x = 0, y = 0, z = 1, name = "input1"},
|
||||||
end
|
{x = 0, y = 0, z = -1, name = "input2"},
|
||||||
|
})
|
||||||
local function gate_get_input_rules_twoinputs(node)
|
|
||||||
return gate_rotate_rules(node, {{x=0, y=0, z=1, name="input1"},
|
|
||||||
{x=0, y=0, z=-1, name="input2"}})
|
|
||||||
end
|
|
||||||
|
|
||||||
local function set_gate(pos, node, state)
|
local function set_gate(pos, node, state)
|
||||||
local gate = minetest.registered_nodes[node.name]
|
local gate = minetest.registered_nodes[node.name]
|
||||||
|
|
||||||
if mesecon.do_overheat(pos) then
|
local new_nodename = state and gate.onstate or gate.offstate
|
||||||
minetest.remove_node(pos)
|
minetest.swap_node(pos, {name = new_nodename, param2 = node.param2})
|
||||||
mesecon.receptor_off(pos, gate_get_output_rules(node))
|
if new_nodename ~= node.name then
|
||||||
minetest.add_item(pos, gate.drop)
|
if mesecon.do_overheat(pos) then
|
||||||
elseif state then
|
minetest.remove_node(pos)
|
||||||
minetest.swap_node(pos, {name = gate.onstate, param2=node.param2})
|
mesecon.receptor_off(pos, gate_get_output_rules(node))
|
||||||
mesecon.receptor_on(pos, gate_get_output_rules(node))
|
minetest.add_item(pos, gate.drop)
|
||||||
else
|
elseif state then
|
||||||
minetest.swap_node(pos, {name = gate.offstate, param2=node.param2})
|
mesecon.receptor_on(pos, gate_get_output_rules(node))
|
||||||
mesecon.receptor_off(pos, gate_get_output_rules(node))
|
else
|
||||||
|
mesecon.receptor_off(pos, gate_get_output_rules(node))
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -53,11 +44,36 @@ local function update_gate(pos, node, link, newstate)
|
|||||||
if gate.inputnumber == 1 then
|
if gate.inputnumber == 1 then
|
||||||
set_gate(pos, node, gate.assess(newstate == "on"))
|
set_gate(pos, node, gate.assess(newstate == "on"))
|
||||||
elseif gate.inputnumber == 2 then
|
elseif gate.inputnumber == 2 then
|
||||||
local meta = minetest.get_meta(pos)
|
-- Inputs are stored in param2. Bit 5 is always set.
|
||||||
meta:set_int(link.name, newstate == "on" and 1 or 0)
|
-- input1 is bit 6 and input2 is bit 7.
|
||||||
|
local val1, val2
|
||||||
local val1 = meta:get_int("input1") == 1
|
if node.param2 >= 32 then
|
||||||
local val2 = meta:get_int("input2") == 1
|
-- Bit 5 is set, so param2 is in the proper format.
|
||||||
|
if link.name == "input1" then
|
||||||
|
val1 = newstate == "on"
|
||||||
|
val2 = node.param2 >= 128
|
||||||
|
else
|
||||||
|
val1 = node.param2 % 128 >= 64
|
||||||
|
val2 = newstate == "on"
|
||||||
|
end
|
||||||
|
else
|
||||||
|
-- Migrate old gates where the inputs are stored as metadata.
|
||||||
|
-- This also triggers for newly placed gates.
|
||||||
|
local meta = minetest.get_meta(pos)
|
||||||
|
if link.name == "input1" then
|
||||||
|
val1 = newstate == "on"
|
||||||
|
val2 = meta:get_int("input2") == 1
|
||||||
|
else
|
||||||
|
val1 = meta:get_int("input1") == 1
|
||||||
|
val2 = newstate == "on"
|
||||||
|
end
|
||||||
|
-- Set bit 5 so this won't happen again.
|
||||||
|
node.param2 = node.param2 + 32
|
||||||
|
-- Clear the metadata.
|
||||||
|
meta:set_string("input1", "")
|
||||||
|
meta:set_string("input2", "")
|
||||||
|
end
|
||||||
|
node.param2 = node.param2 % 64 + (val1 and 64 or 0) + (val2 and 128 or 0)
|
||||||
set_gate(pos, node, gate.assess(val1, val2))
|
set_gate(pos, node, gate.assess(val1, val2))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -78,12 +94,13 @@ local function register_gate(name, inputnumber, assess, recipe, description)
|
|||||||
selection_box = selection_box,
|
selection_box = selection_box,
|
||||||
node_box = nodebox,
|
node_box = nodebox,
|
||||||
walkable = true,
|
walkable = true,
|
||||||
sounds = default.node_sound_stone_defaults(),
|
sounds = mesecon.node_sound.stone,
|
||||||
assess = assess,
|
assess = assess,
|
||||||
onstate = basename.."_on",
|
onstate = basename.."_on",
|
||||||
offstate = basename.."_off",
|
offstate = basename.."_off",
|
||||||
inputnumber = inputnumber,
|
inputnumber = inputnumber,
|
||||||
after_dig_node = mesecon.do_cooldown,
|
after_dig_node = mesecon.do_cooldown,
|
||||||
|
on_rotate = mesecon.on_rotate_horiz,
|
||||||
},{
|
},{
|
||||||
tiles = {
|
tiles = {
|
||||||
"jeija_microcontroller_bottom.png^".."jeija_gate_off.png^"..
|
"jeija_microcontroller_bottom.png^".."jeija_gate_off.png^"..
|
||||||
|
@ -1,2 +1,2 @@
|
|||||||
name = mesecons_gates
|
name = mesecons_gates
|
||||||
depends = default, mesecons, mesecons_microcontroller, mesecons_delayer, mesecons_torch, mesecons_materials
|
depends = mesecons, mesecons_gamecompat, mesecons_microcontroller, mesecons_delayer, mesecons_torch, mesecons_materials
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
local S = minetest.get_translator(minetest.get_current_modname())
|
||||||
|
|
||||||
-- HYDRO_TURBINE
|
-- HYDRO_TURBINE
|
||||||
-- Water turbine:
|
-- Water turbine:
|
||||||
-- Active if flowing >water< above it
|
-- Active if flowing >water< above it
|
||||||
@ -17,13 +19,13 @@ minetest.register_node("mesecons_hydroturbine:hydro_turbine_off", {
|
|||||||
is_ground_content = false,
|
is_ground_content = false,
|
||||||
wield_scale = {x=0.75, y=0.75, z=0.75},
|
wield_scale = {x=0.75, y=0.75, z=0.75},
|
||||||
groups = {dig_immediate=2},
|
groups = {dig_immediate=2},
|
||||||
description="Water Turbine",
|
description = S("Water Turbine"),
|
||||||
paramtype = "light",
|
paramtype = "light",
|
||||||
selection_box = {
|
selection_box = {
|
||||||
type = "fixed",
|
type = "fixed",
|
||||||
fixed = { -0.5, -0.5, -0.5, 0.5, 1.5, 0.5 },
|
fixed = { -0.5, -0.5, -0.5, 0.5, 1.5, 0.5 },
|
||||||
},
|
},
|
||||||
sounds = default.node_sound_metal_defaults(),
|
sounds = mesecon.node_sound.metal,
|
||||||
mesecons = {receptor = {
|
mesecons = {receptor = {
|
||||||
state = mesecon.state.off
|
state = mesecon.state.off
|
||||||
}},
|
}},
|
||||||
@ -47,13 +49,13 @@ minetest.register_node("mesecons_hydroturbine:hydro_turbine_on", {
|
|||||||
inventory_image = "jeija_hydro_turbine_inv.png",
|
inventory_image = "jeija_hydro_turbine_inv.png",
|
||||||
drop = "mesecons_hydroturbine:hydro_turbine_off 1",
|
drop = "mesecons_hydroturbine:hydro_turbine_off 1",
|
||||||
groups = {dig_immediate=2,not_in_creative_inventory=1},
|
groups = {dig_immediate=2,not_in_creative_inventory=1},
|
||||||
description="Water Turbine",
|
description = S("Water Turbine"),
|
||||||
paramtype = "light",
|
paramtype = "light",
|
||||||
selection_box = {
|
selection_box = {
|
||||||
type = "fixed",
|
type = "fixed",
|
||||||
fixed = { -0.5, -0.5, -0.5, 0.5, 1.5, 0.5 },
|
fixed = { -0.5, -0.5, -0.5, 0.5, 1.5, 0.5 },
|
||||||
},
|
},
|
||||||
sounds = default.node_sound_metal_defaults(),
|
sounds = mesecon.node_sound.metal,
|
||||||
mesecons = {receptor = {
|
mesecons = {receptor = {
|
||||||
state = mesecon.state.on
|
state = mesecon.state.on
|
||||||
}},
|
}},
|
||||||
@ -64,8 +66,8 @@ minetest.register_node("mesecons_hydroturbine:hydro_turbine_on", {
|
|||||||
local function is_flowing_water(pos)
|
local function is_flowing_water(pos)
|
||||||
local name = minetest.get_node(pos).name
|
local name = minetest.get_node(pos).name
|
||||||
local is_water = minetest.get_item_group(name, "water") > 0
|
local is_water = minetest.get_item_group(name, "water") > 0
|
||||||
local is_flowing = minetest.registered_items[name].liquidtype == "flowing"
|
local def = minetest.registered_items[name]
|
||||||
return (is_water and is_flowing)
|
return is_water and (def and def.liquidtype == "flowing")
|
||||||
end
|
end
|
||||||
|
|
||||||
minetest.register_abm({
|
minetest.register_abm({
|
||||||
@ -97,9 +99,8 @@ nodenames = {"mesecons_hydroturbine:hydro_turbine_on"},
|
|||||||
minetest.register_craft({
|
minetest.register_craft({
|
||||||
output = "mesecons_hydroturbine:hydro_turbine_off 2",
|
output = "mesecons_hydroturbine:hydro_turbine_off 2",
|
||||||
recipe = {
|
recipe = {
|
||||||
{"","default:stick", ""},
|
{"","group:stick", ""},
|
||||||
{"default:stick", "default:steel_ingot", "default:stick"},
|
{"group:stick", "mesecons_gamecompat:steel_ingot", "group:stick"},
|
||||||
{"","default:stick", ""},
|
{"","group:stick", ""},
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
2
mesecons_hydroturbine/locale/mesecons_hydroturbine.de.tr
Normal file
2
mesecons_hydroturbine/locale/mesecons_hydroturbine.de.tr
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
# textdomain: mesecons_hydroturbine
|
||||||
|
Water Turbine=Wasserturbine
|
4
mesecons_hydroturbine/locale/mesecons_hydroturbine.eo.tr
Normal file
4
mesecons_hydroturbine/locale/mesecons_hydroturbine.eo.tr
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
# textdomain: mesecons_hydroturbine
|
||||||
|
|
||||||
|
### init.lua ###
|
||||||
|
Water Turbine=Akva Turbino
|
4
mesecons_hydroturbine/locale/template.txt
Normal file
4
mesecons_hydroturbine/locale/template.txt
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
# textdomain: mesecons_hydroturbine
|
||||||
|
|
||||||
|
### init.lua ###
|
||||||
|
Water Turbine=
|
@ -1,2 +1,2 @@
|
|||||||
name = mesecons_hydroturbine
|
name = mesecons_hydroturbine
|
||||||
depends = default, mesecons
|
depends = mesecons, mesecons_gamecompat
|
||||||
|
@ -1,17 +1,13 @@
|
|||||||
local screwdriver_exists = minetest.global_exists("screwdriver")
|
local S = minetest.get_translator(minetest.get_current_modname())
|
||||||
|
|
||||||
local function insulated_wire_get_rules(node)
|
local insulated_wire_get_rules = mesecon.horiz_rules_getter({
|
||||||
local rules = {{x = 1, y = 0, z = 0},
|
{x = 1, y = 0, z = 0},
|
||||||
{x =-1, y = 0, z = 0}}
|
{x = -1, y = 0, z = 0},
|
||||||
if node.param2 == 1 or node.param2 == 3 then
|
})
|
||||||
return mesecon.rotate_rules_right(rules)
|
|
||||||
end
|
|
||||||
return rules
|
|
||||||
end
|
|
||||||
|
|
||||||
minetest.register_node("mesecons_insulated:insulated_on", {
|
minetest.register_node("mesecons_insulated:insulated_on", {
|
||||||
drawtype = "nodebox",
|
drawtype = "nodebox",
|
||||||
description = "Straight Insulated Mesecon",
|
description = S("Straight Insulated Mesecon"),
|
||||||
tiles = {
|
tiles = {
|
||||||
"jeija_insulated_wire_sides_on.png",
|
"jeija_insulated_wire_sides_on.png",
|
||||||
"jeija_insulated_wire_sides_on.png",
|
"jeija_insulated_wire_sides_on.png",
|
||||||
@ -36,19 +32,19 @@ minetest.register_node("mesecons_insulated:insulated_on", {
|
|||||||
},
|
},
|
||||||
groups = {dig_immediate = 3, not_in_creative_inventory = 1},
|
groups = {dig_immediate = 3, not_in_creative_inventory = 1},
|
||||||
drop = "mesecons_insulated:insulated_off",
|
drop = "mesecons_insulated:insulated_off",
|
||||||
sounds = default.node_sound_defaults(),
|
sounds = mesecon.node_sound.default,
|
||||||
mesecons = {conductor = {
|
mesecons = {conductor = {
|
||||||
state = mesecon.state.on,
|
state = mesecon.state.on,
|
||||||
offstate = "mesecons_insulated:insulated_off",
|
offstate = "mesecons_insulated:insulated_off",
|
||||||
rules = insulated_wire_get_rules
|
rules = insulated_wire_get_rules
|
||||||
}},
|
}},
|
||||||
on_blast = mesecon.on_blastnode,
|
on_blast = mesecon.on_blastnode,
|
||||||
on_rotate = screwdriver_exists and screwdriver.rotate_simple,
|
on_rotate = mesecon.on_rotate_horiz,
|
||||||
})
|
})
|
||||||
|
|
||||||
minetest.register_node("mesecons_insulated:insulated_off", {
|
minetest.register_node("mesecons_insulated:insulated_off", {
|
||||||
drawtype = "nodebox",
|
drawtype = "nodebox",
|
||||||
description = "Straight Insulated Mesecon",
|
description = S("Straight Insulated Mesecon"),
|
||||||
tiles = {
|
tiles = {
|
||||||
"jeija_insulated_wire_sides_off.png",
|
"jeija_insulated_wire_sides_off.png",
|
||||||
"jeija_insulated_wire_sides_off.png",
|
"jeija_insulated_wire_sides_off.png",
|
||||||
@ -72,14 +68,14 @@ minetest.register_node("mesecons_insulated:insulated_off", {
|
|||||||
fixed = { -16/32-0.001, -17/32, -3/32, 16/32+0.001, -13/32, 3/32 }
|
fixed = { -16/32-0.001, -17/32, -3/32, 16/32+0.001, -13/32, 3/32 }
|
||||||
},
|
},
|
||||||
groups = {dig_immediate = 3},
|
groups = {dig_immediate = 3},
|
||||||
sounds = default.node_sound_defaults(),
|
sounds = mesecon.node_sound.default,
|
||||||
mesecons = {conductor = {
|
mesecons = {conductor = {
|
||||||
state = mesecon.state.off,
|
state = mesecon.state.off,
|
||||||
onstate = "mesecons_insulated:insulated_on",
|
onstate = "mesecons_insulated:insulated_on",
|
||||||
rules = insulated_wire_get_rules
|
rules = insulated_wire_get_rules
|
||||||
}},
|
}},
|
||||||
on_blast = mesecon.on_blastnode,
|
on_blast = mesecon.on_blastnode,
|
||||||
on_rotate = screwdriver_exists and screwdriver.rotate_simple,
|
on_rotate = mesecon.on_rotate_horiz,
|
||||||
})
|
})
|
||||||
|
|
||||||
minetest.register_craft({
|
minetest.register_craft({
|
||||||
|
2
mesecons_insulated/locale/mesecons_insulated.de.tr
Normal file
2
mesecons_insulated/locale/mesecons_insulated.de.tr
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
# textdomain: mesecons_insulated
|
||||||
|
Straight Insulated Mesecon=Isolierte Mesecongerade
|
4
mesecons_insulated/locale/mesecons_insulated.eo.tr
Normal file
4
mesecons_insulated/locale/mesecons_insulated.eo.tr
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
# textdomain: mesecons_insulated
|
||||||
|
|
||||||
|
### init.lua ###
|
||||||
|
Straight Insulated Mesecon=Rekta Izolita Mesekonduktilo
|
4
mesecons_insulated/locale/template.txt
Normal file
4
mesecons_insulated/locale/template.txt
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
# textdomain: mesecons_insulated
|
||||||
|
|
||||||
|
### init.lua ###
|
||||||
|
Straight Insulated Mesecon=
|
@ -1,3 +1,2 @@
|
|||||||
name = mesecons_insulated
|
name = mesecons_insulated
|
||||||
depends = default, mesecons
|
depends = mesecons, mesecons_gamecompat
|
||||||
optional_depends = screwdriver
|
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
local S = minetest.get_translator(minetest.get_current_modname())
|
||||||
|
|
||||||
-- MESELAMPS
|
-- MESELAMPS
|
||||||
-- A lamp is "is an electrical device used to create artificial light" (wikipedia)
|
-- A lamp is "is an electrical device used to create artificial light" (wikipedia)
|
||||||
-- guess what?
|
-- guess what?
|
||||||
@ -26,7 +28,7 @@ minetest.register_node("mesecons_lamp:lamp_on", {
|
|||||||
selection_box = mesecon_lamp_box,
|
selection_box = mesecon_lamp_box,
|
||||||
groups = {dig_immediate = 3,not_in_creative_inventory = 1, mesecon_effector_on = 1},
|
groups = {dig_immediate = 3,not_in_creative_inventory = 1, mesecon_effector_on = 1},
|
||||||
drop = "mesecons_lamp:lamp_off 1",
|
drop = "mesecons_lamp:lamp_off 1",
|
||||||
sounds = default.node_sound_glass_defaults(),
|
sounds = mesecon.node_sound.glass,
|
||||||
mesecons = {effector = {
|
mesecons = {effector = {
|
||||||
action_off = function (pos, node)
|
action_off = function (pos, node)
|
||||||
minetest.swap_node(pos, {name = "mesecons_lamp:lamp_off", param2 = node.param2})
|
minetest.swap_node(pos, {name = "mesecons_lamp:lamp_off", param2 = node.param2})
|
||||||
@ -50,8 +52,8 @@ minetest.register_node("mesecons_lamp:lamp_off", {
|
|||||||
node_box = mesecon_lamp_box,
|
node_box = mesecon_lamp_box,
|
||||||
selection_box = mesecon_lamp_box,
|
selection_box = mesecon_lamp_box,
|
||||||
groups = {dig_immediate=3, mesecon_receptor_off = 1, mesecon_effector_off = 1},
|
groups = {dig_immediate=3, mesecon_receptor_off = 1, mesecon_effector_off = 1},
|
||||||
description = "Mesecon Lamp",
|
description = S("Mesecon Lamp"),
|
||||||
sounds = default.node_sound_glass_defaults(),
|
sounds = mesecon.node_sound.glass,
|
||||||
mesecons = {effector = {
|
mesecons = {effector = {
|
||||||
action_on = function (pos, node)
|
action_on = function (pos, node)
|
||||||
minetest.swap_node(pos, {name = "mesecons_lamp:lamp_on", param2 = node.param2})
|
minetest.swap_node(pos, {name = "mesecons_lamp:lamp_on", param2 = node.param2})
|
||||||
@ -64,8 +66,8 @@ minetest.register_node("mesecons_lamp:lamp_off", {
|
|||||||
minetest.register_craft({
|
minetest.register_craft({
|
||||||
output = "mesecons_lamp:lamp_off 1",
|
output = "mesecons_lamp:lamp_off 1",
|
||||||
recipe = {
|
recipe = {
|
||||||
{"", "default:glass", ""},
|
{"", "mesecons_gamecompat:glass", ""},
|
||||||
{"group:mesecon_conductor_craftable", "default:steel_ingot", "group:mesecon_conductor_craftable"},
|
{"group:mesecon_conductor_craftable", "mesecons_gamecompat:steel_ingot", "group:mesecon_conductor_craftable"},
|
||||||
{"", "default:glass", ""},
|
{"", "mesecons_gamecompat:glass", ""},
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
2
mesecons_lamp/locale/mesecons_lamp.de.tr
Normal file
2
mesecons_lamp/locale/mesecons_lamp.de.tr
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
# textdomain: mesecons_lamp
|
||||||
|
Mesecon Lamp=Meseconlampe
|
4
mesecons_lamp/locale/mesecons_lamp.eo.tr
Normal file
4
mesecons_lamp/locale/mesecons_lamp.eo.tr
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
# textdomain: mesecons_lamp
|
||||||
|
|
||||||
|
### init.lua ###
|
||||||
|
Mesecon Lamp=Mesekonduktila Lampo
|
4
mesecons_lamp/locale/template.txt
Normal file
4
mesecons_lamp/locale/template.txt
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
# textdomain: mesecons_lamp
|
||||||
|
|
||||||
|
### init.lua ###
|
||||||
|
Mesecon Lamp=
|
@ -1,2 +1,2 @@
|
|||||||
name = mesecons_lamp
|
name = mesecons_lamp
|
||||||
depends = default, mesecons
|
depends = mesecons, mesecons_gamecompat
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
local S = minetest.get_translator(minetest.get_current_modname())
|
||||||
|
|
||||||
local lightstone_rules = {
|
local lightstone_rules = {
|
||||||
{x=0, y=0, z=-1},
|
{x=0, y=0, z=-1},
|
||||||
{x=1, y=0, z=0},
|
{x=1, y=0, z=0},
|
||||||
@ -23,7 +25,7 @@ function mesecon.lightstone_add(name, base_item, texture_off, texture_on, desc)
|
|||||||
is_ground_content = false,
|
is_ground_content = false,
|
||||||
groups = {cracky = 2, mesecon_effector_off = 1, mesecon = 2},
|
groups = {cracky = 2, mesecon_effector_off = 1, mesecon = 2},
|
||||||
description = desc,
|
description = desc,
|
||||||
sounds = default.node_sound_stone_defaults(),
|
sounds = mesecon.node_sound.stone,
|
||||||
mesecons = {effector = {
|
mesecons = {effector = {
|
||||||
rules = lightstone_rules,
|
rules = lightstone_rules,
|
||||||
action_on = function (pos, node)
|
action_on = function (pos, node)
|
||||||
@ -38,7 +40,7 @@ function mesecon.lightstone_add(name, base_item, texture_off, texture_on, desc)
|
|||||||
groups = {cracky = 2, not_in_creative_inventory = 1, mesecon = 2},
|
groups = {cracky = 2, not_in_creative_inventory = 1, mesecon = 2},
|
||||||
drop = "mesecons_lightstone:lightstone_" .. name .. "_off",
|
drop = "mesecons_lightstone:lightstone_" .. name .. "_off",
|
||||||
light_source = minetest.LIGHT_MAX - 2,
|
light_source = minetest.LIGHT_MAX - 2,
|
||||||
sounds = default.node_sound_stone_defaults(),
|
sounds = mesecon.node_sound.stone,
|
||||||
mesecons = {effector = {
|
mesecons = {effector = {
|
||||||
rules = lightstone_rules,
|
rules = lightstone_rules,
|
||||||
action_off = function (pos, node)
|
action_off = function (pos, node)
|
||||||
@ -52,22 +54,22 @@ function mesecon.lightstone_add(name, base_item, texture_off, texture_on, desc)
|
|||||||
output = "mesecons_lightstone:lightstone_" .. name .. "_off",
|
output = "mesecons_lightstone:lightstone_" .. name .. "_off",
|
||||||
recipe = {
|
recipe = {
|
||||||
{"",base_item,""},
|
{"",base_item,""},
|
||||||
{base_item,"default:torch",base_item},
|
{base_item,"mesecons_gamecompat:torch",base_item},
|
||||||
{"","group:mesecon_conductor_craftable",""}
|
{"","group:mesecon_conductor_craftable",""}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
mesecon.lightstone_add("red", "dye:red", "jeija_lightstone_red_off.png", "jeija_lightstone_red_on.png", "Red Lightstone")
|
mesecon.lightstone_add("red", "mesecons_gamecompat:dye_red", "jeija_lightstone_red_off.png", "jeija_lightstone_red_on.png", S("Red Lightstone"))
|
||||||
mesecon.lightstone_add("green", "dye:green", "jeija_lightstone_green_off.png", "jeija_lightstone_green_on.png", "Green Lightstone")
|
mesecon.lightstone_add("green", "mesecons_gamecompat:dye_green", "jeija_lightstone_green_off.png", "jeija_lightstone_green_on.png", S("Green Lightstone"))
|
||||||
mesecon.lightstone_add("blue", "dye:blue", "jeija_lightstone_blue_off.png", "jeija_lightstone_blue_on.png", "Blue Lightstone")
|
mesecon.lightstone_add("blue", "mesecons_gamecompat:dye_blue", "jeija_lightstone_blue_off.png", "jeija_lightstone_blue_on.png", S("Blue Lightstone"))
|
||||||
mesecon.lightstone_add("gray", "dye:grey", "jeija_lightstone_gray_off.png", "jeija_lightstone_gray_on.png", "Grey Lightstone")
|
mesecon.lightstone_add("gray", "mesecons_gamecompat:dye_grey", "jeija_lightstone_gray_off.png", "jeija_lightstone_gray_on.png", S("Grey Lightstone"))
|
||||||
mesecon.lightstone_add("darkgray", "dye:dark_grey", "jeija_lightstone_darkgray_off.png", "jeija_lightstone_darkgray_on.png", "Dark Grey Lightstone")
|
mesecon.lightstone_add("darkgray", "mesecons_gamecompat:dye_dark_grey", "jeija_lightstone_darkgray_off.png", "jeija_lightstone_darkgray_on.png", S("Dark Grey Lightstone"))
|
||||||
mesecon.lightstone_add("yellow", "dye:yellow", "jeija_lightstone_yellow_off.png", "jeija_lightstone_yellow_on.png", "Yellow Lightstone")
|
mesecon.lightstone_add("yellow", "mesecons_gamecompat:dye_yellow", "jeija_lightstone_yellow_off.png", "jeija_lightstone_yellow_on.png", S("Yellow Lightstone"))
|
||||||
mesecon.lightstone_add("orange", "dye:orange", "jeija_lightstone_orange_off.png", "jeija_lightstone_orange_on.png", "Orange Lightstone")
|
mesecon.lightstone_add("orange", "mesecons_gamecompat:dye_orange", "jeija_lightstone_orange_off.png", "jeija_lightstone_orange_on.png", S("Orange Lightstone"))
|
||||||
mesecon.lightstone_add("white", "dye:white", "jeija_lightstone_white_off.png", "jeija_lightstone_white_on.png", "White Lightstone")
|
mesecon.lightstone_add("white", "mesecons_gamecompat:dye_white", "jeija_lightstone_white_off.png", "jeija_lightstone_white_on.png", S("White Lightstone"))
|
||||||
mesecon.lightstone_add("pink", "dye:pink", "jeija_lightstone_pink_off.png", "jeija_lightstone_pink_on.png", "Pink Lightstone")
|
mesecon.lightstone_add("pink", "mesecons_gamecompat:dye_pink", "jeija_lightstone_pink_off.png", "jeija_lightstone_pink_on.png", S("Pink Lightstone"))
|
||||||
mesecon.lightstone_add("magenta", "dye:magenta", "jeija_lightstone_magenta_off.png", "jeija_lightstone_magenta_on.png", "Magenta Lightstone")
|
mesecon.lightstone_add("magenta", "mesecons_gamecompat:dye_magenta", "jeija_lightstone_magenta_off.png", "jeija_lightstone_magenta_on.png", S("Magenta Lightstone"))
|
||||||
mesecon.lightstone_add("cyan", "dye:cyan", "jeija_lightstone_cyan_off.png", "jeija_lightstone_cyan_on.png", "Cyan Lightstone")
|
mesecon.lightstone_add("cyan", "mesecons_gamecompat:dye_cyan", "jeija_lightstone_cyan_off.png", "jeija_lightstone_cyan_on.png", S("Cyan Lightstone"))
|
||||||
mesecon.lightstone_add("violet", "dye:violet", "jeija_lightstone_violet_off.png", "jeija_lightstone_violet_on.png", "Violet Lightstone")
|
mesecon.lightstone_add("violet", "mesecons_gamecompat:dye_violet", "jeija_lightstone_violet_off.png", "jeija_lightstone_violet_on.png", S("Violet Lightstone"))
|
||||||
|
13
mesecons_lightstone/locale/mesecons_lightstone.de.tr
Normal file
13
mesecons_lightstone/locale/mesecons_lightstone.de.tr
Normal 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
|
15
mesecons_lightstone/locale/mesecons_lightstone.eo.tr
Normal file
15
mesecons_lightstone/locale/mesecons_lightstone.eo.tr
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
# textdomain: mesecons_lightstone
|
||||||
|
|
||||||
|
### init.lua ###
|
||||||
|
Red Lightstone=Ruĝa Lumŝtono
|
||||||
|
Green Lightstone=Verda Lumŝtono
|
||||||
|
Blue Lightstone=Blua Lumŝtono
|
||||||
|
Grey Lightstone=Griza Lumŝtono
|
||||||
|
Dark Grey Lightstone=Malhela Griza Lumŝtono
|
||||||
|
Yellow Lightstone=Flava Lumŝtono
|
||||||
|
Orange Lightstone=Oranĝa Lumŝtono
|
||||||
|
White Lightstone=Blanka Lumŝtono
|
||||||
|
Pink Lightstone=Rozkolora Lumŝtono
|
||||||
|
Magenta Lightstone=Magenta Lumŝtono
|
||||||
|
Cyan Lightstone=Cejana Lumŝtono
|
||||||
|
Violet Lightstone=Viola Lumŝtono
|
15
mesecons_lightstone/locale/template.txt
Normal file
15
mesecons_lightstone/locale/template.txt
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
# textdomain: mesecons_lightstone
|
||||||
|
|
||||||
|
### init.lua ###
|
||||||
|
Red Lightstone=
|
||||||
|
Green Lightstone=
|
||||||
|
Blue Lightstone=
|
||||||
|
Grey Lightstone=
|
||||||
|
Dark Grey Lightstone=
|
||||||
|
Yellow Lightstone=
|
||||||
|
Orange Lightstone=
|
||||||
|
White Lightstone=
|
||||||
|
Pink Lightstone=
|
||||||
|
Magenta Lightstone=
|
||||||
|
Cyan Lightstone=
|
||||||
|
Violet Lightstone=
|
@ -1,2 +1,2 @@
|
|||||||
name = mesecons_lightstone
|
name = mesecons_lightstone
|
||||||
depends = default, mesecons, dye
|
depends = mesecons, mesecons_gamecompat
|
||||||
|
@ -28,6 +28,8 @@
|
|||||||
-- (see where local env is defined)
|
-- (see where local env is defined)
|
||||||
-- Something nice to play is is appending minetest.env to it.
|
-- Something nice to play is is appending minetest.env to it.
|
||||||
|
|
||||||
|
local S = minetest.get_translator(minetest.get_current_modname())
|
||||||
|
|
||||||
local BASENAME = "mesecons_luacontroller:luacontroller"
|
local BASENAME = "mesecons_luacontroller:luacontroller"
|
||||||
|
|
||||||
local rules = {
|
local rules = {
|
||||||
@ -201,11 +203,13 @@ end
|
|||||||
-------------------------
|
-------------------------
|
||||||
|
|
||||||
local function safe_print(param)
|
local function safe_print(param)
|
||||||
local string_meta = getmetatable("")
|
if mesecon.setting("luacontroller_print_behavior", "log") == "log" then
|
||||||
local sandbox = string_meta.__index
|
local string_meta = getmetatable("")
|
||||||
string_meta.__index = string -- Leave string sandbox temporarily
|
local sandbox = string_meta.__index
|
||||||
print(dump(param))
|
string_meta.__index = string -- Leave string sandbox temporarily
|
||||||
string_meta.__index = sandbox -- Restore string sandbox
|
minetest.log("action", string.format("[mesecons_luacontroller] print(%s)", dump(param)))
|
||||||
|
string_meta.__index = sandbox -- Restore string sandbox
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function safe_date()
|
local function safe_date()
|
||||||
@ -234,6 +238,16 @@ local function safe_string_find(...)
|
|||||||
return string.find(...)
|
return string.find(...)
|
||||||
end
|
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 function remove_functions(x)
|
||||||
local tp = type(x)
|
local tp = type(x)
|
||||||
if tp == "function" then
|
if tp == "function" then
|
||||||
@ -374,7 +388,10 @@ local function clean_and_weigh_digiline_message(msg, back_references)
|
|||||||
return msg, #msg + 25
|
return msg, #msg + 25
|
||||||
elseif t == "number" then
|
elseif t == "number" then
|
||||||
-- Numbers are passed by value so need not be touched, and cost 8 bytes
|
-- 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
|
return msg, 8
|
||||||
elseif t == "boolean" then
|
elseif t == "boolean" then
|
||||||
-- Booleans are passed by value so need not be touched, and cost 1
|
-- Booleans are passed by value so need not be touched, and cost 1
|
||||||
@ -470,7 +487,12 @@ local safe_globals = {
|
|||||||
|
|
||||||
local function create_environment(pos, mem, event, itbl, send_warning)
|
local function create_environment(pos, mem, event, itbl, send_warning)
|
||||||
-- Gather variables for the environment
|
-- Gather variables for the environment
|
||||||
local vports = minetest.registered_nodes[minetest.get_node(pos).name].virtual_portstates
|
local node_def = minetest.registered_nodes[minetest.get_node(pos).name]
|
||||||
|
if not node_def then return end
|
||||||
|
|
||||||
|
local vports = node_def.virtual_portstates
|
||||||
|
if not vports then return end
|
||||||
|
|
||||||
local vports_copy = {}
|
local vports_copy = {}
|
||||||
for k, v in pairs(vports) do vports_copy[k] = v end
|
for k, v in pairs(vports) do vports_copy[k] = v end
|
||||||
local rports = get_real_port_states(pos)
|
local rports = get_real_port_states(pos)
|
||||||
@ -498,6 +520,7 @@ local function create_environment(pos, mem, event, itbl, send_warning)
|
|||||||
reverse = string.reverse,
|
reverse = string.reverse,
|
||||||
sub = string.sub,
|
sub = string.sub,
|
||||||
find = safe_string_find,
|
find = safe_string_find,
|
||||||
|
split = safe_string_split,
|
||||||
},
|
},
|
||||||
math = {
|
math = {
|
||||||
abs = math.abs,
|
abs = math.abs,
|
||||||
@ -627,6 +650,7 @@ local function run_inner(pos, code, event)
|
|||||||
-- Create environment
|
-- Create environment
|
||||||
local itbl = {}
|
local itbl = {}
|
||||||
local env = create_environment(pos, mem, event, itbl, send_warning)
|
local env = create_environment(pos, mem, event, itbl, send_warning)
|
||||||
|
if not env then return false, "Env does not exist. Controller has been moved?" end
|
||||||
|
|
||||||
local success, msg
|
local success, msg
|
||||||
-- Create the sandbox and execute code
|
-- Create the sandbox and execute code
|
||||||
@ -845,7 +869,7 @@ for d = 0, 1 do
|
|||||||
}
|
}
|
||||||
|
|
||||||
minetest.register_node(node_name, {
|
minetest.register_node(node_name, {
|
||||||
description = "Luacontroller",
|
description = S("Luacontroller"),
|
||||||
drawtype = "nodebox",
|
drawtype = "nodebox",
|
||||||
tiles = {
|
tiles = {
|
||||||
top,
|
top,
|
||||||
@ -865,7 +889,7 @@ for d = 0, 1 do
|
|||||||
node_box = node_box,
|
node_box = node_box,
|
||||||
on_construct = reset_meta,
|
on_construct = reset_meta,
|
||||||
on_receive_fields = on_receive_fields,
|
on_receive_fields = on_receive_fields,
|
||||||
sounds = default.node_sound_stone_defaults(),
|
sounds = mesecon.node_sound.stone,
|
||||||
mesecons = mesecons,
|
mesecons = mesecons,
|
||||||
digiline = digiline,
|
digiline = digiline,
|
||||||
-- Virtual portstates are the ports that
|
-- Virtual portstates are the ports that
|
||||||
@ -914,7 +938,7 @@ minetest.register_node(BASENAME .. "_burnt", {
|
|||||||
node_box = node_box,
|
node_box = node_box,
|
||||||
on_construct = reset_meta,
|
on_construct = reset_meta,
|
||||||
on_receive_fields = on_receive_fields,
|
on_receive_fields = on_receive_fields,
|
||||||
sounds = default.node_sound_stone_defaults(),
|
sounds = mesecon.node_sound.stone,
|
||||||
virtual_portstates = {a = false, b = false, c = false, d = false},
|
virtual_portstates = {a = false, b = false, c = false, d = false},
|
||||||
mesecons = {
|
mesecons = {
|
||||||
effector = {
|
effector = {
|
||||||
|
@ -0,0 +1,2 @@
|
|||||||
|
# textdomain: mesecons_luacontroller
|
||||||
|
Luacontroller=Luacontroller
|
@ -0,0 +1,4 @@
|
|||||||
|
# textdomain: mesecons_luacontroller
|
||||||
|
|
||||||
|
### init.lua ###
|
||||||
|
Luacontroller=Luaregilo
|
4
mesecons_luacontroller/locale/template.txt
Normal file
4
mesecons_luacontroller/locale/template.txt
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
# textdomain: mesecons_luacontroller
|
||||||
|
|
||||||
|
### init.lua ###
|
||||||
|
Luacontroller=
|
@ -1,2 +1,2 @@
|
|||||||
name = mesecons_luacontroller
|
name = mesecons_luacontroller
|
||||||
depends = default, mesecons
|
depends = mesecons, mesecons_gamecompat
|
||||||
|
38
mesecons_luacontroller/spec/lightweight_interrupt_spec.lua
Normal file
38
mesecons_luacontroller/spec/lightweight_interrupt_spec.lua
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
require("mineunit")
|
||||||
|
|
||||||
|
-- This test is done in a separate file since it requires different configuration at startup.
|
||||||
|
mineunit("core")
|
||||||
|
minetest.settings:set("mesecon.luacontroller_lightweight_interrupts", "true")
|
||||||
|
|
||||||
|
fixture("mesecons_luacontroller")
|
||||||
|
|
||||||
|
describe("LuaController lightweight interrupt", function()
|
||||||
|
local pos = {x = 0, y = 0, z = 0}
|
||||||
|
|
||||||
|
before_each(function()
|
||||||
|
mesecon._test_place(pos, "mesecons_luacontroller:luacontroller0000")
|
||||||
|
mineunit:execute_globalstep() -- Execute receptor_on action
|
||||||
|
end)
|
||||||
|
|
||||||
|
after_each(function()
|
||||||
|
mesecon._test_reset()
|
||||||
|
world.clear()
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("works", function()
|
||||||
|
mesecon._test_program_luac(pos, [[
|
||||||
|
if event.type == "program" then
|
||||||
|
interrupt(5)
|
||||||
|
interrupt(10)
|
||||||
|
elseif event.type == "interrupt" then
|
||||||
|
port.a = not pin.a
|
||||||
|
end
|
||||||
|
]])
|
||||||
|
mineunit:execute_globalstep(0.1)
|
||||||
|
mineunit:execute_globalstep(9)
|
||||||
|
assert.equal("mesecons_luacontroller:luacontroller0000", world.get_node(pos).name)
|
||||||
|
mineunit:execute_globalstep(1)
|
||||||
|
mineunit:execute_globalstep(0.1)
|
||||||
|
assert.equal("mesecons_luacontroller:luacontroller0001", world.get_node(pos).name)
|
||||||
|
end)
|
||||||
|
end)
|
176
mesecons_luacontroller/spec/luac_spec.lua
Normal file
176
mesecons_luacontroller/spec/luac_spec.lua
Normal file
@ -0,0 +1,176 @@
|
|||||||
|
require("mineunit")
|
||||||
|
|
||||||
|
fixture("mesecons_luacontroller")
|
||||||
|
|
||||||
|
-- Digiline is not tested, since that would require the digiline mod.
|
||||||
|
|
||||||
|
describe("LuaController", function()
|
||||||
|
local pos = {x = 0, y = 0, z = 0}
|
||||||
|
local pos_a = {x = -1, y = 0, z = 0}
|
||||||
|
|
||||||
|
before_each(function()
|
||||||
|
mesecon._test_place(pos, "mesecons_luacontroller:luacontroller0000")
|
||||||
|
mineunit:execute_globalstep() -- Execute receptor_on action
|
||||||
|
end)
|
||||||
|
|
||||||
|
after_each(function()
|
||||||
|
mesecon._test_reset()
|
||||||
|
world.clear()
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("rejects binary code", function()
|
||||||
|
local ok = mesecon._test_program_luac(pos, string.dump(function() end))
|
||||||
|
assert.is_false(ok)
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("I/O", function()
|
||||||
|
mesecon._test_place(pos_a, "mesecons:test_receptor_on")
|
||||||
|
mineunit:execute_globalstep() -- Execute receptor_on action
|
||||||
|
mineunit:execute_globalstep() -- Execute activate/change actions
|
||||||
|
mesecon._test_program_luac(pos, [[
|
||||||
|
port.a = not pin.a
|
||||||
|
port.b = not pin.b
|
||||||
|
port.c = not pin.c
|
||||||
|
port.d = not pin.d
|
||||||
|
]])
|
||||||
|
assert.equal("mesecons_luacontroller:luacontroller1110", world.get_node(pos).name)
|
||||||
|
mesecon._test_dig(pos_a)
|
||||||
|
mineunit:execute_globalstep() -- Execute receptor_off action
|
||||||
|
mineunit:execute_globalstep() -- Execute deactivate/change actions
|
||||||
|
assert.equal("mesecons_luacontroller:luacontroller0001", world.get_node(pos).name)
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("memory", function()
|
||||||
|
mesecon._test_program_luac(pos, [[
|
||||||
|
if not mem.x then
|
||||||
|
mem.x = {}
|
||||||
|
mem.x[mem.x] = {true, "", 1.2}
|
||||||
|
else
|
||||||
|
local b, s, n = unpack(mem.x[mem.x])
|
||||||
|
if b == true and s == "" and n == 1.2 then
|
||||||
|
port.d = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
]])
|
||||||
|
assert.equal("mesecons_luacontroller:luacontroller0000", world.get_node(pos).name)
|
||||||
|
mesecon._test_place(pos_a, "mesecons:test_receptor_on")
|
||||||
|
mineunit:execute_globalstep() -- Execute receptor_on action
|
||||||
|
mineunit:execute_globalstep() -- Execute activate/change actions
|
||||||
|
assert.equal("mesecons_luacontroller:luacontroller1000", world.get_node(pos).name)
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("interrupts without IDs", function()
|
||||||
|
mesecon._test_program_luac(pos, [[
|
||||||
|
if event.type == "program" then
|
||||||
|
interrupt(4)
|
||||||
|
interrupt(8)
|
||||||
|
elseif event.type == "interrupt" then
|
||||||
|
port.a = not pin.a
|
||||||
|
end
|
||||||
|
]])
|
||||||
|
mineunit:execute_globalstep(0.1)
|
||||||
|
mineunit:execute_globalstep(3)
|
||||||
|
assert.equal("mesecons_luacontroller:luacontroller0000", world.get_node(pos).name)
|
||||||
|
mineunit:execute_globalstep(1)
|
||||||
|
mineunit:execute_globalstep(0.1)
|
||||||
|
assert.equal("mesecons_luacontroller:luacontroller0001", world.get_node(pos).name)
|
||||||
|
mineunit:execute_globalstep(3)
|
||||||
|
assert.equal("mesecons_luacontroller:luacontroller0001", world.get_node(pos).name)
|
||||||
|
mineunit:execute_globalstep(1)
|
||||||
|
mineunit:execute_globalstep(0.1)
|
||||||
|
assert.equal("mesecons_luacontroller:luacontroller0000", world.get_node(pos).name)
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("interrupts with IDs", function()
|
||||||
|
mesecon._test_program_luac(pos, [[
|
||||||
|
if event.type == "program" then
|
||||||
|
interrupt(2, "a")
|
||||||
|
interrupt(4, "a")
|
||||||
|
interrupt(16, "b")
|
||||||
|
elseif event.type == "interrupt" then
|
||||||
|
if event.iid == "a" then
|
||||||
|
interrupt(5, "b")
|
||||||
|
interrupt(4, "b")
|
||||||
|
end
|
||||||
|
port.a = not pin.a
|
||||||
|
end
|
||||||
|
]])
|
||||||
|
mineunit:execute_globalstep(0.1)
|
||||||
|
mineunit:execute_globalstep(3)
|
||||||
|
assert.equal("mesecons_luacontroller:luacontroller0000", world.get_node(pos).name)
|
||||||
|
mineunit:execute_globalstep(1)
|
||||||
|
mineunit:execute_globalstep(0.1)
|
||||||
|
assert.equal("mesecons_luacontroller:luacontroller0001", world.get_node(pos).name)
|
||||||
|
mineunit:execute_globalstep(3)
|
||||||
|
assert.equal("mesecons_luacontroller:luacontroller0001", world.get_node(pos).name)
|
||||||
|
mineunit:execute_globalstep(1)
|
||||||
|
mineunit:execute_globalstep(0.1)
|
||||||
|
assert.equal("mesecons_luacontroller:luacontroller0000", world.get_node(pos).name)
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("limits interrupt ID size", function()
|
||||||
|
mesecon._test_program_luac(pos, [[
|
||||||
|
if event.type == "program" then
|
||||||
|
interrupt(0, (" "):rep(257))
|
||||||
|
elseif event.type == "interrupt" then
|
||||||
|
port.a = not pin.a
|
||||||
|
end
|
||||||
|
]])
|
||||||
|
mineunit:execute_globalstep(3)
|
||||||
|
mineunit:execute_globalstep(3)
|
||||||
|
assert.equal("mesecons_luacontroller:luacontroller0000", world.get_node(pos).name)
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("string.rep", function()
|
||||||
|
mesecon._test_program_luac(pos, [[
|
||||||
|
(" "):rep(64000)
|
||||||
|
port.a = true
|
||||||
|
]])
|
||||||
|
assert.equal("mesecons_luacontroller:luacontroller0001", world.get_node(pos).name)
|
||||||
|
mesecon._test_program_luac(pos, [[
|
||||||
|
(" "):rep(64001)
|
||||||
|
port.b = true
|
||||||
|
]])
|
||||||
|
assert.equal("mesecons_luacontroller:luacontroller0000", world.get_node(pos).name)
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("string.find", function()
|
||||||
|
mesecon._test_program_luac(pos, [[
|
||||||
|
port.a = (" a"):find("a", nil, true) == 2
|
||||||
|
]])
|
||||||
|
assert.equal("mesecons_luacontroller:luacontroller0001", world.get_node(pos).name)
|
||||||
|
mesecon._test_program_luac(pos, [[
|
||||||
|
(" a"):find("a", nil)
|
||||||
|
port.b = true
|
||||||
|
]])
|
||||||
|
assert.equal("mesecons_luacontroller:luacontroller0000", world.get_node(pos).name)
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("overheats", function()
|
||||||
|
mesecon._test_program_luac(pos, [[
|
||||||
|
interrupt(0)
|
||||||
|
interrupt(0)
|
||||||
|
]])
|
||||||
|
mineunit:execute_globalstep() -- Execute 2 interrupts
|
||||||
|
mineunit:execute_globalstep() -- Execute 4 interrupts
|
||||||
|
mineunit:execute_globalstep() -- Execute 8 interrupts
|
||||||
|
mineunit:execute_globalstep() -- Execute 16 interrupts
|
||||||
|
assert.equal("mesecons_luacontroller:luacontroller_burnt", world.get_node(pos).name)
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("limits memory", function()
|
||||||
|
mesecon._test_program_luac(pos, [[
|
||||||
|
port.a = true
|
||||||
|
mem.x = (" "):rep(50000) .. (" "):rep(50000)
|
||||||
|
]])
|
||||||
|
assert.equal("mesecons_luacontroller:luacontroller_burnt", world.get_node(pos).name)
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("limits run time", function()
|
||||||
|
mesecon._test_program_luac(pos, [[
|
||||||
|
port.a = true
|
||||||
|
for i = 1, 1000000 do end
|
||||||
|
]])
|
||||||
|
assert.equal("mesecons_luacontroller:luacontroller0000", world.get_node(pos).name)
|
||||||
|
end)
|
||||||
|
end)
|
1
mesecons_luacontroller/spec/mineunit.conf
Normal file
1
mesecons_luacontroller/spec/mineunit.conf
Normal file
@ -0,0 +1 @@
|
|||||||
|
fixture_paths = {"../.test_fixtures"}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user