From 8a771ebfce80dc2967147cabbbd78eaa1743fd94 Mon Sep 17 00:00:00 2001 From: ancientmarinerdev Date: Mon, 8 May 2023 16:28:21 +0100 Subject: [PATCH] Allow adjustment of attack frequency. Reduce attack frequency of Hoglins. Move on_step and do_states functionality off of the attack timer on to their own timer. --- mods/ENTITIES/mcl_mobs/api.lua | 68 +++++++++---------------- mods/ENTITIES/mcl_mobs/api.txt | 1 + mods/ENTITIES/mcl_mobs/combat.lua | 50 +++++++----------- mods/ENTITIES/mcl_mobs/effects.lua | 15 ++++++ mods/ENTITIES/mcl_mobs/init.lua | 1 + mods/ENTITIES/mobs_mc/hoglin+zoglin.lua | 1 + 6 files changed, 62 insertions(+), 74 deletions(-) diff --git a/mods/ENTITIES/mcl_mobs/api.lua b/mods/ENTITIES/mcl_mobs/api.lua index 622366fea..231d23fdb 100644 --- a/mods/ENTITIES/mcl_mobs/api.lua +++ b/mods/ENTITIES/mcl_mobs/api.lua @@ -300,20 +300,28 @@ end function mob_class:do_states(dtime) --if self.can_open_doors then check_doors(self) end - if self.state == "stand" then - self:do_states_stand() - elseif self.state == PATHFINDING then + -- knockback timer. set in on_punch + if self.pause_timer > 0 then + self.pause_timer = self.pause_timer - dtime + return + end + + if self.state == PATHFINDING then self:check_gowp(dtime) - elseif self.state == "walk" then - self:do_states_walk() - elseif self.state == "runaway" then - -- runaway when punched - self:do_states_runaway() elseif self.state == "attack" then - -- attack routines (explode, dogfight, shoot, dogshoot) if self:do_states_attack(dtime) then return true end + else + if mcl_util.check_dtime_timer(self, dtime, "onstep_dostates", 1) then + if self.state == "stand" then + self:do_states_stand() + elseif self.state == "walk" then + self:do_states_walk() + elseif self.state == "runaway" then + self:do_states_runaway() + end + end end end @@ -323,21 +331,6 @@ local function update_timers (self, dtime) self.pause_timer = self.pause_timer - dtime return true end - - -- attack timer. Not anymore, it seems. Used for also occassionally processing mob step too! - self.timer = self.timer + dtime - - if self.state ~= "attack" and self.state ~= PATHFINDING then - if self.timer < 1 then - return true - end - self.timer = 0 - end - - -- never go over 100 - if self.timer > 100 then - self.timer = 1 - end end function mob_class:outside_limits() @@ -364,6 +357,8 @@ function mob_class:outside_limits() end end + + local function on_step_work (self, dtime) local pos = self.object:get_pos() if not pos then return end @@ -424,35 +419,22 @@ local function on_step_work (self, dtime) self:check_aggro(dtime) + self:check_particlespawners(dtime) + if self.do_custom and self.do_custom(self, dtime) == false then return end - -- In certain circumstances, we abandon processing of certain functionality - local skip_processing = false - if update_timers(self, dtime) then - skip_processing = true - end - - if not skip_processing then + if mcl_util.check_dtime_timer(self, dtime, "onstep_occassional", 1) then self:check_breeding() if player_in_active_range then self:check_item_pickup() self:set_armor_texture() - - if self.opinion_sound_cooloff > 0 then - self.opinion_sound_cooloff = self.opinion_sound_cooloff - dtime - end - -- mob plays random sound at times. Should be 120. Zombie and mob farms are ridiculous - if math.random(1, 70) == 1 then - self:mob_sound("random", true) - end + self:step_opinion_sound(dtime) end - - self:check_particlespawners(dtime) - - if self:do_states(dtime) then return end end + if self:do_states(dtime) then return end + if mobs_debug then self:update_tag() end if not self.object:get_luaentity() then diff --git a/mods/ENTITIES/mcl_mobs/api.txt b/mods/ENTITIES/mcl_mobs/api.txt index 5b5809bca..fe0da4be2 100644 --- a/mods/ENTITIES/mcl_mobs/api.txt +++ b/mods/ENTITIES/mcl_mobs/api.txt @@ -262,6 +262,7 @@ functions needed for the mob to work properly which contains the following: 'custom_visual_size' will not reset visual_size from the base class on reload 'noyaw' If true this mob will not automatically change yaw 'particlespawners' Table of particlespawners attached to the mob. This is implemented in a coord safe manner i.e. spawners are only sent to players within the player_transfer_distance (and automatically removed). This enables infinitely lived particlespawners. + 'attack_frequency' Attack frequency in seconds. If unset, this defaults to 1. Implemented for melee only atm. mobs:gopath(self,target,callback_arrived) pathfind a way to target and run callback on arrival diff --git a/mods/ENTITIES/mcl_mobs/combat.lua b/mods/ENTITIES/mcl_mobs/combat.lua index 872a85d46..0ec1044f5 100644 --- a/mods/ENTITIES/mcl_mobs/combat.lua +++ b/mods/ENTITIES/mcl_mobs/combat.lua @@ -835,6 +835,11 @@ function mob_class:do_states_attack (dtime) local s = self.object:get_pos() local p = self.attack:get_pos() or s + self.timer = self.timer + dtime + if self.timer > 100 then + self.timer = 1 + end + -- stop attacking if player invisible or out of range if not self.attack or not self.attack:get_pos() @@ -1033,54 +1038,45 @@ function mob_class:do_states_attack (dtime) -- move towards enemy if beyond mob reach if dist > self.reach then - -- path finding by rnd - if self.pathfinding -- only if mob has pathfinding enabled - and enable_pathfinding then - + if enable_pathfinding and self.pathfinding then self:smart_mobs(s, p, dist, dtime) end if self:is_at_cliff_or_danger() then - self:set_velocity( 0) self:set_animation( "stand") local yaw = self.object:get_yaw() or 0 yaw = self:set_yaw( yaw + 0.78, 8) else - if self.path.stuck then - self:set_velocity( self.walk_velocity) + self:set_velocity(self.walk_velocity) else - self:set_velocity( self.run_velocity) + self:set_velocity(self.run_velocity) end - if self.animation and self.animation.run_start then - self:set_animation( "run") + self:set_animation("run") else - self:set_animation( "walk") + self:set_animation("walk") end end - else -- rnd: if inside reach range - self.path.stuck = false self.path.stuck_timer = 0 self.path.following = false -- not stuck anymore self:set_velocity( 0) - if not self.custom_attack then + local attack_frequency = self.attack_frequency or 1 - if self.timer > 1 then + if self.timer > attack_frequency then + self.timer = 0 - self.timer = 0 - - if self.double_melee_attack - and math.random(1, 2) == 1 then - self:set_animation( "punch2") + if not self.custom_attack then + if self.double_melee_attack and math.random(1, 2) == 1 then + self:set_animation("punch2") else - self:set_animation( "punch") + self:set_animation("punch") end local p2 = p @@ -1090,8 +1086,6 @@ function mob_class:do_states_attack (dtime) s2.y = s2.y + .5 if self:line_of_sight( p2, s2) == true then - - -- play attack sound self:mob_sound("attack") -- punch player (or what player is attached to) @@ -1104,13 +1098,7 @@ function mob_class:do_states_attack (dtime) damage_groups = {fleshy = self.damage} }, nil) end - end - else -- call custom attack every second - if self.custom_attack - and self.timer > 1 then - - self.timer = 0 - + else self.custom_attack(self, p) end end @@ -1136,7 +1124,7 @@ function mob_class:do_states_attack (dtime) yaw = self:set_yaw( yaw, 0, dtime) - local stay_away_from_player = vector.new(0,0,0) + local stay_away_from_player = vector.zero() --strafe back and fourth diff --git a/mods/ENTITIES/mcl_mobs/effects.lua b/mods/ENTITIES/mcl_mobs/effects.lua index 4a4452f7f..696994d0d 100644 --- a/mods/ENTITIES/mcl_mobs/effects.lua +++ b/mods/ENTITIES/mcl_mobs/effects.lua @@ -4,6 +4,8 @@ local active_particlespawners = {} local disable_blood = minetest.settings:get_bool("mobs_disable_blood") local DEFAULT_FALL_SPEED = -9.81*1.5 +local PATHFINDING = "gowp" + local player_transfer_distance = tonumber(minetest.settings:get("player_transfer_distance")) or 128 if player_transfer_distance == 0 then player_transfer_distance = math.huge end @@ -136,6 +138,19 @@ function mob_class:mob_sound(soundname, is_opinion, fixed_pitch) end end +function mob_class:step_opinion_sound(dtime) + if self.state ~= "attack" and self.state ~= PATHFINDING then + + if self.opinion_sound_cooloff > 0 then + self.opinion_sound_cooloff = self.opinion_sound_cooloff - dtime + end + -- mob plays random sound at times. Should be 120. Zombie and mob farms are ridiculous + if math.random(1, 70) == 1 then + self:mob_sound("random", true) + end + end +end + function mob_class:add_texture_mod(mod) local full_mod = "" local already_added = false diff --git a/mods/ENTITIES/mcl_mobs/init.lua b/mods/ENTITIES/mcl_mobs/init.lua index bdc062470..6bd39b2cf 100644 --- a/mods/ENTITIES/mcl_mobs/init.lua +++ b/mods/ENTITIES/mcl_mobs/init.lua @@ -154,6 +154,7 @@ function mcl_mobs.register_mob(name, def) description = def.description, type = def.type, attack_type = def.attack_type, + attack_frequency = def.attack_frequency, fly = def.fly or false, fly_in = def.fly_in or {"air", "__airlike"}, owner = def.owner or "", diff --git a/mods/ENTITIES/mobs_mc/hoglin+zoglin.lua b/mods/ENTITIES/mobs_mc/hoglin+zoglin.lua index 8bad858a8..7154a6537 100644 --- a/mods/ENTITIES/mobs_mc/hoglin+zoglin.lua +++ b/mods/ENTITIES/mobs_mc/hoglin+zoglin.lua @@ -19,6 +19,7 @@ local hoglin = { xp_max = 9, armor = {fleshy = 90}, attack_type = "dogfight", + attack_frequency = 3; damage = 4, reach = 3, collisionbox = {-.6, -0.01, -.6, .6, 1.4, .6},