Compare commits

...

43 Commits

Author SHA1 Message Date
teknomunk
ec0929fc69 Start GUI 2024-06-28 11:53:57 +02:00
teknomunk
9298cad435 Fix typo in variable name 2024-06-28 11:53:57 +02:00
teknomunk
b77aea899c Implement showDeathMessages gamerule 2024-06-28 11:53:57 +02:00
teknomunk
ce3a7aa0da Implement respawnBlocksExplode gamerule 2024-06-28 11:53:57 +02:00
teknomunk
96eac616b0 Implement doMobLoot gamerule 2024-06-28 11:53:57 +02:00
teknomunk
e4ebd3c641 Add fireDamage game rule (fallDamage and drowningDamage don't work in mcl_damage) 2024-06-28 11:53:57 +02:00
teknomunk
97f3919c94 Add additional gamerules for damage types 2024-06-28 11:53:57 +02:00
teknomunk
53cbeb2cef Fix typo 2024-06-28 11:53:57 +02:00
teknomunk
3e3104547d Add gamerule naturalRegeneration and make mcl_health_regen_delay a tunable setting 2024-06-28 11:53:57 +02:00
teknomunk
f620e5f031 Change handling of mcl_showAdvancementMessages 2024-06-28 11:53:57 +02:00
teknomunk
36c2e1334a Nether portal delay settings 2024-06-28 11:53:57 +02:00
teknomunk
4a950aea75 Add settings file 2024-06-28 11:53:57 +02:00
teknomunk
693c68e1b0 Implement doVinesSpread 2024-06-28 11:53:57 +02:00
teknomunk
ffc11faa24 Add gamerule keepInventory and migrate existing setting value from mcl_keepInvetory 2024-06-28 11:53:57 +02:00
teknomunk
f7a7990f1c Add setting for damage_enabled 2024-06-28 11:53:57 +02:00
teknomunk
d4286ff535 Implement doDaylightCycle, add on_change hook for tunables and make sure they are not called when loaded 2024-06-28 11:53:57 +02:00
teknomunk
f0d9c5c83c Remove debug print(), add game rules maxEntityCramming, snowAccumulationHeight 2024-06-28 11:53:57 +02:00
teknomunk
25e4aa5983 Fix default value handling during set (allows bool settings to be set to false), add game rules: doMobSpawning, disableRaids, doWeatherCycle, doFireTick 2024-06-28 11:53:57 +02:00
teknomunk
d02ddae55b Change API so most parameters are in a definition table, add /gamerule chatcommand, implement gamerule announceAdvancements 2024-06-28 11:53:57 +02:00
teknomunk
c98f2e63ff Make awards use the notification delay setting 2024-06-28 11:53:57 +02:00
teknomunk
9737f97c57 Finish initial implementation of setting tuning with get/set commands 2024-06-28 11:53:57 +02:00
teknomunk
21e3af0ecf Start implementing dynamic rules/tuning 2024-06-28 11:53:57 +02:00
the-real-herowl
026ea5940c Merge pull request 'release/0.87.2' (#4457) from release/0.87.2 into master
Reviewed-on: https://git.minetest.land/VoxeLibre/VoxeLibre/pulls/4457
2024-06-24 03:43:09 +02:00
the-real-herowl
be9fece0d3 Post-hotfix reset version 0.88.0-SNAPSHOT 2024-06-24 03:41:37 +02:00
the-real-herowl
27f8a008c3 Update release notes for hotfix v0.87.2 2024-06-24 03:40:15 +02:00
the-real-herowl
8bbceddbc2 Updated release credits and set version for hotfix v0.87.2 2024-06-24 03:28:19 +02:00
the-real-herowl
6e70c760d6 Fix some formspecs on mobile (#4456)
This should allow renaming items on the anvil when using mobile. This also may improve mobile craftguide experience.

Reviewed-on: https://git.minetest.land/VoxeLibre/VoxeLibre/pulls/4456
Co-authored-by: the-real-herowl <wiktor_t-i@proton.me>
Co-committed-by: the-real-herowl <wiktor_t-i@proton.me>
2024-06-24 03:26:02 +02:00
the-real-herowl
53802b270d Merge pull request 'Prevent mob conversion code from crashing' (#4421) from teknomunk/MineClone2:fix-conversion-crash into master
Reviewed-on: https://git.minetest.land/VoxeLibre/VoxeLibre/pulls/4421
Reviewed-by: the-real-herowl <the-real-herowl@noreply.git.minetest.land>
2024-06-24 03:07:19 +02:00
teknomunk
3928e12634 Fix two more crashes, stray space 2024-06-24 03:06:26 +02:00
teknomunk
304550d90c Fix parameter name 2024-06-24 03:06:26 +02:00
teknomunk
0a2336ad82 Handle conversion of mobs that were incorrectly converted 2024-06-24 03:06:26 +02:00
teknomunk
75a767a0ab Mob spawner conversion 2024-06-24 03:06:26 +02:00
teknomunk
7e0afd7e21 Remove debug logging 2024-06-24 03:06:26 +02:00
teknomunk
15fa925aae More fields to strip 2024-06-24 03:06:26 +02:00
teknomunk
4935f5fdda Add debug logging 2024-06-24 03:06:26 +02:00
teknomunk
41032ec999 Use correct variable name 2024-06-24 03:06:26 +02:00
teknomunk
d64ee18f75 Strip some fields from the mob's staticdata on conversion 2024-06-24 03:06:26 +02:00
teknomunk
1942384fe5 Move object remove after position check 2024-06-24 03:06:26 +02:00
teknomunk
9b50dd6565 Update to use new_object instead of obj 2024-06-24 03:06:26 +02:00
teknomunk
a88951ac6a More safety checks 2024-06-24 03:06:26 +02:00
teknomunk
bc343769ee Add guard to prevent crash when converting old mobs and the minetest fails to create the new entity 2024-06-24 03:06:26 +02:00
seventeenthShulker
8aa65f85f2 Fix extra 'Stair' in Polished Blackstone Brick nodes (#4450)
Some of the longest block names were erroneous. Farewell, Polished Blackstone Brick Stair Stairs and Polished Blackstone Brick Stair Slab.

Reviewed-on: https://git.minetest.land/VoxeLibre/VoxeLibre/pulls/4450
Reviewed-by: the-real-herowl <the-real-herowl@noreply.git.minetest.land>
Co-authored-by: seventeenthShulker <c545d588-7ff2-49b9-b537-0b3f769083ad@anonaddy.me>
Co-committed-by: seventeenthShulker <c545d588-7ff2-49b9-b537-0b3f769083ad@anonaddy.me>
2024-06-23 23:40:36 +02:00
qoheniac
e27e70a91b fix wrong name for diorite stairs (#4359)
Reviewed-on: https://git.minetest.land/VoxeLibre/VoxeLibre/pulls/4359
Reviewed-by: teknomunk <teknomunk@protonmail.com>
Co-authored-by: qoheniac <qoheniac@noreply.git.minetest.land>
Co-committed-by: qoheniac <qoheniac@noreply.git.minetest.land>
2024-06-23 23:39:09 +02:00
51 changed files with 505 additions and 95 deletions

@ -20,10 +20,8 @@
* epCode
* chmodsayshello
* MrRar
* FossFanatic
* SmokeyDope
* Faerraven / Michieal
* Codiac
* rudzik8
* teknomunk
@ -36,6 +34,8 @@
* NO11
* SumianVoice
* PrairieWind
* FossFanatic
* Codiac
## Contributors
* RandomLegoBrick
@ -140,6 +140,7 @@
* SOS-Games
* Bram
* qoheniac
* WillConker
## Music
* Jordach for the jukebox music compilation from Big Freaking Dig

@ -34,7 +34,18 @@ mcl_damage = {
}
}
local damage_enabled = minetest.settings:get_bool("enabled_damage",true)
local damage_enabled = vl_tuning.setting("damage_enabled", "bool",{
default = minetest.settings:get_bool("enabled_damage",true)
})
local fall_damage_enabled = vl_tuning.setting("gamerule:fallDamage", "bool", {
default = true
})
local drowning_damage_enabled = vl_tuning.setting("gamerule:drowningDamage", "bool", {
default = true
})
local fire_damage_enabled = vl_tuning.setting("gamerule:fireDamage", "bool", {
default = true
})
function mcl_damage.register_modifier(func, priority)
table.insert(mcl_damage.modifiers, {func = func, priority = priority or 0})
@ -142,7 +153,7 @@ function mcl_damage.register_type(name, def)
end
minetest.register_on_player_hpchange(function(player, hp_change, mt_reason)
if not damage_enabled then return 0 end
if not damage_enabled[1] then return 0 end
if hp_change < 0 then
if player:get_hp() <= 0 then
return 0
@ -153,10 +164,18 @@ minetest.register_on_player_hpchange(function(player, hp_change, mt_reason)
end, true)
minetest.register_on_player_hpchange(function(player, hp_change, mt_reason)
if not damage_enabled then return 0 end
-- Check if damage is enabled
if not damage_enabled[1] then return 0 end
local mcl_reason = mcl_damage.from_mt(mt_reason)
if not fire_damage_enabled[1] and mcl_reason.type == "fire" then return 0 end
--if not drowning_damage_enabled[1] and mcl_reason.type == "drown" then return 0 end
--if not fall_damage_enabled[1] and mcl_reason.type == "fall" then return 0 end
--minetest.log("action", "mcl_reason = "..dump(mcl_reason)..", mt_reason = "..dump(mt_reason))
if player:get_hp() > 0 then
if hp_change < 0 then
mcl_damage.run_damage_callbacks(player, -hp_change, mcl_damage.from_mt(mt_reason))
mcl_damage.run_damage_callbacks(player, -hp_change, mcl_reason)
end
end
end, false)

@ -1,3 +1,4 @@
name = mcl_damage
author = Fleckenstein
description = Minecraft-like damage reason system
depends = vl_tuning

@ -0,0 +1,48 @@
local modname = "vl_tuning"
local modpath = minetest.get_modpath(modname)
local S = minetest.get_translator(modname)
local F = function(f) return minetest.formspec_escape(S(f)) end
function vl_tuning.show_formspec(player_name, tab)
if not tab then tab = 1 end
local gamerules = {}
local settings = {}
for name,_ in pairs(vl_tuning.registered_settings) do
if name:sub(0,#"gamerule:") == "gamerule:" then
table.insert(gamerules, name)
else
table.insert(settings, name)
end
end
local formspec =
"formspec_version[4]"..
"size[25,15,true]"..
"tabheader[0,0;tab;"..
F("Game Rules")..","..
F("Settings")..
";"..tab..";false;false]"
minetest.show_formspec(player_name, "vl_tuning:settings", formspec)
end
minetest.register_on_player_receive_fields(function(player, formname, fields)
if formname ~= "vl_tuning:settings" then return end
minetest.log("action",dump({
player = player,
fields = fields,
formname = formname,
}))
if fields.quit then
return
end
vl_tuning.show_formspec(player:get_player_name(), fields.tab)
end)
minetest.register_chatcommand("settings",{
func = function(player_name, param)
dofile(modpath.."/gui.lua")
vl_tuning.show_formspec(player_name)
end
})

@ -0,0 +1,157 @@
local modname = minetest.get_current_modname()
local modpath = minetest.get_modpath(modname)
local S = minetest.get_translator(modname)
local storage = minetest.get_mod_storage()
local mod = {}
vl_tuning = mod
-- All registered tunable parameters
local tunables = {}
vl_tuning.registered_settings = tunables
-- Supported variable types
local tunable_types = {
bool = {
to_string = tostring,
from_string = function(value)
return (value == "true")
end
},
number = {
to_string = tostring,
from_string = tonumber,
},
string = {
to_string = function(v) return v end,
from_string = function(v) return v end,
},
}
-- Tunable metatable functions
local tunable_class = {}
function tunable_class:set(value, no_hook)
local self_type = self.type
if type(value) == "string" then
local new_value = self_type.from_string(value)
if new_value == nil then new_value = self.default end
self[1] = new_value
else
self[1] = value
end
minetest.log("action", "[vl_tuning] Set "..self.setting.." to "..dump(self[1]))
-- Call on_change hook
if not no_hook then
local hook = self.on_change
if hook then hook(self) end
end
-- Persist value
storage:set_string(self.setting,self_type.to_string(self[1]))
end
function tunable_class:get_string()
return self.type.to_string(self[1])
end
function mod.setting(setting, setting_type, def )
-- return the existing setting if it was previously registered. Don't update the definition
local tunable = tunables[setting]
if tunable then return tunable end
assert(setting_type)
assert(def)
-- Setup the tunable data
tunable = table.copy(def)
tunable.setting = setting
tunable.type = tunable_types[setting_type]
tunable[1] = tunable.default
setmetatable(tunable, {__index=tunable_class})
-- Load the setting value from mod storage
local setting_value = storage:get_string(setting)
if setting_value and setting_value ~= "" then
tunable:set(setting_value, true)
minetest.log("action", "[vl_tuning] Loading "..setting.." = "..dump(setting_value).." ("..dump(tunable[1])..")")
end
-- Add to the list of all available settings
tunables[setting] = tunable
-- Provide it so that the current value in [1] can be accessed without having to call into this API again
return tunable
end
minetest.register_chatcommand("set_setting", {
description = S("Admin tool to tune settings and game rules"),
params = S("<setting> <value>"),
privs = { debug = true },
func = function(name, params_raw)
-- Split apart the params
local params = {}
for str in string.gmatch(params_raw, "([^ ]+)") do
params[#params + 1] = str
end
if #params ~= 2 then
return false, S("Usage: /tune <setting> <value>")
end
local tunable = tunables[params[1]]
if not tunable then
return false, S("Setting @1 doesn't exist", params[1])
end
minetest.log("action", "[vl_tuning] "..name.." set ".. params[1] .." to "..params[2])
tunable:set(params[2])
return true
end
})
minetest.register_chatcommand("get_setting", {
description = S("Admin tool to view settings and game rules"),
params = S("<setting>"),
privs = { debug = true },
func = function(name, param)
local tunable = tunables[param]
if tunable then
return true, tunable:get_string()
else
return false, S("Setting @1 doesn't exist", param)
end
end
})
minetest.register_chatcommand("gamerule", {
description = S("Display or set customizable options"),
params = S("<rule> [<value>]"),
privs = { server = true },
func = function(name, params_raw)
-- Split apart the params
local params = {}
for str in string.gmatch(params_raw, "([^ ]+)") do
params[#params + 1] = str
end
if #params < 1 or #params > 2 then
return false, S("Usage: /gamerule <rule> [<value>]")
end
local tunable = tunables["gamerule:"..params[1]]
if not tunable then
return false, S("Game rule @1 doesn't exist", params[1])
end
local value = params[2]
if value then
minetest.log("action", "[vl_tuning] Setting game rule "..params[1].." to "..params[2])
tunable:set(params[2])
return true
else
return true, tunable:get_string()
end
end
})
dofile(modpath.."/settings.lua")
dofile(modpath.."/gui.lua")

@ -0,0 +1,3 @@
name = vl_tuning
author = teknomunk
description = Framework for dynamic tuning and game rules

@ -0,0 +1,12 @@
local modname = minetest.get_current_modname()
local S = minetest.get_translator(modname)
local mod = vl_tuning
mod.keep_inventory = vl_tuning.setting("gamerule:keepInventory", "bool", {
default = minetest.settings:get_bool("mcl_keepInventory", false),
})
mod.respawn_blocks_explode = vl_tuning.setting("gamerule:respawnBlocksExplode", "bool", {
description = S("Prevents beds/respawn anchors from exploding in other dimensions."),
default = true,
})

@ -150,6 +150,11 @@ function mob_class:mob_activate(staticdata, def, dtime)
local tmp = minetest.deserialize(staticdata)
if tmp then
-- Patch incorrectly converted mobs
if tmp.base_mesh ~= minetest.registered_entities[self.name].mesh then
mcl_mobs.strip_staticdata(tmp)
end
for _,stat in pairs(tmp) do
self[_] = stat
end

@ -342,13 +342,33 @@ function mcl_mobs.register_mob(name, def)
minetest.register_entity(name, setmetatable(final_def,mcl_mobs.mob_class_meta))
end -- END mcl_mobs.register_mob function
local STRIP_FIELDS = { "mesh", "base_size", "textures", "base_mesh", "base_texture" }
function mcl_mobs.strip_staticdata(unpacked_staticdata)
-- Strip select fields from the staticdata to prevent conversion issues
for i = 1,#STRIP_FIELDS do
unpacked_staticdata[STRIP_FIELDS[i]] = nil
end
end
function mcl_mobs.register_conversion(old_name, new_name)
minetest.register_entity(old_name, {
on_activate = function(self, staticdata, dtime)
local obj = minetest.add_entity(self.object:get_pos(), new_name, staticdata)
local hook = (obj:get_luaentity() or {})._on_after_convert
if hook then hook(obj) end
self.object:remove()
local unpacked_staticdata = minetest.deserialize(staticdata)
mcl_mobs.strip_staticdata(unpacked_staticdata)
staticdata = minetest.serialize(unpacked_staticdata)
local old_object = self.object
if not old_object then return end
local pos = old_object:get_pos()
if not pos then return end
old_object:remove()
local new_object = minetest.add_entity(pos, new_name, staticdata)
if not new_object then return end
local hook = (new_object:get_luaentity() or {})._on_after_convert
if hook then hook(new_object) end
end,
_convert_to = new_name,
})
@ -572,7 +592,12 @@ function mcl_mobs.register_egg(mob, desc, background_color, overlay_color, addeg
--minetest.log("min light: " .. mob_light_lvl[1])
--minetest.log("max light: " .. mob_light_lvl[2])
mcl_mobspawners.setup_spawner(pointed_thing.under, itemstack:get_name(), mob_light_lvl[1], mob_light_lvl[2])
-- Handle egg conversion
local mob_name = itemstack:get_name()
local convert_to = (minetest.registered_entities[mob_name] or {})._convert_to
if convert_to then mob_name = convert_to end
mcl_mobspawners.setup_spawner(pointed_thing.under, mob_name, mob_light_lvl[1], mob_light_lvl[2])
if not minetest.is_creative_enabled(name) then
itemstack:take_item()
end

@ -1,5 +1,5 @@
name = mcl_mobs
author = PilzAdam
description = Adds a mob API for mods to add animals or monsters, etc.
depends = mcl_particles, mcl_luck
depends = mcl_particles, mcl_luck, vl_tuning
optional_depends = mcl_weather, mcl_explosions, mcl_hunger, mcl_worlds, invisibility, lucky_block, cmi, doc_identifier, mcl_armor, mcl_portals, mcl_experience, mcl_sculk

@ -1,8 +1,18 @@
local modname = minetest.get_current_modname()
local S = minetest.get_translator(modname)
local math, vector, minetest, mcl_mobs = math, vector, minetest, mcl_mobs
local mob_class = mcl_mobs.mob_class
local validate_vector = mcl_util.validate_vector
local ENTITY_CRAMMING_MAX = 24
local gamerule_maxEntityCramming = vl_tuning.setting("gamerule:maxEntityCramming", "number", {
description = S("The maximum number of pushable entities a mob or player can push, before taking 6♥♥♥ entity cramming damage per half-second."),
default = 24,
})
local gamerule_doMobLoot = vl_tuning.setting("gamerule:doMobLoot", "bool", {
description = S("Whether mobs should drop items and experience orbs."),
default = true,
})
local CRAMMING_DAMAGE = 3
local DEATH_DELAY = 0.5
local DEFAULT_FALL_SPEED = -9.81*1.5
@ -472,6 +482,8 @@ function mob_class:check_for_death(cause, cmi_cause)
-- TODO other env damage shouldn't drop xp
-- "rain", "water", "drowning", "suffocation"
if not gamerule_doMobLoot[1] then return end
-- dropped cooked item if mob died in fire or lava
if cause == "lava" or cause == "fire" then
self:item_drop(true, 0)
@ -501,13 +513,10 @@ function mob_class:check_for_death(cause, cmi_cause)
end
end
end
end
-- execute custom death function
if self.on_die then
local pos = self.object:get_pos()
local on_die_exit = self.on_die(self, pos, cmi_cause)
if on_die_exit ~= true then
@ -933,7 +942,7 @@ function mob_class:check_entity_cramming()
local l = o:get_luaentity()
if l and l.is_mob and l.health > 0 then table.insert(mobs,l) end
end
local clear = #mobs < ENTITY_CRAMMING_MAX
local clear = #mobs < gamerule_maxEntityCramming[1]
local ncram = {}
for _,l in pairs(mobs) do
if l then
@ -947,7 +956,7 @@ function mob_class:check_entity_cramming()
end
end
for i,l in pairs(ncram) do
if i > ENTITY_CRAMMING_MAX then
if i > gamerule_maxEntityCramming[1] then
l.cram = true
else
l.cram = nil

@ -1,7 +1,12 @@
--lua locals
local S = minetest.get_translator("mcl_mobs")
local math, vector, minetest, mcl_mobs = math, vector, minetest, mcl_mobs
local mob_class = mcl_mobs.mob_class
local gamerule_doMobSpawning = vl_tuning.setting("gamerule:doMobSpawning", "bool", {
description = S("Whether mobs should spawn naturally, or via global spawning logic, such as for cats, phantoms, patrols, wandering traders, or zombie sieges. Does not affect special spawning attempts, like monster spawners, raids, or iron golems."), default = true
})
local modern_lighting = minetest.settings:get_bool("mcl_mobs_modern_lighting", true)
local nether_threshold = tonumber(minetest.settings:get("mcl_mobs_nether_threshold")) or 11
local end_threshold = tonumber(minetest.settings:get("mcl_mobs_end_threshold")) or 0
@ -905,8 +910,6 @@ end
mcl_mobs.spawn_group = spawn_group
local S = minetest.get_translator("mcl_mobs")
minetest.register_chatcommand("spawn_mob",{
privs = { debug = true },
description=S("spawn_mob is a chatcommand that allows you to type in the name of a mob without 'typing mobs_mc:' all the time like so; 'spawn_mob spider'. however, there is more you can do with this special command, currently you can edit any number, boolean, and string variable you choose with this format: spawn_mob 'any_mob:var<mobs_variable=variable_value>:'. any_mob being your mob of choice, mobs_variable being the variable, and variable value being the value of the chosen variable. and example of this format: \n spawn_mob skeleton:var<passive=true>:\n this would spawn a skeleton that wouldn't attack you. REMEMBER-THIS> when changing a number value always prefix it with 'NUM', example: \n spawn_mob skeleton:var<jump_height=NUM10>:\n this setting the skelly's jump height to 10. if you want to make multiple changes to a mob, you can, example: \n spawn_mob skeleton:var<passive=true>::var<jump_height=NUM10>::var<fly_in=air>::var<fly=true>:\n etc."),
@ -1187,6 +1190,7 @@ if mobs_spawn then
local timer = 0
minetest.register_globalstep(function(dtime)
if not gamerule_doMobSpawning[1] then return end
timer = timer + dtime
if timer < WAIT_FOR_SPAWN_ATTEMPT then return end

@ -2,6 +2,10 @@
mcl_raids = {}
local S = minetest.get_translator(minetest.get_current_modname())
local gamerule_disableRaids = vl_tuning.setting("gamerule:disableRaids", "bool", {
description = S("Whether raids are disabled"), default = false,
})
-- Define the amount of illagers to spawn each wave.
local waves = {
{
@ -291,6 +295,8 @@ mcl_events.register_event("raid",{
exclusive_to_area = 128,
enable_bossbar = true,
cond_start = function(self)
if gamerule_disableRaids[1] then return false end
--minetest.log("Cond start raid")
local r = {}
for _,p in pairs(minetest.get_connected_players()) do

@ -1,3 +1,3 @@
name = mcl_raids
author = PrairieWind
depends = mcl_events, mobs_mc, mcl_potions, mcl_bells, mcl_achievements
depends = mcl_events, mobs_mc, mcl_potions, mcl_bells, mcl_achievements, vl_tuning

@ -1,5 +1,5 @@
name = mcl_weather
author = xeranas
description = Weather and sky handling: Rain, snow, thunderstorm, End and Nether ambience
depends = mcl_init, mcl_worlds
depends = mcl_init, mcl_worlds, vl_tuning
optional_depends = lightning

@ -1,3 +1,6 @@
local modname = minetest.get_current_modname()
local S = minetest.get_translator(modname)
local mods_loaded = false
local NIGHT_VISION_RATIO = 0.45
@ -7,6 +10,28 @@ local water_color = "#3F76E4"
local mg_name = minetest.get_mapgen_setting("mg_name")
-- Daylight cycle handling
local fixed_time = vl_tuning.setting("fixed_daylight_time", "number", {
description = S("Time of day to use when gamerule:doDaylightCycle == false"),
default = 0.5
})
local gamerule_doDaylightCycle = vl_tuning.setting("gamerule:doDaylightCycle", "bool",{
description = S("Whether the daylight cycle and moon phases progress"),
default = true,
on_change = function(self)
if not self[1] then
fixed_time:set(minetest.get_timeofday())
end
end
})
local function daylightCycle()
if not gamerule_doDaylightCycle[1] and fixed_time[1] then
minetest.set_timeofday(fixed_time[1])
end
minetest.after(1, daylightCycle)
end
minetest.after(1, daylightCycle)
function mcl_weather.set_sky_box_clear(player, sky, fog)
local pos = player:get_pos()
if minetest.get_item_group(minetest.get_node(vector.new(pos.x,pos.y+1.5,pos.z)).name, "water") ~= 0 then return end

@ -1,10 +1,16 @@
local get_connected_players = minetest.get_connected_players
local modname = minetest.get_current_modname()
local S = minetest.get_translator(modname)
mcl_weather.snow = {}
local PARTICLES_COUNT_SNOW = tonumber(minetest.settings:get("mcl_weather_snow_particles")) or 100
mcl_weather.snow.init_done = false
local mgname = minetest.get_mapgen_setting("mg_name")
local gamerule_snowAccumulationHeight = vl_tuning.setting("gamerule:snowAccumulationHeight", "number", {
description = S("The maximum number of snow layers that can be accumulated on each block"),
default = 1, min = 0, max = 8
})
local snow_biomes = {
"ColdTaiga_underground",
@ -139,14 +145,16 @@ minetest.register_abm({
if node.name:find("snow") then
local l = node.name:sub(-1)
l = tonumber(l)
if node.name == "mcl_core:snow" then
nn={name = "mcl_core:snow_2"}
elseif l and l < 7 then
nn={name="mcl_core:snow_"..tostring(math.min(8,l + 1))}
elseif l and l >= 7 then
nn={name = "mcl_core:snowblock"}
if l < gamerule_snowAccumulationHeight[1] then
if node.name == "mcl_core:snow" then
nn={name = "mcl_core:snow_2"}
elseif l and l < 7 then
nn={name="mcl_core:snow_"..tostring(math.min(8,l + 1))}
elseif l and l >= 7 then
nn={name = "mcl_core:snowblock"}
end
if nn then minetest.set_node(pos,nn) end
end
if nn then minetest.set_node(pos,nn) end
else
minetest.set_node(above,{name = "mcl_core:snow"})
end

@ -2,6 +2,10 @@ local S = minetest.get_translator(minetest.get_current_modname())
local math = math
local gamerule_doWeatherCycle = vl_tuning.setting("gamerule:doWeatherCycle", "bool", {
description = S("Whether the weather can change naturally. The /weather command can still change weather."), default = true
})
-- weather states, 'none' is default, other states depends from active mods
mcl_weather.state = "none"
@ -126,6 +130,8 @@ end
local t, wci = 0, mcl_weather.check_interval
minetest.register_globalstep(function(dtime)
if not gamerule_doWeatherCycle[1] then return end
t = t + dtime
if t < wci then return end
t = 0

@ -678,6 +678,7 @@ local function make_formspec(name)
image_button[2.4,0.12;0.8,0.8;craftguide_search_icon.png;search;]
image_button[3.05,0.12;0.8,0.8;craftguide_clear_icon.png;clear;]
field_close_on_enter[filter;false]
field_enter_after_edit[filter;true]
]]
fs[#fs + 1] = fmt([[ tooltip[search;%s]

@ -18,6 +18,15 @@ local modname = minetest.get_current_modname()
local modpath = minetest.get_modpath(modname)
local S = minetest.get_translator(modname)
-- Tunable parameters
local notif_delay = vl_tuning.setting("award_display_time", "number", {
description = S("Amount of time award notification are displayed"), default = 3, min = 2, max = 10
})
local announce_in_chat = vl_tuning.setting("gamerule:announceAdvancements", "bool", {
description = S("Whether advancements should be announced in chat"),
default = minetest.settings:get_bool("mcl_showAdvancementMessages", true),
})
-- The global award namespace
awards = {
show_mode = "hud",
@ -217,7 +226,7 @@ function awards.unlock(name, award)
-- Get award
minetest.log("action", name.." has gotten award "..award)
if minetest.settings:get_bool("mcl_showAdvancementMessages", true) then
if announce_in_chat[1] then
minetest.chat_send_all(S("@1 has made the advancement @2", name, minetest.colorize(mcl_colors.GREEN, "[" .. (awdef.title or award) .. "]")))
end
data.unlocked[award] = award
@ -362,7 +371,7 @@ function awards.unlock(name, award)
direction = 0,
z_index = 102,
})
minetest.after(3, function(name)
minetest.after(notif_delay[1], function(name)
local player = minetest.get_player_by_name(name)
if not player then
return

@ -6,4 +6,4 @@ license = LGPL 2.1 or later
forum = https://forum.minetest.net/viewtopic.php?t=4870
version = 2.3.0
optional_depends = sfinv, unified_inventory
depends = mcl_colors
depends = mcl_colors, vl_tuning

@ -22,10 +22,8 @@ return {
"epCode",
"chmodsayshello",
"MrRar",
"FossFanatic ",
"SmokeyDope",
"Faerraven / Michieal",
"Codiac",
"rudzik8",
"teknomunk",
}},
@ -38,6 +36,8 @@ return {
"NO11",
"SumianVoice",
"PrairieWind",
"FossFanatic",
"Codiac",
}},
{S("Contributors"), 0x52FF00, {
"RandomLegoBrick",
@ -142,6 +142,7 @@ return {
"SOS-Games",
"Bram",
"qoheniac",
"WillConker",
}},
{S("Music"), 0xA60014, {
"Jordach for the jukebox music compilation from Big Freaking Dig",

@ -1,6 +1,10 @@
local S = minetest.get_translator(minetest.get_current_modname())
local ASSIST_TIMEOUT_SEC = 5
local gamerule_showDeathMessages = vl_tuning.setting("gamerule:showDeathMessages", "bool", {
description = S("Whether death messages are put into chat when a player dies. Also affects whether a message is sent to the pet's owner when the pet dies."),
default = minetest.settings:get_bool("mcl_showDeathMessages", true),
})
mcl_death_messages = {
assist = {},
@ -204,9 +208,7 @@ local function fallback_translator(s)
end
mcl_damage.register_on_death(function(obj, reason)
if not minetest.settings:get_bool("mcl_showDeathMessages", true) then
return
end
if not gamerule_showDeathMessages[1] then return end
local send_to

@ -1,4 +1,4 @@
name = mcl_death_messages
author = 4Evergreen4
description = Shows messages in chat when a player dies.
depends = mcl_colors
depends = mcl_colors, vl_tuning

@ -237,8 +237,9 @@ minetest.register_on_leaveplayer(function(player)
caches[player] = nil
end)
local keep_inventory = vl_tuning.setting("gamerule:keepInventory")
minetest.register_on_dieplayer(function(player)
if not minetest.settings:get_bool("mcl_keepInventory", false) then
if not keep_inventory[1] then
mcl_experience.throw_xp(player:get_pos(), mcl_experience.get_xp(player))
mcl_experience.set_xp(player, 0)
end

@ -1,4 +1,4 @@
name = mcl_experience
author = oilboi
description = eXPerience mod
depends = mcl_gamemode, mcl_luck
description = eXPerience mod
depends = mcl_gamemode, mcl_luck, vl_tuning

@ -28,6 +28,7 @@ local function get_anvil_formspec(set_name)
"field[4.125,0.75;7.25,1;name;;" .. F(set_name) .. "]",
"field_close_on_enter[name;false]",
"field_enter_after_edit[name;true]",
"set_focus[name;true]",
mcl_formspec.get_itemslot_bg_v4(1.625, 2.6, 1, 1),

@ -10,6 +10,8 @@ local explosions_mod = minetest.get_modpath("mcl_explosions")
local spawn_mod = minetest.get_modpath("mcl_spawn")
local pos_to_dim = minetest.get_modpath("mcl_worlds") and mcl_worlds.pos_to_dimension or function(pos) return "overworld" end
local gamerule_respawnBlocksExplode = vl_tuning.respawn_blocks_explode
local function mcl_log (message)
mcl_util.mcl_log (message, "[Beds]")
end
@ -384,7 +386,7 @@ function mcl_beds.on_rightclick(pos, player, is_top)
minetest.remove_node(pos)
minetest.remove_node(string.sub(node.name, -4) == "_top" and vector.subtract(pos, dir) or vector.add(pos, dir))
if explosions_mod then
if explosions_mod and gamerule_respawnBlocksExplode[1] then
mcl_explosions.explode(pos, 5, {drop_chance = 1.0, fire = true})
end
return

@ -1,5 +1,5 @@
name = mcl_beds
author = BlockMen
description =
depends = playerphysics
optional_depends = mcl_sounds, mcl_worlds, mcl_wool, mcl_dye, mcl_explosions, mcl_weather, mcl_spawn, doc, mesecons
depends = playerphysics, vl_tuning
optional_depends = mcl_sounds, mcl_worlds, mcl_wool, mcl_dye, mcl_explosions, mcl_weather, mcl_spawn, doc, mesecons

@ -4,6 +4,7 @@
--Nether roof at y -28933
local S = minetest.get_translator(minetest.get_current_modname())
--local mod_doc = minetest.get_modpath("doc") -> maybe add documentation ?
local gamerule_respawnBlocksExplode = vl_tuning.respawn_blocks_explode
for i=0,4 do
@ -12,7 +13,7 @@ for i=0,4 do
minetest.set_node(pos, {name="mcl_beds:respawn_anchor_charged_" .. i+1})
itemstack:take_item()
elseif mcl_worlds.pos_to_dimension(pos) ~= "nether" then
if node.name ~= "mcl_beds:respawn_anchor" then --only charged respawn anchors are exploding in the overworld & end in minecraft
if gamerule_respawnBlocksExplode[1] and node.name ~= "mcl_beds:respawn_anchor" then --only charged respawn anchors are exploding in the overworld & end in minecraft
mcl_explosions.explode(pos, 5, {drop_chance = 0, fire = true})
end
elseif string.match(node.name, "mcl_beds:respawn_anchor_charged_") then

@ -196,7 +196,7 @@ end
mcl_stairs.register_stair_and_slab("blackstone", "mcl_blackstone:blackstone",
{cracky=3, pickaxey=1, material_stone=1},
{"mcl_blackstone_top.png", "mcl_blackstone_top.png", "mcl_blackstone_side.png"},
S("Blackstone Stairs"),
S("Blackstone Stair"),
S("Blackstone Slab"),
mcl_sounds.node_sound_stone_defaults(), 6, 2,
S("Double Blackstone Slab"), nil)
@ -204,7 +204,7 @@ mcl_stairs.register_stair_and_slab("blackstone", "mcl_blackstone:blackstone",
mcl_stairs.register_stair_and_slab("blackstone_polished", "mcl_blackstone:blackstone_polished",
{cracky=3, pickaxey=1, material_stone=1},
{"mcl_blackstone_polished.png"},
S("Polished Blackstone Stairs"),
S("Polished Blackstone Stair"),
S("Polished Blackstone Slab"),
mcl_sounds.node_sound_stone_defaults(), 6, 2,
S("Double Polished Blackstone Slab"), nil)
@ -212,7 +212,7 @@ mcl_stairs.register_stair_and_slab("blackstone_polished", "mcl_blackstone:blacks
mcl_stairs.register_stair_and_slab("blackstone_chiseled_polished", "mcl_blackstone:blackstone_chiseled_polished",
{cracky=3, pickaxey=1, material_stone=1},
{"mcl_blackstone_chiseled_polished.png"},
S("Chiseled Polished Blackstone Stairs"),
S("Chiseled Polished Blackstone Stair"),
S("Chiseled Polished Blackstone Slab"),
mcl_sounds.node_sound_stone_defaults(), 6, 2,
S("Double Chiseled Polished Blackstone Slab"), nil)
@ -220,10 +220,10 @@ mcl_stairs.register_stair_and_slab("blackstone_chiseled_polished", "mcl_blacksto
mcl_stairs.register_stair_and_slab("blackstone_brick_polished", "mcl_blackstone:blackstone_brick_polished",
{cracky=3, pickaxey=1, material_stone=1},
{"mcl_blackstone_polished_bricks.png"},
S("Polished Blackstone Brick Stair Stairs"),
S("Polished Blackstone Brick Stair Slab"),
S("Polished Blackstone Brick Stair"),
S("Polished Blackstone Brick Slab"),
mcl_sounds.node_sound_stone_defaults(), 6, 2,
S("Double Polished Blackstone Brick Stair Slab"), nil)
S("Double Polished Blackstone Brick Slab"), nil)
--Wall
mcl_walls.register_wall(

@ -9,10 +9,10 @@ Blackstone Slab=Schwarzstein Stufe
Polished Blackstone Slab=Polierte Schwarzstein Stufe
Chiseled Polished Blackstone Slab=Gemeißelte Polierte Schwarzstein Stufe
Polished Blackstone Brick Slab=Polierte Schwarzsteinziegel Stufe
Blackstone Stairs=Schwarzstein Treppe
Polished Blackstone Stairs=Polierte Schwarzstein Treppe
Chiseled Polished Blackstone Stairs=Gemeißelte Polierte Schwarzstein Treppe
Polished Blackstone Brick Stairs=Polierte Schwarzsteinziegel Treppe
Blackstone Stair=Schwarzstein Treppe
Polished Blackstone Stair=Polierte Schwarzstein Treppe
Chiseled Polished Blackstone Stair=Gemeißelte Polierte Schwarzstein Treppe
Polished Blackstone Brick Stair=Polierte Schwarzsteinziegel Treppe
Quartz Bricks=Quartz Ziegel
Soul Torch=Seelenfakel
Soul Lantern=Seelenlaterne

@ -2,7 +2,9 @@
-- Lava vs water interactions
--
local modpath = minetest.get_modpath(minetest.get_current_modname())
local modname = minetest.get_current_modname()
local modpath = minetest.get_modpath(modname)
local S = minetest.get_translator(modname)
local mg_name = minetest.get_mapgen_setting("mg_name")
@ -1277,12 +1279,17 @@ end
---------------------
-- Vine generating --
---------------------
local do_vines_spread = vl_tuning.setting("gamerule:doVinesSpread", "bool", {
description = S("Whether vines can spread to other blocks. Cave vines, weeping vines, and twisting vines are not affected."),
default = true,
})
minetest.register_abm({
label = "Vines growth",
nodenames = {"mcl_core:vine"},
interval = 47,
chance = 4,
action = function(pos, node, active_object_count, active_object_count_wider)
if not do_vines_spread[1] then return end
-- First of all, check if we are even supported, otherwise, let's die!
if not mcl_core.check_vines_supported(pos, node) then

@ -1,4 +1,4 @@
name = mcl_core
description = Core items of MineClone 2: Basic biome blocks (dirt, sand, stones, etc.), derived items, glass, sugar cane, cactus, barrier, mining tools, hand, craftitems, and misc. items which don't really fit anywhere else.
depends = mcl_autogroup, mcl_init, mcl_sounds, mcl_particles, mcl_util, mcl_worlds, doc_items, mcl_enchanting, mcl_colors, mcl_stonecutter
depends = mcl_autogroup, mcl_init, mcl_sounds, mcl_particles, mcl_util, mcl_worlds, doc_items, mcl_enchanting, mcl_colors, mcl_stonecutter, vl_tuning
optional_depends = doc

@ -1,3 +1,3 @@
name = mcl_farming
depends = mcl_core, mcl_sounds, mcl_wool, mcl_torches, mcl_weather, mobs_mc, mcl_colors, mcl_init
depends = mcl_core, mcl_sounds, mcl_wool, mcl_torches, mcl_weather, mobs_mc, mcl_colors, mcl_init, vl_tuning
optional_depends = mcl_armor, doc

@ -169,8 +169,9 @@ if minetest.get_modpath("mcl_armor") then
add_pumpkin_hud(player)
end
end)
local keep_inventory = vl_tuning.setting("gamerule:keepInventory")
minetest.register_on_dieplayer(function(player)
if not minetest.settings:get_bool("mcl_keepInventory") then
if not keep_inventory[1] then
remove_pumpkin_hud(player)
end
end)

@ -7,6 +7,9 @@ local modpath = minetest.get_modpath(modname)
local S = minetest.get_translator(modname)
local has_mcl_portals = minetest.get_modpath("mcl_portals")
local gamerule_doFireTick = vl_tuning.setting("gamerule:doFireTick", "bool", {
description = S("Whether fire should spread and naturally extinguish"), default = true
})
local set_node = minetest.set_node
local get_node = minetest.get_node
@ -366,6 +369,8 @@ else -- Fire enabled
chance = 12,
catch_up = false,
action = function(pos)
if not gamerule_doFireTick[1] then return end
local p = get_ignitable(pos)
if p then
spawn_fire(p)
@ -383,6 +388,8 @@ else -- Fire enabled
chance = 9,
catch_up = false,
action = function(pos)
if not gamerule_doFireTick[1] then return end
local p=get_ignitable_by_lava(pos)
if p then
spawn_fire(p)
@ -397,6 +404,8 @@ else -- Fire enabled
chance = 3,
catch_up = false,
action = function(pos)
if not gamerule_doFireTick[1] then return end
local p=has_flammable(pos)
if p then
local n=minetest.get_node_or_nil(p)
@ -418,6 +427,8 @@ else -- Fire enabled
chance = 18,
catch_up = false,
action = function(pos)
if not gamerule_doFireTick[1] then return end
local p = has_flammable(pos)
if not p then
return

@ -1,3 +1,3 @@
name = mcl_fire
depends = mcl_core, mcl_worlds, mcl_sounds, mcl_particles, mcl_util
optional_depends = mcl_portals
optional_depends = mcl_portals, vl_tuning

@ -83,6 +83,13 @@ local function respawn_doll(pos)
local mob = meta:get_string("Mob")
local doll
if mob and mob ~= "" then
-- Handle conversion of mob spawners
local convert_to = (minetest.registered_entities[mob] or {})._convert_to
if convert_to then
mob = convert_to
meta:set_string("Mob", mob)
end
doll = find_doll(pos)
if not doll then
doll = spawn_doll(pos)
@ -128,7 +135,6 @@ function mcl_mobspawners.setup_spawner(pos, Mob, MinLight, MaxLight, MaxMobsInAr
end
set_doll_properties(doll, Mob)
-- Start spawning very soon
local t = minetest.get_node_timer(pos)
t:start(2)
@ -165,7 +171,6 @@ local function spawn_mobs(pos, elapsed)
local count = 0
local ent
local timer = minetest.get_node_timer(pos)
-- spawn mob if player detected and in range
@ -367,7 +372,6 @@ doll_def.on_activate = function(self, staticdata, dtime_s)
self.object:set_velocity({x=0, y=0, z=0})
self.object:set_acceleration({x=0, y=0, z=0})
self.object:set_armor_groups({immortal=1})
end
doll_def.on_step = function(self, dtime)

@ -1,4 +1,4 @@
name = mcl_portals
description = Adds buildable portals to the Nether and End dimensions.
depends = mcl_nether, mcl_end, mcl_particles, mcl_spawn, mcl_credits, mcl_structures
depends = mcl_nether, mcl_end, mcl_particles, mcl_spawn, mcl_credits, mcl_structures, vl_tuning
optional_depends = awards, doc

@ -85,7 +85,14 @@ local LIM_MIN, LIM_MAX = mcl_vars.mapgen_edge_min, mcl_vars.mapgen_edge_max
local PLAYER_COOLOFF, MOB_COOLOFF = 3, 14 -- for this many seconds they won't teleported again
local TOUCH_CHATTER_TIME = 1 -- prevent multiple teleportation attempts caused by multiple portal touches, for this number of seconds
local CHATTER_US = TOUCH_CHATTER_TIME * 1000000
local DELAY = 3 -- seconds before teleporting in Nether portal in Survival mode (4 minus ABM interval time)
local nether_portal_creative_delay = vl_tuning.setting("gamerule:playersNetherPortalCreativeDelay", "number", {
default = 0,
})
local nether_portal_survival_delay = vl_tuning.setting("gamerule:playersNetherPortalDefaultDelay", "number", {
default = 4,
})
-- Speeds up the search by allowing some non-air nodes to be replaced when
-- looking for acceptable portal locations. Setting this lower means the
-- algorithm will do more searching. Even at 0, there is no risk of finding
@ -1477,12 +1484,16 @@ local function teleport(obj, portal_pos)
if cooloff[obj] then return end
local delay = math.max(0, nether_portal_survival_delay[1] - 1)
if minetest.is_creative_enabled(name) then
teleport_no_delay(obj, portal_pos)
return
delay = math.max(0, nether_portal_creative_delay[1] - 1)
end
minetest.after(DELAY, teleport_no_delay, obj, portal_pos)
if delay == 0 then
teleport_no_delay(obj, portal_pos)
else
minetest.after(delay, teleport_no_delay, obj, portal_pos)
end
end
minetest.register_abm({

@ -407,9 +407,10 @@ minetest.register_globalstep(function(dtime)
end
end)
local keep_inventory = vl_tuning.setting("gamerule:keepInventory")
minetest.register_on_dieplayer(function(player)
remove_shield_hud(player)
if not minetest.settings:get_bool("mcl_keepInventory") then
if not keep_inventory[1] then
remove_shield_entity(player, 1)
remove_shield_entity(player, 2)
end

@ -1,3 +1,3 @@
name = mcl_shields
author = NO11
depends = mcl_damage, mcl_enchanting, mcl_banners, mcl_util, playerphysics
depends = mcl_damage, mcl_enchanting, mcl_banners, mcl_util, playerphysics, vl_tuning

@ -77,7 +77,7 @@ mcl_stairs.register_slab("granite", "mcl_core:granite",
mcl_stairs.register_stair("diorite", "mcl_core:diorite",
{pickaxey=1, material_stone=1},
{"mcl_core_diorite.png"},
S("Granite Stairs"),
S("Diorite Stairs"),
mcl_sounds.node_sound_stone_defaults(), 0.8, 0.8)
mcl_stairs.register_slab("diorite", "mcl_core:diorite",
{pickaxey=1, material_stone=1},

@ -6,6 +6,8 @@ mcl_death_drop = {}
mcl_death_drop.registered_dropped_lists = {}
local keep_inventory = vl_tuning.setting("gamerule:keepInventory")
function mcl_death_drop.register_dropped_list(inv, listname, drop)
table.insert(mcl_death_drop.registered_dropped_lists, {inv = inv, listname = listname, drop = drop})
end
@ -16,8 +18,7 @@ mcl_death_drop.register_dropped_list("PLAYER", "armor", true)
mcl_death_drop.register_dropped_list("PLAYER", "offhand", true)
minetest.register_on_dieplayer(function(player)
local keep = minetest.settings:get_bool("mcl_keepInventory", false)
if keep == false then
if not keep_inventory[1] then
-- Drop inventory, crafting grid and armor
local playerinv = player:get_inventory()
local pos = player:get_pos()

@ -1,4 +1,4 @@
name = mcl_death_drop
author = Wuzzy
description = Makes all items in inventory drop after player death.
depends = mcl_armor, mcl_enchanting
depends = mcl_armor, mcl_enchanting, vl_tuning

@ -3,6 +3,13 @@ local modpath = minetest.get_modpath(modname)
local S = minetest.get_translator(modname)
local max_tick_timer = vl_tuning.setting("health_regen_delay", "number", {
default = tonumber(minetest.settings:get("mcl_health_regen_delay")) or 0.5,
})
local natural_regeneration = vl_tuning.setting("gamerule:naturalRegeneration", "bool", {
default = true,
})
mcl_hunger = {}
--[[ This variable tells you if the hunger gameplay mechanic is active.
@ -241,7 +248,6 @@ minetest.register_globalstep(function(dtime)
local food_level = mcl_hunger.get_hunger(player)
local food_saturation_level = mcl_hunger.get_saturation(player)
local player_health = player:get_hp()
local max_tick_timer = tonumber(minetest.settings:get("mcl_health_regen_delay")) or 0.5
if food_tick_timer > 4 then
food_tick_timer = 0
@ -253,7 +259,7 @@ minetest.register_globalstep(function(dtime)
end
if food_level >= 18 then -- slow regeneration
if player_health > 0 and player_health < player:get_properties().hp_max then
if natural_regeneration[1] and player_health > 0 and player_health < player:get_properties().hp_max then
player:set_hp(player_health+1)
mcl_hunger.exhaust(player_name, mcl_hunger.EXHAUST_REGEN)
mcl_hunger.update_exhaustion_hud(player)
@ -269,8 +275,8 @@ minetest.register_globalstep(function(dtime)
end
end
elseif food_tick_timer > max_tick_timer and food_level == 20 and food_saturation_level > 0 then -- fast regeneration
if player_health > 0 and player_health < player:get_properties().hp_max then
elseif food_tick_timer > max_tick_timer[1] and food_level == 20 and food_saturation_level > 0 then -- fast regeneration
if natural_regeneration[1] and player_health > 0 and player_health < player:get_properties().hp_max then
food_tick_timer = 0
player:set_hp(player_health+1)
mcl_hunger.exhaust(player_name, mcl_hunger.EXHAUST_REGEN)

@ -1,4 +1,4 @@
name = mcl_hunger
author = BlockMen
description = Adds a simple hunger meachanic with satiation, food poisoning and different healing.
depends = hudbars
depends = hudbars, vl_tuning

@ -735,8 +735,10 @@ end
init()
if not minetest.settings:get_bool("mcl_keepInventory", false) then
minetest.register_on_respawnplayer(function(player)
local keep_inventory = vl_tuning.setting("gamerule:keepInventory")
minetest.register_on_respawnplayer(function(player)
if not keep_inventory[1] then
mcl_skins.update_player_skin(player) -- ensures players have their cape again after dying with an elytra
end)
end
end
end)

@ -1,4 +1,4 @@
name = mcl_skins
author = MrRar
description = Advanced player skin customization.
depends = mcl_player
depends = mcl_player, vl_tuning

@ -16,6 +16,7 @@
* SOS-Games
* Bram
* qoheniac
* WillConker
### Game rename
Based on months of collecting suggestions, analysis and vetting of possible names, community voting and discussion between developers, the rename of the game has reached its conclusion! The project has been renamed to **VoxeLibre**.
@ -165,16 +166,34 @@ One of our tools, the Python script allowing conversion of Minecraft resource pa
* XP orbs related crash by teknomunk
* Ghast fireball related crash by Araca
* Crash related to server restart while a player is dead by teknomunk
* Crashes related to the new effects API - by teknomunk and Herowl
* Crashes related to the new effects API by teknomunk and Herowl
## 0.87.1 hotfix
* Fixed crash when shooting potions from a dispenser - by teknomunk
* Fixed crash related to custom mobspawners - by teknomunk
* Fixed beacon crash - by teknomunk
* Fixed eye of ender crash - by Herowl
* Fixed Stalker texture generation - by teknomunk
* Correctly refresh enchanted tool capabilities - by teknomunk
* Fixed creative inventory misbehaving - by Herowl
* Fixed variable definition in mob spawning code - by teknomunk
* Updated documentation - by Herowl and teknomunk
* Increased stack size for snowballs and eggs - by JoseDouglas26
* Fixed crash when shooting potions from a dispenser by teknomunk
* Fixed crash related to custom mobspawners by teknomunk
* Fixed beacon crash by teknomunk
* Fixed eye of ender crash by Herowl
* Fixed Stalker texture generation by teknomunk
* Correctly refresh enchanted tool capabilities by teknomunk
* Fixed creative inventory misbehaving by Herowl
* Fixed variable definition in mob spawning code by teknomunk
* Updated documentation by Herowl and teknomunk
* Increased stack size for snowballs and eggs by JoseDouglas26
## 0.87.2 hotfix
* Zombie texture improvements by SmokeyDope
* Wrong name of diorite stairs fixed by qoheniac
* Fixed flint and steel wearing down when not placing fire by JoseDouglas26 and WillConker
* Fixed brewing stands' rotation by JoseDouglas26 and WillConker
* Fixed beacon formspec by teknomunk
* Made all hollow logs breakable properly by teknomunk
* Instructions on how to eat added to the help menu by teknomunk
* Potion conversion fixed by Herowl
* Fixed some node names by seventeenthShulker
* Fixed anvil and craftguide formspecs on mobile by Herowl
* Fixed effect loading by Herowl
* Fixed crash while fighting wither by teknomunk
* Fixed crash when bonemealing sweet berry bushes by teknomunk
* Fixed some mob conversion crashes by teknomunk
* Fixed crash related to the frost walker enchantment by WillConker
* Fixed some mob-related crashes by Herowl