Implement proper drowning for mobs

This commit is contained in:
Wuzzy 2019-10-02 18:28:28 +02:00
parent 40b5c5c2a5
commit 14d4bec8a9
2 changed files with 66 additions and 11 deletions

View File

@ -720,22 +720,22 @@ local do_env_damage = function(self)
self.health = self.health - self.water_damage self.health = self.health - self.water_damage
-- TODO: Damage particle
effect(pos, 5, "bubble.png", nil, nil, 1, nil) effect(pos, 5, "bubble.png", nil, nil, 1, nil)
if check_for_death(self, "water", {type = "environment", if check_for_death(self, "water", {type = "environment",
pos = pos, node = self.standing_in}) then return end pos = pos, node = self.standing_in}) then return end
end end
-- lava or fire -- lava
elseif self.lava_damage elseif self.lava_damage
and (nodef.groups.lava and (nodef.groups.lava) then
or self.standing_in == node_fire
or self.standing_in == node_permanent_flame) then
if self.lava_damage ~= 0 then if self.lava_damage ~= 0 then
self.health = self.health - self.lava_damage self.health = self.health - self.lava_damage
-- TODO: Damage particle
effect(pos, 5, "fire_basic_flame.png", nil, nil, 1, nil) effect(pos, 5, "fire_basic_flame.png", nil, nil, 1, nil)
if check_for_death(self, "lava", {type = "environment", if check_for_death(self, "lava", {type = "environment",
@ -747,12 +747,44 @@ local do_env_damage = function(self)
self.health = self.health - nodef.damage_per_second self.health = self.health - nodef.damage_per_second
-- TODO: Damage particle
effect(pos, 5, "tnt_smoke.png") effect(pos, 5, "tnt_smoke.png")
if check_for_death(self, "dps", {type = "environment", if check_for_death(self, "dps", {type = "environment",
pos = pos, node = self.standing_in}) then return end pos = pos, node = self.standing_in}) then return end
end end
-- Drowning damage
if self.breath_max ~= -1 then
local drowning = false
if self.breathes_in_water then
if minetest.get_item_group(self.standing_in, "water") == 0 then
drowning = true
end
elseif nodef.drowning > 0 then
drowning = true
end
if drowning then
self.breath = math.max(0, self.breath - 1)
effect(pos, 2, "bubble.png", nil, nil, 1, nil)
if self.breath <= 0 then
-- TODO: Damage particle
effect(pos, 5, "bubble.png", nil, nil, 1, nil)
if nodef.drowning > 0 then
self.health = self.health - nodef.drowning
else
self.health = self.health - 4
end
end
if check_for_death(self, "drowning", {type = "environment",
pos = pos, node = self.standing_in}) then return end
else
self.breath = math.min(self.breath_max, self.breath + 1)
end
end
--- suffocation inside solid node --- suffocation inside solid node
-- FIXME: Redundant with mcl_playerplus -- FIXME: Redundant with mcl_playerplus
if (self.suffocation == true) if (self.suffocation == true)
@ -2776,6 +2808,9 @@ local mob_activate = function(self, staticdata, def, dtime)
if self.health == 0 then if self.health == 0 then
self.health = random (self.hp_min, self.hp_max) self.health = random (self.hp_min, self.hp_max)
end end
if self.breath == nil then
self.breath = self.breath_max
end
-- pathfinding init -- pathfinding init
self.path = {} self.path = {}
@ -3052,6 +3087,15 @@ if def.can_despawn ~= nil then
else else
can_despawn = true can_despawn = true
end end
local function scale_difficulty(value, default, min, special)
if (not value) or (value == default) or (value == special) then
return default
else
return max(min, value) * difficulty
end
end
minetest.register_entity(name, { minetest.register_entity(name, {
stepheight = def.stepheight or 1.1, -- was 0.6 stepheight = def.stepheight or 1.1, -- was 0.6
@ -3069,8 +3113,10 @@ minetest.register_entity(name, {
drawtype = def.drawtype, -- DEPRECATED, use rotate instead drawtype = def.drawtype, -- DEPRECATED, use rotate instead
rotate = math.rad(def.rotate or 0), -- 0=front, 90=side, 180=back, 270=side2 rotate = math.rad(def.rotate or 0), -- 0=front, 90=side, 180=back, 270=side2
lifetimer = def.lifetimer or 57.73, lifetimer = def.lifetimer or 57.73,
hp_min = max(1, (def.hp_min or 5) * difficulty), hp_min = scale_difficulty(def.hp_min, 5, 1),
hp_max = max(1, (def.hp_max or 10) * difficulty), hp_max = scale_difficulty(def.hp_max, 10, 1),
breath_max = scale_difficulty(def.breath_max, 15, 1, -1),
breathes_in_water = def.breathes_in_water or false,
physical = true, physical = true,
collisionbox = def.collisionbox or {-0.25, -0.25, -0.25, 0.25, 0.25, 0.25}, collisionbox = def.collisionbox or {-0.25, -0.25, -0.25, 0.25, 0.25, 0.25},
selectionbox = def.selectionbox or def.collisionbox, selectionbox = def.selectionbox or def.collisionbox,
@ -3081,11 +3127,11 @@ minetest.register_entity(name, {
view_range = def.view_range or 16, view_range = def.view_range or 16,
walk_velocity = def.walk_velocity or 1, walk_velocity = def.walk_velocity or 1,
run_velocity = def.run_velocity or 2, run_velocity = def.run_velocity or 2,
damage = max(0, (def.damage or 0) * difficulty), damage = scale_difficulty(def.damage, 0, 0),
light_damage = def.light_damage or 0, light_damage = def.light_damage or 0,
sunlight_damage = def.sunlight_damage or 0, sunlight_damage = def.sunlight_damage or 0,
water_damage = def.water_damage or 0, water_damage = def.water_damage or 0,
lava_damage = def.lava_damage or 0, lava_damage = def.lava_damage or 8,
suffocation = def.suffocation or true, suffocation = def.suffocation or true,
fall_damage = def.fall_damage or 1, fall_damage = def.fall_damage or 1,
fall_speed = def.fall_speed or -10, -- must be lower than -2 (default: -10) fall_speed = def.fall_speed or -10, -- must be lower than -2 (default: -10)

View File

@ -28,8 +28,13 @@ functions needed for the mob to work properly which contains the following:
"monster" attacks player or npc on sight. "monster" attacks player or npc on sight.
"npc" walk around and will defend themselves if hit first, they "npc" walk around and will defend themselves if hit first, they
kill monsters. kill monsters.
'hp_min' has the minimum health value the mob can spawn with. 'hp_min' the minimum health value the mob can spawn with.
'hp_max' has the maximum health value the mob can spawn with. 'hp_max' the maximum health value the mob can spawn with.
'breath_max' The maximum breath value the mob can spawn with and can have.
If -1 (default), mob does not take drowning damage.
'breathes_in_water' If true, mob loses breath when not in water. Otherwise,
mob loses breath when inside a node with `drowning` attribute
set (default: false).
'armor' holds strength of mob, 100 is normal, lower is more powerful 'armor' holds strength of mob, 100 is normal, lower is more powerful
and needs more hits and better weapons to kill. and needs more hits and better weapons to kill.
'passive' when true allows animals to defend themselves when hit, 'passive' when true allows animals to defend themselves when hit,
@ -58,7 +63,7 @@ functions needed for the mob to work properly which contains the following:
'water_damage' holds the damage per second infliced to mobs when standing in 'water_damage' holds the damage per second infliced to mobs when standing in
water. water.
'lava_damage' holds the damage per second inflicted to mobs when standing 'lava_damage' holds the damage per second inflicted to mobs when standing
in lava or fire. in lava (default: 8).
'light_damage' holds the damage per second inflicted to mobs when it's too 'light_damage' holds the damage per second inflicted to mobs when it's too
bright (above 13 light). bright (above 13 light).
'suffocation' when true causes mobs to suffocate inside solid blocks (2 damage per second). 'suffocation' when true causes mobs to suffocate inside solid blocks (2 damage per second).
@ -299,6 +304,10 @@ for each mob.
'self.health' contains current health of mob (cannot exceed 'self.health' contains current health of mob (cannot exceed
self.hp_max) self.hp_max)
'self.breath' contains current breath of mob, if mob takes drowning
damage at all (cannot exceed self.breath_max). Breath
decreases by 1 each second while in a node with drowning
damage and increases by 1 each second otherwise.
'self.texture_list' contains list of all mob textures 'self.texture_list' contains list of all mob textures
'self.child_texture' contains mob child texture when growing up 'self.child_texture' contains mob child texture when growing up
'self.base_texture' contains current skin texture which was randomly 'self.base_texture' contains current skin texture which was randomly