Further movement improvements

This commit is contained in:
kno10 2024-10-03 12:56:40 +02:00
parent 8c38745f6c
commit a5cfaed843
6 changed files with 28 additions and 34 deletions

View File

@ -28,8 +28,9 @@ if minetest.settings:get_bool("only_peaceful_mobs", false) then
end) end)
end end
-- not used yet
function mob_class:safe_remove() function mob_class:safe_remove()
self.removed = true self._removed = true
minetest.after(0,function(obj) minetest.after(0,function(obj)
if obj and obj:get_pos() then if obj and obj:get_pos() then
mcl_burning.extinguish(obj) mcl_burning.extinguish(obj)
@ -121,14 +122,11 @@ end
function mob_class:mob_activate(staticdata, def, dtime) function mob_class:mob_activate(staticdata, def, dtime)
if not self.object:get_pos() or staticdata == "remove" then if not self.object:get_pos() or staticdata == "remove" then
mcl_burning.extinguish(self.object) self:safe_remove()
self.object:remove()
return return
end end
if self.type == "monster" if self.type == "monster" and minetest.settings:get_bool("only_peaceful_mobs", false) then
and minetest.settings:get_bool("only_peaceful_mobs", false) then self:safe_remove()
mcl_burning.extinguish(self.object)
self.object:remove()
return return
end end
@ -310,16 +308,17 @@ end
local function on_step_work(self, dtime, moveresult) local function on_step_work(self, dtime, moveresult)
local pos = self.object:get_pos() local pos = self.object:get_pos()
if not pos or self.removed then return end if not pos or self._removed then return end
if self:check_despawn(pos, dtime) then return end
if self:outside_limits() then return end if self:outside_limits() then return end
if self:check_despawn(pos, dtime) then return end
pos = self:limit_vel_acc_for_large_dtime(pos, dtime, moveresult) -- limit maximum movement to reduce lag effects pos = self:limit_vel_acc_for_large_dtime(pos, dtime, moveresult) -- limit maximum movement to reduce lag effects
self:update_standing(pos, moveresult) -- update what we know of the mobs environment for physics and movement self:update_standing(pos, moveresult) -- update what we know of the mobs environment for physics and movement
local player_in_active_range = self:player_in_active_range() local player_in_active_range = self:player_in_active_range()
-- The following functions return true when the mob died and we should stop processing -- The following functions return true when the mob died and we should stop processing
if self:check_suspend(player_in_active_range) then return end if self:check_suspend(player_in_active_range) then return end
if self:gravity_and_floating(pos, dtime, moveresult) then return end if self:gravity_and_floating(pos, dtime, moveresult) then return end -- keep early, for gravity!
if self:check_dying() then return end
if self:step_damage(dtime, pos) then return end if self:step_damage(dtime, pos) then return end
self:check_water_flow(dtime, pos) self:check_water_flow(dtime, pos)

View File

@ -651,7 +651,7 @@ function mob_class:on_punch(hitter, tflp, tool_capabilities, dir)
self._kb_turn = false self._kb_turn = false
end end
end) end)
self.object:add_velocity(vector_new(dir.x * kb, up*2, dir.z * kb )) self.object:add_velocity(vector_new(dir.x * kb, up, dir.z * kb ))
self.pause_timer = 0.25 self.pause_timer = 0.25
end end
@ -1004,11 +1004,14 @@ function mob_class:do_states_attack(dtime)
if random(40) == 1 then self.strafe_direction = self.strafe_direction * -1 end if random(40) == 1 then self.strafe_direction = self.strafe_direction * -1 end
local dir = -atan2(p.x - s.x, p.z - s.z) local dir = -atan2(p.x - s.x, p.z - s.z)
self.object:add_velocity(vector_new(-sin(dir + self.strafe_direction) * 0.8, 0, cos(dir + self.strafe_direction) * 0.8)) self.acceleration.x = self.acceleration.x - sin(dir + self.strafe_direction) * 8
self.acceleration.z = self.acceleration.z + cos(dir + self.strafe_direction) * 8
--stay away from player so as to shoot them --stay away from player so as to shoot them
if self.avoid_distance and dist < self.avoid_distance and self.shooter_avoid_enemy then if self.avoid_distance and dist < self.avoid_distance and self.shooter_avoid_enemy then
local f = 0.3 * (self.avoid_distance - dist) / self.avoid_distance local f = (self.avoid_distance - dist) / self.avoid_distance
self.object:add_velocity(-sin(dir) * f, 0, cos(dir) * f) --self:set_velocity(f * self.walk_velocity) --self.object:add_velocity(vector_new(-sin(dir) * f, 0, cos(dir) * f))
self.acceleration.x = self.acceleration.x - sin(dir) * f * 8
self.acceleration.z = self.acceleration.z + cos(dir) * f * 8
end end
else else
self:set_velocity(0) self:set_velocity(0)

View File

@ -304,7 +304,7 @@ function mob_class:do_jump()
return false return false
end end
v.y = math.min(v.y, 0) + math.sqrt(self.jump_height * 20) + (in_water or self._can_jump_cliff and 0.5 or 0) v.y = math.min(v.y, 0) + math.sqrt(self.jump_height * 20 + (in_water or self._can_jump_cliff and 10 or 0))
v.y = math.min(-self.fall_speed, math.max(v.y, self.fall_speed)) v.y = math.min(-self.fall_speed, math.max(v.y, self.fall_speed))
self.object:set_velocity(v) self.object:set_velocity(v)
self:set_animation("run") self:set_animation("run")
@ -617,9 +617,9 @@ function mob_class:do_states_walk()
-- facing wall? then turn -- facing wall? then turn
local facing_wall = false local facing_wall = false
-- todo: use moveresult collision info here? -- todo: use moveresult collision info here?
if self:get_velocity_xyz() < 0.1 then if moveresult and moveresult.collides and self:get_velocity_xyz() < 0.1 then
facing_wall = true facing_wall = true
elseif not facing_wall then else --if not facing_wall then
local cbox = self.collisionbox local cbox = self.collisionbox
local dir_x, dir_z = -sin(yaw - QUARTERPI) * (cbox[4] + 0.5), cos(yaw - QUARTERPI) * (cbox[4] + 0.5) local dir_x, dir_z = -sin(yaw - QUARTERPI) * (cbox[4] + 0.5), cos(yaw - QUARTERPI) * (cbox[4] + 0.5)
local nodface = minetest.registered_nodes[minetest.get_node(vector_offset(s, dir_x, (cbox[5] - cbox[2]) * 0.5, dir_z)).name] local nodface = minetest.registered_nodes[minetest.get_node(vector_offset(s, dir_x, (cbox[5] - cbox[2]) * 0.5, dir_z)).name]

View File

@ -168,7 +168,7 @@ function mob_class:collision()
local pos = self.object:get_pos() local pos = self.object:get_pos()
if not pos then return 0,0 end if not pos then return 0,0 end
local x, z = 0, 0 local x, z = 0, 0
local width = -self.collisionbox[1] + self.collisionbox[4] + 0.5 local width = -self.collisionbox[1] + self.collisionbox[4]
for _,object in pairs(minetest.get_objects_inside_radius(pos, width)) do for _,object in pairs(minetest.get_objects_inside_radius(pos, width)) do
local ent = object:get_luaentity() local ent = object:get_luaentity()
if object:is_player() or (ent and ent.is_mob and object ~= self.object) then if object:is_player() or (ent and ent.is_mob and object ~= self.object) then
@ -190,19 +190,6 @@ function mob_class:collision()
return x, z return x, z
end end
function mob_class:check_death_and_slow_mob()
local d = 0.7
local dying = self:check_dying()
if dying then d = 0.92 end
local v = self.object:get_velocity()
if v then
--diffuse object velocity
self.object:set_velocity(vector.new(v.x*d, v.y, v.z*d))
end
return dying
end
-- move mob in facing direction -- move mob in facing direction
function mob_class:set_velocity(v) function mob_class:set_velocity(v)
self.target_vel = v self.target_vel = v
@ -880,6 +867,7 @@ function mob_class:limit_vel_acc_for_large_dtime(pos, dtime, moveresult)
-- because we cannot check for collission, we simply allow the extra acceleration to lag a timestep: -- because we cannot check for collission, we simply allow the extra acceleration to lag a timestep:
-- pos = pos + self.acceleration * edtime * 0.5 * rdtime -- pos = pos + self.acceleration * edtime * 0.5 * rdtime
end end
vel.x, vel.z = vel.x * 0.9, vel.z * 0.9 -- general slowdown factor
self.object:set_velocity(vel) self.object:set_velocity(vel)
self.object:set_pos(pos) self.object:set_pos(pos)
return pos return pos
@ -941,8 +929,9 @@ function mob_class:check_water_flow(dtime, pos)
end end
function mob_class:check_dying() function mob_class:check_dying()
if ((self.state and self.state=="die") or self:check_for_death()) and not self.animation.die_end then if (self.state and self.state == "die" or self:check_for_death()) and not self.animation.die_end then
local rot = self.object:get_rotation() local rot = self.object:get_rotation()
self:set_velocity(0) -- intentional movements stop
if rot then if rot then
rot.z = ((HALFPI - rot.z) * .2) + rot.z rot.z = ((HALFPI - rot.z) * .2) + rot.z
self.object:set_rotation(rot) self.object:set_rotation(rot)
@ -957,6 +946,7 @@ function mob_class:check_suspend(player_in_active_range)
self:set_animation("stand", true) self:set_animation("stand", true)
if self.object:get_velocity() then if self.object:get_velocity() then
self.object:set_velocity(vector.zero()) self.object:set_velocity(vector.zero())
self.object:set_acceleration(vector.zero())
end end
return true return true
end end

View File

@ -52,6 +52,7 @@ mcl_mobs.register_mob("mobs_mc:ghast", {
fall_damage = 0, fall_damage = 0,
view_range = 64, view_range = 64,
attack_type = "dogshoot", attack_type = "dogshoot",
see_through_opaque = false,
arrow = "mobs_mc:fireball", arrow = "mobs_mc:fireball",
shoot_interval = 5, shoot_interval = 5,
shoot_offset = -0.5, shoot_offset = -0.5,

View File

@ -117,6 +117,7 @@ mcl_mobs.register_mob("mobs_mc:wither", {
}, },
harmed_by_heal = true, harmed_by_heal = true,
is_boss = true, is_boss = true,
see_through_opaque = false,
extra_hostile = true, extra_hostile = true,
attack_exception = function(p) attack_exception = function(p)
local ent = p:get_luaentity() local ent = p:get_luaentity()
@ -252,7 +253,7 @@ mcl_mobs.register_mob("mobs_mc:wither", {
z = p.z - s.z z = p.z - s.z
} }
local yaw = (atan2(vec.z, vec.x) +math.pi/ 2) - self.rotate local yaw = (math.atan2(vec.z, vec.x) +math.pi/ 2) - self.rotate
if p.x > s.x then yaw = yaw +math.pi end if p.x > s.x then yaw = yaw +math.pi end
yaw = self:set_yaw( yaw, 0, dtime) yaw = self:set_yaw( yaw, 0, dtime)