improvements to mineshaft cart variety + /locate

This commit is contained in:
kno10 2024-09-05 23:13:08 +02:00
parent 24ffd409d1
commit b8b3ff7f70
7 changed files with 75 additions and 2 deletions

@ -371,6 +371,7 @@ local function ecb_spawn_dungeon(blockpos, action, calls_remaining, param)
end end
set_node(pos, {name="mcl_chests:chest", param2=facedir}) set_node(pos, {name="mcl_chests:chest", param2=facedir})
vl_structures.construct_nodes(pos, pos, {"mcl_chests:chest"})
local meta = get_meta(pos) local meta = get_meta(pos)
if logging then if logging then
minetest.log("action", "[mcl_dungeons] Filling chest " .. tostring(c) .. " at " .. minetest.pos_to_string(pos)) minetest.log("action", "[mcl_dungeons] Filling chest " .. tostring(c) .. " at " .. minetest.pos_to_string(pos))

@ -423,7 +423,7 @@ if mg_name == "v6" then
dofile(modpath.."/v6.lua") dofile(modpath.."/v6.lua")
end end
--[[ -- still needed?
minetest.register_lbm({ minetest.register_lbm({
label = "Fix grass palette indexes", -- This LBM fixes any incorrect grass palette indexes. label = "Fix grass palette indexes", -- This LBM fixes any incorrect grass palette indexes.
name = "mcl_mapgen_core:fix_grass_palette_indexes", name = "mcl_mapgen_core:fix_grass_palette_indexes",
@ -492,6 +492,7 @@ minetest.register_lbm({
end 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 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 -- 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. -- be coloured correctly.

@ -391,6 +391,7 @@ end
-- Chests -- Chests
local function PlaceChest(pos, param2) local function PlaceChest(pos, param2)
if SetNodeIfCanBuild(pos, {name=tsm_railcorridors.nodes.chest, param2=param2}) then 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 meta = minetest.get_meta(pos)
local inv = meta:get_inventory() local inv = meta:get_inventory()
local items = tsm_railcorridors.get_treasures(pr) local items = tsm_railcorridors.get_treasures(pr)

@ -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 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},... } -- e.g. { ["mcl_chests:chest_small"] = {loot},... }
terrain_feature =, -- affects placement priority and disables logging for uninteresting structures 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 daughters =, -- substructures to spawn, unstable API
} }
``` ```

@ -112,6 +112,7 @@ function vl_structures.place_structure(pos, def, pr, blockseed, rot)
if log_enabled then if log_enabled then
minetest.log("action","[vl_structures] "..def.name.." placed at "..minetest.pos_to_string(pp)) minetest.log("action","[vl_structures] "..def.name.." placed at "..minetest.pos_to_string(pp))
end 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 return true
elseif log_enabled then elseif log_enabled then
if def.place_func then if def.place_func then
@ -177,6 +178,38 @@ function vl_structures.register_structure(name,def)
end end
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 -- 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. -- Maybe we can eventually remove this - the end portal should likely go into the mapgen itself.
minetest.register_on_mods_loaded(function() minetest.register_on_mods_loaded(function()
@ -193,6 +226,6 @@ mcl_mapgen_core.register_generator("static structures", nil, function(minp, maxp
end end
end end
return false, false, false return false, false, false
end, 100, true) end, 100, true) -- light in the end is sensitive to these options
end) end)

@ -42,3 +42,38 @@ minetest.register_on_mods_loaded(function()
minetest.registered_chatcommands["spawnstruct"].params = p minetest.registered_chatcommands["spawnstruct"].params = p
end) 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
})

@ -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.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.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.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 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)) 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 end