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.

This commit is contained in:
ancientmarinerdev 2023-05-08 16:28:21 +01:00
parent d14c074d6c
commit 8a771ebfce
6 changed files with 62 additions and 74 deletions

@ -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

@ -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

@ -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

@ -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

@ -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 "",

@ -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},