forked from VoxeLibre/VoxeLibre
Merge pull request 'Hoglins attack frequency reduced now due to new attack_frequency mob setting' (#3700) from hoglin_attack_fix into master
Reviewed-on: MineClone2/MineClone2#3700
This commit is contained in:
commit
c62694f9e4
|
@ -300,43 +300,28 @@ end
|
||||||
function mob_class:do_states(dtime)
|
function mob_class:do_states(dtime)
|
||||||
--if self.can_open_doors then check_doors(self) end
|
--if self.can_open_doors then check_doors(self) end
|
||||||
|
|
||||||
if self.state == "stand" then
|
|
||||||
self:do_states_stand()
|
|
||||||
elseif 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
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local function update_timers (self, dtime)
|
|
||||||
-- knockback timer. set in on_punch
|
-- knockback timer. set in on_punch
|
||||||
if self.pause_timer > 0 then
|
if self.pause_timer > 0 then
|
||||||
self.pause_timer = self.pause_timer - dtime
|
self.pause_timer = self.pause_timer - dtime
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
if self.state == PATHFINDING then
|
||||||
|
self:check_gowp(dtime)
|
||||||
|
elseif self.state == "attack" then
|
||||||
|
if self:do_states_attack(dtime) then
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
else
|
||||||
-- attack timer. Not anymore, it seems. Used for also occassionally processing mob step too!
|
if mcl_util.check_dtime_timer(self, dtime, "onstep_dostates", 1) then
|
||||||
self.timer = self.timer + dtime
|
if self.state == "stand" then
|
||||||
|
self:do_states_stand()
|
||||||
if self.state ~= "attack" and self.state ~= PATHFINDING then
|
elseif self.state == "walk" then
|
||||||
if self.timer < 1 then
|
self:do_states_walk()
|
||||||
return true
|
elseif self.state == "runaway" then
|
||||||
|
self:do_states_runaway()
|
||||||
end
|
end
|
||||||
self.timer = 0
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- never go over 100
|
|
||||||
if self.timer > 100 then
|
|
||||||
self.timer = 1
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -364,6 +349,8 @@ function mob_class:outside_limits()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
local function on_step_work (self, dtime)
|
local function on_step_work (self, dtime)
|
||||||
local pos = self.object:get_pos()
|
local pos = self.object:get_pos()
|
||||||
if not pos then return end
|
if not pos then return end
|
||||||
|
@ -424,34 +411,21 @@ local function on_step_work (self, dtime)
|
||||||
|
|
||||||
self:check_aggro(dtime)
|
self:check_aggro(dtime)
|
||||||
|
|
||||||
|
self:check_particlespawners(dtime)
|
||||||
|
|
||||||
if self.do_custom and self.do_custom(self, dtime) == false then return end
|
if self.do_custom and self.do_custom(self, dtime) == false then return end
|
||||||
|
|
||||||
-- In certain circumstances, we abandon processing of certain functionality
|
if mcl_util.check_dtime_timer(self, dtime, "onstep_occassional", 1) then
|
||||||
local skip_processing = false
|
|
||||||
if update_timers(self, dtime) then
|
|
||||||
skip_processing = true
|
|
||||||
end
|
|
||||||
|
|
||||||
if not skip_processing then
|
|
||||||
self:check_breeding()
|
self:check_breeding()
|
||||||
|
|
||||||
if player_in_active_range then
|
if player_in_active_range then
|
||||||
self:check_item_pickup()
|
self:check_item_pickup()
|
||||||
self:set_armor_texture()
|
self:set_armor_texture()
|
||||||
|
self:step_opinion_sound(dtime)
|
||||||
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
|
end
|
||||||
|
|
||||||
self:check_particlespawners(dtime)
|
|
||||||
|
|
||||||
if self:do_states(dtime) then return end
|
if self:do_states(dtime) then return end
|
||||||
end
|
|
||||||
|
|
||||||
if mobs_debug then self:update_tag() end
|
if mobs_debug then self:update_tag() end
|
||||||
|
|
||||||
|
|
|
@ -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
|
'custom_visual_size' will not reset visual_size from the base class on reload
|
||||||
'noyaw' If true this mob will not automatically change yaw
|
'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.
|
'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
|
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 s = self.object:get_pos()
|
||||||
local p = self.attack:get_pos() or s
|
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
|
-- stop attacking if player invisible or out of range
|
||||||
if not self.attack
|
if not self.attack
|
||||||
or not self.attack:get_pos()
|
or not self.attack:get_pos()
|
||||||
|
@ -1033,51 +1038,42 @@ function mob_class:do_states_attack (dtime)
|
||||||
|
|
||||||
-- move towards enemy if beyond mob reach
|
-- move towards enemy if beyond mob reach
|
||||||
if dist > self.reach then
|
if dist > self.reach then
|
||||||
|
|
||||||
-- path finding by rnd
|
-- path finding by rnd
|
||||||
if self.pathfinding -- only if mob has pathfinding enabled
|
if enable_pathfinding and self.pathfinding then
|
||||||
and enable_pathfinding then
|
|
||||||
|
|
||||||
self:smart_mobs(s, p, dist, dtime)
|
self:smart_mobs(s, p, dist, dtime)
|
||||||
end
|
end
|
||||||
|
|
||||||
if self:is_at_cliff_or_danger() then
|
if self:is_at_cliff_or_danger() then
|
||||||
|
|
||||||
self:set_velocity( 0)
|
self:set_velocity( 0)
|
||||||
self:set_animation( "stand")
|
self:set_animation( "stand")
|
||||||
local yaw = self.object:get_yaw() or 0
|
local yaw = self.object:get_yaw() or 0
|
||||||
yaw = self:set_yaw( yaw + 0.78, 8)
|
yaw = self:set_yaw( yaw + 0.78, 8)
|
||||||
else
|
else
|
||||||
|
|
||||||
if self.path.stuck then
|
if self.path.stuck then
|
||||||
self:set_velocity(self.walk_velocity)
|
self:set_velocity(self.walk_velocity)
|
||||||
else
|
else
|
||||||
self:set_velocity(self.run_velocity)
|
self:set_velocity(self.run_velocity)
|
||||||
end
|
end
|
||||||
|
|
||||||
if self.animation and self.animation.run_start then
|
if self.animation and self.animation.run_start then
|
||||||
self:set_animation("run")
|
self:set_animation("run")
|
||||||
else
|
else
|
||||||
self:set_animation("walk")
|
self:set_animation("walk")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
else -- rnd: if inside reach range
|
else -- rnd: if inside reach range
|
||||||
|
|
||||||
self.path.stuck = false
|
self.path.stuck = false
|
||||||
self.path.stuck_timer = 0
|
self.path.stuck_timer = 0
|
||||||
self.path.following = false -- not stuck anymore
|
self.path.following = false -- not stuck anymore
|
||||||
|
|
||||||
self:set_velocity( 0)
|
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
|
if not self.custom_attack then
|
||||||
and math.random(1, 2) == 1 then
|
if self.double_melee_attack and math.random(1, 2) == 1 then
|
||||||
self:set_animation("punch2")
|
self:set_animation("punch2")
|
||||||
else
|
else
|
||||||
self:set_animation("punch")
|
self:set_animation("punch")
|
||||||
|
@ -1090,8 +1086,6 @@ function mob_class:do_states_attack (dtime)
|
||||||
s2.y = s2.y + .5
|
s2.y = s2.y + .5
|
||||||
|
|
||||||
if self:line_of_sight( p2, s2) == true then
|
if self:line_of_sight( p2, s2) == true then
|
||||||
|
|
||||||
-- play attack sound
|
|
||||||
self:mob_sound("attack")
|
self:mob_sound("attack")
|
||||||
|
|
||||||
-- punch player (or what player is attached to)
|
-- punch player (or what player is attached to)
|
||||||
|
@ -1104,13 +1098,7 @@ function mob_class:do_states_attack (dtime)
|
||||||
damage_groups = {fleshy = self.damage}
|
damage_groups = {fleshy = self.damage}
|
||||||
}, nil)
|
}, nil)
|
||||||
end
|
end
|
||||||
end
|
else
|
||||||
else -- call custom attack every second
|
|
||||||
if self.custom_attack
|
|
||||||
and self.timer > 1 then
|
|
||||||
|
|
||||||
self.timer = 0
|
|
||||||
|
|
||||||
self.custom_attack(self, p)
|
self.custom_attack(self, p)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -1136,7 +1124,7 @@ function mob_class:do_states_attack (dtime)
|
||||||
|
|
||||||
yaw = self:set_yaw( yaw, 0, 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
|
--strafe back and fourth
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,8 @@ local active_particlespawners = {}
|
||||||
local disable_blood = minetest.settings:get_bool("mobs_disable_blood")
|
local disable_blood = minetest.settings:get_bool("mobs_disable_blood")
|
||||||
local DEFAULT_FALL_SPEED = -9.81*1.5
|
local DEFAULT_FALL_SPEED = -9.81*1.5
|
||||||
|
|
||||||
|
local PATHFINDING = "gowp"
|
||||||
|
|
||||||
local player_transfer_distance = tonumber(minetest.settings:get("player_transfer_distance")) or 128
|
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
|
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
|
||||||
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)
|
function mob_class:add_texture_mod(mod)
|
||||||
local full_mod = ""
|
local full_mod = ""
|
||||||
local already_added = false
|
local already_added = false
|
||||||
|
|
|
@ -154,6 +154,7 @@ function mcl_mobs.register_mob(name, def)
|
||||||
description = def.description,
|
description = def.description,
|
||||||
type = def.type,
|
type = def.type,
|
||||||
attack_type = def.attack_type,
|
attack_type = def.attack_type,
|
||||||
|
attack_frequency = def.attack_frequency,
|
||||||
fly = def.fly or false,
|
fly = def.fly or false,
|
||||||
fly_in = def.fly_in or {"air", "__airlike"},
|
fly_in = def.fly_in or {"air", "__airlike"},
|
||||||
owner = def.owner or "",
|
owner = def.owner or "",
|
||||||
|
|
|
@ -19,8 +19,9 @@ local hoglin = {
|
||||||
xp_max = 9,
|
xp_max = 9,
|
||||||
armor = {fleshy = 90},
|
armor = {fleshy = 90},
|
||||||
attack_type = "dogfight",
|
attack_type = "dogfight",
|
||||||
|
attack_frequency = 3;
|
||||||
damage = 4,
|
damage = 4,
|
||||||
reach = 3,
|
reach = 1.9,
|
||||||
collisionbox = {-.6, -0.01, -.6, .6, 1.4, .6},
|
collisionbox = {-.6, -0.01, -.6, .6, 1.4, .6},
|
||||||
visual = "mesh",
|
visual = "mesh",
|
||||||
mesh = "extra_mobs_hoglin.b3d",
|
mesh = "extra_mobs_hoglin.b3d",
|
||||||
|
@ -63,7 +64,7 @@ local hoglin = {
|
||||||
punch_end = 32,
|
punch_end = 32,
|
||||||
},
|
},
|
||||||
fear_height = 4,
|
fear_height = 4,
|
||||||
view_range = 32,
|
view_range = 16,
|
||||||
floats = 0,
|
floats = 0,
|
||||||
custom_attack = function(self)
|
custom_attack = function(self)
|
||||||
if self.state == "attack" and self.reach > vector.distance(self.object:get_pos(), self.attack:get_pos()) then
|
if self.state == "attack" and self.reach > vector.distance(self.object:get_pos(), self.attack:get_pos()) then
|
||||||
|
|
Loading…
Reference in New Issue