add modgen
This commit is contained in:
parent
55c97761ca
commit
af2207ea40
|
@ -0,0 +1,58 @@
|
|||
local import_mod = ...
|
||||
|
||||
local function get_mod_chunk_mtime(chunk_pos)
|
||||
local _,_,mtime = import_mod.read_chunk_header(chunk_pos)
|
||||
return mtime
|
||||
end
|
||||
|
||||
local function get_world_chunk_mtime(chunk_pos)
|
||||
local mtime = import_mod.storage:get_int(minetest.pos_to_string(chunk_pos))
|
||||
if mtime == 0 then
|
||||
return nil
|
||||
else
|
||||
return mtime
|
||||
end
|
||||
end
|
||||
|
||||
local cache = {}
|
||||
local function check_player_pos(player)
|
||||
local ppos = player:get_pos()
|
||||
local chunk_pos = import_mod.get_chunkpos(ppos)
|
||||
|
||||
-- cache access
|
||||
local cache_key = minetest.pos_to_string(chunk_pos)
|
||||
if cache[cache_key] then
|
||||
return
|
||||
end
|
||||
cache[cache_key] = true
|
||||
|
||||
-- retrieve timestamps
|
||||
local mod_mtime = get_mod_chunk_mtime(chunk_pos)
|
||||
local world_mtime = get_world_chunk_mtime(chunk_pos)
|
||||
|
||||
if not mod_mtime then
|
||||
-- the chunk isn't available in the mod
|
||||
return
|
||||
end
|
||||
|
||||
if world_mtime and world_mtime >= mod_mtime then
|
||||
-- world chunk is same or newer (?) than the one in the mod
|
||||
return
|
||||
end
|
||||
|
||||
local mapblock_min, mapblock_max = import_mod.get_mapblock_bounds_from_chunk(chunk_pos)
|
||||
local min = import_mod.get_mapblock_bounds_from_mapblock(mapblock_min)
|
||||
local _, max = import_mod.get_mapblock_bounds_from_mapblock(mapblock_max)
|
||||
|
||||
minetest.delete_area(min, max)
|
||||
end
|
||||
|
||||
local function check_players()
|
||||
for _, player in ipairs(minetest.get_connected_players()) do
|
||||
check_player_pos(player)
|
||||
end
|
||||
minetest.after(1, check_players)
|
||||
end
|
||||
|
||||
print("[modgen] map auto-update enabled")
|
||||
minetest.after(1, check_players)
|
|
@ -0,0 +1,20 @@
|
|||
local import_mod = ...
|
||||
|
||||
function import_mod.decode_uint16(str, ofs)
|
||||
ofs = ofs or 0
|
||||
local a, b = string.byte(str, ofs + 1, ofs + 2)
|
||||
return a + b * 0x100
|
||||
end
|
||||
|
||||
local function lshift(x, by)
|
||||
return x * 2 ^ by
|
||||
end
|
||||
|
||||
function import_mod.decode_uint32(data, offset)
|
||||
return (
|
||||
string.byte(data,1+offset) +
|
||||
lshift(string.byte(data,2+offset), 8) +
|
||||
lshift(string.byte(data,3+offset), 16) +
|
||||
lshift(string.byte(data,4+offset), 24)
|
||||
)
|
||||
end
|
|
@ -0,0 +1,52 @@
|
|||
local import_mod = ...
|
||||
|
||||
function import_mod.deserialize(data, mapblock_pos)
|
||||
|
||||
local pos1 = vector.multiply(mapblock_pos, 16)
|
||||
local pos2 = vector.add(pos1, 15) -- inclusive
|
||||
|
||||
local manip = minetest.get_voxel_manip()
|
||||
local e1, e2 = manip:read_from_map(pos1, pos2)
|
||||
local area = VoxelArea:new({MinEdge=e1, MaxEdge=e2})
|
||||
|
||||
local node_data = manip:get_data()
|
||||
local param1 = manip:get_light_data()
|
||||
local param2 = manip:get_param2_data()
|
||||
|
||||
local j = 1
|
||||
for z=pos1.z,pos2.z do
|
||||
for x=pos1.x,pos2.x do
|
||||
for y=pos1.y,pos2.y do
|
||||
local i = area:index(x,y,z)
|
||||
node_data[i] = data.node_ids[j]
|
||||
param1[i] = data.param1[j]
|
||||
param2[i] = data.param2[j]
|
||||
j = j + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
manip:set_data(node_data)
|
||||
manip:set_light_data(param1)
|
||||
manip:set_param2_data(param2)
|
||||
manip:write_to_map(false)
|
||||
|
||||
-- deserialize metadata
|
||||
if data.metadata and data.metadata.meta then
|
||||
for pos_str, md in pairs(data.metadata.meta) do
|
||||
local relative_pos = minetest.string_to_pos(pos_str)
|
||||
local absolute_pos = vector.add(pos1, relative_pos)
|
||||
minetest.get_meta(absolute_pos):from_table(md)
|
||||
end
|
||||
end
|
||||
|
||||
-- deserialize node timers
|
||||
if data.metadata and data.metadata.timers then
|
||||
for pos_str, timer_data in pairs(data.metadata.timers) do
|
||||
local relative_pos = minetest.string_to_pos(pos_str)
|
||||
local absolute_pos = vector.add(pos1, relative_pos)
|
||||
minetest.get_node_timer(absolute_pos):set(timer_data.timeout, timer_data.elapsed)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
|
@ -0,0 +1,46 @@
|
|||
--- Modgen import mod
|
||||
-- writes the mapblocks back to the world
|
||||
-- hard-dependency- and global-free
|
||||
|
||||
-- mod name and path
|
||||
local modname = minetest.get_current_modname()
|
||||
local MP = minetest.get_modpath(modname)
|
||||
|
||||
local import_mod = {
|
||||
-- storage
|
||||
storage = minetest.get_mod_storage()
|
||||
}
|
||||
|
||||
-- local functions/helpers
|
||||
loadfile(MP .. "/decode.lua")(import_mod)
|
||||
loadfile(MP .. "/util.lua")(import_mod)
|
||||
loadfile(MP .. "/load_chunk.lua")(import_mod)
|
||||
loadfile(MP .. "/register_mapgen.lua")(import_mod)
|
||||
loadfile(MP .. "/read_manifest.lua")(import_mod)
|
||||
loadfile(MP .. "/nodename_check.lua")(import_mod)
|
||||
loadfile(MP .. "/uid_check.lua")(import_mod)
|
||||
loadfile(MP .. "/localize_nodeids.lua")(import_mod)
|
||||
loadfile(MP .. "/deserialize.lua")(import_mod)
|
||||
|
||||
local manifest = import_mod.read_manifest()
|
||||
|
||||
-- check world uid
|
||||
import_mod.uid_check(manifest)
|
||||
|
||||
-- check if the nodes are available in the current world
|
||||
minetest.register_on_mods_loaded(function()
|
||||
import_mod.nodename_check(manifest)
|
||||
end)
|
||||
|
||||
-- initialize mapgen
|
||||
import_mod.register_mapgen(manifest)
|
||||
|
||||
if minetest.get_modpath("modgen") then
|
||||
-- modgen available, make it aware of the loaded import_mod
|
||||
modgen.register_import_mod(manifest, MP)
|
||||
end
|
||||
|
||||
-- check if the auto-update feature is enabled
|
||||
if minetest.settings:get_bool("import_mod.auto_update.enabled") then
|
||||
loadfile(MP .. "/auto_update.lua")(import_mod)
|
||||
end
|
|
@ -0,0 +1,78 @@
|
|||
local import_mod = ...
|
||||
|
||||
local modname = minetest.get_current_modname()
|
||||
local MP = minetest.get_modpath(modname)
|
||||
|
||||
local function get_chunk_name(chunk_pos)
|
||||
return MP .. "/map/chunk_" .. chunk_pos.x .. "_" .. chunk_pos.y .. "_" .. chunk_pos.z .. ".bin"
|
||||
end
|
||||
|
||||
function import_mod.read_chunk_header(chunk_pos)
|
||||
local filename = get_chunk_name(chunk_pos)
|
||||
local file = io.open(filename, "rb")
|
||||
if file then
|
||||
local version = string.byte(file:read(1))
|
||||
local mapblock_count = string.byte(file:read(1))
|
||||
local mtime = import_mod.decode_uint32(file:read(4), 0)
|
||||
return version, mapblock_count, mtime
|
||||
end
|
||||
end
|
||||
|
||||
local function read_chunkdata(chunk_pos)
|
||||
local filename = get_chunk_name(chunk_pos)
|
||||
local file = io.open(filename, "rb")
|
||||
if file then
|
||||
local version = string.byte(file:read(1))
|
||||
local mapblock_count = string.byte(file:read(1))
|
||||
local mtime = import_mod.decode_uint32(file:read(4), 0)
|
||||
local data = file:read("*all")
|
||||
return version, mapblock_count, mtime, minetest.decompress(data, "deflate"), #data
|
||||
end
|
||||
end
|
||||
|
||||
-- local vars for faster access
|
||||
local insert, byte, decode_uint16 = table.insert, string.byte, import_mod.decode_uint16
|
||||
|
||||
function import_mod.load_chunk(chunk_pos, manifest)
|
||||
local version, mapblock_count, _, chunk_data = read_chunkdata(chunk_pos)
|
||||
if not chunk_data then
|
||||
-- write current os.time to modstorage
|
||||
import_mod.storage:set_int(minetest.pos_to_string(chunk_pos), os.time())
|
||||
return
|
||||
end
|
||||
if version ~= manifest.version then
|
||||
error("couldn't load chunk " .. minetest.pos_to_string(chunk_pos) ..
|
||||
" serialization-version: " .. version)
|
||||
end
|
||||
|
||||
local manifest_offset = 1 + (4096 * 4 * mapblock_count)
|
||||
local chunk_manifest = minetest.parse_json(string.sub(chunk_data, manifest_offset))
|
||||
|
||||
for mbi=1, mapblock_count do
|
||||
local mapblock_manifest = chunk_manifest.mapblocks[mbi]
|
||||
local mapblock = {
|
||||
node_ids = {},
|
||||
param1 = {},
|
||||
param2 = {},
|
||||
metadata = mapblock_manifest.metadata
|
||||
}
|
||||
|
||||
for i=1,4096 do
|
||||
local node_id = decode_uint16(chunk_data, ((mbi-1) * 4096 * 2) + (i * 2) - 2)
|
||||
local param1 = byte(chunk_data, (4096 * 2 * mapblock_count) + ((mbi-1) * 4096) + i)
|
||||
local param2 = byte(chunk_data, (4096 * 3 * mapblock_count) + ((mbi-1) * 4096) + i)
|
||||
|
||||
insert(mapblock.node_ids, node_id)
|
||||
insert(mapblock.param1, param1)
|
||||
insert(mapblock.param2, param2)
|
||||
end
|
||||
|
||||
import_mod.localize_nodeids(manifest.node_mapping, mapblock.node_ids)
|
||||
import_mod.deserialize(mapblock, mapblock_manifest.pos)
|
||||
end
|
||||
|
||||
if chunk_manifest.mtime then
|
||||
-- write emerge chunk mtime to modstorage
|
||||
import_mod.storage:set_int(minetest.pos_to_string(chunk_pos), chunk_manifest.mtime)
|
||||
end
|
||||
end
|
|
@ -0,0 +1,32 @@
|
|||
local import_mod = ...
|
||||
|
||||
local air_content_id = minetest.get_content_id("air")
|
||||
|
||||
-- local nodename->id cache
|
||||
local local_nodename_to_id_mapping = {} -- name -> id
|
||||
|
||||
function import_mod.localize_nodeids(node_mapping, node_ids)
|
||||
local foreign_nodeid_to_name_mapping = {} -- id -> name
|
||||
for k, v in pairs(node_mapping) do
|
||||
foreign_nodeid_to_name_mapping[v] = k
|
||||
end
|
||||
|
||||
for i, node_id in ipairs(node_ids) do
|
||||
local node_name = foreign_nodeid_to_name_mapping[node_id]
|
||||
local local_node_id = local_nodename_to_id_mapping[node_name]
|
||||
if not local_node_id then
|
||||
if minetest.registered_nodes[node_name] then
|
||||
-- node is locally available
|
||||
local_node_id = minetest.get_content_id(node_name)
|
||||
else
|
||||
-- node is not available here
|
||||
-- TODO: make replacements configurable
|
||||
local_node_id = air_content_id
|
||||
end
|
||||
local_nodename_to_id_mapping[node_name] = local_node_id
|
||||
|
||||
end
|
||||
|
||||
node_ids[i] = local_node_id
|
||||
end
|
||||
end
|
|
@ -0,0 +1,110 @@
|
|||
{
|
||||
"bounds" :
|
||||
{
|
||||
"max" :
|
||||
{
|
||||
"x" : -1.0,
|
||||
"y" : 1.0,
|
||||
"z" : 0.0
|
||||
},
|
||||
"min" :
|
||||
{
|
||||
"x" : -1.0,
|
||||
"y" : 1.0,
|
||||
"z" : 0.0
|
||||
}
|
||||
},
|
||||
"chunks" : 6.0,
|
||||
"mtime" : 1660543987.0,
|
||||
"next_id" : 84.0,
|
||||
"node_mapping" :
|
||||
{
|
||||
"air" : 0.0,
|
||||
"an_televator:televator" : 24.0,
|
||||
"mesecons:wire_00000000_off" : 58.0,
|
||||
"mesecons:wire_00010000_off" : 51.0,
|
||||
"mesecons:wire_00010000_on" : 37.0,
|
||||
"mesecons:wire_00010001_on" : 41.0,
|
||||
"mesecons:wire_00100000_off" : 56.0,
|
||||
"mesecons:wire_00100010_off" : 9.0,
|
||||
"mesecons:wire_00100010_on" : 71.0,
|
||||
"mesecons:wire_00110000_off" : 19.0,
|
||||
"mesecons:wire_00110001_off" : 29.0,
|
||||
"mesecons:wire_00110010_on" : 44.0,
|
||||
"mesecons:wire_01000000_off" : 11.0,
|
||||
"mesecons:wire_01000000_on" : 35.0,
|
||||
"mesecons:wire_01000100_off" : 59.0,
|
||||
"mesecons:wire_01000100_on" : 62.0,
|
||||
"mesecons:wire_01010000_off" : 17.0,
|
||||
"mesecons:wire_01010000_on" : 40.0,
|
||||
"mesecons:wire_01010001_off" : 82.0,
|
||||
"mesecons:wire_01010001_on" : 36.0,
|
||||
"mesecons:wire_01010101_on" : 39.0,
|
||||
"mesecons:wire_01100000_off" : 27.0,
|
||||
"mesecons:wire_01100000_on" : 34.0,
|
||||
"mesecons:wire_01100010_off" : 81.0,
|
||||
"mesecons:wire_01100100_off" : 10.0,
|
||||
"mesecons:wire_01110000_off" : 16.0,
|
||||
"mesecons:wire_01110000_on" : 70.0,
|
||||
"mesecons:wire_01110011_off" : 80.0,
|
||||
"mesecons:wire_01110100_on" : 77.0,
|
||||
"mesecons:wire_01110111_on" : 76.0,
|
||||
"mesecons:wire_10000000_off" : 49.0,
|
||||
"mesecons:wire_10001000_off" : 21.0,
|
||||
"mesecons:wire_10010000_off" : 47.0,
|
||||
"mesecons:wire_10010000_on" : 42.0,
|
||||
"mesecons:wire_10010001_off" : 50.0,
|
||||
"mesecons:wire_10011000_off" : 48.0,
|
||||
"mesecons:wire_10011000_on" : 72.0,
|
||||
"mesecons:wire_10100000_off" : 13.0,
|
||||
"mesecons:wire_10100000_on" : 33.0,
|
||||
"mesecons:wire_10100010_off" : 23.0,
|
||||
"mesecons:wire_10100010_on" : 75.0,
|
||||
"mesecons:wire_10101000_off" : 7.0,
|
||||
"mesecons:wire_10101000_on" : 73.0,
|
||||
"mesecons:wire_10101010_off" : 6.0,
|
||||
"mesecons:wire_10110000_off" : 67.0,
|
||||
"mesecons:wire_10110000_on" : 74.0,
|
||||
"mesecons:wire_10110001_off" : 28.0,
|
||||
"mesecons:wire_11000000_off" : 46.0,
|
||||
"mesecons:wire_11000000_on" : 68.0,
|
||||
"mesecons:wire_11000100_off" : 22.0,
|
||||
"mesecons:wire_11001000_on" : 31.0,
|
||||
"mesecons:wire_11010000_off" : 15.0,
|
||||
"mesecons:wire_11010000_on" : 38.0,
|
||||
"mesecons:wire_11100000_off" : 66.0,
|
||||
"mesecons:wire_11100100_off" : 8.0,
|
||||
"mesecons:wire_11101010_off" : 79.0,
|
||||
"mesecons:wire_11110000_off" : 55.0,
|
||||
"mesecons:wire_11110000_on" : 43.0,
|
||||
"mesecons:wire_11111110_off" : 63.0,
|
||||
"mesecons:wire_11111111_off" : 65.0,
|
||||
"mesecons_commandblock:commandblock_off" : 4.0,
|
||||
"mesecons_detector:object_detector_off" : 25.0,
|
||||
"mesecons_extrawires:vertical_bottom_off" : 52.0,
|
||||
"mesecons_extrawires:vertical_off" : 53.0,
|
||||
"mesecons_extrawires:vertical_top_off" : 57.0,
|
||||
"mesecons_gates:not_on" : 45.0,
|
||||
"mesecons_gates:or_off" : 78.0,
|
||||
"mesecons_gates:or_on" : 69.0,
|
||||
"mesecons_lightstone:lightstone_white_off" : 61.0,
|
||||
"mesecons_lightstone:lightstone_white_on" : 64.0,
|
||||
"mesecons_pistons:piston_pusher_sticky" : 32.0,
|
||||
"mesecons_pistons:piston_sticky_off" : 5.0,
|
||||
"mesecons_pistons:piston_sticky_on" : 30.0,
|
||||
"mesecons_powerplant:power_plant" : 12.0,
|
||||
"mesecons_torch:mesecon_torch_on" : 83.0,
|
||||
"portalgun:autocheckpoint" : 18.0,
|
||||
"portalgun:cplps3" : 20.0,
|
||||
"portalgun:plantform_nu1" : 14.0,
|
||||
"portalgun:testblock" : 1.0,
|
||||
"portalgun:testblocks" : 60.0,
|
||||
"portalgun:toxwater_1" : 3.0,
|
||||
"portalgun:toxwater_2" : 2.0,
|
||||
"portalgun:turretgun_spawner" : 54.0,
|
||||
"portalgun:wscspawner5" : 26.0
|
||||
},
|
||||
"size" : 48642.0,
|
||||
"uid" : "278350",
|
||||
"version" : 4.0
|
||||
}
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1 @@
|
|||
optional_depends = modgen, technic_worldgen
|
|
@ -0,0 +1,25 @@
|
|||
local import_mod = ...
|
||||
|
||||
function import_mod.nodename_check(manifest)
|
||||
-- assemble node-list from registered lbm's
|
||||
local lbm_nodes = {}
|
||||
for _, lbm in ipairs(minetest.registered_lbms) do
|
||||
if type(lbm.nodenames) == "string" then
|
||||
-- duh, list as string
|
||||
lbm_nodes[lbm.nodenames] = true
|
||||
else
|
||||
-- proper list, add all regardless if they are a "group:*"
|
||||
for _, nodename in ipairs(lbm.nodenames) do
|
||||
lbm_nodes[nodename] = true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
for nodename in pairs(manifest.node_mapping) do
|
||||
if not minetest.registered_nodes[nodename]
|
||||
and not minetest.registered_aliases[nodename]
|
||||
and not lbm_nodes[nodename] then
|
||||
error("node not found and not aliased: " .. nodename)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,12 @@
|
|||
local import_mod = ...
|
||||
|
||||
local modname = minetest.get_current_modname()
|
||||
local MP = minetest.get_modpath(modname)
|
||||
|
||||
function import_mod.read_manifest()
|
||||
local infile = io.open(MP .. "/manifest.json", "r")
|
||||
local instr = infile:read("*a")
|
||||
infile:close()
|
||||
|
||||
return minetest.parse_json(instr or "{}")
|
||||
end
|
|
@ -0,0 +1,6 @@
|
|||
|
||||
## Modgen import mod
|
||||
|
||||
**This folder and its contents are autogenerated, do not edit directly**
|
||||
|
||||
For more infos, see: https://github.com/Buckaroobanzay/modgen
|
|
@ -0,0 +1,7 @@
|
|||
local import_mod = ...
|
||||
|
||||
function import_mod.register_mapgen(manifest)
|
||||
minetest.register_on_generated(function(minp)
|
||||
import_mod.load_chunk(import_mod.get_chunkpos(minp), manifest)
|
||||
end)
|
||||
end
|
|
@ -0,0 +1,12 @@
|
|||
local import_mod = ...
|
||||
|
||||
function import_mod.uid_check(manifest)
|
||||
local world_uid = import_mod.storage:get_string("uid")
|
||||
if world_uid ~= "" and world_uid ~= manifest.uid then
|
||||
-- abort if the uids don't match, something fishy might be going on
|
||||
error("modgen uids don't match, aborting for your safety!")
|
||||
end
|
||||
|
||||
-- write modgen uid to world-storage
|
||||
import_mod.storage:set_string("uid", manifest.uid)
|
||||
end
|
|
@ -0,0 +1,40 @@
|
|||
local import_mod = ...
|
||||
|
||||
function import_mod.get_mapblock_pos(pos)
|
||||
return vector.floor( vector.divide(pos, 16))
|
||||
end
|
||||
|
||||
function import_mod.get_mapblock(pos)
|
||||
return vector.floor( vector.divide(pos, 16))
|
||||
end
|
||||
|
||||
function import_mod.get_chunkpos(pos)
|
||||
local mapblock_pos = import_mod.get_mapblock_pos(pos)
|
||||
local aligned_mapblock_pos = vector.add(mapblock_pos, 2)
|
||||
return vector.floor( vector.divide(aligned_mapblock_pos, 5) )
|
||||
end
|
||||
|
||||
function import_mod.get_mapblock_bounds_from_chunk(chunk_pos)
|
||||
local min = vector.subtract( vector.multiply(chunk_pos, 5), 2)
|
||||
local max = vector.add(min, 4)
|
||||
return min, max
|
||||
end
|
||||
|
||||
function import_mod.get_chunk_bounds(pos)
|
||||
local chunk_pos = import_mod.get_chunkpos(pos)
|
||||
local mapblock_min, mapblock_max = import_mod.get_mapblock_bounds_from_chunk(chunk_pos)
|
||||
local min = import_mod.get_mapblock_bounds(mapblock_min)
|
||||
local _, max = import_mod.get_mapblock_bounds(mapblock_max)
|
||||
return min, max
|
||||
end
|
||||
|
||||
function import_mod.get_mapblock_bounds_from_mapblock(mapblock)
|
||||
local min = vector.multiply(mapblock, 16)
|
||||
local max = vector.add(min, 15)
|
||||
return min, max
|
||||
end
|
||||
|
||||
function import_mod.get_mapblock_bounds(pos)
|
||||
local mapblock = import_mod.get_mapblock(pos)
|
||||
return import_mod.get_mapblock_bounds_from_mapblock(mapblock)
|
||||
end
|
Loading…
Reference in New Issue