enable suffocation, add area check when spawning, code tidy and tweaks

This commit is contained in:
TenPlus1 2020-05-01 10:29:12 +01:00
parent e4198b2a21
commit 32e8d069f7
3 changed files with 90 additions and 39 deletions

124
api.lua
View File

@ -6,7 +6,7 @@ local use_cmi = minetest.global_exists("cmi")
mobs = { mobs = {
mod = "redo", mod = "redo",
version = "20200430", version = "20200501",
intllib = S, intllib = S,
invis = minetest.global_exists("invisibility") and invisibility or {} invis = minetest.global_exists("invisibility") and invisibility or {}
} }
@ -594,8 +594,7 @@ function mob_class:do_stay_near()
local r = self.view_range local r = self.view_range
local nearby_nodes = minetest.find_nodes_in_area( local nearby_nodes = minetest.find_nodes_in_area(
{x = pos.x - r, y = pos.y - 1, z = pos.z - r}, {x = pos.x - r, y = pos.y - 1, z = pos.z - r},
{x = pos.x + r, y = pos.y + 1, z = pos.z + r}, {x = pos.x + r, y = pos.y + 1, z = pos.z + r}, searchnodes)
searchnodes)
if #nearby_nodes < 1 then if #nearby_nodes < 1 then
return false return false
@ -622,20 +621,22 @@ end
-- custom particle effects -- custom particle effects
local effect = function(pos, amount, texture, min_size, max_size, radius, gravity, glow) local effect = function(
pos, amount, texture, min_size, max_size, radius, gravity, glow, fall)
radius = radius or 2 radius = radius or 2
min_size = min_size or 0.5 min_size = min_size or 0.5
max_size = max_size or 1 max_size = max_size or 1
gravity = gravity or -10 gravity = gravity or -10
glow = glow or 0 glow = glow or 0
fall = fall and 0 or -radius
minetest.add_particlespawner({ minetest.add_particlespawner({
amount = amount, amount = amount,
time = 0.25, time = 0.25,
minpos = pos, minpos = pos,
maxpos = pos, maxpos = pos,
minvel = {x = -radius, y = -radius, z = -radius}, minvel = {x = -radius, y = fall, z = -radius},
maxvel = {x = radius, y = radius, z = radius}, maxvel = {x = radius, y = radius, z = radius},
minacc = {x = 0, y = gravity, z = 0}, minacc = {x = 0, y = gravity, z = 0},
maxacc = {x = 0, y = gravity, z = 0}, maxacc = {x = 0, y = gravity, z = 0},
@ -1014,19 +1015,20 @@ function mob_class:do_env_damage()
if self:check_for_death({type = "environment", if self:check_for_death({type = "environment",
pos = pos, node = self.standing_in}) then return true end pos = pos, node = self.standing_in}) then return true end
end end
--[[
--- suffocation inside solid node --- suffocation inside solid node
if self.suffocation ~= 0 if (self.suffocation ~= 0)
and nodef.walkable == true and (nodef.walkable == nil or nodef.walkable == true)
and nodef.groups.disable_suffocation ~= 1 and (nodef.collision_box == nil or nodef.collision_box.type == "regular")
and nodef.drawtype == "normal" then and (nodef.node_box == nil or nodef.node_box.type == "regular")
and (nodef.groups.disable_suffocation ~= 1) then
self.health = self.health - self.suffocation self.health = self.health - self.suffocation
if self:check_for_death({type = "environment", if self:check_for_death({type = "suffocation",
pos = pos, node = self.standing_in}) then return true end pos = pos, node = self.standing_in}) then return true end
end end
]]
return self:check_for_death({type = "unknown"}) return self:check_for_death({type = "unknown"})
end end
@ -2764,7 +2766,8 @@ function mob_class:on_punch(hitter, tflp, tool_capabilities, dir)
-- print ("Mob Damage is", damage) -- print ("Mob Damage is", damage)
if use_cmi if use_cmi
and cmi.notify_punch(self.object, hitter, tflp, tool_capabilities, dir, damage) then and cmi.notify_punch(
self.object, hitter, tflp, tool_capabilities, dir, damage) then
return return
end end
@ -2816,18 +2819,23 @@ function mob_class:on_punch(hitter, tflp, tool_capabilities, dir)
if not disable_blood and self.blood_amount > 0 then if not disable_blood and self.blood_amount > 0 then
local pos = self.object:get_pos() local pos = self.object:get_pos()
local blood = self.blood_texture
local amount = self.blood_amount
pos.y = pos.y + (-self.collisionbox[2] + self.collisionbox[5]) * .5 pos.y = pos.y + (-self.collisionbox[2] + self.collisionbox[5]) * .5
-- lots of damage = more blood :)
if damage > 10 then
amount = self.blood_amount * 2
end
-- do we have a single blood texture or multiple? -- do we have a single blood texture or multiple?
if type(self.blood_texture) == "table" then if type(self.blood_texture) == "table" then
blood = self.blood_texture[random(1, #self.blood_texture)]
local blood = self.blood_texture[random(1, #self.blood_texture)]
effect(pos, self.blood_amount, blood, nil, nil, 1, nil)
else
effect(pos, self.blood_amount, self.blood_texture, nil, nil, 1, nil)
end end
effect(pos, amount, blood, 1, 2, 1.75, nil, nil, true)
end end
-- do damage -- do damage
@ -2928,7 +2936,8 @@ function mob_class:on_punch(hitter, tflp, tool_capabilities, dir)
self:do_attack(hitter) self:do_attack(hitter)
-- alert others to the attack -- alert others to the attack
local objs = minetest.get_objects_inside_radius(hitter:get_pos(), self.view_range) local objs = minetest.get_objects_inside_radius(
hitter:get_pos(), self.view_range)
local obj = nil local obj = nil
for n = 1, #objs do for n = 1, #objs do
@ -3638,6 +3647,13 @@ function mobs:spawn_specific(name, nodes, neighbors, min_light, max_light,
return return
end end
-- mobs cannot spawn in protected areas when enabled
if not spawn_protected
and minetest.is_protected(pos, "") then
--print ("--- inside protected area", name)
return
end
-- only spawn away from player -- only spawn away from player
local objs = minetest.get_objects_inside_radius(pos, 8) local objs = minetest.get_objects_inside_radius(pos, 8)
@ -3649,32 +3665,67 @@ function mobs:spawn_specific(name, nodes, neighbors, min_light, max_light,
end end
end end
-- do we have enough height clearance to spawn mob? -- do we have enough space to spawn mob? (thanks wuzzy)
local ent = minetest.registered_entities[name] local ent = minetest.registered_entities[name]
local height = max(1, math.ceil( local width_x = max(1,
(ent.collisionbox[5] or 0.25) - math.ceil(ent.collisionbox[4] - ent.collisionbox[1]))
(ent.collisionbox[2] or -0.25) - 1)) local min_x, max_x
for n = 0, height do if width_x % 2 == 0 then
max_x = math.floor(width_x / 2)
min_x = -(max_x - 1)
else
max_x = math.floor(width_x / 2)
min_x = -max_x
end
local pos2 = {x = pos.x, y = pos.y + n, z = pos.z} local width_z = max(1,
math.ceil(ent.collisionbox[6] - ent.collisionbox[3]))
local min_z, max_z
if width_z % 2 == 0 then
max_z = math.floor(width_z / 2)
min_z = -(max_z - 1)
else
max_z = math.floor(width_z / 2)
min_z = -max_z
end
local max_y = max(0,
math.ceil(ent.collisionbox[5] - ent.collisionbox[2]) - 1)
for y = 0, max_y do
for x = min_x, max_x do
for z = min_z, max_z do
local pos2 = {
x = pos.x + x,
y = pos.y + y,
z = pos.z + z}
if minetest.registered_nodes[
node_ok(pos2).name].walkable == true then
--print ("--- not enough space to spawn", name)
if minetest.registered_nodes[node_ok(pos2).name].walkable == true then
--print ("--- inside block", name, node_ok(pos2).name)
return return
end end
end end
end
-- mobs cannot spawn in protected areas when enabled
if not spawn_protected
and minetest.is_protected(pos, "") then
--print ("--- inside protected area", name)
return
end end
-- spawn mob half block higher than ground -- spawn mob 1/2 node above ground
pos.y = pos.y + 0.5 pos.y = pos.y + 0.5
-- tweak X/Z spawn pos
if width_x % 2 == 0 then
pos.x = pos.x + 0.5
end
if width_z % 2 == 0 then
pos.z = pos.z + 0.5
end
local mob = minetest.add_entity(pos, name) local mob = minetest.add_entity(pos, name)
--[[ --[[
print ("[mobs] Spawned " .. name .. " at " print ("[mobs] Spawned " .. name .. " at "
@ -3757,8 +3808,7 @@ 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 or self.timer > 150 then
or within_limits(pos, 0) then
self.object:remove() ; -- print ("removed arrow") self.object:remove() ; -- print ("removed arrow")

View File

@ -68,7 +68,8 @@ functions needed for the mob to work properly which contains the following:
level is between the min and max values below level is between the min and max values below
'light_damage_min' minimum light value when mob is affected (default: 14) 'light_damage_min' minimum light value when mob is affected (default: 14)
'light_damage_max' maximum light value when mob is affected (default: 15) 'light_damage_max' maximum light value when mob is affected (default: 15)
'suffocation' when true causes mobs to suffocate inside solid blocks. 'suffocation' when > 0 mobs will suffocate inside solid blocks and will be
hurt by the value given every second (0 to disable).
'floats' when set to 1 mob will float in water, 0 has them sink. 'floats' when set to 1 mob will float in water, 0 has them sink.
'follow' mobs follow player when holding any of the items which appear 'follow' mobs follow player when holding any of the items which appear
on this table, the same items can be fed to a mob to tame or on this table, the same items can be fed to a mob to tame or

View File

@ -23,7 +23,7 @@ Lucky Blocks: 9
Changelog: Changelog:
- 1.51 - Added some node checks for dangerous nodes, jumping and falling tweaks (thx for idea wuzzy) - 1.51 - Added some node checks for dangerous nodes, jumping and falling tweaks, spawn area check (thx for idea wuzzy), re-enabled mob suffocation
- 1.50 - Added new line_of_sight function that uses raycasting if mt5.0 is found, (thanks Astrobe), dont spawn mobs if world anchor nearby (technic or simple_anchor mods), chinese local added - 1.50 - Added new line_of_sight function that uses raycasting if mt5.0 is found, (thanks Astrobe), dont spawn mobs if world anchor nearby (technic or simple_anchor mods), chinese local added
- 1.49- Added mobs:force_capture(self, player) function, api functions now use metatables thanks to bell07 - 1.49- Added mobs:force_capture(self, player) function, api functions now use metatables thanks to bell07
- 1.48- Add mobs:set_velocity(self, velocity) global function - 1.48- Add mobs:set_velocity(self, velocity) global function