From 7000c5220d9ce8864e028d3b035d86040e7de7aa Mon Sep 17 00:00:00 2001 From: orwell96 Date: Sun, 18 Oct 2020 15:27:55 +0200 Subject: Initial working state --- mapgen.lua | 167 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 167 insertions(+) create mode 100644 mapgen.lua (limited to 'mapgen.lua') diff --git a/mapgen.lua b/mapgen.lua new file mode 100644 index 0000000..ad63bd7 --- /dev/null +++ b/mapgen.lua @@ -0,0 +1,167 @@ +-- mapgen.lua - code that actually writes the game world based on the structures in the allocation map. + + +local mg_verbose = function() end +--local mg_verbose = cellworld.debug + +-- on mapgen init, set the mapgen to singlenode +minetest.register_on_mapgen_init(function(mgparams) + minetest.set_mapgen_setting("mg_name", "singlenode", true) + -- TODO maybe fixate the structure set in the cellworld meta. +end) + +-- placeholder for when something goes wrong with the mapgen +minetest.register_node("cellworld:placeholder", { + description = "Cellworld Unknown Node Placeholder", + tiles = {"cellworld_placeholder.png"}, + is_ground_content = false, + groups = {cracky = 3,}, +}) + +local placeholder_content_id = minetest.get_content_id("cellworld:placeholder") + +-- file-scoped buffer for vm node data +local vm_data = {} + +local function place_cell_actions(basepos, actions, area, clipminw, clipmaxw) + for _, action in ipairs(actions) do + if action.action == "fill" then + local nodeid = minetest.get_content_id(action.node) + if not nodeid then + cellworld.warn("Unknown node",action.node,", filling with placeholder"); + nodeid = placeholder_content_id + end + local rxl, ryl, rzl, rxu, ryu, rzu = unpack(action.coords) -- these are relative + if rxu=axl and ayu>=ayl and azu>=azl then + --local i = 0 + for index in area:iter(axl, ayl, azl, axu, ayu, azu) do + --i = i + 1 + --mg_verbose("va iter",i,"index",index,"pos",area:position(index)) + vm_data[index] = nodeid + end + else + mg_verbose("Outside of voxel area!") + end + elseif action.action == "log" then + cellworld.log("Cell Generation Log:",action.message) + end + end +end + + +local function place_cell_on_vmanip(cellpos, cell, borders, area, clipminw, clipmaxw) + local basepos = cellworld.cell_to_world_pos(cellpos) + -- place "structure" + mg_verbose("plave_cell_on_vmanip structure at basepos",basepos) + place_cell_actions(basepos, cell.structure, area, clipminw, clipmaxw) + -- check exits + if cell.exits then + for _,border in ipairs(borders) do + if cell.exits[border] then + -- does this exit match one in the neighbor? + local n_cellpos = vector.add(cellpos, cellworld.direction_to_vector[border]) + local n_stname, n_relpos = cellworld.alloc_get_structure_at(n_cellpos) + if n_stname then + local n_struct = cellworld.structures[n_stname] + if n_struct then + local n_border = cellworld.opposite_directions[border] + local n_cell = cellworld.get_structure_cell(n_struct, n_relpos) + if n_cell.exits and n_cell.exits[n_border] then + -- place exit + mg_verbose("border",border,"exit matches to",n_stname,n_relpos) + place_cell_actions(basepos, cell.exits[border], area, clipminw, clipmaxw) + end + end + end + end + end + end +end + + +local function allocate_chunk(minp, maxp) + local minwpos = cellworld.world_to_cell_pos(minp) + local maxwpos = cellworld.world_to_cell_pos(maxp) + local margin = vector.new(2,2,2) + + local allocmin = vector.subtract(minwpos, margin) + local allocmax = vector.subtract(maxwpos, margin) + + cellworld.gridgen_generate_cells(allocmin, allocmax) +end + + +local function run_chunk_generation(minposgen, maxposgen, emin, emax, vm, area) + vm:get_data(vm_data) + + local mincell = cellworld.world_to_cell_pos(minposgen) + local maxcell = cellworld.world_to_cell_pos(maxposgen) + local i = 0 + -- iterate over the current area + for x,y,z,cid in cellworld.alloc_get_area_iterator(mincell, maxcell) do + -- back to world position + local cellpos = vector.new(x,y,z) + --local basepos = cellworld.cell_to_world_pos(vector.new(x,y,z)) + local stname, relcell = cellworld.alloc_resolve_cid(x,y,z,cid) + if not stname then + cellworld.warn("Cell at",basepos," is not allocated during mapgen callback. Ignoring!") + else + local struct = cellworld.structures[stname] + if not struct then + cellworld.warn("Cell at",basepos," has unknown structure",stname,". Ignoring!") + else + mg_verbose("At cellpos",cellpos,"placing",stname,"cell",relcell) + -- resolve structure cell + local cell = cellworld.get_structure_cell(struct, relcell) + local borders = cellworld.get_border_sides(relcell, struct.size, true) + place_cell_on_vmanip(cellpos, cell, borders, area, minposgen, maxposgen) + end + end + i = i + 1 + end + mg_verbose("run_chunk_generation generated",i,"cells") + + vm:set_data(vm_data) +end + + + +-- this callback skeleton is taken from https://github.com/srifqi/superflat/blob/master/init.lua +minetest.register_on_generated(function(minp, maxp, seed) + cellworld.log("==================================================") + cellworld.log("Generating chunk: ",minp, maxp) + local t1 = os.clock() + + allocate_chunk(minp, maxp) + + local chugent = os.clock()-t1 + cellworld.log("Structure allocation took",string.format("%.2f", chugent*1000),"ms") + local t2 = os.clock() + + local vm, emin, emax = minetest.get_mapgen_object("voxelmanip") + local area = VoxelArea:new{MinEdge = emin, MaxEdge = emax} + + run_chunk_generation(minp, maxp, emin, emax, vm, area) + + vm:write_to_map() + vm:set_lighting({day = 15, night = 15}) + vm:update_liquids() + vm:calc_lighting() + + local chugent2 = os.clock()-t2 + local gentotal = os.clock()-t1 + cellworld.log("Generation took",string.format("%.2f", chugent2*1000),"ms, total", string.format("%.2f", gentotal*1000),"ms") +end) -- cgit v1.2.3