Added few sanity checks, higher pitch sounds for child mobs

This commit is contained in:
tenplus1 2020-04-29 15:01:21 +01:00
parent a934d80631
commit 064b59f01d
3 changed files with 90 additions and 40 deletions

97
api.lua
View File

@ -6,7 +6,7 @@ local use_cmi = minetest.global_exists("cmi")
mobs = { mobs = {
mod = "redo", mod = "redo",
version = "20200427", version = "20200429",
intllib = S, intllib = S,
invis = minetest.global_exists("invisibility") and invisibility or {} invis = minetest.global_exists("invisibility") and invisibility or {}
} }
@ -150,12 +150,21 @@ local mob_class_meta = {__index = mob_class}
-- play sound -- play sound
function mob_class:mob_sound(sound) function mob_class:mob_sound(sound)
local pitch = 1.0
-- higher pitch for a child
if self.child then pitch = pitch * 1.5 end
-- a little random pitch to be different
pitch = pitch + math.random(-10, 10) * 0.005
if sound then if sound then
minetest.sound_play(sound, { minetest.sound_play(sound, {
object = self.object, object = self.object,
gain = 1.0, gain = 1.0,
max_hear_distance = self.sounds.distance max_hear_distance = self.sounds.distance,
}) pitch = pitch
}, true)
end end
end end
@ -215,6 +224,12 @@ end
-- move mob in facing direction -- move mob in facing direction
function mob_class:set_velocity(v) function mob_class:set_velocity(v)
-- halt mob if it has been ordered to stay
if self.order == "stand" then
self.object:set_velocity({x = 0, y = 0, z = 0})
return
end
local c_x, c_y = 0, 0 local c_x, c_y = 0, 0
-- can mob be pushed, if so calculate direction -- can mob be pushed, if so calculate direction
@ -222,12 +237,6 @@ function mob_class:set_velocity(v)
c_x, c_y = unpack(self:collision()) c_x, c_y = unpack(self:collision())
end end
-- halt mob if it has been ordered to stay
if self.order == "stand" then
self.object:set_velocity({x = 0, y = 0, z = 0})
return
end
local yaw = (self.object:get_yaw() or 0) + self.rotate local yaw = (self.object:get_yaw() or 0) + self.rotate
-- nil check for velocity -- nil check for velocity
@ -668,6 +677,12 @@ end
-- drop items -- drop items
function mob_class:item_drop() function mob_class:item_drop()
-- no drops if disabled by setting
if not mobs_drop_items then return end
-- no drops for child mobs
if self.child then return end
local pos = self.object:get_pos() local pos = self.object:get_pos()
-- check for drops function -- check for drops function
@ -678,12 +693,6 @@ function mob_class:item_drop()
return return
end end
-- no drops if disabled by setting
if not mobs_drop_items then return end
-- no drops for child mobs
if self.child then return end
-- was mob killed by player? -- was mob killed by player?
local death_by_player = self.cause_of_death and self.cause_of_death.puncher local death_by_player = self.cause_of_death and self.cause_of_death.puncher
and self.cause_of_death.puncher:is_player() or nil and self.cause_of_death.puncher:is_player() or nil
@ -742,12 +751,17 @@ function mob_class:check_for_death(cmi_cause)
return false return false
end end
local damaged = self.health < self.old_health
self.old_health = self.health self.old_health = self.health
-- still got some health? play hurt sound -- still got some health? play hurt sound
if self.health > 0 then if self.health > 0 then
self:mob_sound(self.sounds.damage) -- only play hurt sound if damaged
if damaged then
self:mob_sound(self.sounds.damage)
end
-- make sure health isn't higher than max -- make sure health isn't higher than max
if self.health > self.hp_max then if self.health > self.hp_max then
@ -1117,8 +1131,6 @@ function mob_class:do_jump()
end end
else else
self.facing_fence = true self.facing_fence = true
return false
end end
-- if we jumped against a block/wall 4 times then turn -- if we jumped against a block/wall 4 times then turn
@ -1510,6 +1522,10 @@ function mob_class:smart_mobs(s, p, dist, dtime)
minetest.after(1, function(self) minetest.after(1, function(self)
if not self.object:get_luaentity() then
return
end
if self.object:get_luaentity() then if self.object:get_luaentity() then
if has_lineofsight then if has_lineofsight then
@ -1560,7 +1576,15 @@ function mob_class:smart_mobs(s, p, dist, dtime)
local dropheight = 6 local dropheight = 6
if self.fear_height ~= 0 then dropheight = self.fear_height end if self.fear_height ~= 0 then dropheight = self.fear_height end
self.path.way = minetest.find_path(s, p1, 16, self.stepheight, dropheight, "Dijkstra") local jumpheight = 0
if self.jump and self.jump_height >= 4 then
jumpheight = min(math.ceil(self.jump_height / 4), 4)
elseif self.stepheight > 0.5 then
jumpheight = 1
end
self.path.way = minetest.find_path(s, p1, 16, jumpheight,
dropheight, "Dijkstra")
--[[ --[[
-- show path using particles -- show path using particles
@ -1680,8 +1704,9 @@ function mob_class:smart_mobs(s, p, dist, dtime)
-- will try again in 2 second -- will try again in 2 second
self.path.stuck_timer = stuck_timeout - 2 self.path.stuck_timer = stuck_timeout - 2
-- frustration! cant find the damn path :( elseif s.y < p1.y and (not self.fly) then
--self:mob_sound(self.sounds.random) self:do_jump() --add jump to pathfinding
self.path.following = true
else else
-- yay i found path -- yay i found path
self:mob_sound(self.sounds.war_cry) self:mob_sound(self.sounds.war_cry)
@ -1901,8 +1926,7 @@ end
function mob_class:follow_flop() function mob_class:follow_flop()
-- find player to follow -- find player to follow
if (self.follow ~= "" if (self.follow ~= "" or self.order == "follow")
or self.order == "follow")
and not self.following and not self.following
and self.state ~= "attack" and self.state ~= "attack"
and self.state ~= "runaway" then and self.state ~= "runaway" then
@ -2342,7 +2366,7 @@ function mob_class:do_states(dtime)
effect(pos, 32, "tnt_smoke.png", nil, nil, node_break_radius, 1, 0) effect(pos, 32, "tnt_smoke.png", nil, nil, node_break_radius, 1, 0)
end end
return return true
end end
end end
@ -2772,12 +2796,12 @@ function mob_class:on_punch(hitter, tflp, tool_capabilities, dir)
minetest.sound_play(weapon_def.sounds[s], { minetest.sound_play(weapon_def.sounds[s], {
object = self.object, object = self.object,
max_hear_distance = 8 max_hear_distance = 8
}) }, true)
else else
minetest.sound_play("default_punch", { minetest.sound_play("default_punch", {
object = self.object, object = self.object,
max_hear_distance = 5 max_hear_distance = 5
}) }, true)
end end
-- blood_particles -- blood_particles
@ -3321,7 +3345,7 @@ function mob_class:on_step(dtime)
self:follow_flop() self:follow_flop()
self:do_states(dtime) if self:do_states(dtime) then return end
self:do_jump() self:do_jump()
@ -3702,6 +3726,7 @@ function mobs:register_arrow(name, def)
hit_player = def.hit_player, hit_player = def.hit_player,
hit_node = def.hit_node, hit_node = def.hit_node,
hit_mob = def.hit_mob, hit_mob = def.hit_mob,
hit_object = def.hit_object,
drop = def.drop or false, -- drops arrow as registered item when true drop = def.drop or false, -- drops arrow as registered item when true
collisionbox = def.collisionbox or {0, 0, 0, 0, 0, 0}, collisionbox = def.collisionbox or {0, 0, 0, 0, 0, 0},
timer = 0, timer = 0,
@ -3723,7 +3748,8 @@ function mobs:register_arrow(name, def)
local pos = self.object:get_pos() local pos = self.object:get_pos()
if self.switch == 0 if self.switch == 0
or self.timer > 150 then or self.timer > 150
or within_limits(pos, 0) then
self.object:remove() ; -- print ("removed arrow") self.object:remove() ; -- print ("removed arrow")
@ -3796,6 +3822,19 @@ function mobs:register_arrow(name, def)
return return
end end
if entity
and self.hit_object
and (not entity._cmi_is_mob)
and tostring(player) ~= self.owner_id
and entity.name ~= self.object:get_luaentity().name then
self:hit_object(player)
self.object:remove(); -- print ("hit object")
return
end
end end
end end
@ -3821,7 +3860,7 @@ function mobs:safe_boom(self, pos, radius)
pos = pos, pos = pos,
gain = 1.0, gain = 1.0,
max_hear_distance = self.sounds and self.sounds.distance or 32 max_hear_distance = self.sounds and self.sounds.distance or 32
}) }, true)
entity_physics(pos, radius) entity_physics(pos, radius)

View File

@ -399,6 +399,8 @@ This function registers a arrow for mobs with the attack type shoot.
'hit_mob' a function that is called when the arrow hits a mob; 'hit_mob' a function that is called when the arrow hits a mob;
this function should hurt the mob, the parameters are this function should hurt the mob, the parameters are
(self, player) (self, player)
'hit_object' a function that is called when the arrow hits an object;
this function parameters are (self, player)
'hit_node' a function that is called when the arrow hits a node, the 'hit_node' a function that is called when the arrow hits a node, the
parameters are (self, pos, node) parameters are (self, pos, node)
'tail' when set to 1 adds a trail or tail to mob arrows 'tail' when set to 1 adds a trail or tail to mob arrows

View File

@ -131,7 +131,7 @@ function mobs.attach(entity, player)
local rot_view = 0 local rot_view = 0
if entity.player_rotation.y == 90 then if entity.player_rotation.y == 90 then
rot_view = math.pi/2 rot_view = math.pi / 2
end end
attach_at = entity.driver_attach_at attach_at = entity.driver_attach_at
@ -151,11 +151,13 @@ function mobs.attach(entity, player)
} }
}) })
minetest.after(0.2, function() minetest.after(0.2, function(name)
default.player_set_animation(player, "sit" , 30) local player = minetest.get_player_by_name(name)
end) if player then
default.player_set_animation(player, "sit" , 30)
end
end, player:get_player_name())
--player:set_look_yaw(entity.object:get_yaw() - rot_view)
player:set_look_horizontal(entity.object:get_yaw() - rot_view) player:set_look_horizontal(entity.object:get_yaw() - rot_view)
end end
@ -168,11 +170,18 @@ function mobs.detach(player, offset)
local pos = player:get_pos() local pos = player:get_pos()
pos = {x = pos.x + offset.x, y = pos.y + 0.2 + offset.y, z = pos.z + offset.z} pos = {
x = pos.x + offset.x,
y = pos.y + 0.2 + offset.y,
z = pos.z + offset.z
}
minetest.after(0.1, function() minetest.after(0.1, function(name, pos)
player:set_pos(pos) local player = minetest.get_player_by_name(name)
end) if player then
player:set_pos(pos)
end
end, player:get_player_name(), pos)
end end
@ -290,7 +299,7 @@ function mobs.drive(entity, moving_anim, stand_anim, can_fly, dtime)
-- Set position, velocity and acceleration -- Set position, velocity and acceleration
local p = entity.object:get_pos() local p = entity.object:get_pos()
local new_velo = {x = 0, y = 0, z = 0} local new_velo
local new_acce = {x = 0, y = -9.8, z = 0} local new_acce = {x = 0, y = -9.8, z = 0}
p.y = p.y - 0.5 p.y = p.y - 0.5
@ -315,7 +324,7 @@ function mobs.drive(entity, moving_anim, stand_anim, can_fly, dtime)
minetest.sound_play("default_punch", { minetest.sound_play("default_punch", {
object = entity.object, object = entity.object,
max_hear_distance = 5 max_hear_distance = 5
}) }, true)
entity.object:punch(entity.object, 1.0, { entity.object:punch(entity.object, 1.0, {
full_punch_interval = 1.0, full_punch_interval = 1.0,