diff --git a/mods/MAPGEN/mcl_dungeons/init.lua b/mods/MAPGEN/mcl_dungeons/init.lua index 381aab2af..4dd70b91a 100644 --- a/mods/MAPGEN/mcl_dungeons/init.lua +++ b/mods/MAPGEN/mcl_dungeons/init.lua @@ -371,6 +371,7 @@ local function ecb_spawn_dungeon(blockpos, action, calls_remaining, param) end set_node(pos, {name="mcl_chests:chest", param2=facedir}) + vl_structures.construct_nodes(pos, pos, {"mcl_chests:chest"}) local meta = get_meta(pos) if logging then minetest.log("action", "[mcl_dungeons] Filling chest " .. tostring(c) .. " at " .. minetest.pos_to_string(pos)) diff --git a/mods/MAPGEN/mcl_mapgen_core/init.lua b/mods/MAPGEN/mcl_mapgen_core/init.lua index 739d87186..2c0c94ff2 100644 --- a/mods/MAPGEN/mcl_mapgen_core/init.lua +++ b/mods/MAPGEN/mcl_mapgen_core/init.lua @@ -423,7 +423,7 @@ if mg_name == "v6" then dofile(modpath.."/v6.lua") end ---[[ +-- still needed? minetest.register_lbm({ label = "Fix grass palette indexes", -- This LBM fixes any incorrect grass palette indexes. name = "mcl_mapgen_core:fix_grass_palette_indexes", @@ -492,6 +492,7 @@ minetest.register_lbm({ end }) +--[[ No longer necessary? Ugly? -- We go outside x and y for where trees are placed next to a biome that has already been generated. -- We go above maxp.y because trees can often get placed close to the top of a generated area and folliage may not -- be coloured correctly. diff --git a/mods/MAPGEN/tsm_railcorridors/init.lua b/mods/MAPGEN/tsm_railcorridors/init.lua index 88259be1f..00be166df 100644 --- a/mods/MAPGEN/tsm_railcorridors/init.lua +++ b/mods/MAPGEN/tsm_railcorridors/init.lua @@ -391,6 +391,7 @@ end -- Chests local function PlaceChest(pos, param2) if SetNodeIfCanBuild(pos, {name=tsm_railcorridors.nodes.chest, param2=param2}) then + vl_structures.construct_nodes(pos, pos, {tsm_railcorridors.nodes.chest}) local meta = minetest.get_meta(pos) local inv = meta:get_inventory() local items = tsm_railcorridors.get_treasures(pr) diff --git a/mods/MAPGEN/vl_structures/API.md b/mods/MAPGEN/vl_structures/API.md index 5a4b3fb32..3e9e5f53b 100644 --- a/mods/MAPGEN/vl_structures/API.md +++ b/mods/MAPGEN/vl_structures/API.md @@ -33,6 +33,7 @@ Structures in this API are defined using the following table: loot =, -- a table of loot tables for mcl_loot indexed by node names -- ignored for place_func, to be removed -- e.g. { ["mcl_chests:chest_small"] = {loot},... } terrain_feature =, -- affects placement priority and disables logging for uninteresting structures + no_registry =, -- do not register the structure for the /locate command (implied for terrain features) daughters =, -- substructures to spawn, unstable API } ``` diff --git a/mods/MAPGEN/vl_structures/api.lua b/mods/MAPGEN/vl_structures/api.lua index de6e7350b..b67bd3b6b 100644 --- a/mods/MAPGEN/vl_structures/api.lua +++ b/mods/MAPGEN/vl_structures/api.lua @@ -112,6 +112,7 @@ function vl_structures.place_structure(pos, def, pr, blockseed, rot) if log_enabled then minetest.log("action","[vl_structures] "..def.name.." placed at "..minetest.pos_to_string(pp)) end + if def.name and not (def.terrain_feature or def.no_registry) then vl_structures.register_structures_spawn(def.name, pos) end return true elseif log_enabled then if def.place_func then @@ -177,6 +178,38 @@ function vl_structures.register_structure(name,def) end end +-- Persistent structure registry +local mod_storage = minetest.get_mod_storage() +local vl_structures_spawn_cache = {} +function vl_structures.register_structures_spawn(name, pos) + if not name or not pos then return end + local data = vl_structures_spawn_cache[name] + if not data then + data = mod_storage:get("vl_structures:spawns:"..name) + data = data and minetest.deserialize(data) or {} + end + table.insert(data, pos) + mod_storage:set_string("vl_structures:"..name, minetest.serialize(data)) + vl_structures_spawn_cache[name] = data +end +function vl_structures.get_structure_spawns(name) + if name == nil then + local ret = {} + for k, _ in pairs(vl_structures_spawn_cache) do + table.insert(ret, k) + end + return ret + end + local data = vl_structures_spawn_cache[name] + if not data then + data = mod_storage:get("vl_structures:spawns:"..name) + if not data then return nil end + data = minetest.deserialize(data) + vl_structures_spawn_cache[name] = data + end + return table.copy(data) +end + -- To avoid a cyclic dependency, run this when modules have finished loading -- Maybe we can eventually remove this - the end portal should likely go into the mapgen itself. minetest.register_on_mods_loaded(function() @@ -193,6 +226,6 @@ mcl_mapgen_core.register_generator("static structures", nil, function(minp, maxp end end return false, false, false -end, 100, true) +end, 100, true) -- light in the end is sensitive to these options end) diff --git a/mods/MAPGEN/vl_structures/commands.lua b/mods/MAPGEN/vl_structures/commands.lua index ffae8db4a..53dbf9929 100644 --- a/mods/MAPGEN/vl_structures/commands.lua +++ b/mods/MAPGEN/vl_structures/commands.lua @@ -42,3 +42,38 @@ minetest.register_on_mods_loaded(function() minetest.registered_chatcommands["spawnstruct"].params = p end) +--- /locate chat command +minetest.register_chatcommand("locate", { + params = "", + description = S("Locate a pre-defined structure near your position."), + privs = {debug = true}, + func = function(name, param) + local player = minetest.get_player_by_name(name) + if not player then return end + local pos = player:get_pos() + if not pos then return end + if param == "" then + local data = vl_structures.get_structure_spawns() + local datastr = "" + for i, d in ipairs(data) do datastr = datastr .. (i > 1 and " | " or "") .. d end + if datastr == "" then + minetest.chat_send_player(name, S("Error: No structure type given, and no structures were recently spawned.")) + else + minetest.chat_send_player(name, S("Error: No structure type given. Recently spawned structures include: "..datastr.."”.")) + end + return + end + local data = vl_structures.get_structure_spawns(param) + local bestd, bestp = 1e9, nil + for _, p in ipairs(data or {}) do + local sdx = math.abs(p.x-pos.x) + math.abs(p.y-pos.y) + math.abs(p.z-pos.z) + if sdx < bestd or not bestv then bestd, bestp = sdx, p end + end + if bestp then + minetest.chat_send_player(name, S("A "..param.." can be found at "..minetest.pos_to_string(bestp))) + else + minetest.chat_send_player(name, S("Structure type not known or no structure of this type spawned yet.")) + end + end +}) + diff --git a/mods/MAPGEN/vl_structures/emerge.lua b/mods/MAPGEN/vl_structures/emerge.lua index bde17d59c..ee7f1b7ce 100644 --- a/mods/MAPGEN/vl_structures/emerge.lua +++ b/mods/MAPGEN/vl_structures/emerge.lua @@ -140,6 +140,7 @@ local function emerge_schematics(blockpos, action, calls_remaining, param) if def.loot then vl_structures.fill_chests(pmin,pmax,def.loot,pr) end if def.construct_nodes then vl_structures.construct_nodes(pmin,pmax,def.construct_nodes) end if def.after_place then def.after_place(pos,def,pr,pmin,pmax,size,param.rotation) end + if def.name and not (def.terrain_feature or def.no_registry) then vl_structures.register_structures_spawn(def.name, pos) end if logging and not def.terrain_feature then minetest.log("action", "[vl_structures] "..(def.name or "unnamed").." spawned at "..minetest.pos_to_string(pos).." in "..string.format("%.2fms (main: %.2fms)", (os.clock()-start)*1000, (endmain-startmain)*1000)) end