Make mobs respect liquid/climbable physics if dead

This commit is contained in:
Wuzzy 2024-04-06 18:12:43 +02:00
parent 4bbfac8e05
commit b2f1b18e88
8 changed files with 47 additions and 11 deletions

View File

@ -1,6 +1,7 @@
-- Behavior functions for land animals
local DEATH_DRAG = 0.05
local DEATH_DRAG_LIQUID = 0.2
local random_yaw = function()
return math.random(0, 360) / 360 * (math.pi*2)
@ -282,9 +283,38 @@ rp_mobs_mobs.task_queues.land_roam = function(settings)
return tq
end
-- Default mob physics for dying
rp_mobs_mobs.land_roamer_dying_step = function(self, dtime)
-- Make mob come to a halt horizontally
rp_mobs.drag(self, dtime, vector.new(DEATH_DRAG, 0, DEATH_DRAG), {"x", "z"})
-- Returns a default dying_step functionn for `rp_mobs.handle_dying`.
-- If enabled, this can toggle gravity in liquids climbable nodes,
-- and put the mob smoothly to a halt using drag.
-- This assumes that `rp_mobs.scan_environment` is used.
-- Parameters:
-- * `can_swim`: turn off gravity in swimmable nodes
-- * `can_climb`: turn off gravity in climbable nodes
rp_mobs_mobs.get_dying_step = function(can_swim, can_climb)
return function(mob, dtime)
if not mob._env_node then
return
end
local drag, drag_axes
local grav = mob._temp_custom_state.dying_gravity == true
if (can_swim and (rp_mobs_mobs.is_liquid(mob._env_node.name) or rp_mobs_mobs.is_liquid(mob._env_node_floor.name)))
or (can_climb and (rp_mobs_mobs.is_climbable(mob._env_node.name) or rp_mobs_mobs.is_climbable(mob._env_node_floor.name))) then
-- Make mob come to a halt horizontally and vertically
drag = vector.new(DEATH_DRAG, DEATH_DRAG_LIQUID, DEATH_DRAG)
drag_axes = { "x", "y", "z" }
if grav then
mob.object:set_acceleration(vector.zero())
mob._temp_custom_state.dying_gravity = false
end
else
-- Make mob come to a halt horizontally
drag = vector.new(DEATH_DRAG, 0, DEATH_DRAG)
drag_axes = { "x", "z" }
if not grav then
mob.object:set_acceleration(rp_mobs.GRAVITY_VECTOR)
mob._temp_custom_state.dying_gravity = true
end
end
rp_mobs.drag(mob, dtime, drag, drag_axes)
end
end

View File

@ -101,7 +101,7 @@ rp_mobs.register_mob("rp_mobs_mobs:boar", {
end,
get_staticdata = rp_mobs.get_staticdata_default,
on_step = function(self, dtime, moveresult)
rp_mobs.handle_dying(self, dtime, moveresult, rp_mobs_mobs.land_roamer_dying_step)
rp_mobs.handle_dying(self, dtime, moveresult, rp_mobs_mobs.get_dying_step(true, false))
rp_mobs.scan_environment(self, dtime, -0.3)
rp_mobs.handle_environment_damage(self, dtime, moveresult)
rp_mobs.handle_tasks(self, dtime, moveresult)

View File

@ -207,7 +207,7 @@ rp_mobs.register_mob("rp_mobs_mobs:mineturtle", {
end,
get_staticdata = rp_mobs.get_staticdata_default,
on_step = function(self, dtime, moveresult)
rp_mobs.handle_dying(self, dtime, moveresult, rp_mobs_mobs.land_roamer_dying_step)
rp_mobs.handle_dying(self, dtime, moveresult, rp_mobs_mobs.get_dying_step(true, false))
rp_mobs.scan_environment(self, dtime, -0.3)
rp_mobs.handle_environment_damage(self, dtime, moveresult)
rp_mobs.handle_tasks(self, dtime, moveresult)

View File

@ -220,7 +220,7 @@ rp_mobs.register_mob("rp_mobs_mobs:sheep", {
end,
get_staticdata = rp_mobs.get_staticdata_default,
on_step = function(self, dtime, moveresult)
rp_mobs.handle_dying(self, dtime, moveresult, rp_mobs_mobs.land_roamer_dying_step)
rp_mobs.handle_dying(self, dtime, moveresult, rp_mobs_mobs.get_dying_step(true, false))
rp_mobs.scan_environment(self, dtime, -0.3)
rp_mobs.handle_environment_damage(self, dtime, moveresult)
rp_mobs.handle_tasks(self, dtime, moveresult)

View File

@ -90,7 +90,7 @@ rp_mobs.register_mob("rp_mobs_mobs:skunk", {
end,
get_staticdata = rp_mobs.get_staticdata_default,
on_step = function(self, dtime, moveresult)
rp_mobs.handle_dying(self, dtime, moveresult, rp_mobs_mobs.land_roamer_dying_step)
rp_mobs.handle_dying(self, dtime, moveresult, rp_mobs_mobs.get_dying_step(true, false))
rp_mobs.scan_environment(self, dtime, -0.1)
rp_mobs.handle_environment_damage(self, dtime, moveresult)
rp_mobs.handle_tasks(self, dtime, moveresult)

View File

@ -1362,7 +1362,7 @@ rp_mobs.register_mob("rp_mobs_mobs:villager", {
rp_mobs.add_task_queue(self, find_sites_task_queue)
end,
on_step = function(self, dtime, moveresult)
rp_mobs.handle_dying(self, dtime, moveresult, rp_mobs_mobs.land_roamer_dying_step)
rp_mobs.handle_dying(self, dtime, moveresult, rp_mobs_mobs.get_dying_step(true, true))
rp_mobs.scan_environment(self, dtime)
rp_mobs.handle_environment_damage(self, dtime, moveresult)
rp_mobs.handle_tasks(self, dtime, moveresult)

View File

@ -96,7 +96,7 @@ rp_mobs.register_mob("rp_mobs_mobs:walker", {
end,
get_staticdata = rp_mobs.get_staticdata_default,
on_step = function(self, dtime, moveresult)
rp_mobs.handle_dying(self, dtime, moveresult, rp_mobs_mobs.land_roamer_dying_step)
rp_mobs.handle_dying(self, dtime, moveresult, rp_mobs_mobs.get_dying_step(true, false))
rp_mobs.scan_environment(self, dtime, -0.5)
rp_mobs.handle_environment_damage(self, dtime, moveresult)
rp_mobs.handle_tasks(self, dtime, moveresult)

View File

@ -25,6 +25,12 @@ rp_mobs_mobs.is_walkable = function(nodename)
return ndef and ndef.walkable
end
-- Returns true if node is climbable
rp_mobs_mobs.is_climbable = function(nodename)
local ndef = minetest.registered_nodes[nodename]
return ndef and ndef.climbable
end
-- Returns true if the node(s) in front of the mob are safe.
-- This is considered unsafe:
-- * damage_per_second > 0