mirror of
				https://github.com/minetest-mods/MoreMesecons.git
				synced 2025-10-31 08:05:28 +01:00 
			
		
		
		
	Compare commits
	
		
			8 Commits
		
	
	
		
			new-wirele
			...
			e7533b8724
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| e7533b8724 | |||
|  | 67875f9c6e | ||
|  | de765f7f7b | ||
|  | 7ba7a5cceb | ||
|  | f2de7c89b1 | ||
|  | 0000cfb474 | ||
|  | 9aa0e6ab3d | ||
|  | 23b96b9db6 | 
							
								
								
									
										10
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								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 <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. | ||||
|  | ||||
|   | ||||
| @@ -64,3 +64,5 @@ minetest.register_craft({ | ||||
| 	recipe = {	{"mesecons_blinkyplant:blinky_plant_off"}, | ||||
| 			{"default:mese_crystal_fragment"},} | ||||
| }) | ||||
|  | ||||
| minetest.log("action", "[moremesecons_adjustable_blinky_plant] loaded.") | ||||
|   | ||||
| @@ -156,3 +156,5 @@ minetest.register_abm({ | ||||
| 		end | ||||
| 	end, | ||||
| }) | ||||
|  | ||||
| minetest.log("action", "[moremesecons_adjustable_player_detector] loaded.") | ||||
|   | ||||
| @@ -172,3 +172,5 @@ minetest.register_craft({ | ||||
| 		{"group:mesecon_conductor_craftable","default:mese_crystal","group:mesecon_conductor_craftable"} | ||||
| 	} | ||||
| }) | ||||
|  | ||||
| minetest.log("action", "[moremesecons_commandblock] loaded.") | ||||
|   | ||||
| @@ -79,3 +79,5 @@ minetest.register_craft({ | ||||
| 	output = "moremesecons_conductor_signalchanger:conductor_signalchanger_off", | ||||
| 	recipe = {{"group:mesecon_conductor_craftable","moremesecons_signalchanger:signalchanger_off"}} | ||||
| }) | ||||
|  | ||||
| minetest.log("action", "[moremesecons_conductor_signalchanger] loaded.") | ||||
|   | ||||
| @@ -93,3 +93,5 @@ minetest.register_craft({ | ||||
| 	output = "moremesecons_dual_delayer:dual_delayer_00 2", | ||||
| 	recipe = {"mesecons_delayer:delayer_off_1", "mesecons_delayer:delayer_off_1"} | ||||
| }) | ||||
|  | ||||
| minetest.log("action", "[moremesecons_dual_delayer] loaded.") | ||||
|   | ||||
| @@ -139,3 +139,5 @@ minetest.register_abm({ | ||||
| 		end | ||||
| 	end, | ||||
| }) | ||||
|  | ||||
| minetest.log("action", "[moremesecons_entity_detector] loaded.") | ||||
|   | ||||
| @@ -46,3 +46,5 @@ minetest.register_craft({ | ||||
| 	recipe = {	{"default:torch"}, | ||||
| 			{"default:mese_crystal_fragment"},} | ||||
| }) | ||||
|  | ||||
| minetest.log("action", "[moremesecons_igniter] loaded.") | ||||
|   | ||||
| @@ -102,3 +102,5 @@ minetest.register_craft({ | ||||
| 		{"", "default:mese_crystal_fragment", ""} | ||||
| 	} | ||||
| }) | ||||
|  | ||||
| minetest.log("action", "[moremesecons_induction_transmitter] loaded.") | ||||
|   | ||||
| @@ -82,3 +82,5 @@ minetest.register_craft({ | ||||
| 	output = "moremesecons_injector_controller:injector_controller_off", | ||||
| 	recipe = {{"mesecons_blinkyplant:blinky_plant_off","mesecons_gates:and_off"}} | ||||
| }) | ||||
|  | ||||
| minetest.log("action", "[moremesecons_injector_controller] loaded.") | ||||
|   | ||||
| @@ -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 | ||||
| @@ -141,3 +131,5 @@ if moremesecons.setting("jammer", "enable_lbm", false) then | ||||
| 		action = add_jammer | ||||
| 	}) | ||||
| end | ||||
|  | ||||
| minetest.log("action", "[moremesecons_jammer] loaded.") | ||||
|   | ||||
| @@ -120,25 +120,30 @@ minetest.register_node("moremesecons_luablock:luablock", { | ||||
| 				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) | ||||
|  | ||||
| 			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 | ||||
| 			if _VERSION == "Lua 5.1" then | ||||
| 				func, err = loadstring(code) | ||||
| 				if func then | ||||
| 					setfenv(func, env) | ||||
| 				end | ||||
| 			else | ||||
| 				func, err = load(code, nil, "t", env) | ||||
| 			end | ||||
| 			if not func then | ||||
| 				meta:set_string("errmsg", err) | ||||
| 				make_formspec(meta, pos) | ||||
| 				return | ||||
| 			end | ||||
| 			-- Set the "pos" global | ||||
| 			local old_pos | ||||
| 			if minetest.global_exists("pos") then | ||||
| 				old_pos = pos -- In case there's already an existing "pos" global | ||||
| 			end | ||||
| 			pos = table.copy(npos) | ||||
|  | ||||
| 			local good, err = pcall(func) | ||||
| 			pos = old_pos | ||||
|  | ||||
| 			if not good then -- Runtime error | ||||
| 				meta:set_string("errmsg", err) | ||||
| @@ -146,8 +151,12 @@ minetest.register_node("moremesecons_luablock:luablock", { | ||||
| 				return | ||||
| 			end | ||||
|  | ||||
| 			meta:set_string("mem", minetest.serialize(env.mem)) | ||||
|  | ||||
| 			meta:set_string("errmsg", "") | ||||
| 			make_formspec(meta, pos) | ||||
| 		end | ||||
| 	}} | ||||
| }) | ||||
|  | ||||
| minetest.log("action", "[moremesecons_luablock] loaded.") | ||||
|   | ||||
| @@ -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 | ||||
| @@ -356,3 +352,5 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) | ||||
| 		return | ||||
| 	end | ||||
| end) | ||||
|  | ||||
| minetest.log("action", "[moremesecons_luacontroller_tool] loaded.") | ||||
|   | ||||
| @@ -116,3 +116,5 @@ minetest.register_craft({ | ||||
| 	output = "default:mesechest_locked", | ||||
| 	recipe = {{"group:mesecon_conductor_craftable", "default:chest_locked", "group:mesecon_conductor_craftable"}} | ||||
| }) | ||||
|  | ||||
| minetest.log("action", "[moremesecons_mesechest] loaded.") | ||||
|   | ||||
| @@ -60,3 +60,5 @@ minetest.register_node("moremesecons_playerkiller:playerkiller", { | ||||
| 	end, | ||||
| 	sounds = default.node_sound_stone_defaults(), | ||||
| }) | ||||
|  | ||||
| minetest.log("action", "[moremesecons_playerkiller] loaded.") | ||||
|   | ||||
| @@ -121,3 +121,5 @@ minetest.register_craft({ | ||||
| 	recipe = {{"mesecons_luacontroller:luacontroller0000", "mesecons_noteblock:noteblock"}, | ||||
| 		{"group:wood", "group:wood"}} | ||||
| }) | ||||
|  | ||||
| minetest.log("action", "[moremesecons_sayer] loaded.") | ||||
|   | ||||
| @@ -79,3 +79,5 @@ minetest.register_craft({ | ||||
| 	output = "moremesecons_signalchanger:signalchanger_off", | ||||
| 	recipe = {{"group:mesecon_conductor_craftable","moremesecons_switchtorch:switchtorch_off","group:mesecon_conductor_craftable"}} | ||||
| }) | ||||
|  | ||||
| minetest.log("action", "[moremesecons_signalchanger] loaded.") | ||||
|   | ||||
| @@ -127,3 +127,5 @@ minetest.register_abm({ | ||||
| -- 2 = x+1 | ||||
| -- 0 = y+1 | ||||
| -- 1 = y-1 | ||||
|  | ||||
| minetest.log("action", "[moremesecons_switchtorch] loaded.") | ||||
|   | ||||
| @@ -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, | ||||
| @@ -106,3 +106,5 @@ if moremesecons.setting("teleporter", "enable_lbm", false) then | ||||
| 		action = register | ||||
| 	}) | ||||
| end | ||||
|  | ||||
| minetest.log("action", "[moremesecons_teleporter] loaded.") | ||||
|   | ||||
| @@ -25,11 +25,14 @@ 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 | ||||
| @@ -125,3 +128,5 @@ minetest.register_craft({ | ||||
|  | ||||
| minetest.register_alias("moremesecons_temporarygate:temporarygate_off", "moremesecons_timegate:timegate_off") | ||||
| minetest.register_alias("moremesecons_temporarygate:temporarygate_on", "moremesecons_timegate:timegate_on") | ||||
|  | ||||
| minetest.log("action", "[moremesecons_timegate] loaded.") | ||||
|   | ||||
| @@ -1 +0,0 @@ | ||||
| vector_extras? | ||||
| @@ -52,53 +52,331 @@ function moremesecons.remove_data_from_pos(sto, pos) | ||||
| 	sto.storage:set_string(sto.name, minetest.serialize(sto.tab)) | ||||
| 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 | ||||
| -- Some additional vector 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 | ||||
| -- 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 | ||||
|  | ||||
| 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 | ||||
| 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 | ||||
| 		result = { | ||||
| 			version = "MapDataStorage_v1", | ||||
| 			indices = "return {" .. table.concat(indices, ",") .. "}", | ||||
| 			values = minetest.serialize(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 | ||||
| 	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 | ||||
|  | ||||
|  | ||||
| -- 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.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 | ||||
| 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 | ||||
|  | ||||
| if not vector.unpack then | ||||
| 	function vector.unpack(pos) | ||||
| 		return pos.z, pos.y, pos.x | ||||
| 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, v 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, v 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 | ||||
|  | ||||
| minetest.log("action", "[moremesecons_utils] loaded.") | ||||
| --~ do_test() | ||||
|   | ||||
| @@ -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 | ||||
| @@ -482,3 +484,5 @@ if storage:get_string("wireless_meta_2") == "" then | ||||
| 	end | ||||
| 	minetest.log("action", "[moremesecons_wireless] Done!") | ||||
| end | ||||
|  | ||||
| minetest.log("action", "[moremesecons_wireless] loaded.") | ||||
|   | ||||
		Reference in New Issue
	
	Block a user