108 lines
3.0 KiB
Lua
108 lines
3.0 KiB
Lua
|
|
-- mapblock_lib schematic catalog
|
|
building_lib.register_placement("mapblock_lib", {
|
|
place = function(self, mapblock_pos, building_def, rotation, callback)
|
|
callback = callback or function() end
|
|
|
|
local catalog
|
|
local offset = {x=0, y=0, z=0}
|
|
local cache = false
|
|
|
|
if type(building_def.catalog) == "table" then
|
|
catalog = mapblock_lib.get_catalog(building_def.catalog.filename)
|
|
offset = building_def.catalog.offset or {x=0, y=0, z=0}
|
|
cache = building_def.catalog.cache
|
|
else
|
|
catalog = mapblock_lib.get_catalog(building_def.catalog)
|
|
end
|
|
|
|
if cache and building_def._cache and building_def._cache[rotation] then
|
|
-- rotated building already cached
|
|
building_def._cache[rotation](mapblock_pos)
|
|
callback()
|
|
return
|
|
else
|
|
-- initialize cache if not already done
|
|
building_def._cache = building_def._cache or {}
|
|
end
|
|
|
|
local size = self.get_size(self, mapblock_pos, building_def, 0)
|
|
|
|
local catalog_pos1 = vector.add({x=0, y=0, z=0}, offset)
|
|
local catalog_pos2 = vector.add(catalog_pos1, vector.add(size, -1))
|
|
|
|
local iterator = mapblock_lib.pos_iterator(catalog_pos1, catalog_pos2)
|
|
|
|
local function worker()
|
|
local catalog_pos = iterator()
|
|
if not catalog_pos then
|
|
return callback()
|
|
end
|
|
|
|
-- transform catalog position relative to offset
|
|
local rel_pos = vector.subtract(catalog_pos, offset)
|
|
local max_pos = vector.subtract(catalog_pos2, offset)
|
|
local rotated_rel_catalog_pos = mapblock_lib.rotate_pos(rel_pos, max_pos, rotation)
|
|
|
|
-- translate to world-coords
|
|
local world_pos = vector.add(mapblock_pos, rotated_rel_catalog_pos)
|
|
local replace = building_def.replace
|
|
if type(building_def.replace) == "function" then
|
|
replace = building_def.replace(mapblock_pos, building_def)
|
|
end
|
|
|
|
local place_fn = catalog:prepare(catalog_pos, {
|
|
on_metadata = building_def.on_metadata,
|
|
transform = {
|
|
rotate = {
|
|
axis = "y",
|
|
angle = rotation,
|
|
disable_orientation = building_def.disable_orientation
|
|
},
|
|
replace = replace
|
|
}
|
|
})
|
|
|
|
-- cache prepared mapblock if enabled
|
|
if cache then
|
|
-- verify size constraints for caching
|
|
assert(vector.equals(size, {x=1, y=1, z=1}))
|
|
building_def._cache[rotation] = place_fn
|
|
end
|
|
|
|
if place_fn then
|
|
-- only place if possible (mapblock found in catalog)
|
|
place_fn(world_pos)
|
|
end
|
|
minetest.after(0, worker)
|
|
end
|
|
|
|
worker()
|
|
end,
|
|
|
|
get_size = function(_, _, building_def, rotation)
|
|
local size
|
|
if type(building_def.catalog) == "table" then
|
|
size = building_def.catalog.size or {x=1, y=1, z=1}
|
|
else
|
|
local catalog = mapblock_lib.get_catalog(building_def.catalog)
|
|
size = catalog:get_size()
|
|
end
|
|
return mapblock_lib.rotate_size(size, rotation)
|
|
end,
|
|
|
|
validate = function(_, building_def)
|
|
local catalogfilename = building_def.catalog
|
|
if type(building_def.catalog) == "table" then
|
|
catalogfilename = building_def.catalog.filename
|
|
end
|
|
|
|
local catalog, err = mapblock_lib.get_catalog(catalogfilename)
|
|
if catalog then
|
|
return true
|
|
else
|
|
return false, err
|
|
end
|
|
end
|
|
})
|