diff --git a/builtin/game/register.lua b/builtin/game/register.lua index 4ecf6ec71..3e11c7e20 100644 --- a/builtin/game/register.lua +++ b/builtin/game/register.lua @@ -442,6 +442,11 @@ local function make_registration_wrap(reg_fn_name, clear_fn_name) local orig_reg_fn = core[reg_fn_name] core[reg_fn_name] = function(def) + if def.name ~= nil then + if list[def.name] then + error("Attempt to register already registered element - '" .. def.name .. "'", 2) + end + end local retval = orig_reg_fn(def) if retval ~= nil then if def.name ~= nil then @@ -464,7 +469,28 @@ local function make_registration_wrap(reg_fn_name, clear_fn_name) return list end -local function make_wrap_deregistration(reg_fn, clear_fn, list) +local function make_wrap_override_deregistration(reg_fn, clear_fn, list) + local override = function (key, redef) + if type(key) ~= "string" then + error("key is not a string", 2) + end + local def = list[key] + if not def then + error("Attempt to override non-existent element - '" .. key .. "'", 2) + end + for k, v in pairs(redef) do + rawset(def, k, v) + end + local temporary_list = table.copy(list) + clear_fn() + for k,v in pairs(temporary_list) do + if key ~= k then + reg_fn(v) + else + reg_fn(def) + end + end + end local unregister = function (key) if type(key) ~= "string" then error("key is not a string", 2) @@ -480,7 +506,17 @@ local function make_wrap_deregistration(reg_fn, clear_fn, list) end end end - return unregister + return override, unregister +end +local function make_wrap_reregistration(reg_fn, clear_fn, list) + local reregistration = function () + local temporary_list = table.copy(list) + clear_fn() + for _,v in pairs(temporary_list) do + reg_fn(v) + end + end + return reregistration end core.registered_on_player_hpchanges = { modifiers = { }, loggers = { } } @@ -521,9 +557,19 @@ core.registered_biomes = make_registration_wrap("register_biome", "cle core.registered_ores = make_registration_wrap("register_ore", "clear_registered_ores") core.registered_decorations = make_registration_wrap("register_decoration", "clear_registered_decorations") -core.unregister_biome = make_wrap_deregistration(core.register_biome, +core.override_biome, core.unregister_biome = make_wrap_override_deregistration(core.register_biome, core.clear_registered_biomes, core.registered_biomes) +core.override_ore, core.unregister_ore = make_wrap_override_deregistration(core.register_ore, + core.clear_registered_ores, core.registered_ores) +core.reregister_ores = make_wrap_reregistration(core.register_ore, + core.clear_registered_ores, core.registered_ores) + +core.override_decoration, core.unregister_decoration = make_wrap_override_deregistration(core.register_decoration, + core.clear_registered_decorations, core.registered_decorations) +core.reregister_decorations = make_wrap_reregistration(core.register_decoration, + core.clear_registered_decorations, core.registered_decorations) + local make_registration = builtin_shared.make_registration local make_registration_reverse = builtin_shared.make_registration_reverse diff --git a/doc/lua_api.md b/doc/lua_api.md index 7461127c2..9491d0f0f 100644 --- a/doc/lua_api.md +++ b/doc/lua_api.md @@ -5466,21 +5466,44 @@ Call these functions only at load time! * Returns an integer object handle uniquely identifying the registered ore on success. * The order of ore registrations determines the order of ore generation. +* `minetest.override_ore(name, ore definition)` + * Override existing ore. +* `minetest.unregister_ore(name)` + * Unregisters the decoration from the engine, and deletes the entry with key + `name` from `minetest.registered_decorations`. +* `minetest.reregister_ores()` + * Clears all ores currently registered and register them again. + * Can be used after overriding/unregistering biome/bimes. * `minetest.register_biome(biome definition)` * Returns an integer object handle uniquely identifying the registered biome on success. To get the biome ID, use `minetest.get_biome_id`. +* `minetest.override_biome(name, redefinition)` + * Override existing biome. + * Warning: This alters the biome to biome ID correspondences, so any + decorations or ores using the 'biomes' field must afterwards be cleared + and re-registered. Functions `minetest.reregister_decorations` and + `minetest.reregister_ores` can be used for it. * `minetest.unregister_biome(name)` * Unregisters the biome from the engine, and deletes the entry with key `name` from `minetest.registered_biomes`. * Warning: This alters the biome to biome ID correspondences, so any decorations or ores using the 'biomes' field must afterwards be cleared - and re-registered. + and re-registered. Functions `minetest.reregister_decorations` and + `minetest.reregister_ores` can be used for it. * `minetest.register_decoration(decoration definition)` * Returns an integer object handle uniquely identifying the registered decoration on success. To get the decoration ID, use `minetest.get_decoration_id`. * The order of decoration registrations determines the order of decoration generation. +* `minetest.override_decoration(name, decoration definition)` + * Override existing decoration. +* `minetest.unregister_decoration(name)` + * Unregisters the decoration from the engine, and deletes the entry with key + `name` from `minetest.registered_decorations`. +* `minetest.reregister_decorations()` + * Clears all decorations currently registered and register them again. + * Can be used after overriding/unregistering biome/bimes. * `minetest.register_schematic(schematic definition)` * Returns an integer object handle uniquely identifying the registered schematic on success. @@ -5493,7 +5516,8 @@ Call these functions only at load time! * Clears all biomes currently registered. * Warning: Clearing and re-registering biomes alters the biome to biome ID correspondences, so any decorations or ores using the 'biomes' field must - afterwards be cleared and re-registered. + afterwards be cleared and re-registered. Functions `minetest.reregister_decorations` and + `minetest.reregister_ores` can be used for it. * `minetest.clear_registered_decorations()` * Clears all decorations currently registered. * `minetest.clear_registered_ores()` @@ -9566,6 +9590,10 @@ See [Ores] section above for essential information. ```lua { + name = "default:iron_ore_1", + -- Optional field name. This is used as key in minetest.registered_ores table. + -- Nameed ores can be overriden by minetest.override_ore function. + ore_type = "", -- Supported: "scatter", "sheet", "puff", "blob", "vein", "stratum" @@ -9765,6 +9793,10 @@ See [Decoration types]. Used by `minetest.register_decoration`. ```lua { + name = "default:grass_decoration", + -- Optional field name. Is used as key in minetest.registered_decorations table. + -- Named decorations can be overriden by minetest.override_decoration function. + deco_type = "simple", -- Type. "simple" or "schematic" supported @@ -9928,7 +9960,7 @@ Chat command definition Used by `minetest.register_chatcommand`. Specifies the function to be called and the privileges required when a player -issues the command. A help message that is the concatenation of the params and +issues the command. A help message tdecorations the concatenation of the params and description fields is shown when the "/help" chatcommand is issued. ```lua diff --git a/games/devtest/mods/basenodes/init.lua b/games/devtest/mods/basenodes/init.lua index 249c7fbd8..2953402cb 100644 --- a/games/devtest/mods/basenodes/init.lua +++ b/games/devtest/mods/basenodes/init.lua @@ -20,6 +20,12 @@ minetest.register_node("basenodes:desert_stone", { groups = {cracky=3}, }) +minetest.register_node("basenodes:test_ore", { + description = "Test ore in stone", + tiles = {"default_stone.png^basenodes_test_ore.png"}, + groups = {cracky=3}, +}) + minetest.register_node("basenodes:dirt_with_grass", { description = "Dirt with Grass", tiles ={"default_grass.png", diff --git a/games/devtest/mods/basenodes/textures/basenodes_test_ore.png b/games/devtest/mods/basenodes/textures/basenodes_test_ore.png new file mode 100644 index 000000000..1de3a9ada Binary files /dev/null and b/games/devtest/mods/basenodes/textures/basenodes_test_ore.png differ diff --git a/games/devtest/mods/mapgen/init.lua b/games/devtest/mods/mapgen/init.lua index a5f9128fb..bb122a90f 100644 --- a/games/devtest/mods/mapgen/init.lua +++ b/games/devtest/mods/mapgen/init.lua @@ -53,8 +53,10 @@ end minetest.clear_registered_biomes() minetest.clear_registered_decorations() +minetest.clear_registered_ores() if minetest.settings:get_bool("devtest_register_biomes", true) then + minetest.log("action", "Devtest: register biomes") minetest.register_biome({ name = "mapgen:grassland", node_top = "basenodes:dirt_with_grass", @@ -101,4 +103,85 @@ if minetest.settings:get_bool("devtest_register_biomes", true) then heat_point = 50, humidity_point = 50, }) + + minetest.register_biome({ + name = "mapgen:desert", + node_top = "basenodes:desert_stone", -- error, to try override of it, to fix it + depth_top = 1, + node_filler = "basenodes:desert_sand", + depth_filler = 1, + node_riverbed = "basenodes:sand", + depth_riverbed = 2, + node_dungeon = "basenodes:cobble", + node_dungeon_alt = "basenodes:mossycobble", + node_dungeon_stair = "stairs:stair_cobble", + y_max = 31000, + y_min = 4, + heat_point = 60, + humidity_point = 40, + }) +end + +if minetest.settings:get_bool("devtest_override_biomes", true) then + minetest.log("action", "Devtest: override biomes") + minetest.override_biome("mapgen:desert", { + node_top = "basenodes:desert_sand" + }) +end + +if minetest.settings:get_bool("devtest_register_decorations", true) then + minetest.log("action", "Devtest: register decorations") + minetest.register_decoration({ + name = "mapgen:junglegrass", + deco_type = "simple", + place_on = "basenodes:dirt_with_grass", + sidelen = 16, + noise_params = { + offset = 0, + scale = 0.007, + spread = {x = 100, y = 100, z = 100}, + seed = 329, + octaves = 3, + persist = 0.6 + }, + y_max = 30, + y_min = 1, + biomes = {"mapgen:grassland"}, + decoration = "basenodes:leaves", + }) +end + +if minetest.settings:get_bool("devtest_override_decorations", true) then + minetest.log("action", "Devtest: override decorations") + minetest.override_decoration("mapgen:junglegrass", { + decoration = "basenodes:junglegrass" + }) + + minetest.reregister_decorations() +end + +if minetest.settings:get_bool("devtest_register_ores", true) then + minetest.log("action", "Devtest: register ores") + minetest.register_ore({ + name = "mapgen:test_ore", + ore_type = "scatter", + ore = "basenodes:desert_stone", + wherein = "basenodes:stone", + clust_scarcity = 8 * 8 * 8, + clust_num_ores = 9, + clust_size = 3, + y_max = 31000, + y_min = -31000, + biomes = {"mapgen:grassland_under"} + }) +end + +if minetest.settings:get_bool("devtest_override_ores", true) then + minetest.log("action", "Devtest: override ores") + minetest.override_ore("mapgen:test_ore", { + ore = "basenodes:test_ore", + biomes = {"mapgen:grassland_under", "mapgen:grassland"}, + }) + + minetest.reregister_ores() end diff --git a/games/devtest/settingtypes.txt b/games/devtest/settingtypes.txt index c4365643e..ffa627fb7 100644 --- a/games/devtest/settingtypes.txt +++ b/games/devtest/settingtypes.txt @@ -30,3 +30,18 @@ devtest_dungeon_mossycobble (Generate mossy cobblestone) bool false # If enabled, some very basic biomes will be registered. devtest_register_biomes (Register biomes) bool true + +# If enabled, minetest.override_biome function will be tested over some of registered biome/biomes. +devtest_overide_biomes (Override biomes) bool true + +# If enabled, some very basic decorations will be registered. +devtest_register_decorations (Register decorations) bool true + +# If enabled, minetest.override_decoration function will be tested over some of registered decoration/decorations. +devtest_overide_decorations (Override biomes) bool true + +# If enabled, some very basic ores will be registered. +devtest_register_ores (Register ores) bool true + +# If enabled, minetest.override_ore function will be tested over some of registered ore/ores. +devtest_overide_ores (Override ores) bool true