Combat (mostly PvE) rebalancing (#4005)

-Added short mob invulnerability time after being hit
-Added separate shorter range for hitting mobs (as opposed to node interaction)
-Reworked mob knockback
-Slowed down natural health regeneration from saturation
-Added a setting for the saturation health regen speed

Reviewed-on: https://git.minetest.land/MineClone2/MineClone2/pulls/4005
Reviewed-by: the-real-herowl <the-real-herowl@noreply.git.minetest.land>
Co-authored-by: Eliy21 <eliy21@noreply.git.minetest.land>
Co-committed-by: Eliy21 <eliy21@noreply.git.minetest.land>
This commit is contained in:
Eliy21 2023-11-23 00:32:23 +00:00 committed by the-real-herowl
parent 4df6f82c64
commit 7cbba73d50
5 changed files with 46 additions and 10 deletions

View file

@ -532,11 +532,28 @@ function mob_class:on_punch(hitter, tflp, tool_capabilities, dir)
return return
end end
local time_now = minetest.get_us_time()
local is_player = hitter:is_player() local is_player = hitter:is_player()
if is_player then if is_player then
local time_diff = time_now - self.invul_timestamp
-- check for invulnerability time in microseconds (0.5 second)
if time_diff <= 500000 and time_diff >= 0 then
return
end
local mob_pos = self.object:get_pos()
local player_pos = hitter:get_pos()
-- is mob out of reach?
if vector.distance(mob_pos, player_pos) > 3 then
return
end
-- is mob protected? -- is mob protected?
if self.protected and minetest.is_protected(self.object:get_pos(), hitter:get_player_name()) then if self.protected and minetest.is_protected(mob_pos, hitter:get_player_name()) then
return return
end end
@ -545,7 +562,7 @@ function mob_class:on_punch(hitter, tflp, tool_capabilities, dir)
end end
-- set/update 'drop xp' timestamp if hitted by player -- set/update 'drop xp' timestamp if hitted by player
self.xp_timestamp = minetest.get_us_time() self.xp_timestamp = time_now
end end
@ -657,6 +674,9 @@ function mob_class:on_punch(hitter, tflp, tool_capabilities, dir)
-- do damage -- do damage
self.health = self.health - damage self.health = self.health - damage
-- give invulnerability
self.invul_timestamp = time_now
-- skip future functions if dead, except alerting others -- skip future functions if dead, except alerting others
if self:check_for_death( "hit", {type = "punch", puncher = hitter}) then if self:check_for_death( "hit", {type = "punch", puncher = hitter}) then
die = true die = true
@ -672,10 +692,10 @@ function mob_class:on_punch(hitter, tflp, tool_capabilities, dir)
if not v then return end if not v then return end
local r = 1.4 - math.min(punch_interval, 1.4) local r = 1.4 - math.min(punch_interval, 1.4)
local kb = r * (math.abs(v.x)+math.abs(v.z)) local kb = r * (math.abs(v.x)+math.abs(v.z))
local up = 2 local up = 2.625
if die==true then if die==true then
kb=kb*2 kb=kb*1.25
end end
-- if already in air then dont go up anymore when hit -- if already in air then dont go up anymore when hit
@ -689,7 +709,7 @@ function mob_class:on_punch(hitter, tflp, tool_capabilities, dir)
if tool_capabilities.damage_groups["knockback"] then if tool_capabilities.damage_groups["knockback"] then
kb = tool_capabilities.damage_groups["knockback"] kb = tool_capabilities.damage_groups["knockback"]
else else
kb = kb * 1.5 kb = kb * 1.25
end end
@ -699,9 +719,19 @@ function mob_class:on_punch(hitter, tflp, tool_capabilities, dir)
end end
if hitter and is_player then if hitter and is_player then
local wielditem = hitter:get_wielded_item() local wielditem = hitter:get_wielded_item()
kb = kb + 3 * mcl_enchanting.get_enchantment(wielditem, "knockback") local hv = hitter:get_velocity()
elseif luaentity and luaentity._knockback then local dir_dot = (hv.x * dir.x) + (hv.z * dir.z)
local player_mag = math.sqrt((hv.x * hv.x) + (hv.z * hv.z))
local mob_mag = math.sqrt((v.x * v.x) + (v.z * v.z))
kb = kb + 9 * mcl_enchanting.get_enchantment(wielditem, "knockback")
-- add player velocity to mob knockback
if dir_dot > 0 and mob_mag <= player_mag * 0.625 then
kb = kb + ((math.abs(hv.x) + math.abs(hv.z)) * r)
end
elseif luaentity and luaentity._knockback and die == false then
kb = kb + luaentity._knockback kb = kb + luaentity._knockback
elseif luaentity and luaentity._knockback and die == true then
kb = kb + luaentity._knockback * 0.25
end end
self._kb_turn = true self._kb_turn = true
self._turn_to=self.object:get_yaw()-1.57 self._turn_to=self.object:get_yaw()-1.57

View file

@ -171,6 +171,7 @@ function mcl_mobs.register_mob(name, def)
xp_min = def.xp_min or 0, xp_min = def.xp_min or 0,
xp_max = def.xp_max or 0, xp_max = def.xp_max or 0,
xp_timestamp = 0, xp_timestamp = 0,
invul_timestamp = 0,
breath_max = def.breath_max or 15, breath_max = def.breath_max or 15,
breathes_in_water = def.breathes_in_water or false, breathes_in_water = def.breathes_in_water or false,
physical = true, physical = true,

View file

@ -48,7 +48,7 @@ function mcl_bows.shoot_arrow(arrow_item, pos, dir, yaw, shooter, power, damage,
damage = damage + (enchantments.power + 1) / 4 damage = damage + (enchantments.power + 1) / 4
end end
if enchantments.punch then if enchantments.punch then
knockback = enchantments.punch * 3 knockback = enchantments.punch * 21
end end
if enchantments.flame then if enchantments.flame then
mcl_burning.set_on_fire(obj, math.huge) mcl_burning.set_on_fire(obj, math.huge)

View file

@ -146,8 +146,9 @@ minetest.register_globalstep(function(dtime)
local food_level = mcl_hunger.get_hunger(player) local food_level = mcl_hunger.get_hunger(player)
local food_saturation_level = mcl_hunger.get_saturation(player) local food_saturation_level = mcl_hunger.get_saturation(player)
local player_health = player:get_hp() local player_health = player:get_hp()
local max_tick_timer = tonumber(minetest.settings:get("mcl_health_regen_delay")) or 4
if food_tick_timer > 4.0 then if food_tick_timer > max_tick_timer then
food_tick_timer = 0 food_tick_timer = 0
-- let hunger work always -- let hunger work always
@ -173,7 +174,7 @@ minetest.register_globalstep(function(dtime)
end end
end end
elseif food_tick_timer > 0.5 and food_level == 20 and food_saturation_level > 0 then -- fast regeneration 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 < 20 then if player_health > 0 and player_health < 20 then
food_tick_timer = 0 food_tick_timer = 0
player:set_hp(player_health+1) player:set_hp(player_health+1)

View file

@ -95,6 +95,10 @@ mcl_creative_dig_speed (Creative mode dig speed) float 0.2
# If enabled the hunger mechanic will be active # If enabled the hunger mechanic will be active
mcl_enable_hunger (Hunger mechanic) bool true mcl_enable_hunger (Hunger mechanic) bool true
# Health regeneration delay when hunger bar is full
# Default:4
mcl_health_regen_delay (Health regen delay) float 4 0
[Mobs] [Mobs]
# If enabled, mobs will spawn naturally. This does not affect # If enabled, mobs will spawn naturally. This does not affect
# affect mob spawners. # affect mob spawners.