Redo the death effect

This commit is contained in:
Wuzzy 2020-12-05 04:33:23 +01:00
parent 411e180477
commit ed3afc6e49
10 changed files with 71 additions and 59 deletions

View file

@ -9,6 +9,7 @@ local MAX_MOB_NAME_LENGTH = 30
local HORNY_TIME = 30 local HORNY_TIME = 30
local HORNY_AGAIN_TIME = 300 local HORNY_AGAIN_TIME = 300
local CHILD_GROW_TIME = 60*20 local CHILD_GROW_TIME = 60*20
local DEATH_DELAY = 0.5
local MOB_CAP = {} local MOB_CAP = {}
MOB_CAP.hostile = 70 MOB_CAP.hostile = 70
@ -334,7 +335,7 @@ local remove_texture_mod = function(self, mod)
end end
-- set defined animation -- set defined animation
local set_animation = function(self, anim) local set_animation = function(self, anim, fixed_frame)
if not self.animation if not self.animation
or not anim then return end or not anim then return end
@ -349,9 +350,17 @@ local set_animation = function(self, anim)
self.animation.current = anim self.animation.current = anim
local a_start = self.animation[anim .. "_start"]
local a_end
if fixed_frame then
a_end = a_start
else
a_end = self.animation[anim .. "_end"]
end
self.object:set_animation({ self.object:set_animation({
x = self.animation[anim .. "_start"], x = a_start,
y = self.animation[anim .. "_end"]}, y = a_end},
self.animation[anim .. "_speed"] or self.animation.speed_normal or 15, self.animation[anim .. "_speed"] or self.animation.speed_normal or 15,
0, self.animation[anim .. "_loop"] ~= false) 0, self.animation[anim .. "_loop"] ~= false)
end end
@ -669,6 +678,10 @@ end
-- check if mob is dead or only hurt -- check if mob is dead or only hurt
local check_for_death = function(self, cause, cmi_cause) local check_for_death = function(self, cause, cmi_cause)
if self.state == "die" then
return true
end
-- has health actually changed? -- has health actually changed?
if self.health == self.old_health and self.health > 0 then if self.health == self.old_health and self.health > 0 then
return false return false
@ -713,6 +726,9 @@ local check_for_death = function(self, cause, cmi_cause)
return false return false
end end
mob_sound(self, "death")
local function death_handle(self)
-- dropped cooked item if mob died in fire or lava -- dropped cooked item if mob died in fire or lava
if cause == "lava" or cause == "fire" then if cause == "lava" or cause == "fire" then
item_drop(self, true) item_drop(self, true)
@ -720,33 +736,37 @@ local check_for_death = function(self, cause, cmi_cause)
item_drop(self, nil) item_drop(self, nil)
end end
mob_sound(self, "death")
local pos = self.object:get_pos() local pos = self.object:get_pos()
if mod_experience and self.hp_min and self.hp_max then if mod_experience and self.hp_min and self.hp_max then
mcl_experience.throw_experience(pos, math.ceil( math.random(self.hp_min,self.hp_max+5) / 5) ) mcl_experience.throw_experience(pos, math.ceil( math.random(self.hp_min,self.hp_max+5) / 5) )
end end
end
-- execute custom death function -- execute custom death function
if self.on_die then if self.on_die then
self.on_die(self, pos) death_handle(self)
local pos = self.object:get_pos()
local on_die_exit = self.on_die(self, pos)
if use_cmi then if use_cmi then
cmi.notify_die(self.object, cmi_cause) cmi.notify_die(self.object, cmi_cause)
end end
if on_die_exit == true then
self.object:remove() self.object:remove()
return true return true
end end
end
local collisionbox local collisionbox
if self.collisionbox then if self.collisionbox then
collisionbox = table.copy(self.collisionbox) collisionbox = table.copy(self.collisionbox)
end end
local length = 0
-- default death function and die animation (if defined) -- default death function and die animation (if defined)
if self.animation if self.animation
and self.animation.die_start and self.animation.die_start
@ -754,7 +774,15 @@ local check_for_death = function(self, cause, cmi_cause)
local frames = self.animation.die_end - self.animation.die_start local frames = self.animation.die_end - self.animation.die_start
local speed = self.animation.die_speed or 15 local speed = self.animation.die_speed or 15
local length = max(frames / speed, 0) length = max(frames / speed, 0) + DEATH_DELAY
set_animation(self, "die")
else
local rot = self.object:get_rotation()
rot.z = math.pi/2
self.object:set_rotation(rot)
length = 1 + DEATH_DELAY
set_animation(self, "stand", true)
end
self.attack = nil self.attack = nil
self.v_start = false self.v_start = false
@ -766,7 +794,6 @@ local check_for_death = function(self, cause, cmi_cause)
pointable = false, pointable = false,
}) })
set_velocity(self, 0) set_velocity(self, 0)
set_animation(self, "die")
minetest.after(length, function(self) minetest.after(length, function(self)
if not self.object:get_luaentity() then if not self.object:get_luaentity() then
@ -776,18 +803,12 @@ local check_for_death = function(self, cause, cmi_cause)
cmi.notify_die(self.object, cmi_cause) cmi.notify_die(self.object, cmi_cause)
end end
death_handle(self)
local dpos = self.object:get_pos()
self.object:remove() self.object:remove()
mobs.death_effect(pos) mobs.death_effect(dpos)
end, self) end, self)
else
if use_cmi then
cmi.notify_die(self.object, cmi_cause)
end
self.object:remove()
mobs.death_effect(pos, collisionbox)
end
return true return true
end end
@ -2690,7 +2711,7 @@ end
-- returns true if mob died -- returns true if mob died
local falling = function(self, pos) local falling = function(self, pos)
if self.fly then if self.fly and self.state ~= "die" then
return return
end end

View file

@ -284,10 +284,9 @@ Custom Definition Functions
Along with the above mob registry settings we can also use custom functions to Along with the above mob registry settings we can also use custom functions to
enhance mob functionality and have them do many interesting things: enhance mob functionality and have them do many interesting things:
'on_die' a function that is called when the mob is killed the 'on_die' a function that is called when the mob is killed; the
parameters are (self, pos). When this function is used, parameters are (self, pos). Return true to skip the builtin
the death particles will be skipped on death. You can get death animation and death effects
them back by calling mobs:death_effect manually
'on_rightclick' its same as in minetest.register_entity() 'on_rightclick' its same as in minetest.register_entity()
'on_blast' is called when an explosion happens near mob when using TNT 'on_blast' is called when an explosion happens near mob when using TNT
functions, parameters are (object, damage) and returns functions, parameters are (object, damage) and returns

View file

@ -33,12 +33,10 @@ mobs:register_mob("mobs_mc:bat", {
run_speed = 80, run_speed = 80,
run_start = 0, run_start = 0,
run_end = 40, run_end = 40,
-- TODO: Less ugly death animation die_speed = 60,
--[[ die_speed = 60,
die_start = 40, die_start = 40,
die_end = 80, die_end = 80,
die_loop = false, die_loop = false,
]]
}, },
walk_chance = 100, walk_chance = 100,
fall_damage = 0, fall_damage = 0,

View file

@ -81,7 +81,6 @@ mobs:register_mob("mobs_mc:creeper", {
local r = math.random(1, #mobs_mc.items.music_discs) local r = math.random(1, #mobs_mc.items.music_discs)
minetest.add_item({x=pos.x, y=pos.y+1, z=pos.z}, mobs_mc.items.music_discs[r]) minetest.add_item({x=pos.x, y=pos.y+1, z=pos.z}, mobs_mc.items.music_discs[r])
end end
mobs.death_effect(pos, self.collisionbox)
end, end,
maxdrops = 2, maxdrops = 2,
drops = { drops = {

View file

@ -507,7 +507,6 @@ mobs:register_mob("mobs_mc:enderman", {
if self._taken_node ~= nil and self._taken_node ~= "" then if self._taken_node ~= nil and self._taken_node ~= "" then
minetest.add_item(pos, self._taken_node) minetest.add_item(pos, self._taken_node)
end end
mobs.death_effect(pos, self.collisionbox)
end, end,
do_punch = function(self, hitter, tflp, tool_caps, dir) do_punch = function(self, hitter, tflp, tool_caps, dir)
-- damage from rain caused by itself so we don't want it to attack itself. -- damage from rain caused by itself so we don't want it to attack itself.

View file

@ -175,8 +175,6 @@ local horse = {
mobs.detach(self.driver, {x = 1, y = 0, z = 1}) mobs.detach(self.driver, {x = 1, y = 0, z = 1})
end end
mobs.death_effect(pos, self.collisionbox)
end, end,
on_rightclick = function(self, clicker) on_rightclick = function(self, clicker)

View file

@ -111,7 +111,6 @@ mobs:register_mob("mobs_mc:llama", {
if self.driver then if self.driver then
mobs.detach(self.driver, {x = 1, y = 0, z = 1}) mobs.detach(self.driver, {x = 1, y = 0, z = 1})
end end
mobs.death_effect(pos, self.collisionbox)
end, end,

View file

@ -79,7 +79,6 @@ mobs:register_mob("mobs_mc:pig", {
if self.driver then if self.driver then
mobs.detach(self.driver, {x = 1, y = 0, z = 1}) mobs.detach(self.driver, {x = 1, y = 0, z = 1})
end end
mobs.death_effect(pos, self.collisionbox)
end, end,
on_rightclick = function(self, clicker) on_rightclick = function(self, clicker)

View file

@ -51,6 +51,7 @@ local spawn_children_on_die = function(child_mob, children_count, spawn_distance
end end
end, children, self.attack) end, children, self.attack)
end end
return true
end end
end end

View file

@ -1053,7 +1053,6 @@ mobs:register_mob("mobs_mc:villager", {
return_fields(player) return_fields(player)
end end
end end
mobs.death_effect(pos, self.collisionbox)
end, end,
}) })