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
-- not used yet
function mob_class:safe_remove()
self.removed = true
self._removed = true
minetest.after(0,function(obj)
if obj and obj:get_pos() then
mcl_burning.extinguish(obj)
@ -121,14 +122,11 @@ end
function mob_class:mob_activate(staticdata, def, dtime)
if not self.object:get_pos() or staticdata == "remove" then
mcl_burning.extinguish(self.object)
self.object:remove()
self:safe_remove()
return
end
if self.type == "monster"
and minetest.settings:get_bool("only_peaceful_mobs", false) then
mcl_burning.extinguish(self.object)
self.object:remove()
if self.type == "monster" and minetest.settings:get_bool("only_peaceful_mobs", false) then
self:safe_remove()
return
end
@ -310,16 +308,17 @@ end
local function on_step_work(self, dtime, moveresult)
local pos = self.object:get_pos()
if not pos or self.removed then return end
if self:check_despawn(pos, dtime) then return end
if not pos or self._removed 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
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()
-- 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: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
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
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
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
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
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
self.object:add_velocity(-sin(dir) * f, 0, cos(dir) * f)
local f = (self.avoid_distance - dist) / self.avoid_distance
--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
else
self:set_velocity(0)
@ -1020,7 +1023,7 @@ function mob_class:do_states_attack(dtime)
if self.shoot_interval and self.timer > self.shoot_interval and random(1, 100) <= 60
and not minetest.raycast(vector_offset(p, 0, self.shoot_offset, 0), vector_offset(self.attack:get_pos(), 0, 1.5, 0), false, false):next() then
self.timer = 0
self:set_animation( "shoot")
self:set_animation("shoot")
-- play shoot attack sound
self:mob_sound("shoot_attack")

View File

@ -304,7 +304,7 @@ function mob_class:do_jump()
return false
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))
self.object:set_velocity(v)
self:set_animation("run")
@ -617,9 +617,9 @@ function mob_class:do_states_walk()
-- facing wall? then turn
local facing_wall = false
-- 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
elseif not facing_wall then
else --if not facing_wall then
local cbox = self.collisionbox
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]

View File

@ -168,7 +168,7 @@ function mob_class:collision()
local pos = self.object:get_pos()
if not pos then return 0,0 end
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
local ent = object:get_luaentity()
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
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
function mob_class:set_velocity(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:
-- pos = pos + self.acceleration * edtime * 0.5 * rdtime
end
vel.x, vel.z = vel.x * 0.9, vel.z * 0.9 -- general slowdown factor
self.object:set_velocity(vel)
self.object:set_pos(pos)
return pos
@ -941,8 +929,9 @@ function mob_class:check_water_flow(dtime, pos)
end
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()
self:set_velocity(0) -- intentional movements stop
if rot then
rot.z = ((HALFPI - rot.z) * .2) + rot.z
self.object:set_rotation(rot)
@ -957,6 +946,7 @@ function mob_class:check_suspend(player_in_active_range)
self:set_animation("stand", true)
if self.object:get_velocity() then
self.object:set_velocity(vector.zero())
self.object:set_acceleration(vector.zero())
end
return true
end

View File

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

View File

@ -117,6 +117,7 @@ mcl_mobs.register_mob("mobs_mc:wither", {
},
harmed_by_heal = true,
is_boss = true,
see_through_opaque = false,
extra_hostile = true,
attack_exception = function(p)
local ent = p:get_luaentity()
@ -252,7 +253,7 @@ mcl_mobs.register_mob("mobs_mc:wither", {
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
yaw = self:set_yaw( yaw, 0, dtime)