diff --git a/README.md b/README.md index fcb429a..f58e817 100644 --- a/README.md +++ b/README.md @@ -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
+By @paly2 and @HybridDog
+With the participation of @LeMagnesium (bugfix), @Ataron (textures), @JAPP (texture). -Dependencies: [Mesecons](https://github.com/Jeija/minetest-mod-mesecons/) -Optional dependencies: [vector_extras](https://github.com/HybridDog/vector_extras/) [digilines](https://github.com/minetest-mods/digilines) +Dependencies: [Mesecons](https://github.com/Jeija/minetest-mod-mesecons/)
+Optional dependencies: [digilines](https://github.com/minetest-mods/digilines) MoreMesecons is a mod for minetest which adds some mesecons items. diff --git a/moremesecons_jammer/init.lua b/moremesecons_jammer/init.lua index 92bf7dd..1e4e3f1 100644 --- a/moremesecons_jammer/init.lua +++ b/moremesecons_jammer/init.lua @@ -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 diff --git a/moremesecons_luacontroller_tool/init.lua b/moremesecons_luacontroller_tool/init.lua index a50876e..ca53801 100644 --- a/moremesecons_luacontroller_tool/init.lua +++ b/moremesecons_luacontroller_tool/init.lua @@ -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 diff --git a/moremesecons_teleporter/init.lua b/moremesecons_teleporter/init.lua index 315630d..87bca1f 100644 --- a/moremesecons_teleporter/init.lua +++ b/moremesecons_teleporter/init.lua @@ -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 @@ -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, diff --git a/moremesecons_utils/depends.txt b/moremesecons_utils/depends.txt deleted file mode 100644 index 926e802..0000000 --- a/moremesecons_utils/depends.txt +++ /dev/null @@ -1 +0,0 @@ -vector_extras? diff --git a/moremesecons_utils/init.lua b/moremesecons_utils/init.lua index 37c513f..98ed9d8 100644 --- a/moremesecons_utils/init.lua +++ b/moremesecons_utils/init.lua @@ -85,6 +85,16 @@ MapDataStorage.__index = { 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 @@ -201,9 +211,10 @@ MapDataStorage.__index = { return iterfunc end, iterAll = function(self) - local pairsfunc = pairs(self) + local previous_vi = nil local function iterfunc() - local vi, v = pairsfunc() + local vi, v = next(self, previous_vi) + previous_vi = vi if not vi then return end @@ -219,11 +230,91 @@ MapDataStorage.__index = { z = z - 0x8000 return {x=x, y=y, z=z}, v end + return iterfunc + end, + serialize = function(self) + local serialize_data = minetest.serialize + 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] = ("%a"):format(vi) + values[i] = serialize_data(v) + end + result = { + version = "MapDataStorage_v1", + indices = "return {" .. table.concat(indices, ",") .. "}", + values = "return {" .. table.concat(values, ",") .. "}", + } + return minetest.serialize(result) 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 + indices = minetest.deserialize(data.indices) + values = minetest.deserialize(data.values) + 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 +-- 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 + +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("teleporters_rids_v2") + 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") @@ -284,53 +375,5 @@ local function do_test() --~ data:iterAll() end +--~ do_test() -do_test() - - -if not vector.get_data_from_pos then - function vector.get_data_from_pos(tab, z,y,x) - local data = tab[z] - if data then - data = data[y] - if data then - return data[x] - end - end - end -end - -if not vector.set_data_to_pos then - function vector.set_data_to_pos(tab, z,y,x, data) - if tab[z] then - if tab[z][y] then - tab[z][y][x] = data - return - end - tab[z][y] = {[x] = data} - return - end - tab[z] = {[y] = {[x] = data}} - end -end - -if not vector.remove_data_from_pos then - function vector.remove_data_from_pos(tab, z,y,x) - if vector.get_data_from_pos(tab, z,y,x) == nil then - return - end - tab[z][y][x] = nil - if not next(tab[z][y]) then - tab[z][y] = nil - end - if not next(tab[z]) then - tab[z] = nil - end - end -end - -if not vector.unpack then - function vector.unpack(pos) - return pos.z, pos.y, pos.x - end -end diff --git a/moremesecons_wireless/init.lua b/moremesecons_wireless/init.lua index 5d163ff..dbed9a3 100644 --- a/moremesecons_wireless/init.lua +++ b/moremesecons_wireless/init.lua @@ -458,16 +458,18 @@ if storage:get_string("wireless_meta_2") == "" then minetest.log("action", "[moremesecons_wireless] Migrating mod storage data...") local jammers_1 = minetest.deserialize(storage:get_string("jammers")) - local get = vector.get_data_from_pos - local set = vector.set_data_to_pos - local remove = vector.remove_data_from_pos + 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 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, z,y,x)) + set_channel(pos, get(wireless_meta_1.channels, pos)) end end end