Optimize fall damage, Fix height checks

This commit is contained in:
ElCeejo 2022-07-07 14:26:58 -07:00
parent d69fae95d5
commit d7f019083a
2 changed files with 40 additions and 33 deletions

View file

@ -126,7 +126,15 @@ function creatura.action_move(self, pos2, timeout, method, speed_factor, anim)
local function func(_self) local function func(_self)
timer = timer - _self.dtime timer = timer - _self.dtime
self:animate(anim or "walk") self:animate(anim or "walk")
local safe = true
if _self.max_fall
and _self.max_fall > 0 then
local pos = self.object:get_pos()
if not pos then return end
safe = _self:is_pos_safe(pos2)
end
if timer <= 0 if timer <= 0
or not safe
or _self:move_to(pos2, method or "creatura:obstacle_avoidance", speed_factor or 0.5) then or _self:move_to(pos2, method or "creatura:obstacle_avoidance", speed_factor or 0.5) then
return true return true
end end

View file

@ -159,21 +159,18 @@ end
-- Turn to specified yaw -- Turn to specified yaw
local function lerp_rad(a, b, w)
local cs = (1 - w) * cos(a) + w * cos(b)
local sn = (1 - w) * sin(a) + w * sin(b)
return atan2(sn, cs)
end
function mob:turn_to(tyaw, rate) function mob:turn_to(tyaw, rate)
self._tyaw = tyaw self._tyaw = tyaw
local weight = rate or 10 rate = rate or 5
local yaw = self.object:get_yaw() local yaw = self.object:get_yaw()
local step = math.min(self.dtime * rate, abs(diff(yaw, tyaw)) % (pi2))
yaw = yaw + pi self.object:set_yaw(lerp_rad(yaw, tyaw, step))
tyaw = (tyaw + pi) % pi2
local step = math.min(self.dtime * weight, abs(tyaw - yaw) % pi2)
local dir = abs(tyaw - yaw) > pi and -1 or 1
dir = tyaw > yaw and dir * 1 or dir * -1
local nyaw = (yaw + step * dir) % pi2
self.object:set_yaw(nyaw - pi)
self.last_yaw = self.object:get_yaw() self.last_yaw = self.object:get_yaw()
end end
@ -383,6 +380,7 @@ end
function mob:is_pos_safe(pos) function mob:is_pos_safe(pos)
local mob_pos = self.object:get_pos() local mob_pos = self.object:get_pos()
if not pos then return end
local node = minetest.get_node(pos) local node = minetest.get_node(pos)
if not node then return false end if not node then return false end
if minetest.get_item_group(node.name, "igniter") > 0 if minetest.get_item_group(node.name, "igniter") > 0
@ -1102,29 +1100,30 @@ end
function mob:_vitals() function mob:_vitals()
local stand_pos = self.object:get_pos() local stand_pos = self.object:get_pos()
if not stand_pos then return end if not stand_pos then return end
local fall_start = self._fall_start local max_fall = self.max_fall or 0
if self.is_falling if max_fall > 0 then
and not fall_start local fall_start = self._fall_start
and self.max_fall > 0 then if self.is_falling
self._fall_start = stand_pos.y and not fall_start then
elseif fall_start self._fall_start = stand_pos.y
and self.max_fall > 0 then elseif fall_start then
if self.touching_ground if self.touching_ground
and not self.in_liquid then and not self.in_liquid then
local damage = fall_start - stand_pos.y local damage = fall_start - stand_pos.y
if damage < (self.max_fall or 3) then if damage < max_fall then
self._fall_start = nil
return
end
local resist = self.fall_resistance or 0
self:hurt(damage - (damage * resist))
self:indicate_damage()
if random(4) < 2 then
self:play_sound("hurt")
end
self._fall_start = nil
elseif self.in_liquid then
self._fall_start = nil self._fall_start = nil
return
end end
local resist = self.fall_resistance or 0
self:hurt(damage - (damage * (resist * 0.1)))
self:indicate_damage()
if random(4) < 2 then
self:play_sound("hurt")
end
self._fall_start = nil
elseif self.in_liquid then
self._fall_start = nil
end end
end end
if self:timer(1) then if self:timer(1) then