From 32e8d069f76ff2c8ca2c745127826ff5fa78b032 Mon Sep 17 00:00:00 2001 From: TenPlus1 Date: Fri, 1 May 2020 10:29:12 +0100 Subject: [PATCH] enable suffocation, add area check when spawning, code tidy and tweaks --- api.lua | 124 ++++++++++++++++++++++++++++++++++++++---------------- api.txt | 3 +- readme.MD | 2 +- 3 files changed, 90 insertions(+), 39 deletions(-) diff --git a/api.lua b/api.lua index 4c10ed1..0945f82 100644 --- a/api.lua +++ b/api.lua @@ -6,7 +6,7 @@ local use_cmi = minetest.global_exists("cmi") mobs = { mod = "redo", - version = "20200430", + version = "20200501", intllib = S, invis = minetest.global_exists("invisibility") and invisibility or {} } @@ -594,8 +594,7 @@ function mob_class:do_stay_near() local r = self.view_range 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}, - searchnodes) + {x = pos.x + r, y = pos.y + 1, z = pos.z + r}, searchnodes) if #nearby_nodes < 1 then return false @@ -622,20 +621,22 @@ end -- 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 min_size = min_size or 0.5 max_size = max_size or 1 gravity = gravity or -10 glow = glow or 0 + fall = fall and 0 or -radius minetest.add_particlespawner({ amount = amount, time = 0.25, minpos = pos, maxpos = pos, - minvel = {x = -radius, y = -radius, z = -radius}, + minvel = {x = -radius, y = fall, z = -radius}, maxvel = {x = radius, y = radius, z = radius}, minacc = {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", pos = pos, node = self.standing_in}) then return true end end ---[[ + --- suffocation inside solid node - if self.suffocation ~= 0 - and nodef.walkable == true - and nodef.groups.disable_suffocation ~= 1 - and nodef.drawtype == "normal" then + if (self.suffocation ~= 0) + and (nodef.walkable == nil or nodef.walkable == true) + and (nodef.collision_box == nil or nodef.collision_box.type == "regular") + and (nodef.node_box == nil or nodef.node_box.type == "regular") + and (nodef.groups.disable_suffocation ~= 1) then 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 end -]] + return self:check_for_death({type = "unknown"}) end @@ -2764,7 +2766,8 @@ function mob_class:on_punch(hitter, tflp, tool_capabilities, dir) -- print ("Mob Damage is", damage) 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 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 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 + -- lots of damage = more blood :) + if damage > 10 then + amount = self.blood_amount * 2 + end + -- do we have a single blood texture or multiple? if type(self.blood_texture) == "table" then - - 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) + blood = self.blood_texture[random(1, #self.blood_texture)] end + + effect(pos, amount, blood, 1, 2, 1.75, nil, nil, true) + end -- do damage @@ -2928,7 +2936,8 @@ function mob_class:on_punch(hitter, tflp, tool_capabilities, dir) self:do_attack(hitter) -- 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 for n = 1, #objs do @@ -3638,6 +3647,13 @@ function mobs:spawn_specific(name, nodes, neighbors, min_light, max_light, return 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 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 - -- 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 height = max(1, math.ceil( - (ent.collisionbox[5] or 0.25) - - (ent.collisionbox[2] or -0.25) - 1)) + local width_x = max(1, + math.ceil(ent.collisionbox[4] - ent.collisionbox[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 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 + -- 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) --[[ print ("[mobs] Spawned " .. name .. " at " @@ -3757,8 +3808,7 @@ function mobs:register_arrow(name, def) local pos = self.object:get_pos() if self.switch == 0 - or self.timer > 150 - or within_limits(pos, 0) then + or self.timer > 150 then self.object:remove() ; -- print ("removed arrow") diff --git a/api.txt b/api.txt index 5b54699..840de8e 100644 --- a/api.txt +++ b/api.txt @@ -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 'light_damage_min' minimum light value when mob is affected (default: 14) '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. '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 diff --git a/readme.MD b/readme.MD index ae6dfb2..73d68e0 100644 --- a/readme.MD +++ b/readme.MD @@ -23,7 +23,7 @@ Lucky Blocks: 9 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.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