forked from VoxeLibre/VoxeLibre
Merge pull request 'Add some mob object checks to avoid crashing' (#3324) from fix_ghast_kill_crash into master
Reviewed-on: MineClone2/MineClone2#3324 Reviewed-by: 𝕵𝖔𝖍𝖆𝖓𝖓𝖊𝖘 𝕱𝖗𝖎𝖙𝖟 <mrrar@noreply.git.minetest.land>
This commit is contained in:
commit
6d60fb4160
|
@ -335,24 +335,27 @@ function mob_class:on_step(dtime)
|
||||||
|
|
||||||
if self:check_despawn(pos, dtime) then return true end
|
if self:check_despawn(pos, dtime) then return true end
|
||||||
|
|
||||||
self:slow_mob()
|
if self:check_death_and_slow_mob() then
|
||||||
|
--minetest.log("action", "Mob is dying: ".. tostring(self.name))
|
||||||
|
-- Do we abandon out of here now?
|
||||||
|
end
|
||||||
|
|
||||||
if self:falling(pos) then return end
|
if self:falling(pos) then return end
|
||||||
self:check_suspend()
|
self:check_suspend()
|
||||||
|
|
||||||
self:check_water_flow()
|
|
||||||
|
|
||||||
self:env_danger_movement_checks (dtime)
|
|
||||||
|
|
||||||
if not self.fire_resistant then
|
if not self.fire_resistant then
|
||||||
mcl_burning.tick(self.object, dtime, self)
|
mcl_burning.tick(self.object, dtime, self)
|
||||||
-- mcl_burning.tick may remove object immediately
|
-- mcl_burning.tick may remove object immediately
|
||||||
if not self.object:get_pos() then return end
|
if not self.object:get_pos() then return end
|
||||||
end
|
end
|
||||||
|
|
||||||
if mobs_debug then self:update_tag() end
|
|
||||||
|
|
||||||
if self.state == "die" then return end
|
if self.state == "die" then return end
|
||||||
|
|
||||||
|
self:check_water_flow()
|
||||||
|
self:env_danger_movement_checks (dtime)
|
||||||
|
|
||||||
|
if mobs_debug then self:update_tag() end
|
||||||
|
|
||||||
self:follow_flop() -- Mob following code.
|
self:follow_flop() -- Mob following code.
|
||||||
|
|
||||||
self:set_animation_speed() -- set animation speed relitive to velocity
|
self:set_animation_speed() -- set animation speed relitive to velocity
|
||||||
|
|
|
@ -279,6 +279,7 @@ function mob_class:env_danger_movement_checks(dtime)
|
||||||
yaw = self:set_yaw( yaw, 8)
|
yaw = self:set_yaw( yaw, 8)
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
|
-- This code should probably be moved to movement code
|
||||||
if self.move_in_group ~= false then
|
if self.move_in_group ~= false then
|
||||||
self:check_herd(dtime)
|
self:check_herd(dtime)
|
||||||
end
|
end
|
||||||
|
|
|
@ -47,7 +47,8 @@ end
|
||||||
|
|
||||||
function mob_class:player_in_active_range()
|
function mob_class:player_in_active_range()
|
||||||
for _,p in pairs(minetest.get_connected_players()) do
|
for _,p in pairs(minetest.get_connected_players()) do
|
||||||
if vector.distance(self.object:get_pos(),p:get_pos()) <= mob_active_range then return true end
|
local pos = self.object:get_pos()
|
||||||
|
if pos and vector.distance(pos, p:get_pos()) <= mob_active_range then return true end
|
||||||
-- slightly larger than the mc 32 since mobs spawn on that circle and easily stand still immediately right after spawning.
|
-- slightly larger than the mc 32 since mobs spawn on that circle and easily stand still immediately right after spawning.
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -182,15 +183,17 @@ function mob_class:collision()
|
||||||
return({x,z})
|
return({x,z})
|
||||||
end
|
end
|
||||||
|
|
||||||
function mob_class:slow_mob()
|
function mob_class:check_death_and_slow_mob()
|
||||||
local d = 0.85
|
local d = 0.85
|
||||||
if self:check_dying() then d = 0.92 end
|
local dying = self:check_dying()
|
||||||
|
if dying then d = 0.92 end
|
||||||
|
|
||||||
local v = self.object:get_velocity()
|
local v = self.object:get_velocity()
|
||||||
if v then
|
if v then
|
||||||
--diffuse object velocity
|
--diffuse object velocity
|
||||||
self.object:set_velocity({x = v.x*d, y = v.y, z = v.z*d})
|
self.object:set_velocity({x = v.x*d, y = v.y, z = v.z*d})
|
||||||
end
|
end
|
||||||
|
return dying
|
||||||
end
|
end
|
||||||
|
|
||||||
-- move mob in facing direction
|
-- move mob in facing direction
|
||||||
|
@ -519,17 +522,16 @@ function mob_class:check_for_death(cause, cmi_cause)
|
||||||
|
|
||||||
self:set_velocity(0)
|
self:set_velocity(0)
|
||||||
local acc = self.object:get_acceleration()
|
local acc = self.object:get_acceleration()
|
||||||
acc.x, acc.y, acc.z = 0, DEFAULT_FALL_SPEED, 0
|
if acc then
|
||||||
self.object:set_acceleration(acc)
|
acc.x, acc.y, acc.z = 0, DEFAULT_FALL_SPEED, 0
|
||||||
|
self.object:set_acceleration(acc)
|
||||||
|
end
|
||||||
|
|
||||||
local length
|
local length
|
||||||
-- default death function and die animation (if defined)
|
-- default death function and die animation (if defined)
|
||||||
if self.instant_death then
|
if self.instant_death then
|
||||||
length = 0
|
length = 0
|
||||||
elseif self.animation
|
elseif self.animation and self.animation.die_start and self.animation.die_end then
|
||||||
and self.animation.die_start
|
|
||||||
and self.animation.die_end then
|
|
||||||
|
|
||||||
local frames = self.animation.die_end - self.animation.die_start
|
local frames = self.animation.die_end - self.animation.die_start
|
||||||
local speed = self.animation.die_speed or 15
|
local speed = self.animation.die_speed or 15
|
||||||
length = math.max(frames / speed, 0) + DEATH_DELAY
|
length = math.max(frames / speed, 0) + DEATH_DELAY
|
||||||
|
@ -545,7 +547,6 @@ function mob_class:check_for_death(cause, cmi_cause)
|
||||||
if not self.object:get_luaentity() then
|
if not self.object:get_luaentity() then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
death_handle(self)
|
death_handle(self)
|
||||||
local dpos = self.object:get_pos()
|
local dpos = self.object:get_pos()
|
||||||
local cbox = self.collisionbox
|
local cbox = self.collisionbox
|
||||||
|
@ -554,6 +555,7 @@ function mob_class:check_for_death(cause, cmi_cause)
|
||||||
self.object:remove()
|
self.object:remove()
|
||||||
mcl_mobs.death_effect(dpos, yaw, cbox, not self.instant_death)
|
mcl_mobs.death_effect(dpos, yaw, cbox, not self.instant_death)
|
||||||
end
|
end
|
||||||
|
|
||||||
if length <= 0 then
|
if length <= 0 then
|
||||||
kill(self)
|
kill(self)
|
||||||
else
|
else
|
||||||
|
@ -870,33 +872,32 @@ function mob_class:falling(pos)
|
||||||
|
|
||||||
-- floating in water (or falling)
|
-- floating in water (or falling)
|
||||||
local v = self.object:get_velocity()
|
local v = self.object:get_velocity()
|
||||||
|
if v then
|
||||||
|
if v.y > 0 then
|
||||||
|
-- apply gravity when moving up
|
||||||
|
self.object:set_acceleration({
|
||||||
|
x = 0,
|
||||||
|
y = DEFAULT_FALL_SPEED,
|
||||||
|
z = 0
|
||||||
|
})
|
||||||
|
|
||||||
if v.y > 0 then
|
elseif v.y <= 0 and v.y > self.fall_speed then
|
||||||
|
-- fall downwards at set speed
|
||||||
-- apply gravity when moving up
|
self.object:set_acceleration({
|
||||||
self.object:set_acceleration({
|
x = 0,
|
||||||
x = 0,
|
y = self.fall_speed,
|
||||||
y = DEFAULT_FALL_SPEED,
|
z = 0
|
||||||
z = 0
|
})
|
||||||
})
|
else
|
||||||
|
-- stop accelerating once max fall speed hit
|
||||||
elseif v.y <= 0 and v.y > self.fall_speed then
|
self.object:set_acceleration({x = 0, y = 0, z = 0})
|
||||||
|
end
|
||||||
-- fall downwards at set speed
|
|
||||||
self.object:set_acceleration({
|
|
||||||
x = 0,
|
|
||||||
y = self.fall_speed,
|
|
||||||
z = 0
|
|
||||||
})
|
|
||||||
else
|
|
||||||
-- stop accelerating once max fall speed hit
|
|
||||||
self.object:set_acceleration({x = 0, y = 0, z = 0})
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local acc = self.object:get_acceleration()
|
||||||
|
|
||||||
if minetest.registered_nodes[node_ok(pos).name].groups.lava then
|
if minetest.registered_nodes[node_ok(pos).name].groups.lava then
|
||||||
|
if acc and self.floats_on_lava == 1 then
|
||||||
if self.floats_on_lava == 1 then
|
|
||||||
|
|
||||||
self.object:set_acceleration({
|
self.object:set_acceleration({
|
||||||
x = 0,
|
x = 0,
|
||||||
y = -self.fall_speed / (math.max(1, v.y) ^ 2),
|
y = -self.fall_speed / (math.max(1, v.y) ^ 2),
|
||||||
|
@ -907,9 +908,7 @@ function mob_class:falling(pos)
|
||||||
|
|
||||||
-- in water then float up
|
-- in water then float up
|
||||||
if minetest.registered_nodes[node_ok(pos).name].groups.water then
|
if minetest.registered_nodes[node_ok(pos).name].groups.water then
|
||||||
|
if acc and self.floats == 1 then
|
||||||
if self.floats == 1 then
|
|
||||||
|
|
||||||
self.object:set_acceleration({
|
self.object:set_acceleration({
|
||||||
x = 0,
|
x = 0,
|
||||||
y = -self.fall_speed / (math.max(1, v.y) ^ 2),
|
y = -self.fall_speed / (math.max(1, v.y) ^ 2),
|
||||||
|
@ -917,10 +916,8 @@ function mob_class:falling(pos)
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
|
|
||||||
-- fall damage onto solid ground
|
-- fall damage onto solid ground
|
||||||
if self.fall_damage == 1
|
if self.fall_damage == 1 and self.object:get_velocity().y == 0 then
|
||||||
and self.object:get_velocity().y == 0 then
|
|
||||||
local n = node_ok(vector.offset(pos,0,-1,0)).name
|
local n = node_ok(vector.offset(pos,0,-1,0)).name
|
||||||
local d = (self.old_y or 0) - self.object:get_pos().y
|
local d = (self.old_y or 0) - self.object:get_pos().y
|
||||||
|
|
||||||
|
@ -981,24 +978,31 @@ 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()
|
||||||
rot.z = ((math.pi/2-rot.z)*.2)+rot.z
|
if rot then
|
||||||
self.object:set_rotation(rot)
|
rot.z = ((math.pi/2-rot.z)*.2)+rot.z
|
||||||
|
self.object:set_rotation(rot)
|
||||||
|
end
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function mob_class:check_suspend()
|
function mob_class:check_suspend()
|
||||||
if not self:player_in_active_range() then
|
local pos = self.object:get_pos()
|
||||||
local pos = self.object:get_pos()
|
|
||||||
|
if pos and not self:player_in_active_range() then
|
||||||
local node_under = node_ok(vector.offset(pos,0,-1,0)).name
|
local node_under = node_ok(vector.offset(pos,0,-1,0)).name
|
||||||
local acc = self.object:get_acceleration()
|
|
||||||
self:set_animation( "stand", true)
|
self:set_animation( "stand", true)
|
||||||
if acc.y > 0 or node_under ~= "air" then
|
|
||||||
self.object:set_acceleration(vector.new(0,0,0))
|
local acc = self.object:get_acceleration()
|
||||||
self.object:set_velocity(vector.new(0,0,0))
|
if acc then
|
||||||
end
|
if acc.y > 0 or node_under ~= "air" then
|
||||||
if acc.y == 0 and node_under == "air" then
|
self.object:set_acceleration(vector.new(0,0,0))
|
||||||
self:falling(pos)
|
self.object:set_velocity(vector.new(0,0,0))
|
||||||
|
end
|
||||||
|
if acc.y == 0 and node_under == "air" then
|
||||||
|
self:falling(pos)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue