+local function make_wrap_deregistration(reg_fn, clear_fn, list)
+ local unregister = function (key)
+ if type(key) ~= "string" then
+ error("key is not a string", 2)
+ end
+ if not list[key] then
+ error("Attempt to unregister non-existent element - '" .. key .. "'", 2)
+ end
+ local temporary_list = table.copy(list)
+ clear_fn()
+ for k,v in pairs(temporary_list) do
+ if key ~= k then
+ reg_fn(v)
+ end
+ end
+ end
+ return unregister
+end
+
+core.registered_on_player_hpchanges = { modifiers = { }, loggers = { } }
+
+function core.registered_on_player_hpchange(player, hp_change, reason)
+ local last
+ for i = #core.registered_on_player_hpchanges.modifiers, 1, -1 do
+ local func = core.registered_on_player_hpchanges.modifiers[i]
+ hp_change, last = func(player, hp_change, reason)
+ if type(hp_change) ~= "number" then
+ local debuginfo = debug.getinfo(func)
+ error("The register_on_hp_changes function has to return a number at " ..
+ debuginfo.short_src .. " line " .. debuginfo.linedefined)
+ end
+ if last then
+ break
+ end
+ end
+ for i, func in ipairs(core.registered_on_player_hpchanges.loggers) do
+ func(player, hp_change, reason)
+ end
+ return hp_change
+end
+
+function core.register_on_player_hpchange(func, modifier)
+ if modifier then
+ core.registered_on_player_hpchanges.modifiers[#core.registered_on_player_hpchanges.modifiers + 1] = func
+ else
+ core.registered_on_player_hpchanges.loggers[#core.registered_on_player_hpchanges.loggers + 1] = func
+ end
+ core.callback_origins[func] = {
+ mod = core.get_current_modname() or "??",
+ name = debug.getinfo(1, "n").name or "??"
+ }
+end
+
+core.registered_biomes = make_registration_wrap("register_biome", "clear_registered_biomes")
+core.registered_ores = make_registration_wrap("register_ore", "clear_registered_ores")
+core.registered_decorations = make_registration_wrap("register_decoration", "clear_registered_decorations")