From b25254e516dee623bc1cb8e2de6673aeea84b292 Mon Sep 17 00:00:00 2001 From: Wuzzy Date: Tue, 25 Jul 2017 04:30:23 +0200 Subject: [PATCH] Update mobs mod --- mods/ENTITIES/mobs/api.lua | 202 +++++++++++++-------------------- mods/ENTITIES/mobs/api.txt | 13 +-- mods/ENTITIES/mobs/depends.txt | 2 - mods/ENTITIES/mobs/mount.lua | 2 +- 4 files changed, 84 insertions(+), 135 deletions(-) diff --git a/mods/ENTITIES/mobs/api.lua b/mods/ENTITIES/mobs/api.lua index 74449d2c2..77667596f 100644 --- a/mods/ENTITIES/mobs/api.lua +++ b/mods/ENTITIES/mobs/api.lua @@ -1,9 +1,9 @@ --- Mobs Api (4th July 2017) +-- Mobs Api (14th July 2017) mobs = {} mobs.mod = "redo" -mobs.version = "20170704" +mobs.version = "20170714" -- Intllib @@ -48,7 +48,7 @@ local damage_enabled = minetest.setting_getbool("enable_damage") local peaceful_only = minetest.setting_getbool("only_peaceful_mobs") local disable_blood = minetest.setting_getbool("mobs_disable_blood") local creative = minetest.setting_getbool("creative_mode") -local spawn_protected = tonumber(minetest.setting_get("mobs_spawn_protected")) or 1 +local spawn_protected = minetest.setting_getbool("mobs_spawn_protected") ~= false local remove_far = minetest.setting_getbool("remove_far_mobs") local difficulty = tonumber(minetest.setting_get("mob_difficulty")) or 1.0 local show_health = false @@ -64,6 +64,13 @@ local enable_pathfinding = true local stuck_timeout = 3 -- how long before mob gets stuck in place and starts searching local stuck_path_timeout = 10 -- how long will mob follow path before giving up +-- default nodes +local node_fire = "mcl_fire:fire" +local node_permanent_flame = "mcl_fire:eternal_fire" +local node_ice = "mcl_core:ice" +local node_snowblock = "mcl_core:snowblock" +local node_snow = "mcl_core:snow" +mobs.fallback_node = minetest.registered_aliases["mapgen_dirt"] or "mcl_core:dirt" -- play sound local mob_sound = function(self, sound) @@ -242,9 +249,10 @@ end local flight_check = function(self, pos_w) local nod = self.standing_in + local def = minetest.registered_nodes[nod] if type(self.fly_in) == "string" - and (nod == self.fly_in or nod == self.fly_in:gsub("_source", "_flowing")) then + and (nod == self.fly_in or def.liquid_alternative_flowing ~= "") then return true @@ -252,7 +260,7 @@ local flight_check = function(self, pos_w) for _,fly_in in pairs(self.fly_in) do - if nod == fly_in or nod == fly_in:gsub("_source", "_flowing") then + if nod == fly_in or def.liquid_alternative_flowing ~= "" then return true end @@ -507,7 +515,7 @@ end -- get node but use fallback for nil or unknown local node_ok = function(pos, fallback) - fallback = fallback or "mcl_core:dirt" + fallback = fallback or mobs.fallback_node local node = minetest.get_node_or_nil(pos) @@ -598,8 +606,8 @@ local do_env_damage = function(self) -- lava or fire elseif self.lava_damage and (nodef.groups.lava - or self.standing_in == "mcl_fire:fire" - or self.standing_in == "mcl_fire:eternal_fire") then + or self.standing_in == node_fire + or self.standing_in == node_permanent_flame) then if self.lava_damage ~= 0 then @@ -681,7 +689,7 @@ local do_jump = function(self) }) -- thin blocks that do not need to be jumped - if nod.name == "mcl_core:snow" then + if nod.name == node_snow then return false end @@ -1049,7 +1057,7 @@ local smart_mobs = function(self, s, p, dist, dtime) if ndef1 and (ndef1.buildable_to or ndef1.groups.liquid) then - minetest.set_node(s, {name = "mcl_core:dirt"}) + minetest.set_node(s, {name = mobs.fallback_node}) end end @@ -1511,7 +1519,7 @@ local do_states = function(self, dtime) and minetest.registered_nodes[self.standing_in].groups.water) then lp = minetest.find_node_near(s, 5, {"group:soil", "group:stone", - "group:sand", "mcl_core:ice", "mcl_core:snowblock"}) + "group:sand", node_ice, node_snowblock}) -- did we find land? if lp then @@ -1675,30 +1683,36 @@ local do_states = function(self, dtime) local pos = self.object:getpos() 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 - mob_sound(self, self.sounds.explode) - - self.object:remove() - - effect(pos, 15, "tnt_smoke.png") - - -- hurt player/mobs caught in blast area - entity_physics(pos, radius) - - return + damage_radius = 0 end - pos.y = pos.y - 1 - - mobs:explosion(pos, radius, 0, 1, self.sounds.explode) - self.object:remove() - entity_physics(pos, radius) + if minetest.get_modpath("tnt") and tnt and tnt.boom + and not minetest.is_protected(pos, "") then + + tnt.boom(pos, { + radius = radius, + damage_radius = damage_radius, + sound = self.sounds.explode, + }) + else + + minetest.sound_play(self.sounds.explode, { + pos = pos, + gain = 1.0, + 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) + end return end @@ -2764,7 +2778,7 @@ function mobs:spawn_specific(name, nodes, neighbors, min_light, max_light, end -- mobs cannot spawn in protected areas when enabled - if spawn_protected == 1 + if not spawn_protected and minetest.is_protected(pos, "") then --print ("--- inside protected area", name) return @@ -2850,96 +2864,6 @@ function mobs:spawn(def) end --- set content id's -local c_air = minetest.get_content_id("air") -local c_ignore = minetest.get_content_id("ignore") -local c_obsidian = minetest.get_content_id("mcl_core:obsidian") -local c_fire = minetest.get_content_id("mcl_fire:fire") - --- explosion (cannot break protected or unbreakable nodes) -function mobs:explosion(pos, radius, fire, smoke, sound) - - radius = radius or 0 - fire = fire or 0 - smoke = smoke or 0 - - -- if area protected or near map limits then no blast damage - if minetest.is_protected(pos, "") - or not within_limits(pos, radius) then - return - end - - -- explosion sound - if sound - and sound ~= "" then - - minetest.sound_play(sound, { - pos = pos, - gain = 1.0, - max_hear_distance = 16 - }) - end - - pos = vector.round(pos) -- voxelmanip doesn't work properly unless pos is rounded ?!?! - - local vm = VoxelManip() - local minp, maxp = vm:read_from_map(vector.subtract(pos, radius), vector.add(pos, radius)) - local a = VoxelArea:new({MinEdge = minp, MaxEdge = maxp}) - local data = vm:get_data() - local p = {} - local pr = PseudoRandom(os.time()) - - for z = -radius, radius do - for y = -radius, radius do - local vi = a:index(pos.x + (-radius), pos.y + y, pos.z + z) - for x = -radius, radius do - - p.x = pos.x + x - p.y = pos.y + y - p.z = pos.z + z - - if (x * x) + (y * y) + (z * z) <= (radius * radius) + pr:next(-radius, radius) - and data[vi] ~= c_air - and data[vi] ~= c_ignore - and data[vi] ~= c_obsidian - and data[vi] ~= c_fire then - - local n = node_ok(p).name - local on_blast = minetest.registered_nodes[n].on_blast - - if on_blast then - - return on_blast(p) - - elseif minetest.registered_nodes[n].groups.unbreakable == 1 then - - -- do nothing - else - - -- after effects - if fire > 0 - and (minetest.registered_nodes[n].groups.flammable - or random(1, 100) <= 30) then - - minetest.set_node(p, {name = "mcl_fire:fire"}) - else - minetest.set_node(p, {name = "air"}) - - if smoke > 0 then - effect(p, 2, "tnt_smoke.png", 3*radius, 5*radius, radius, 0) - end - end - end - end - - vi = vi + 1 - - end - end - end -end - - -- register arrow for shoot attack function mobs:register_arrow(name, def) @@ -3034,16 +2958,12 @@ function mobs:register_arrow(name, def) end local entity = player:get_luaentity() - and player:get_luaentity().name or "" - if self.hit_mob + if entity + and self.hit_mob + and entity._cmi_is_mob == true and tostring(player) ~= self.owner_id - and entity ~= self.object:get_luaentity().name - and entity ~= "__builtin:item" - and entity ~= "__builtin:falling_node" - and entity ~= "gauges:hp_bar" - and entity ~= "mcl_signs:text" - and entity ~= "itemframes:item" then + and entity.name ~= self.object:get_luaentity().name then self.hit_mob(self, player) @@ -3060,6 +2980,38 @@ function mobs:register_arrow(name, def) end +-- compatibility function +function mobs:explosion(pos, radius) + local self = {sounds = {}} + self.sounds.explode = "tnt_explode" + mobs:boom(self, pos, radius) +end + + +-- make explosion with protection and tnt mod check +function mobs:boom(self, pos, radius) + + if minetest.get_modpath("tnt") and tnt and tnt.boom + and not minetest.is_protected(pos, "") then + + tnt.boom(pos, { + radius = radius, + damage_radius = radius, + sound = self.sounds.explode, + }) + else + minetest.sound_play(self.sounds.explode, { + pos = pos, + gain = 1.0, + max_hear_distance = self.sounds.distance or 32 + }) + + entity_physics(pos, radius) + effect(pos, 32, "tnt_smoke.png", radius * 3, radius * 5, radius, 1, 0) + end +end + + -- Register spawn eggs -- Note: This also introduces the “spawn_egg” group: diff --git a/mods/ENTITIES/mobs/api.txt b/mods/ENTITIES/mobs/api.txt index e8a4df067..90a5966e9 100644 --- a/mods/ENTITIES/mobs/api.txt +++ b/mods/ENTITIES/mobs/api.txt @@ -1,5 +1,5 @@ -MOB API (4th July 2017) +MOB API (13th July 2017) The mob api is a function that can be called on by other mods to add new animals or monsters into minetest. @@ -8,7 +8,7 @@ The mob api is a function that can be called on by other mods to add new animals 'enable_damage' if true monsters will attack players (default is true) 'only_peaceful_mobs' if true only animals will spawn in game (default is false) 'mobs_disable_blood' if false blood effects appear when mob is hit (default is false) - 'mobs_spawn_protected' if set to 1 then mobs will not spawn in protected areas (default is 0) + 'mobs_spawn_protected' if set to false then mobs will not spawn in protected areas (default is true) 'remove_far_mobs' if true then mobs that are outside players visual range will be removed (default is false) 'mobname' can change specific mob chance rate (0 to disable) and spawn number e.g. mobs_animal:cow = 1000,5 'mob_difficulty' sets difficulty level (health and hit damage multiplied by this number), defaults to 1.0. @@ -229,15 +229,14 @@ This function registers a spawn egg which can be used by admin to properly spawn 'no_creative' when set to true this stops spawn egg appearing in creative mode for destructive mobs like Dungeon Masters -mobs:explosion(pos, radius, fire, smoke) +mobs:explosion(pos, radius) -- DEPRECATED!!! use mobs:boom() instead -This function generates an explosion which removes nodes in a specific radius and replace them with fire or air. Protection nodes, obsidian and locked chests will not be destroyed although a normal chest will drop it's contents. +mobs:boom(self, pos, radius) +This function generates an explosion which removes nodes in a specific radius and damages any entity caught inside the blast radius. Protection will limit node destruction but not entity damage. + 'self' mob entity 'pos' centre position of explosion 'radius' radius of explosion (typically set to 3) - 'fire' should fire appear in explosion (1=yes, 0=no) - 'smoke' should smoke appear in explosion (1=yes, 0=no) - 'sound' sound played when mob explodes mobs:capture_mob(self, clicker, chance_hand, chance_net, chance_lasso, force_take, replacewith) diff --git a/mods/ENTITIES/mobs/depends.txt b/mods/ENTITIES/mobs/depends.txt index 6b6d81582..bf48588bf 100644 --- a/mods/ENTITIES/mobs/depends.txt +++ b/mods/ENTITIES/mobs/depends.txt @@ -1,6 +1,4 @@ mcl_core -mcl_hunger -mcl_sounds invisibility? intllib? lucky_block? diff --git a/mods/ENTITIES/mobs/mount.lua b/mods/ENTITIES/mobs/mount.lua index 67ad40648..050fbb5da 100644 --- a/mods/ENTITIES/mobs/mount.lua +++ b/mods/ENTITIES/mobs/mount.lua @@ -12,7 +12,7 @@ local crash_threshold = 6.5 -- ignored if enable_crash=false local node_ok = function(pos, fallback) - fallback = fallback or "mcl_core:dirt" + fallback = fallback or mobs.fallback_node local node = minetest.get_node_or_nil(pos)