From 609d52100cd61f038981779b4644dc20092bc934 Mon Sep 17 00:00:00 2001 From: TenPlus1 Date: Mon, 12 Mar 2018 11:32:21 +0000 Subject: [PATCH] added new explosion mob functionality (thanks to Yukitty) --- api.lua | 44 +++++++++++++++++++++++++++++++++----------- api.txt | 16 +++++++++++++++- 2 files changed, 48 insertions(+), 12 deletions(-) diff --git a/api.lua b/api.lua index fe710c7..529228a 100644 --- a/api.lua +++ b/api.lua @@ -1798,7 +1798,7 @@ local do_states = function(self, dtime) local p = self.attack:get_pos() or s local dist = get_distance(p, s) - -- stop attacking if player or out of range + -- stop attacking if player invisible or out of range if dist > self.view_range or not self.attack or not self.attack:get_pos() @@ -1830,16 +1830,35 @@ local do_states = function(self, dtime) yaw = set_yaw(self.object, yaw) - -- start timer when inside reach - if dist < self.reach and not self.v_start then + local node_break_radius = self.explosion_radius or 1 + local entity_damage_radius = self.explosion_damage_radius + or (node_break_radius * 2) + + -- start timer when in reach and line of sight + if not self.v_start + and dist <= self.reach + and line_of_sight(self, s, p, 2) then + self.v_start = true self.timer = 0 self.blinktimer = 0 + mob_sound(self, self.sounds.fuse) -- print ("=== explosion timer started", self.explosion_timer) + + -- stop timer if out of blast radius or direct line of sight + elseif self.allow_fuse_reset + and self.v_start + and (dist > max(self.reach, entity_damage_radius) + 0.5 + or not line_of_sight(self, s, p, 2)) then + self.v_start = false + self.timer = 0 + self.blinktimer = 0 + self.blinkstatus = false + self.object:settexturemod("") end -- walk right up to player when timer active - if dist < 1.5 and self.v_start then + if dist < 1.5 then set_velocity(self, 0) else set_velocity(self, self.run_velocity) @@ -1851,7 +1870,8 @@ local do_states = function(self, dtime) set_animation(self, "walk") end - if self.v_start then + -- walk right up to player unless the timer is active + if self.v_start and (self.stop_to_explode or dist < 1.5) then self.timer = self.timer + dtime self.blinktimer = (self.blinktimer or 0) + dtime @@ -1874,14 +1894,13 @@ local do_states = function(self, dtime) if self.timer > self.explosion_timer then local pos = self.object:get_pos() - local radius = self.explosion_radius or 1 - local damage_radius = radius -- dont damage anything if area protected or next to water if minetest.find_node_near(pos, 1, {"group:water"}) or minetest.is_protected(pos, "") then damage_radius = 0 + node_break_radius = 0 end self.object:remove() @@ -1890,8 +1909,8 @@ local do_states = function(self, dtime) and not minetest.is_protected(pos, "") then tnt.boom(pos, { - radius = radius, - damage_radius = damage_radius, + radius = node_break_radius, + damage_radius = entity_damage_radius, sound = self.sounds.explode, }) else @@ -1902,8 +1921,8 @@ local do_states = function(self, dtime) max_hear_distance = self.sounds.distance or 32 }) - entity_physics(pos, damage_radius) - effect(pos, 32, "tnt_smoke.png", radius * 3, radius * 5, radius, 1, 0) + entity_physics(pos, entity_damage_radius) + effect(pos, 32, "tnt_smoke.png", nil, nil, node_break_radius, 1, 0) end return @@ -2889,7 +2908,10 @@ minetest.register_entity(name, { pathfinding = def.pathfinding, immune_to = def.immune_to or {}, explosion_radius = def.explosion_radius, + explosion_damage_radius = def.explosion_damage_radius, explosion_timer = def.explosion_timer or 3, + allow_fuse_reset = def.allow_fuse_reset or true, + stop_to_explode = def.stop_to_explode or true, custom_attack = def.custom_attack, double_melee_attack = def.double_melee_attack, dogshoot_switch = def.dogshoot_switch, diff --git a/api.txt b/api.txt index 8e71b0a..379807c 100644 --- a/api.txt +++ b/api.txt @@ -86,7 +86,20 @@ functions needed for the mob to work properly which contains the following: view_range. 'dogshoot' has melee attack when inside reach and shoot attack when inside view_range. - 'explode' causes mob to explode when inside reach. + 'explode' causes mob to stop and explode when inside reach. + 'explosion_radius' the radius of explosion node destruction, + defaults to 1 + 'explosion_damage_radius' the radius of explosion entity & player damage, + defaults to explosion_radius * 2 + 'explosion_timer' number of seconds before mob explodes while its target + is still inside reach or explosion_damage_radius, + defaults to 3. + 'allow_fuse_reset' Allow 'explode' attack_type to reset fuse and resume + chasing if target leaves the blast radius or line of + sight. Defaults to true. + 'stop_to_explode' When set to true (default), mob must stop and wait for + explosion_timer in order to explode. If false, mob will + continue chasing. 'explosion_radius' has the radius of the explosion which defaults to 1. 'explosion_timer' number of seconds before mob explodes while still inside view range. @@ -129,6 +142,7 @@ functions needed for the mob to work properly which contains the following: 'damage' sound heard when mob is hurt. 'death' played when mob is killed. 'jump' played when mob jumps. + 'fuse' sound played when mob explode timer starts. 'explode' sound played when mob explodes. 'drops' table of items that are dropped when mob is killed, fields are: