123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206 |
- map_master.registered_maps = {}
- local map_def_prototype =
- {
- middle = {x = 0, z = 0},
- }
- local function assert_vector(vec, msg)
- assert(type(vec.x) == "number" and
- type(vec.y) == "number" and
- type(vec.z) == "number", msg)
- end
- function map_master.register_map(name, def)
- assert(type(name) == "string",
- "Error registering map: name must be a string")
- assert_vector(def.size,
- "Error registering map: size must be a vector")
- assert(def.size.x > 0 and
- def.size.y > 0 and
- def.size.z > 0,
- "Error registering map: x, y and z of size must be positive")
- assert_vector(def.spawnpoint,
- "Error registering map: spawnpoint must be a vector")
- assert(type(def.path) == "string",
- "Error registering map: Path must be a string")
- local copy = {}
- for k, v in pairs(map_def_prototype)
- do
- copy[k] = v
- end
- for k, v in pairs(def)
- do
- copy[k] = v
- end
- map_master.registered_maps[name] = copy
- end
- local function set_spawnpoint(map)
- local minpos =
- {
- x = map.middle.x - map.size.x * 8 ,
- y = -19,
- z = map.middle.z - map.size.z * 8,
- }
- local spawn = vector.add(minpos, map.spawnpoint)
- movable_spawnpoint.set_spawnpoint(spawn)
- end
- local function place_schematics(map, done_callback)
- --defining variables that persist throughout iteration
- --by having them outside the iterating function
- local minpos =
- {
- x = map.middle.x - map.size.x * 8 ,
- y = -19,
- z = map.middle.z - map.size.z * 8,
- }
- local i, ii, iii = 0, 0, 0
- local ix = minpos.x
- local iy = minpos.y
- local iz = minpos.z
- --iterating funciton that will run asynchronously
- local function place_async()
- local success
- for I = 1, 10
- do
- local pos1 = vector.new(ix, iy, iz)
- local filename = map.path..i.."_"..ii.."_"..iii..".mts"
- success = minetest.place_schematic(
- pos1,
- filename,
- nil,
- nil,
- true)
- iii = iii + 1
- iz = iz + 16
- if iii == map.size.z
- then
- iii = 0
- iz = minpos.z
- ii = ii + 1
- iy = iy + 16
- if ii == map.size.y
- then
- ii = 0
- iy = minpos.y
- i = i + 1
- ix = ix + 16
- end
- end
- if i >= map.size.x or not success
- then
- break
- end
- end
- if i < map.size.x and success
- then
- --asynchronous looping
- minetest.after(0.05, place_async)
- elseif done_callback
- then
- done_callback(success)
- end
- end
- place_async()
- end
- local function place_border_volume(pos1, pos2, vm_buffer)
- local pmin =
- {
- x = math.min(pos1.x, pos2.x),
- y = math.min(pos1.y, pos2.y),
- z = math.min(pos1.z, pos2.z),
- }
- local pmax =
- {
- x = math.max(pos1.x, pos2.x),
- y = math.max(pos1.y, pos2.y),
- z = math.max(pos1.z, pos2.z),
- }
- local cid = minetest.get_content_id("invisible_wall")
- local vm = VoxelManip()
- local emin, emax = vm:read_from_map(pmin, pmax)
- local data = vm:get_data(vm_buffer)
- local area = VoxelArea:new{MinEdge = emin, MaxEdge = emax}
- for iz = pmin.z, pmax.z
- do
- for iy = pmin.y, pmax.y
- do
- for ix = pmin.x, pmax.x
- do
- data[area:index(ix, iy, iz)] = cid
- end
- end
- end
- vm:set_data(data)
- vm:write_to_map()
- end
- local function place_borders(map)
- local min =
- {
- x = map.middle.x - map.size.x * 8 - 1,
- y = -19,
- z = map.middle.z - map.size.z * 8 - 1,
- }
- local max =
- {
- x = map.middle.x + map.size.x * 8,
- y = map.size.y * 16,
- z = map.middle.z + map.size.z * 8,
- }
- --placing sides
- local vm_buffer = {}
- place_border_volume(min, {x = max.x, y = max.y, z = min.z}, vm_buffer)
- place_border_volume(min, {x = min.x, y = max.y, z = max.z}, vm_buffer)
- place_border_volume(max, {x = min.x, y = max.y, z = min.z}, vm_buffer)
- place_border_volume(max, {x = max.x, y = min.y, z = min.z}, vm_buffer)
- place_border_volume(max, {x = min.x, y = min.y, z = max.z}, vm_buffer)
- end
- --
- function map_master.load_map(name, done_callback)
- local map = map_master.registered_maps[name]
- if not map
- then
- return false
- end
- place_schematics(map, done_callback)
- place_borders(map)
- set_spawnpoint(map)
- return true
- end
|