Merge remote-tracking branch 'upstream/master'

This commit is contained in:
bri cassa 2021-03-12 12:34:26 +01:00
commit 28411dd7e9
65 changed files with 830 additions and 1038 deletions

22
.luacheckrc Normal file
View File

@ -0,0 +1,22 @@
read_globals = {
-- Defined by Minetest
"vector", "PseudoRandom", "VoxelArea", "table",
-- Mods
"digiline", "default", "creative",
-- Required for the mesechest registration
minetest = {
fields = {
register_lbm = {read_only = false},
register_node = {read_only = false},
registered_on_player_receive_fields = {
read_only = false,
other_fields = true,
},
},
other_fields = true
}
}
globals = {"moremesecons", "mesecon"}
ignore = {"212", "631", "422", "432"}

View File

@ -1,11 +1,11 @@
# MoreMesecons
Based on Mesecons by Jeija
By @paly2 and @HybridDog
With the participation of @LeMagnesium (bugfix), @Ataron (textures), @JAPP (texture).
Based on Mesecons by Jeija <br/>
By @paly2 and @HybridDog <br/>
With the participation of @LeMagnesium (bugfix), @Ataron (textures), @JAPP (texture).
Dependencies: [Mesecons](https://github.com/Jeija/minetest-mod-mesecons/)
Optional dependencies: [vector_extras](https://github.com/HybridDog/vector_extras/) [digilines](https://github.com/minetest-mods/digilines)
Dependencies: [Mesecons](https://github.com/Jeija/minetest-mod-mesecons/) <br/>
Optional dependencies: [digilines](https://github.com/minetest-mods/digilines)
MoreMesecons is a mod for minetest which adds some mesecons items.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 361 B

After

Width:  |  Height:  |  Size: 360 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 237 B

After

Width:  |  Height:  |  Size: 237 B

View File

@ -37,18 +37,18 @@ local object_detector_scan = function (pos)
local scan_all = scanname == ""
local scan_names = scanname:split(',')
local radius = meta:get_int("radius")
if radius == 0 then
if radius <= 0 then
radius = 6
end
for _,obj in pairs(minetest.get_objects_inside_radius(pos, radius)) do
local isname = obj:get_player_name() -- "" is returned if it is not a player; "" ~= nil!
if isname ~= "" then
if scan_all then
return true
return true, isname
end
for _, name in ipairs(scan_names) do
if isname == name then
return true
return true, isname
end
end
end
@ -65,12 +65,32 @@ local object_detector_digiline = {
if channel ~= active_channel then
return
end
meta:set_string("scanname", msg)
if meta:get_string("formspec") ~= "" then
if type(msg) == "string" then
meta:set_string("scanname", msg)
make_formspec(meta)
elseif type(msg) == "table" then
if msg.radius then
local r = tonumber(msg.radius)
if r then
meta:set_int("radius", tonumber(msg.radius))
make_formspec(meta)
end
end
if msg.scanname then
meta:set_string("scanname", msg.scanname)
make_formspec(meta)
end
if msg.command and msg.command == "get" then
local found, name = object_detector_scan(pos)
if not found then
name = ""
end
digiline:receptor_send(pos, digiline.rules.default, channel, name)
end
end
end,
}
},
receptor = {}
}
minetest.register_node("moremesecons_adjustable_player_detector:player_detector_off", {

Binary file not shown.

Before

Width:  |  Height:  |  Size: 624 B

After

Width:  |  Height:  |  Size: 622 B

View File

@ -55,14 +55,14 @@ local function resolve_commands(commands, pos)
local nearest = nil
local min_distance = math.huge
local players = minetest.get_connected_players()
for index, player in pairs(players) do
for _, player in pairs(players) do
local distance = vector.distance(pos, player:getpos())
if distance < min_distance then
min_distance = distance
nearest = player:get_player_name()
end
end
new_commands = commands:gsub("@nearest", nearest)
local new_commands = commands:gsub("@nearest", nearest)
return new_commands, min_distance, new_commands ~= commands
end

View File

@ -5,7 +5,7 @@ local nodebox = {
local function signalchanger_get_output_rules(node)
local rules = {{x=-1, y=0, z=0}}
for i = 0, node.param2 do
for _ = 0, node.param2 do
rules = mesecon.rotate_rules_left(rules)
end
return rules
@ -13,7 +13,7 @@ end
local function signalchanger_get_input_rules(node)
local rules = {{x=0, y=0, z=-1, name="input_on"}, {x=0, y=0, z=1, name="input_off"}, {x=1, y=0, z=0, name="input_signal"}}
for i = 0, node.param2 do
for _ = 0, node.param2 do
rules = mesecon.rotate_rules_left(rules)
end
return rules

Binary file not shown.

Before

Width:  |  Height:  |  Size: 161 B

After

Width:  |  Height:  |  Size: 112 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 158 B

After

Width:  |  Height:  |  Size: 112 B

View File

@ -1,6 +1,6 @@
local function dual_delayer_get_input_rules(node)
local rules = {{x=1, y=0, z=0}}
for i = 0, node.param2 do
for _ = 0, node.param2 do
rules = mesecon.rotate_rules_left(rules)
end
return rules
@ -8,7 +8,7 @@ end
local function dual_delayer_get_output_rules(node)
local rules = {{x=0, y=0, z=1}, {x=0, y=0, z=-1}}
for i = 0, node.param2 do
for _ = 0, node.param2 do
rules = mesecon.rotate_rules_left(rules)
end
return rules
@ -17,19 +17,19 @@ end
local dual_delayer_activate = function(pos, node)
mesecon.receptor_on(pos, {dual_delayer_get_output_rules(node)[1]}) -- Turn on the port 1
minetest.swap_node(pos, {name = "moremesecons_dual_delayer:dual_delayer_10", param2 = node.param2})
minetest.after(0.4, function(pos, node)
minetest.after(0.4, function()
mesecon.receptor_on(pos, {dual_delayer_get_output_rules(node)[2]}) -- Turn on the port 2
minetest.swap_node(pos, {name = "moremesecons_dual_delayer:dual_delayer_11", param2 = node.param2})
end, pos, node)
end)
end
local dual_delayer_deactivate = function(pos, node, link)
mesecon.receptor_off(pos, {dual_delayer_get_output_rules(node)[2]}) -- Turn off the port 2
minetest.swap_node(pos, {name = "moremesecons_dual_delayer:dual_delayer_10", param2 = node.param2})
minetest.after(0.4, function(pos, node)
minetest.after(0.4, function()
mesecon.receptor_off(pos, {dual_delayer_get_output_rules(node)[1]}) -- Turn off the port 1
minetest.swap_node(pos, {name = "moremesecons_dual_delayer:dual_delayer_00", param2 = node.param2})
end, pos, node)
end)
end

Binary file not shown.

Before

Width:  |  Height:  |  Size: 129 B

After

Width:  |  Height:  |  Size: 99 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 189 B

After

Width:  |  Height:  |  Size: 142 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 78 B

After

Width:  |  Height:  |  Size: 78 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 77 B

After

Width:  |  Height:  |  Size: 77 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 554 B

After

Width:  |  Height:  |  Size: 554 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 696 B

After

Width:  |  Height:  |  Size: 674 B

View File

@ -18,10 +18,6 @@ local function induction_transmitter_get_output_rules(node)
return {vector.multiply(minetest.facedir_to_dir(node.param2), 2)}
end
local function induction_transmitter_get_virtual_output_rules(node)
return {minetest.facedir_to_dir(node.param2)}
end
local function act(pos, node, state)
minetest.swap_node(pos, {name = "moremesecons_induction_transmitter:induction_transmitter_"..state, param2 = node.param2})

View File

@ -1,6 +1,6 @@
local injector_controller_get_output_rules = function(node)
local rules = {{x = 0, y = 0, z = 1}}
for i = 0, node.param2 do
for _ = 0, node.param2 do
rules = mesecon.rotate_rules_left(rules)
end
return rules
@ -10,7 +10,7 @@ local injector_controller_get_input_rules = function(node)
local rules = {{x = 0, y = 0, z = -1},
{x = 1, y = 0, z = 0},
{x = -1, y = 0, z = 0}}
for i = 0, node.param2 do
for _ = 0, node.param2 do
rules = mesecon.rotate_rules_left(rules)
end
return rules

View File

@ -1,45 +1,35 @@
-- see wireless jammer
local get = vector.get_data_from_pos
local set = vector.set_data_to_pos
local remove = vector.remove_data_from_pos
local storage = minetest.get_mod_storage()
local jammers = minetest.deserialize(storage:get_string("jammers")) or {}
local jammers = moremesecons.load_MapDataStorage_legacy(storage, "jammers_v2",
"jammers")
local function update_mod_storage()
storage:set_string("jammers", minetest.serialize(jammers))
storage:set_string("jammers_v2", jammers:serialize())
end
local function add_jammer(pos)
if get(jammers, pos.z,pos.y,pos.x) then
if jammers:getAt(pos) then
return
end
set(jammers, pos.z,pos.y,pos.x, true)
jammers:setAt(pos, true)
update_mod_storage()
end
local function remove_jammer(pos)
remove(jammers, pos.z,pos.y,pos.x)
jammers:removeAt(pos)
update_mod_storage()
end
local function is_jammed(pos)
local JAMMER_MAX_DISTANCE = moremesecons.setting("jammer", "max_distance", 10, 1)
local pz,py,px = vector.unpack(pos)
for z,yxs in pairs(jammers) do
if math.abs(pz-z) <= JAMMER_MAX_DISTANCE then
for y,xs in pairs(yxs) do
if math.abs(py-y) <= JAMMER_MAX_DISTANCE then
for x in pairs(xs) do
if math.abs(px-x) <= JAMMER_MAX_DISTANCE
and (px-x)^2+(py-y)^2+(pz-z)^2 <= JAMMER_MAX_DISTANCE^2 then
return true
end
end
end
end
local minp = vector.subtract(pos, JAMMER_MAX_DISTANCE)
local maxp = vector.add(pos, JAMMER_MAX_DISTANCE)
for p in jammers:iter(minp, maxp) do
local d = vector.subtract(pos, p)
if d.x ^ 2 + d.y ^ 2 + d.z ^ 2 <= JAMMER_MAX_DISTANCE^2 then
return true
end
end
return false

Binary file not shown.

Before

Width:  |  Height:  |  Size: 100 B

After

Width:  |  Height:  |  Size: 100 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 112 B

After

Width:  |  Height:  |  Size: 112 B

View File

@ -1,20 +1,21 @@
local md5 = dofile(minetest.get_modpath(minetest.get_current_modname()).."/md5_lua/md5.lua")
local storage = minetest.get_mod_storage()
local hash_table = minetest.deserialize(storage:get_string("hash_table")) or {}
local pos_data = moremesecons.get_storage_data(storage, "pos_data")
local function set_md5(pos, code)
vector.set_data_to_pos(hash_table, pos.z,pos.y,pos.x, md5.sum(code))
storage:set_string("hash_table", minetest.serialize(hash_table))
local function set_data(pos, code, owner)
local data = {
code = code,
owner = owner
}
moremesecons.set_data_to_pos(pos_data, pos, data)
end
local function check_md5(pos, code)
local stored_sum = vector.get_data_from_pos(hash_table, pos.z,pos.y,pos.x)
if not stored_sum then
-- Legacy
set_md5(pos, code)
return true
local function check_data(pos, code, owner)
local stored_data = moremesecons.get_data_from_pos(pos_data, pos)
if not stored_data then
return false
end
if md5.sum(code) ~= stored_sum then
if code ~= stored_data.code
or owner ~= stored_data.owner then
return false
end
return true
@ -22,11 +23,11 @@ end
local function make_formspec(meta, pos)
local code = meta:get_string("code")
local code = minetest.formspec_escape(meta:get_string("code"))
local errmsg = minetest.formspec_escape(meta:get_string("errmsg"))
meta:set_string("formspec",
"size[10,8;]" ..
"textarea[0.5,0.5;10,7;code;Code;"..code.."]" ..
"textarea[0.5,0.5;9.5,7;code;Code;"..code.."]" ..
"label[0.1,7;"..errmsg.."]" ..
"button_exit[4,7.5;2,1;submit;Submit]")
end
@ -97,49 +98,63 @@ minetest.register_node("moremesecons_luablock:luablock", {
end
meta:set_string("code", fields.code)
set_md5(pos, fields.code)
set_data(pos, fields.code, name)
make_formspec(meta, pos)
end,
can_dig = function(pos, player)
local meta = minetest.get_meta(pos)
return meta:get_string("owner") == player:get_player_name()
end,
on_destruct = function(pos)
moremesecons.remove_data_from_pos(pos_data, pos)
end,
mesecons = {effector = {
action_on = function(npos, node)
local meta = minetest.get_meta(npos)
local code = meta:get_string("code")
local owner = meta:get_string("owner")
if code == "" then
return
end
if not check_md5(npos, code) then
minetest.log("warning", "[moremesecons_luablock] Code of LuaBlock at pos "..minetest.pos_to_string(npos).." does not match with its md5 checksum!")
if not check_data(npos, code, owner) then
minetest.log("warning", "[moremesecons_luablock] Metadata of LuaBlock at pos "..minetest.pos_to_string(npos).." does not match its mod storage data!")
return
end
-- We do absolutely no check there.
-- There is no limitation in the number of instruction the LuaBlock can execute
-- or the usage it can make of loops.
-- It is executed in the global namespace.
-- Remember: *The LuaBlock is highly dangerous and should be manipulated cautiously!*
local func, err = loadstring(code)
if not func then
meta:set_string("errmsg", err)
make_formspec(meta, pos)
return
end
-- Set the "pos" global
local old_pos = pos -- In case there's already an existing "pos" global
pos = table.copy(npos)
local good, err = pcall(func)
pos = old_pos
if not good then -- Runtime error
meta:set_string("errmsg", err)
make_formspec(meta, pos)
local env = {}
for k, v in pairs(_G) do
env[k] = v
end
env.pos = table.copy(npos)
env.mem = minetest.deserialize(meta:get_string("mem")) or {}
local func, err_syntax
if _VERSION == "Lua 5.1" then
func, err_syntax = loadstring(code)
if func then
setfenv(func, env)
end
else
func, err_syntax = load(code, nil, "t", env)
end
if not func then
meta:set_string("errmsg", err_syntax)
make_formspec(meta, npos)
return
end
local good, err_runtime = pcall(func)
if not good then
meta:set_string("errmsg", err_runtime)
make_formspec(meta, npos)
return
end
meta:set_string("mem", minetest.serialize(env.mem))
meta:set_string("errmsg", "")
make_formspec(meta, pos)
make_formspec(meta, npos)
end
}}
})

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 62 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -1,2 +1,3 @@
mesecons
mesecons_luacontroller
moremesecons_utils

View File

@ -1,7 +1,3 @@
--[[
vector_extras there: https://github.com/HybridDog/vector_extras
]]
local templates = {MoreMesecons = {
logic = [[-- AND
port.a = pin.b and pin.c
@ -80,14 +76,17 @@ end]]
local file_path = minetest.get_worldpath().."/MoreMesecons_lctt"
-- load templates from a compressed file
local templates_file = io.open(file_path, "rb")
if templates_file then
local templates_raw = templates_file:read("*all")
io.close(templates_file)
if templates_raw
and templates_raw ~= "" then
for name,t in pairs(minetest.deserialize(minetest.decompress(templates_raw))) do
templates[name] = t
do
local templates_file = io.open(file_path, "rb")
if templates_file then
local templates_raw = templates_file:read("*all")
io.close(templates_file)
if templates_raw
and templates_raw ~= "" then
local data = minetest.deserialize(minetest.decompress(templates_raw))
for name,t in pairs(data) do
templates[name] = t
end
end
end
end

Binary file not shown.

Before

Width:  |  Height:  |  Size: 290 B

After

Width:  |  Height:  |  Size: 227 B

View File

@ -2,7 +2,7 @@ local function mesechest_get_output_rules(node)
local rules = {{x=-1, y=0, z=0},
{x=0, y=0, z=-1},
{x=0, y=0, z=1}}
for i = 0, node.param2 do
for _ = 0, node.param2 do
rules = mesecon.rotate_rules_left(rules)
end
return rules

View File

@ -4,7 +4,7 @@ local kill_nearest_player = function(pos)
-- Search the nearest player
local nearest
local min_distance = MAX_DISTANCE
for index, player in pairs(minetest.get_connected_players()) do
for _, player in pairs(minetest.get_connected_players()) do
local distance = vector.distance(pos, player:getpos())
if distance < min_distance then
min_distance = distance

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 KiB

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 454 B

View File

@ -6,7 +6,7 @@ local nodebox = {
local function signalchanger_get_output_rules(node)
local rules = {{x=-1, y=0, z=0},
{x=1, y=0, z=0}}
for i = 0, node.param2 do
for _ = 0, node.param2 do
rules = mesecon.rotate_rules_left(rules)
end
return rules
@ -14,7 +14,7 @@ end
local function signalchanger_get_input_rules(node)
local rules = {{x=0, y=0, z=-1, name="input_on"}, {x=0, y=0, z=1, name="input_off"}}
for i = 0, node.param2 do
for _ = 0, node.param2 do
rules = mesecon.rotate_rules_left(rules)
end
return rules

Binary file not shown.

Before

Width:  |  Height:  |  Size: 158 B

After

Width:  |  Height:  |  Size: 112 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 159 B

After

Width:  |  Height:  |  Size: 112 B

View File

@ -80,7 +80,7 @@ minetest.register_node("moremesecons_switchtorch:switchtorch_on", {
selection_box = torch_selectionbox,
groups = {dig_immediate=3, not_in_creative_inventory = 1},
drop = "moremesecons_switchtorch:switchtorch_off",
light_source = LIGHT_MAX-5,
light_source = 9,
mesecons = {receptor = {
state = mesecon.state.on,
rules = torch_get_output_rules

Binary file not shown.

Before

Width:  |  Height:  |  Size: 119 B

After

Width:  |  Height:  |  Size: 119 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 111 B

After

Width:  |  Height:  |  Size: 111 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 110 B

After

Width:  |  Height:  |  Size: 110 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 116 B

After

Width:  |  Height:  |  Size: 116 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 118 B

After

Width:  |  Height:  |  Size: 118 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 114 B

After

Width:  |  Height:  |  Size: 114 B

View File

@ -1,19 +1,19 @@
local storage = minetest.get_mod_storage()
local teleporters = minetest.deserialize(storage:get_string("teleporters")) or {}
local teleporters_rids = minetest.deserialize(storage:get_string("teleporters_rids")) or {}
local jammers = minetest.deserialize(storage:get_string("jammers")) or {}
local teleporters_rids = moremesecons.load_MapDataStorage_legacy(storage,
"teleporters_rids_v2", "teleporters_rids")
local function update_mod_storage()
storage:set_string("teleporters", minetest.serialize(teleporters))
storage:set_string("teleporters_rids", minetest.serialize(teleporters_rids))
storage:set_string("teleporters_rids_v2", teleporters_rids:serialize())
end
local function register(pos)
if not vector.get_data_from_pos(teleporters_rids, pos.z,pos.y,pos.x) then
if not teleporters_rids:getAt(pos) then
table.insert(teleporters, pos)
vector.set_data_to_pos(teleporters_rids, pos.z,pos.y,pos.x, #teleporters)
teleporters_rids:setAt(pos, #teleporters)
update_mod_storage()
end
end
@ -24,12 +24,12 @@ local function teleport_nearest(pos)
-- Search for the nearest player
local nearest = nil
local min_distance = MAX_PLAYER_DISTANCE
local min_distance_player = MAX_PLAYER_DISTANCE
local players = minetest.get_connected_players()
for index, player in pairs(players) do
for _, player in pairs(players) do
local distance = vector.distance(pos, player:getpos())
if distance <= min_distance then
min_distance = distance
if distance <= min_distance_player then
min_distance_player = distance
nearest = player
end
end
@ -89,10 +89,10 @@ minetest.register_node("moremesecons_teleporter:teleporter", {
sounds = default.node_sound_stone_defaults(),
on_construct = register,
on_destruct = function(pos)
local RID = vector.get_data_from_pos(teleporters_rids, pos.z,pos.y,pos.x)
local RID = teleporters_rids:getAt(pos)
if RID then
table.remove(teleporters, RID)
vector.remove_data_from_pos(teleporters_rids, pos.z,pos.y,pos.x)
teleporters_rids:removeAt(pos)
update_mod_storage()
end
end,

View File

@ -1,6 +1,6 @@
local timegate_get_output_rules = function(node)
local rules = {{x = 0, y = 0, z = 1}}
for i = 0, node.param2 do
for _ = 0, node.param2 do
rules = mesecon.rotate_rules_left(rules)
end
return rules
@ -8,7 +8,7 @@ end
local timegate_get_input_rules = function(node)
local rules = {{x = 0, y = 0, z = -1}}
for i = 0, node.param2 do
for _ = 0, node.param2 do
rules = mesecon.rotate_rules_left(rules)
end
return rules
@ -25,14 +25,17 @@ local function timegate_activate(pos, node)
node.name = "moremesecons_timegate:timegate_on"
minetest.swap_node(pos, node)
mesecon.receptor_on(pos)
minetest.after(time, function(pos, node)
mesecon.receptor_off(pos)
node.name = "moremesecons_timegate:timegate_off"
minetest.swap_node(pos, node)
end, pos, node)
minetest.after(time, function()
local node = minetest.get_node(pos)
if node.name == "moremesecons_timegate:timegate_on" then
mesecon.receptor_off(pos)
node.name = "moremesecons_timegate:timegate_off"
minetest.swap_node(pos, node)
end
end)
end
boxes = {{ -6/16, -8/16, -6/16, 6/16, -7/16, 6/16 }, -- the main slab
local boxes = {{ -6/16, -8/16, -6/16, 6/16, -7/16, 6/16 }, -- the main slab
{ -2/16, -7/16, -4/16, 2/16, -26/64, -3/16 }, -- the jeweled "on" indicator
{ -3/16, -7/16, -3/16, 3/16, -26/64, -2/16 },

Binary file not shown.

Before

Width:  |  Height:  |  Size: 170 B

After

Width:  |  Height:  |  Size: 169 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 171 B

After

Width:  |  Height:  |  Size: 170 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 361 B

After

Width:  |  Height:  |  Size: 361 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 164 B

After

Width:  |  Height:  |  Size: 163 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 169 B

After

Width:  |  Height:  |  Size: 168 B

View File

@ -1 +0,0 @@
vector_extras?

View File

@ -28,55 +28,355 @@ function moremesecons.setting(modname, settingname, default, min)
end
end
-- Vector helpers
-- All the following functions are from the vector_extras mod (https://github.com/HybridDog/vector_extras).
-- If you enable that mod, its functions will be used instead of the ones defined below
-- Storage helpers
if not vector.get_data_from_pos then
function vector.get_data_from_pos(tab, z,y,x)
local data = tab[z]
if data then
data = data[y]
if data then
return data[x]
end
end
end
function moremesecons.get_storage_data(storage, name)
return {
tab = minetest.deserialize(storage:get_string(name)) or {},
name = name,
storage = storage
}
end
if not vector.set_data_to_pos then
function vector.set_data_to_pos(tab, z,y,x, data)
if tab[z] then
if tab[z][y] then
tab[z][y][x] = data
function moremesecons.set_data_to_pos(sto, pos, data)
sto.tab[minetest.hash_node_position(pos)] = data
sto.storage:set_string(sto.name, minetest.serialize(sto.tab))
end
function moremesecons.get_data_from_pos(sto, pos)
return sto.tab[minetest.hash_node_position(pos)]
end
function moremesecons.remove_data_from_pos(sto, pos)
sto.tab[minetest.hash_node_position(pos)] = nil
sto.storage:set_string(sto.name, minetest.serialize(sto.tab))
end
-- Some additional vector helpers
-- The same as minetest.hash_node_position; I copied it to ensure backwards
-- compatibility and used hexadecimal number notation
local function node_position_key(pos)
return (pos.z + 0x8000) * 0x10000 * 0x10000
+ (pos.y + 0x8000) * 0x10000
+ pos.x + 0x8000
end
local MapDataStorage = {}
setmetatable(MapDataStorage, {__call = function()
local obj = {}
setmetatable(obj, MapDataStorage)
return obj
end})
MapDataStorage.__index = {
getAt = function(self, pos)
return self[node_position_key(pos)]
end,
setAt = function(self, pos, data)
-- If x, y or z is omitted, the key corresponds to a position outside
-- of the map (hopefully), so it can be used to skip lines and planes
local vi_z = (pos.z + 0x8000) * 0x10000 * 0x10000
local vi_zy = vi_z + (pos.y + 0x8000) * 0x10000
local vi = vi_zy + pos.x + 0x8000
local is_new = self[vi] == nil
self[vi] = data
if is_new then
self[vi_z] = (self[vi_z] or 0) + 1
self[vi_zy] = (self[vi_zy] or 0) + 1
end
end,
setAtI = function(self, vi, data)
local vi_zy = vi - vi % 0x10000
local vi_z = vi - vi % (0x10000 * 0x10000)
local is_new = self[vi] == nil
self[vi] = data
if is_new then
self[vi_z] = (self[vi_z] or 0) + 1
self[vi_zy] = (self[vi_zy] or 0) + 1
end
end,
removeAt = function(self, pos)
local vi_z = (pos.z + 0x8000) * 0x10000 * 0x10000
local vi_zy = vi_z + (pos.y + 0x8000) * 0x10000
local vi = vi_zy + pos.x + 0x8000
if self[vi] == nil then
-- Nothing to remove
return
end
self[vi] = nil
-- Update existence information for the xy plane and x line
self[vi_z] = self[vi_z] - 1
if self[vi_z] == 0 then
self[vi_z] = nil
self[vi_zy] = nil
return
end
self[vi_zy] = self[vi_zy] - 1
if self[vi_zy] == 0 then
self[vi_zy] = nil
end
end,
iter = function(self, pos1, pos2)
local ystride = 0x10000
local zstride = 0x10000 * 0x10000
-- Skip z values where no data can be found
pos1 = vector.new(pos1)
local vi_z = (pos1.z + 0x8000) * 0x10000 * 0x10000
while not self[vi_z] do
pos1.z = pos1.z + 1
vi_z = vi_z + zstride
if pos1.z > pos2.z then
-- There are no values to iterate through
return function() return end
end
end
-- Skipping y values is not yet implemented and may require much code
local xrange = pos2.x - pos1.x + 1
local yrange = pos2.y - pos1.y + 1
local zrange = pos2.z - pos1.z + 1
-- x-only and y-only parts of the vector index of pos1
local vi_y = (pos1.y + 0x8000) * 0x10000
local vi_x = pos1.x + 0x8000
local y = 0
local z = 0
local vi = node_position_key(pos1)
local pos = vector.new(pos1)
local nextaction = vi + xrange
pos.x = pos.x - 1
vi = vi - 1
local function iterfunc()
-- continue along x until it needs to jump
vi = vi + 1
pos.x = pos.x + 1
if vi ~= nextaction then
local v = self[vi]
if v == nil then
-- No data here
return iterfunc()
end
-- The returned position must not be changed
return pos, v
end
-- Reset x position
vi = vi - xrange
-- Go along y until pos2.y is exceeded
while true do
y = y + 1
pos.y = pos.y + 1
-- Set vi to index(pos1.x, pos1.y + y, pos1.z + z)
vi = vi + ystride
if y == yrange then
break
end
if self[vi - vi_x] then
nextaction = vi + xrange
vi = vi - 1
pos.x = pos1.x - 1
return iterfunc()
end
-- Nothing along this x line, so increase y again
end
-- Go back along y
vi = vi - yrange * ystride
y = 0
pos.y = pos1.y
-- Go along z until pos2.z is exceeded
while true do
z = z + 1
pos.z = pos.z + 1
vi = vi + zstride
if z == zrange then
-- Cuboid finished, return nil
return
end
if self[vi - vi_x - vi_y] then
y = 0
nextaction = vi + xrange
vi = vi - 1
pos.x = pos1.x - 1
return iterfunc()
end
-- Nothing in this xy plane, so increase z again
end
end
return iterfunc
end,
iterAll = function(self)
local previous_vi = nil
local function iterfunc()
local vi, v = next(self, previous_vi)
previous_vi = vi
if not vi then
return
end
tab[z][y] = {[x] = data}
return
local z = math.floor(vi / (0x10000 * 0x10000))
vi = vi - z * 0x10000 * 0x10000
local y = math.floor(vi / 0x10000)
if y == 0 or z == 0 then
-- The index does not refer to a position inside the map
return iterfunc()
end
local x = vi - y * 0x10000 - 0x8000
y = y - 0x8000
z = z - 0x8000
return {x=x, y=y, z=z}, v
end
tab[z] = {[y] = {[x] = data}}
return iterfunc
end,
serialize = function(self)
local indices = {}
local values = {}
local i = 1
for pos, v in self:iterAll() do
local vi = node_position_key(pos)
-- Convert the double reversible to a string;
-- minetest.serialize does not (yet) do this
indices[i] = ("%.17g"):format(vi)
values[i] = v
end
return minetest.serialize({
version = "MapDataStorage_v1",
indices = "return {" .. table.concat(indices, ",") .. "}",
values = minetest.serialize(values),
})
end,
}
MapDataStorage.deserialize = function(txtdata)
local data = minetest.deserialize(txtdata)
if data.version ~= "MapDataStorage_v1" then
minetest.log("error", "Unknown MapDataStorage version: " ..
data.version)
end
-- I assume that minetest.deserialize correctly deserializes the indices,
-- which are in the %a format
local indices = minetest.deserialize(data.indices)
local values = minetest.deserialize(data.values)
if not indices or not values then
return MapDataStorage()
end
data = MapDataStorage()
for i = 1,#indices do
local vi = indices[i]
local v = values[i]
data:setAtI(vi, v)
end
return data
end
moremesecons.MapDataStorage = MapDataStorage
if not vector.remove_data_from_pos then
function vector.remove_data_from_pos(tab, z,y,x)
if vector.get_data_from_pos(tab, z,y,x) == nil then
return
end
tab[z][y][x] = nil
if not next(tab[z][y]) then
tab[z][y] = nil
end
if not next(tab[z]) then
tab[z] = nil
-- Legacy
-- vector_extras there: https://github.com/HybridDog/vector_extras
-- Creates a MapDataStorage object from old vector_extras generated table
function moremesecons.load_old_data_from_pos(t)
local data = MapDataStorage()
for z, yxv in pairs(t) do
for y, xv in pairs(yxv) do
for x, v in pairs(xv) do
data:setAt({x=x, y=y, z=z}, v)
end
end
end
return data
end
if not vector.unpack then
function vector.unpack(pos)
return pos.z, pos.y, pos.x
function moremesecons.load_old_dfp_storage(modstorage, name)
local data = minetest.deserialize(modstorage:get_string(name))
if not data then
return
end
return moremesecons.load_old_data_from_pos(data)
end
function moremesecons.load_MapDataStorage_legacy(modstorage, name, oldname)
local t_old = moremesecons.load_old_dfp_storage(modstorage, oldname)
local t
if t_old and t_old ~= "" then
t = t_old
modstorage:set_string(name, t:serialize())
modstorage:set_string(oldname, nil)
return t
end
t = modstorage:get_string(name)
if t and t ~= "" then
return MapDataStorage.deserialize(t)
end
return MapDataStorage()
end
--[[
-- This testing code shows an example usage of the MapDataStorage code
local function do_test()
print("Test if iter returns correct positions when a lot is set")
local data = MapDataStorage()
local k = 0
for x = -5, 3 do
for y = -5, 3 do
for z = -5, 3 do
k = k + 1
data:setAt({x=x, y=y, z=z}, k)
end
end
end
local expected_positions = {}
for z = -4, 2 do
for y = -4, 2 do
for x = -4, 2 do
expected_positions[#expected_positions+1] = {x=x, y=y, z=z}
end
end
end
local i = 0
for pos in data:iter({x=-4, y=-4, z=-4}, {x=2, y=2, z=2}) do
i = i + 1
assert(vector.equals(pos, expected_positions[i]))
end
print("Test if iter works correctly on a corner")
local found = false
for pos in data:iter({x=-8, y=-7, z=-80}, {x=-5, y=-5, z=-5}) do
assert(not found)
found = true
assert(vector.equals(pos, {x=-5, y=-5, z=-5}))
end
assert(found)
print("Test if iter finds all corners")
local expected_positions = {}
local k = 1
for _, z in ipairs({-9, -6}) do
for _, y in ipairs({-9, -6}) do
for _, x in ipairs({-8, -6}) do
local pos = {x=x, y=y, z=z}
expected_positions[#expected_positions+1] = pos
data:setAt(pos, k)
k = k + 1
end
end
end
local i = 1
for pos, v in data:iter({x=-8, y=-9, z=-9}, {x=-6, y=-6, z=-6}) do
assert(v == i)
assert(vector.equals(pos, expected_positions[i]))
i = i + 1
--~ print("found " .. minetest.pos_to_string(pos))
end
assert(i == 8 + 1, "Not enough or too many corners found")
--~ data:iterAll()
end
do_test()
--]]
minetest.log("action", "[moremesecons_utils] loaded.")

View File

@ -1,107 +1,145 @@
local storage = minetest.get_mod_storage()
local wireless = minetest.deserialize(storage:get_string("wireless")) or {}
local wireless_meta = minetest.deserialize(storage:get_string("wireless_meta")) or {owners = {}, channels = {}, ids = {}}
local jammers = minetest.deserialize(storage:get_string("jammers")) or {}
-- Names wireless_meta, and jammers were used in old versions of this mod.
-- There is legacy code at the end of this file to migrate the mod storage.
local wireless = minetest.deserialize(storage:get_string("networks")) or {}
local wireless_meta = moremesecons.get_storage_data(storage, "wireless_meta_2")
local jammers = moremesecons.get_storage_data(storage, "jammers_2")
local function update_mod_storage()
storage:set_string("wireless", minetest.serialize(wireless))
storage:set_string("wireless_meta", minetest.serialize(wireless_meta))
storage:set_string("jammers", minetest.serialize(jammers))
storage:set_string("networks", minetest.serialize(wireless))
end
-- localize these functions with small names because they work fairly fast
local get = vector.get_data_from_pos
local set = vector.set_data_to_pos
local remove = vector.remove_data_from_pos
local wireless_effector_off
local function remove_wireless(pos)
local owner = get(wireless_meta.owners, pos.z,pos.y,pos.x)
if not owner or owner == "" then
return
end
remove(wireless_meta.owners, pos.z,pos.y,pos.x)
if not wireless[owner] or not next(wireless[owner]) then
wireless[owner] = nil
local wls = moremesecons.get_data_from_pos(wireless_meta, pos)
if not wls then
return
end
local channel = get(wireless_meta.channels, pos.z,pos.y,pos.x)
if not channel or channel == "" then
if not wls.owner or wls.owner == "" then
moremesecons.remove_data_from_pos(wireless_meta, pos)
return
end
table.remove(wireless[owner][channel], get(wireless_meta.ids, pos.z,pos.y,pos.x))
if #wireless[owner][channel] == 0 then
wireless[owner][channel] = nil
if not next(wireless[owner]) then
wireless[owner] = nil
if not wireless[wls.owner] or not next(wireless[wls.owner]) then
wireless[wls.owner] = nil
moremesecons.remove_data_from_pos(wireless_meta, pos)
return
end
if not wls.channel or wls.channel == "" then
moremesecons.remove_data_from_pos(wireless_meta, pos)
return
end
local network = wireless[wls.owner][wls.channel]
if network.sources[wls.id] then
wireless_effector_off(pos)
end
moremesecons.remove_data_from_pos(wireless_meta, pos)
network.members[wls.id] = nil
if not next(network.members) then
wireless[wls.owner][wls.channel] = nil
if not next(wireless[wls.owner]) then
wireless[wls.owner] = nil
end
end
remove(wireless_meta.channels, pos.z,pos.y,pos.x)
remove(wireless_meta.ids, pos.z,pos.y,pos.x)
update_mod_storage()
end
local set_channel
local function set_owner(pos, owner)
if not owner or owner == "" then
return
end
remove_wireless(pos)
local meta = minetest.get_meta(pos)
meta:set_string("owner", owner)
set(wireless_meta.owners, pos.z,pos.y,pos.x, owner)
if meta then
meta:set_string("owner", owner)
end
local wls = moremesecons.get_data_from_pos(wireless_meta, pos) or {}
wls.owner = owner
moremesecons.set_data_to_pos(wireless_meta, pos, wls)
if not wireless[owner] then
wireless[owner] = {}
end
local channel = get(wireless_meta.channels, pos.z,pos.y,pos.x)
if channel and channel ~= "" then
if not wireless[owner][channel] then
wireless[owner][channel] = {}
end
set_channel(pos, channel)
if meta then
meta:set_string("infotext", "Wireless owned by " .. owner .. " on " .. ((wls.channel and wls.channel ~= "") and "channel " .. wls.channel or "undefined channel"))
end
meta:set_string("infotext", "Wireless owned by " .. owner .. " on " .. ((channel and channel ~= "") and "channel " .. channel or "undefined channel"))
end
function set_channel(pos, channel)
local wireless_receptor_on
local wireless_receptor_off
local wireless_effector_on
local function set_channel(pos, channel)
if not channel or channel == "" then
return
end
local meta = minetest.get_meta(pos)
local owner = get(wireless_meta.owners, pos.z,pos.y,pos.x)
if not owner or owner == "" then
local wls = moremesecons.get_data_from_pos(wireless_meta, pos)
if not wls or wls.owner == "" then
return
end
local old_channel = get(wireless_meta.channels, pos.z,pos.y,pos.x)
if old_channel and old_channel ~= "" and old_channel ~= channel then
if wls.id then
remove_wireless(pos)
set_owner(pos, owner)
end
meta:set_string("channel", channel)
set(wireless_meta.channels, pos.z,pos.y,pos.x, channel)
if not wireless[owner] then
wireless[owner] = {}
if meta then
meta:set_string("channel", channel)
end
if not wireless[owner][channel] then
wireless[owner][channel] = {}
wls.channel = channel
moremesecons.set_data_to_pos(wireless_meta, pos, wls)
if not wireless[wls.owner] then
wireless[wls.owner] = {}
end
if not wireless[wls.owner][channel] then
wireless[wls.owner][channel] = {
members = {},
sources = {}
}
end
local id = get(wireless_meta.ids, pos.z,pos.y,pos.x)
if id then
wireless[owner][channel][id] = pos
-- Find the first free ID
local id = 1
while wireless[wls.owner][channel].members[id] do
id = id + 1
end
wls.id = id
moremesecons.set_data_to_pos(wireless_meta, pos, wls)
local network = wireless[wls.owner][channel]
network.members[id] = pos
if meta then
meta:set_int("id", id)
end
update_mod_storage()
if meta then
meta:set_string("infotext", "Wireless owned by " .. wls.owner .. " on channel " .. channel)
end
if wls.effector then
wireless_effector_on(pos)
elseif next(network.sources) then
wireless_receptor_on(pos, id, network, false)
else
table.insert(wireless[owner][channel], pos)
meta:set_int("id", #wireless[owner][channel])
set(wireless_meta.ids, pos.z,pos.y,pos.x, #wireless[owner][channel])
wireless_receptor_off(pos, id, network, false)
end
meta:set_string("infotext", "Wireless owned by " .. owner .. " on channel " .. channel)
end
local function register_wireless(pos)
@ -110,81 +148,137 @@ local function register_wireless(pos)
if owner == "" then
return
end
remove_wireless(pos)
set_owner(pos, owner)
local channel = meta:get_string("channel")
if channel ~= "" then
set_channel(pos, channel)
end
end
update_mod_storage()
local function check_wireless_exists(pos)
local nn = minetest.get_node(pos).name
if nn:sub(1, 30) == "moremesecons_wireless:wireless" then
return true
elseif nn ~= "ignore" then
-- Defer the remove_wireless() call so it doesn't interfere
-- with pairs().
minetest.after(0, remove_wireless, pos)
return false
end
end
function wireless_receptor_on(pos, id, network, check)
if check == false or check_wireless_exists(pos) then
minetest.swap_node(pos, {name = "moremesecons_wireless:wireless_on"})
if not network.sources[id] then
mesecon.receptor_on(pos)
end
end
end
function wireless_receptor_off(pos, id, network, check)
if check == false or check_wireless_exists(pos) then
minetest.swap_node(pos, {name = "moremesecons_wireless:wireless_off"})
mesecon.receptor_off(pos)
end
end
local function activate_network(owner, channel)
local network = wireless[owner][channel]
for i, wl_pos in pairs(network.members) do
wireless_receptor_on(wl_pos, i, network)
end
end
local function deactivate_network(owner, channel)
local network = wireless[owner][channel]
for i, wl_pos in pairs(network.members) do
wireless_receptor_off(wl_pos, i, network)
end
end
local is_jammed
local function wireless_activate(pos)
function wireless_effector_on(pos)
if is_jammed(pos) then
-- jamming doesn't disallow receiving signals, only sending them
return
end
local channel = get(wireless_meta.channels, pos.z,pos.y,pos.x)
local owner = get(wireless_meta.owners, pos.z,pos.y,pos.x)
local id = get(wireless_meta.ids, pos.z,pos.y,pos.x)
if owner == "" or not wireless[owner] or channel == "" or not wireless[owner][channel] then
local wls = moremesecons.get_data_from_pos(wireless_meta, pos)
if not wls then
return
end
minetest.swap_node(pos, {name = "moremesecons_wireless:wireless_on"})
for i, wl_pos in ipairs(wireless[owner][channel]) do
if i ~= id then
minetest.swap_node(wl_pos, {name = "moremesecons_wireless:wireless_on"})
mesecon.receptor_on(wl_pos)
end
wls.effector = true
moremesecons.set_data_to_pos(wireless_meta, pos, wls)
if wls.owner == "" or not wireless[wls.owner] or wls.channel == "" or not wireless[wls.owner][wls.channel] then
return
end
local network = wireless[wls.owner][wls.channel]
network.sources[wls.id] = true
activate_network(wls.owner, wls.channel)
update_mod_storage()
end
local function wireless_deactivate(pos)
function wireless_effector_off(pos)
local wls = moremesecons.get_data_from_pos(wireless_meta, pos)
if not wls then
return
end
wls.effector = nil
moremesecons.set_data_to_pos(wireless_meta, pos, wls)
if wls.owner == "" or not wireless[wls.owner] or wls.channel == "" or not wireless[wls.owner][wls.channel] then
return
end
local network = wireless[wls.owner][wls.channel]
network.sources[wls.id] = nil
if not next(network.sources) then
deactivate_network(wls.owner, wls.channel)
else
-- There is another source in the network. Turn this wireless into
-- a receptor.
mesecon.receptor_on(pos)
end
update_mod_storage()
end
-- This table is required to prevent a message from being sent in loop between wireless nodes
local sending_digilines = {}
local function on_digiline_receive(pos, node, channel, msg)
if is_jammed(pos) then
return
end
local channel = get(wireless_meta.channels, pos.z,pos.y,pos.x)
local owner = get(wireless_meta.owners, pos.z,pos.y,pos.x)
local id = get(wireless_meta.ids, pos.z,pos.y,pos.x)
local wls = moremesecons.get_data_from_pos(wireless_meta, pos)
if owner == "" or not wireless[owner] or channel == "" or not wireless[owner][channel] then
if wls.owner == "" or not wireless[wls.owner] or channel == "" or not wireless[wls.owner][wls.channel] then
return
end
minetest.swap_node(pos, {name = "moremesecons_wireless:wireless_off"})
for i, wl_pos in ipairs(wireless[owner][channel]) do
if i ~= id then
minetest.swap_node(wl_pos, {name = "moremesecons_wireless:wireless_off"})
mesecon.receptor_off(wl_pos)
end
end
end
local function on_digiline_receive(pos, node, channel, msg)
local setchan = minetest.get_meta(pos):get_string("channel") -- Note : the digiline channel is the same as the wireless channel. TODO: Making two different channels and a more complex formspec ?
if channel ~= setchan or is_jammed(pos) or setchan == "" then
local pos_hash = minetest.hash_node_position(pos)
if sending_digilines[pos_hash] then
return
end
local channel = get(wireless_meta.channels, pos.z,pos.y,pos.x)
local owner = get(wireless_meta.owners, pos.z,pos.y,pos.x)
local id = get(wireless_meta.ids, pos.z,pos.y,pos.x)
if owner == "" or not wireless[owner] or channel == "" or not wireless[owner][channel] then
return
end
for i, wl_pos in ipairs(wireless[owner][channel]) do
if i ~= id then
sending_digilines[pos_hash] = true
for i, wl_pos in pairs(wireless[wls.owner][wls.channel].members) do
if i ~= wls.id and check_wireless_exists(wl_pos) then
digiline:receptor_send(wl_pos, digiline.rules.default, channel, msg)
end
end
sending_digilines[pos_hash] = nil
end
mesecon.register_node("moremesecons_wireless:wireless", {
@ -203,13 +297,10 @@ mesecon.register_node("moremesecons_wireless:wireless", {
end,
on_destruct = function(pos)
remove_wireless(pos)
update_mod_storage()
mesecon.receptor_off(pos)
end,
after_place_node = function(pos, placer)
local placername = placer:get_player_name()
set_owner(pos, placer:get_player_name())
update_mod_storage()
end,
on_receive_fields = function(pos, _, fields, player)
local meta = minetest.get_meta(pos)
@ -220,7 +311,6 @@ mesecon.register_node("moremesecons_wireless:wireless", {
-- Old wireless
if not minetest.is_protected(pos, playername) then
set_owner(pos, playername)
update_mod_storage()
else
return
end
@ -228,130 +318,24 @@ mesecon.register_node("moremesecons_wireless:wireless", {
if playername == owner then
set_channel(pos, fields.channel)
update_mod_storage()
end
end,
}, {
tiles = {"moremesecons_wireless_off.png"},
groups = {cracky=3},
mesecons = {effector = {
action_on = wireless_activate,
action_on = wireless_effector_on
}},
}, {
tiles = {"moremesecons_wireless_on.png"},
groups = {cracky=3, not_in_creative_inventory=1},
mesecons = {effector = {
action_off = wireless_deactivate
action_off = wireless_effector_off
}},
})
minetest.register_alias("moremesecons_wireless:wireless", "moremesecons_wireless:wireless_off")
local jammers = {}
local function add_jammer(pos)
if get(jammers, pos.z,pos.y,pos.x) then
return
end
set(jammers, pos.z,pos.y,pos.x, true)
update_mod_storage()
end
local function remove_jammer(pos)
remove(jammers, pos.z,pos.y,pos.x)
update_mod_storage()
end
-- looks big, but should work fast
function is_jammed(pos)
local JAMMER_MAX_DISTANCE = moremesecons.setting("wireless", "jammer_max_distance", 15, 1)
local pz,py,px = vector.unpack(pos)
for z,yxs in pairs(jammers) do
if math.abs(pz-z) <= JAMMER_MAX_DISTANCE then
for y,xs in pairs(yxs) do
if math.abs(py-y) <= JAMMER_MAX_DISTANCE then
for x in pairs(xs) do
if math.abs(px-x) <= JAMMER_MAX_DISTANCE
and (px-x)^2+(py-y)^2+(pz-z)^2 <= JAMMER_MAX_DISTANCE^2 then
return true
end
end
end
end
end
end
return false
end
mesecon.register_node("moremesecons_wireless:jammer", {
description = "Wireless Jammer",
paramtype = "light",
drawtype = "nodebox",
},{
tiles = {"mesecons_wire_off.png^moremesecons_jammer_top.png", "moremesecons_jammer_bottom.png", "mesecons_wire_off.png^moremesecons_jammer_side_off.png"},
node_box = {
type = "fixed",
fixed = {
-- connection
{-1/16, -0.5, -0.5, 1/16, -7/16, 0.5},
{-0.5, -0.5, -1/16, 0.5, -7/16, 1/16},
--stabilization
{-1/16, -7/16, -1/16, 1/16, -6/16, 1/16},
-- fields
{-7/16, -6/16, -7/16, 7/16, -4/16, 7/16},
{-5/16, -4/16, -5/16, 5/16, -3/16, 5/16},
{-3/16, -3/16, -3/16, 3/16, -2/16, 3/16},
{-1/16, -2/16, -1/16, 1/16, -1/16, 1/16},
},
},
groups = {dig_immediate=2},
mesecons = {effector = {
rules = mesecon.rules.flat,
action_on = function(pos)
add_jammer(pos)
minetest.swap_node(pos, {name="moremesecons_wireless:jammer_on"})
end
}}
},{
tiles = {"mesecons_wire_on.png^moremesecons_jammer_top.png", "moremesecons_jammer_bottom.png", "mesecons_wire_on.png^moremesecons_jammer_side_on.png"},
node_box = {
type = "fixed",
fixed = {
-- connection
{-1/16, -0.5, -0.5, 1/16, -7/16, 0.5},
{-0.5, -0.5, -1/16, 0.5, -7/16, 1/16},
--stabilization
{-1/16, -7/16, -1/16, 1/16, 5/16, 1/16},
-- fields
{-7/16, -6/16, -7/16, 7/16, -4/16, 7/16},
{-5/16, -3/16, -5/16, 5/16, -1/16, 5/16},
{-3/16, 0, -3/16, 3/16, 2/16, 3/16},
{-1/16, 3/16, -1/16, 1/16, 5/16, 1/16},
},
},
groups = {dig_immediate=2, not_in_creative_inventory=1},
mesecons = {effector = {
rules = mesecon.rules.flat,
action_off = function(pos)
remove_jammer(pos)
minetest.swap_node(pos, {name="moremesecons_wireless:jammer_off"})
end
}},
on_destruct = remove_jammer,
on_construct = add_jammer,
})
minetest.register_craft({
output = "moremesecons_wireless:jammer_off",
recipe = {
{"moremesecons_wireless:wireless", "mesecons_torch:mesecon_torch_on", "moremesecons_wireless:wireless"}
}
})
minetest.register_craft({
output = "moremesecons_wireless:wireless_off 2",
recipe = {
@ -361,6 +345,104 @@ minetest.register_craft({
}
})
local function remove_jammer(pos)
moremesecons.remove_data_from_pos(jammers, pos)
end
local function add_jammer(pos)
remove_jammer(pos)
moremesecons.set_data_to_pos(jammers, pos, true)
end
function is_jammed(pos)
local JAMMER_MAX_DISTANCE = moremesecons.setting("wireless", "jammer_max_distance", 15, 1)
local JAMMER_MAX_DISTANCE_SQUARE = JAMMER_MAX_DISTANCE^2 -- Cache this result
for pos_hash, _ in pairs(jammers.tab) do
local j_pos = minetest.get_position_from_hash(pos_hash)
-- Fast comparisons first
if math.abs(pos.x - j_pos.x) <= JAMMER_MAX_DISTANCE and
math.abs(pos.y - j_pos.y) <= JAMMER_MAX_DISTANCE and
math.abs(pos.z - j_pos.z) <= JAMMER_MAX_DISTANCE and
(pos.x - j_pos.x)^2 + (pos.y - j_pos.y)^2 + (pos.z - j_pos.z)^2 <= JAMMER_MAX_DISTANCE_SQUARE then
return true
end
end
return false
end
if moremesecons.setting("wireless", "enable_jammer", true) then
mesecon.register_node("moremesecons_wireless:jammer", {
description = "Wireless Jammer",
paramtype = "light",
drawtype = "nodebox",
},{
tiles = {"mesecons_wire_off.png^moremesecons_jammer_top.png", "moremesecons_jammer_bottom.png", "mesecons_wire_off.png^moremesecons_jammer_side_off.png"},
node_box = {
type = "fixed",
fixed = {
-- connection
{-1/16, -0.5, -0.5, 1/16, -7/16, 0.5},
{-0.5, -0.5, -1/16, 0.5, -7/16, 1/16},
--stabilization
{-1/16, -7/16, -1/16, 1/16, -6/16, 1/16},
-- fields
{-7/16, -6/16, -7/16, 7/16, -4/16, 7/16},
{-5/16, -4/16, -5/16, 5/16, -3/16, 5/16},
{-3/16, -3/16, -3/16, 3/16, -2/16, 3/16},
{-1/16, -2/16, -1/16, 1/16, -1/16, 1/16},
},
},
groups = {dig_immediate=2},
mesecons = {effector = {
rules = mesecon.rules.flat,
action_on = function(pos)
add_jammer(pos)
minetest.swap_node(pos, {name="moremesecons_wireless:jammer_on"})
end
}}
},{
tiles = {"mesecons_wire_on.png^moremesecons_jammer_top.png", "moremesecons_jammer_bottom.png", "mesecons_wire_on.png^moremesecons_jammer_side_on.png"},
node_box = {
type = "fixed",
fixed = {
-- connection
{-1/16, -0.5, -0.5, 1/16, -7/16, 0.5},
{-0.5, -0.5, -1/16, 0.5, -7/16, 1/16},
--stabilization
{-1/16, -7/16, -1/16, 1/16, 5/16, 1/16},
-- fields
{-7/16, -6/16, -7/16, 7/16, -4/16, 7/16},
{-5/16, -3/16, -5/16, 5/16, -1/16, 5/16},
{-3/16, 0, -3/16, 3/16, 2/16, 3/16},
{-1/16, 3/16, -1/16, 1/16, 5/16, 1/16},
},
},
groups = {dig_immediate=2, not_in_creative_inventory=1},
mesecons = {effector = {
rules = mesecon.rules.flat,
action_off = function(pos)
remove_jammer(pos)
minetest.swap_node(pos, {name="moremesecons_wireless:jammer_off"})
end
}},
on_destruct = remove_jammer,
on_construct = add_jammer,
})
minetest.register_craft({
output = "moremesecons_wireless:jammer_off",
recipe = {
{"moremesecons_wireless:wireless", "mesecons_torch:mesecon_torch_on", "moremesecons_wireless:wireless"}
}
})
end
if moremesecons.setting("wireless", "enable_lbm", false) then
minetest.register_lbm({
name = "moremesecons_wireless:add_jammer",
@ -377,45 +459,41 @@ if moremesecons.setting("wireless", "enable_lbm", false) then
})
end
-- Legacy
if storage and storage:get_string("wireless_rids") and storage:get_string("wireless_rids") ~= "" then
-- Upgrade mod storage!
local wireless_rids = minetest.deserialize(storage:get_string("wireless_rids"))
local old_wireless = table.copy(wireless)
wireless = {}
if storage:get_string("wireless_meta_2") == "" then
local wireless_meta_1 = minetest.deserialize(storage:get_string("wireless_meta"))
if not wireless_meta_1 then
return
end
minetest.after(0, function(old_wireless)
-- After loading all mods, try to guess owners based on the areas mod database.
-- That won't work for all wireless. Owners of remaining wireless will be set
-- to the first player using their formspec.
if not areas then
return
end
for RID, pos in ipairs(old_wireless) do
local numerous_owners = false
local owner
for _, area in pairs(areas:getAreasAtPos(pos)) do
if owner and area.owner ~= owner then
numerous_owners = true
break
end
owner = area.owner
end
minetest.log("action", "[moremesecons_wireless] Migrating mod storage data...")
local jammers_1 = minetest.deserialize(storage:get_string("jammers"))
if not numerous_owners and owner then
set_owner(pos, owner)
set_channel(pos, minetest.get_meta(pos):get_string("channel"))
end
end
end, old_wireless)
local get = function(t, pos)
-- FIXME: this does not test explicitly for false,
-- but channel is never false
return t[pos.z] and t[pos.z][pos.y] and t[pos.z][pos.y][pos.x]
end
-- Remove wireless_rids from storage
storage:from_table({
jammers = jammers,
wireless_meta = wireless_meta,
wireless = wireless
})
for z, data_z in pairs(wireless_meta_1.owners) do
for y, data_y in pairs(data_z) do
for x, owner in pairs(data_y) do
local pos = {x = x, y = y, z = z}
set_owner(pos, owner)
set_channel(pos, get(wireless_meta_1.channels, pos))
end
end
end
for z, data_z in pairs(jammers_1) do
for y, data_y in pairs(data_z) do
for x, jammer in pairs(data_y) do
local pos = {x = x, y = y, z = z}
moremesecons.set_data_to_pos(jammers, pos, jammer)
end
end
end
minetest.log("action", "[moremesecons_wireless] Done!")
end
minetest.log("action", "[moremesecons_wireless] loaded.")

Binary file not shown.

Before

Width:  |  Height:  |  Size: 170 B

After

Width:  |  Height:  |  Size: 170 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

After

Width:  |  Height:  |  Size: 591 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

After

Width:  |  Height:  |  Size: 592 B

View File

@ -63,6 +63,9 @@ moremesecons_teleporter.enable_lbm (Enable Registration LBM) bool false
[Wireless]
# Whether to enable the wireless jammer node
moremesecons_wireless.enable_jammer (Enable wireless jammer) bool true
# Wireless Jammer action range
# Any value less than or equal to 0 will be changed to 1 and a NaN value will be changed to the default value
moremesecons_wireless.jammer_max_distance (Wireless Jammer action range) float 15