Add Biome ID Lookup
This commit is contained in:
parent
f2035af4dc
commit
c7ae36a3c8
@ -1,9 +1,13 @@
|
||||
-- Arguments
|
||||
-- util: API for uncategorized utility methods
|
||||
local util,skin = ...
|
||||
local map_data,util,skin = ...
|
||||
|
||||
local biome_lookup = {}
|
||||
local biome_ids = {}
|
||||
local fallback_biome_lookup = {}
|
||||
local biomes_ready = false
|
||||
local ready_callbacks = {}
|
||||
local biome_id_to_cartographer_id = {}
|
||||
|
||||
local function match_biome_metrics (biome, height, heat, humidity)
|
||||
return (not height or not biome.min_height or height >= biome.min_height)
|
||||
@ -14,6 +18,33 @@ local function match_biome_metrics (biome, height, heat, humidity)
|
||||
and (not humidity or not biome.max_humidity or humidity <= biome.max_humidity)
|
||||
end
|
||||
|
||||
minetest.after(0, function()
|
||||
if map_data.api_version < 2 then
|
||||
for k,_ in pairs(minetest.registered_biomes) do
|
||||
local biome_id = minetest.get_biome_id(k)
|
||||
map_data.biomes[biome_id] = k
|
||||
biome_ids[k] = biome_id
|
||||
biome_id_to_cartographer_id[biome_id] = biome_id
|
||||
end
|
||||
else
|
||||
for k,v in ipairs(map_data.biomes) do
|
||||
biome_ids[v] = k
|
||||
end
|
||||
for k,_ in pairs(minetest.registered_biomes) do
|
||||
if not biome_ids[k] then
|
||||
table.insert(map_data.biomes, k)
|
||||
biome_ids[k] = #map_data.biomes
|
||||
biome_id_to_cartographer_id[minetest.get_biome_id(k)] = #map_data.biomes
|
||||
else
|
||||
biome_id_to_cartographer_id[minetest.get_biome_id(k)] = biome_ids[k]
|
||||
end
|
||||
end
|
||||
end
|
||||
for _,cb in ipairs(ready_callbacks) do
|
||||
cb()
|
||||
end
|
||||
end)
|
||||
|
||||
-- Contains functions for registering and getting biome-related mapping information
|
||||
return {
|
||||
-- Register a biome with textures to display. Takes arguments as a table.
|
||||
@ -50,6 +81,33 @@ return {
|
||||
table.insert(fallback_biome_lookup, table.copy(args))
|
||||
end,
|
||||
|
||||
-- Convert a minetest biome id (temporary) into a cartography biome id (permanent)
|
||||
--
|
||||
-- id: The biome id to convert
|
||||
--
|
||||
-- Returns the biome's permamnent id, or 0 if not registered
|
||||
convert_biome_id = function(id)
|
||||
return biome_id_to_cartographer_id[id] or 0
|
||||
end,
|
||||
|
||||
-- Get the permanent id of a biome from its name
|
||||
--
|
||||
-- name: A string containing the biome name
|
||||
--
|
||||
-- Returns the biome's permamnent id, or 0 if not registered
|
||||
get_biome_id = function(name)
|
||||
return biome_ids[name] or 0
|
||||
end,
|
||||
|
||||
-- Get the name of a biome from its permanent id
|
||||
--
|
||||
-- id: The biome id
|
||||
--
|
||||
-- Returns the name of the biome, or "" if not registered
|
||||
get_biome_name = function(id)
|
||||
return map_data.biomes[id] or ""
|
||||
end,
|
||||
|
||||
-- Get the texture name (minus index/extension) for the given biome, height, and detail level.
|
||||
--
|
||||
-- name: A string containing the biome name
|
||||
@ -60,7 +118,7 @@ return {
|
||||
--
|
||||
-- Always returns a string with a texture name, if the biome is unregistered it will fallback to other options
|
||||
get_texture = function (name, height, heat, humidity, detail)
|
||||
for _,biome in ipairs(biome_lookup) do
|
||||
for _,biome in pairs(biome_lookup) do
|
||||
if biome.name == name and match_biome_metrics (biome, height, heat, humidity) then
|
||||
return util.get_clamped(biome.textures, detail)
|
||||
end
|
||||
@ -76,4 +134,17 @@ return {
|
||||
-- If we don't have any registered defaults, fallback to a texture
|
||||
return util.get_clamped(skin.default_biome_textures, detail)
|
||||
end,
|
||||
|
||||
-- Is this API ready, or still initializing?
|
||||
is_ready = function()
|
||||
return biomes_ready
|
||||
end,
|
||||
|
||||
on_ready = function(cb)
|
||||
if biomes_ready then
|
||||
cb()
|
||||
else
|
||||
table.insert(ready_callbacks, cb)
|
||||
end
|
||||
end,
|
||||
}
|
||||
|
9
init.lua
9
init.lua
@ -10,15 +10,15 @@ local settings = {
|
||||
};
|
||||
|
||||
-- Includes
|
||||
local map_data = loadfile(modpath .. "/storage.lua") (settings);
|
||||
local map_data,private_storage = loadfile(modpath .. "/storage.lua") (settings);
|
||||
local chunk = loadfile(modpath .. "/chunk_api.lua") ();
|
||||
local gui = loadfile(modpath .. "/formspec.lua") ();
|
||||
local skin = loadfile(modpath .. "/skin_api.lua") ();
|
||||
local util = loadfile(modpath .. "/util.lua") ();
|
||||
local audio = loadfile(modpath .. "/audio.lua") ();
|
||||
local biomes = loadfile(modpath .. "/biome_api.lua") (util, skin);
|
||||
local biomes = loadfile(modpath .. "/biome_api.lua") (map_data, util, skin);
|
||||
local markers = loadfile(modpath .. "/marker_api.lua") ();
|
||||
local scanner = loadfile(modpath .. "/scanner.lua") (map_data, chunk, settings);
|
||||
local scanner = loadfile(modpath .. "/scanner.lua") (map_data, chunk, settings, biomes);
|
||||
local maps = loadfile(modpath .. "/map_api.lua") (map_data, chunk);
|
||||
local materials = loadfile(modpath .. "/material_api.lua") ();
|
||||
local map_formspec = loadfile(modpath .. "/map_formspec.lua") (map_data, gui, skin, util, biomes, markers);
|
||||
@ -44,3 +44,6 @@ cartographer = {
|
||||
-- scanner.lua: Exposes functions for queuing and performing terrain scans
|
||||
scanner = scanner,
|
||||
}
|
||||
|
||||
-- If the API is out of date, update it now
|
||||
private_storage.migrate_data(map_data.api_version, cartographer)
|
||||
|
@ -82,7 +82,7 @@ local function generate_map(x, y, w, h, player_x, player_y, detail, map_scale, h
|
||||
image = get_variant(unknown_tex, i, j, noise),
|
||||
};
|
||||
else
|
||||
local name = minetest.get_biome_name(column[world_j].biome)
|
||||
local name = biomes.get_biome_name(column[world_j].biome)
|
||||
local height = column[world_j].height
|
||||
local heat = column[world_j].heat
|
||||
local humidity = column[world_j].humidity
|
||||
|
14
scanner.lua
14
scanner.lua
@ -2,7 +2,7 @@
|
||||
-- map_data: The cartographer map data table
|
||||
-- chunk: The chunk coordinate conversion API
|
||||
-- settings: The mod settings
|
||||
local map_data, chunk, settings = ...;
|
||||
local map_data, chunk, settings, biome_api = ...;
|
||||
|
||||
local scan_queue = {};
|
||||
|
||||
@ -51,8 +51,8 @@ end
|
||||
--
|
||||
-- Returns the biome, height, heat, and humidity of the scanned region
|
||||
local function get_mapgen_biome(min, max, mmin, mmax)
|
||||
local UNDERGROUND = minetest.get_biome_id("underground");
|
||||
local DEFAULT = minetest.get_biome_id("default");
|
||||
local UNDERGROUND = biome_api.get_biome_id("underground");
|
||||
local DEFAULT = biome_api.get_biome_id("default");
|
||||
|
||||
local biomes = minetest.get_mapgen_object("biomemap");
|
||||
local heights = minetest.get_mapgen_object("heightmap");
|
||||
@ -75,7 +75,7 @@ local function get_mapgen_biome(min, max, mmin, mmax)
|
||||
|
||||
for i = startx,startx + xx,1 do
|
||||
for k = startz,startz + zz,1 do
|
||||
local b = biomes[i + (k * (xxx + 1))];
|
||||
local b = biome_api.convert_biome_id(biomes[i + (k * (xxx + 1))])
|
||||
if b ~= nil and b ~= UNDERGROUND and b ~= DEFAULT then
|
||||
scan_biomes[b] = (scan_biomes[b] or 0) + 1;
|
||||
scan_heights[b] = (scan_heights[b] or 0) + heights[i + (k * (xxx + 1))];
|
||||
@ -115,8 +115,8 @@ end
|
||||
--
|
||||
-- Returns the biome, height, heat, and humidity of the scanned region
|
||||
local function get_biome(min, max)
|
||||
local UNDERGROUND = minetest.get_biome_id("underground");
|
||||
local DEFAULT = minetest.get_biome_id("default");
|
||||
local UNDERGROUND = biome_api.get_biome_id("underground");
|
||||
local DEFAULT = biome_api.get_biome_id("default");
|
||||
local WATER_SOURCE = minetest.registered_aliases["mapgen_water_source"];
|
||||
|
||||
local scan_biomes = {};
|
||||
@ -130,7 +130,7 @@ local function get_biome(min, max)
|
||||
for k = min.z,max.z,1 do
|
||||
local pos = { x=i, y=j, z=k };
|
||||
local biome_data = minetest.get_biome_data(pos)
|
||||
local b = biome_data.biome
|
||||
local b = biome_api.convert_biome_id(biome_data.biome)
|
||||
local node = minetest.get_node(pos).name;
|
||||
if b ~= nil and b ~= UNDERGROUND and b ~= DEFAULT and node ~= "air" and node ~= WATER_SOURCE then
|
||||
pos.y = pos.y + 1;
|
||||
|
66
storage.lua
66
storage.lua
@ -1,9 +1,12 @@
|
||||
-- Arguments
|
||||
-- settings: The mod settings
|
||||
local settings = ...;
|
||||
local settings = ...
|
||||
|
||||
-- The current API version
|
||||
local MAX_API_VERSION = 2
|
||||
|
||||
-- Storage and saving
|
||||
local mod_storage = minetest.get_mod_storage();
|
||||
local mod_storage = minetest.get_mod_storage()
|
||||
local map_data = {
|
||||
-- Scanned map data
|
||||
generated = minetest.deserialize(mod_storage:get_string("map")) or {},
|
||||
@ -11,26 +14,69 @@ local map_data = {
|
||||
-- Maps
|
||||
maps = minetest.deserialize(mod_storage:get_string("maps")) or {},
|
||||
|
||||
biomes = minetest.deserialize(mod_storage:get_string("biomes")) or {},
|
||||
|
||||
-- The next id
|
||||
next_map_id = mod_storage:get_int("next_map_id"),
|
||||
|
||||
-- The version of the map api
|
||||
api_version = mod_storage:get_int("api_version"),
|
||||
};
|
||||
}
|
||||
|
||||
-- Is this API ready, or still initializing?
|
||||
--
|
||||
-- self: The map_data instance
|
||||
function map_data.is_ready(self)
|
||||
return self.api_version == MAX_API_VERSION
|
||||
end
|
||||
|
||||
if map_data.next_map_id == 0 then
|
||||
map_data.next_map_id = 1;
|
||||
map_data.next_map_id = 1
|
||||
end
|
||||
|
||||
if map_data.api_version == 0 then
|
||||
map_data.api_version = 1;
|
||||
map_data.api_version = 1
|
||||
end
|
||||
|
||||
assert(map_data.api_version <= MAX_API_VERSION)
|
||||
|
||||
local private_storage = {
|
||||
migrations = { },
|
||||
}
|
||||
|
||||
-- Update the API version, performing any necessary data migrations
|
||||
function private_storage.migrate_data(version, api)
|
||||
if version <= MAX_API_VERSION then
|
||||
map_data.api_version = version
|
||||
|
||||
for i=version+1,MAX_API_VERSION do
|
||||
if private_storage.migrations[i] then
|
||||
private_storage.migrations[i](api)
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
api.is_ready = true
|
||||
end
|
||||
|
||||
-- API version 2: Generate biomes from existing IDs
|
||||
table.insert(private_storage.migrations, 2, function(api)
|
||||
-- Migration depends on async biome init, so we wait for that then increment the version
|
||||
api.biomes.on_ready(function()
|
||||
private_storage.migrate_data(2, api)
|
||||
end)
|
||||
end)
|
||||
|
||||
local function save()
|
||||
mod_storage:set_string("maps", minetest.serialize(map_data.maps));
|
||||
mod_storage:set_int("next_map_id", map_data.next_map_id);
|
||||
mod_storage:set_string("map", minetest.serialize(map_data.generated));
|
||||
mod_storage:set_string("api_version", minetest.serialize(map_data.api_version));
|
||||
if not map_data:is_ready() then
|
||||
return
|
||||
end
|
||||
mod_storage:set_string("biomes", minetest.serialize(map_data.biomes))
|
||||
mod_storage:set_string("maps", minetest.serialize(map_data.maps))
|
||||
mod_storage:set_int("next_map_id", map_data.next_map_id)
|
||||
mod_storage:set_string("map", minetest.serialize(map_data.generated))
|
||||
mod_storage:set_int("api_version", map_data.api_version)
|
||||
end
|
||||
minetest.register_on_shutdown(save);
|
||||
minetest.register_on_leaveplayer(save);
|
||||
@ -43,4 +89,4 @@ if settings.autosave_freq ~= 0 then
|
||||
minetest.after(settings.autosave_freq, periodic_save);
|
||||
end
|
||||
|
||||
return map_data;
|
||||
return map_data,private_storage
|
||||
|
Loading…
x
Reference in New Issue
Block a user