From 519b237ba85d570d28d2f905e3341bfbe113afde Mon Sep 17 00:00:00 2001 From: ancientmarinerdev Date: Fri, 12 May 2023 19:42:55 +0100 Subject: [PATCH] Jumping check only called once per mob_step and refactor duplicate water danger, cliff fall logic --- mods/ENTITIES/mcl_mobs/api.lua | 27 ++++++----- mods/ENTITIES/mcl_mobs/movement.lua | 75 ++++++++++++++--------------- 2 files changed, 52 insertions(+), 50 deletions(-) diff --git a/mods/ENTITIES/mcl_mobs/api.lua b/mods/ENTITIES/mcl_mobs/api.lua index 092c8939c..485ea1f65 100644 --- a/mods/ENTITIES/mcl_mobs/api.lua +++ b/mods/ENTITIES/mcl_mobs/api.lua @@ -325,6 +325,8 @@ function mob_class:do_states(dtime) return end + self:env_danger_movement_checks (dtime) + if self.state == PATHFINDING then self:check_gowp(dtime) elseif self.state == "attack" then @@ -405,13 +407,13 @@ local function on_step_work (self, dtime) -- End: Death/damage processing self:check_water_flow() - self:env_danger_movement_checks (dtime) - if player_in_active_range then - if mcl_util.check_dtime_timer(self, dtime, "onstep_follow", 0.2) then - self:check_follow() - end + if not self._jumping_cliff then + self._can_jump_cliff = self:can_jump_cliff() + else + self._can_jump_cliff = false end + self:flop() self:check_smooth_rotation(dtime) @@ -421,14 +423,17 @@ local function on_step_work (self, dtime) self:check_head_swivel(dtime) - if self.jump_sound_cooloff > 0 then self.jump_sound_cooloff = self.jump_sound_cooloff - dtime end - self:do_jump() - - self:check_runaway_from() - self:monster_attack() - self:npc_attack() + if mcl_util.check_dtime_timer(self, dtime, "onstep_engage", 0.2) then + self:check_follow() + self:check_runaway_from() + self:monster_attack() + self:npc_attack() + end self:check_herd(dtime) + + if self.jump_sound_cooloff > 0 then self.jump_sound_cooloff = self.jump_sound_cooloff - dtime end + self:do_jump() end self:check_aggro(dtime) diff --git a/mods/ENTITIES/mcl_mobs/movement.lua b/mods/ENTITIES/mcl_mobs/movement.lua index 21595ef54..147930b87 100644 --- a/mods/ENTITIES/mcl_mobs/movement.lua +++ b/mods/ENTITIES/mcl_mobs/movement.lua @@ -4,8 +4,9 @@ local DEFAULT_FALL_SPEED = -9.81*1.5 local FLOP_HEIGHT = 6 local FLOP_HOR_SPEED = 1.5 -local node_snow = "mcl_core:snow" +local CHECK_HERD_FREQUENCY = 4 +local node_snow = "mcl_core:snow" local mobs_griefing = minetest.settings:get_bool("mobs_griefing") ~= false @@ -202,12 +203,8 @@ function mob_class:can_jump_cliff() end -- is mob facing a cliff or danger -function mob_class:is_at_cliff_or_danger(can_jump_cliff) - if can_jump_cliff == nil then - can_jump_cliff = self:can_jump_cliff() - end - - if self.fear_height == 0 or can_jump_cliff or self._jumping_cliff or not self.object:get_luaentity() then -- 0 for no falling protection! +function mob_class:is_at_cliff_or_danger() + if self.fear_height == 0 or self._jumping_cliff or self._can_jump_cliff or not self.object:get_luaentity() then -- 0 for no falling protection! return false end @@ -242,12 +239,16 @@ end -- copy the 'mob facing cliff_or_danger check' from above, and rework to avoid water -function mob_class:is_at_water_danger(can_jump_cliff) - if can_jump_cliff == nil then - can_jump_cliff = self:can_jump_cliff() +function mob_class:is_at_water_danger() + if self.water_damage == 0 and self.breath_max == -1 then + --minetest.log("Do not need a water check for: " .. self.name) + return end - if not self.object:get_luaentity() or can_jump_cliff or self._jumping_cliff then + local in_water_danger = self:is_node_waterhazard(self.standing_in) or self:is_node_waterhazard(self.standing_on) + if in_water_danger then return false end -- If you're in trouble, do not stop + + if not self.object:get_luaentity() or self._jumping_cliff or self._can_jump_cliff then return false end local yaw = self.object:get_yaw() @@ -262,25 +263,16 @@ function mob_class:is_at_water_danger(can_jump_cliff) local ypos = pos.y + self.collisionbox[2] -- just above floor - local free_fall, blocker = minetest.line_of_sight( + local los, blocker = minetest.line_of_sight( vector.new(pos.x + dir_x, ypos, pos.z + dir_z), vector.new(pos.x + dir_x, ypos - 3, pos.z + dir_z)) - if free_fall then - return true - else + if not los then local bnode = minetest.get_node(blocker) local waterdanger = self:is_node_waterhazard(bnode.name) - if - waterdanger and (self:is_node_waterhazard(self.standing_in) or self:is_node_waterhazard( self.standing_on)) then - return false - elseif waterdanger and (self:is_node_waterhazard(self.standing_in) or self:is_node_waterhazard(self.standing_on)) == false then + + if waterdanger and not in_water_danger then return true - else - local def = minetest.registered_nodes[bnode.name] - if def and def.walkable then - return false - end end end @@ -290,24 +282,29 @@ end function mob_class:env_danger_movement_checks(dtime) local yaw = 0 - local can_jump_cliff = self:can_jump_cliff() - if self.state ~= "attack" and self:is_at_water_danger(can_jump_cliff) then - if math.random(1, 10) <= 6 then - self:set_velocity(0) - self.state = "stand" - self:set_animation( "stand") + if self.state ~= "attack" and self:is_at_water_danger() then + --minetest.log("At water danger for mob, stop?: " .. self.name) + if math.random(1, 10) <= 7 then + if self.state ~= "stand" then + self:set_velocity(0) + self.state = "stand" + self:set_animation( "stand") + end yaw = yaw + math.random(-0.5, 0.5) yaw = self:set_yaw( yaw, 8) + return end end - if self:is_at_cliff_or_danger(can_jump_cliff) then - self:set_velocity(0) - self.state = "stand" - self:set_animation( "stand") + --[[if self:is_at_cliff_or_danger(can_jump_cliff) then + if self.state ~= "stand" then + self:set_velocity(0) + self.state = "stand" + self:set_animation( "stand") + end local yaw = self.object:get_yaw() or 0 yaw = self:set_yaw( yaw + 0.78, 8) - end + end--]] end -- jump if facing a solid node (not fences or gates) @@ -378,7 +375,7 @@ function mob_class:do_jump() end local ndef = minetest.registered_nodes[nod.name] - if self.walk_chance == 0 or ndef and ndef.walkable or self:can_jump_cliff() then + if self.walk_chance == 0 or ndef and ndef.walkable or self._can_jump_cliff then if minetest.get_item_group(nod.name, "fence") == 0 and minetest.get_item_group(nod.name, "fence_gate") == 0 @@ -388,7 +385,7 @@ function mob_class:do_jump() v.y = self.jump_height + 0.1 * 3 - if self:can_jump_cliff() then + if self._can_jump_cliff then v=vector.multiply(v, vector.new(2.8,1,2.8)) end @@ -724,7 +721,7 @@ function mob_class:flop() return elseif self.state == "flop" then self.state = "stand" - self.object:set_acceleration({x = 0, y = 0, z = 0}) + self.object:set_acceleration(vector.zero()) self:set_velocity(0) end end @@ -756,7 +753,7 @@ function mob_class:check_herd(dtime) if self.move_in_group == false then return end check_herd_timer = check_herd_timer + dtime - if check_herd_timer < 4 then return end + if check_herd_timer < CHECK_HERD_FREQUENCY then return end check_herd_timer = 0 for _,o in pairs(minetest.get_objects_inside_radius(pos,self.view_range)) do local l = o:get_luaentity()