diff --git a/api.lua b/api.lua index 9acf5bf..63d4a80 100644 --- a/api.lua +++ b/api.lua @@ -1,9 +1,9 @@ --- Mobs Api (16th June 2017) +-- Mobs Api (18th June 2017) mobs = {} mobs.mod = "redo" -mobs.version = "20170616" +mobs.version = "20170618" -- Intllib @@ -23,6 +23,9 @@ end mobs.intllib = S +-- CMI support check +local use_cmi = minetest.global_exists("cmi") + -- Invisibility mod check mobs.invis = {} if rawget(_G, "invisibility") then @@ -370,7 +373,7 @@ end -- check if mob is dead or only hurt -local check_for_death = function(self, cause) +local check_for_death = function(self, cause, cmi_cause) -- has health actually changed? if self.health == self.old_health and self.health > 0 then @@ -419,6 +422,11 @@ local check_for_death = function(self, cause) if self.on_die then self.on_die(self, pos) + + if use_cmi then + cmi.notify_die(self.object, cmi_cause) + end + self.object:remove() return true @@ -439,9 +447,19 @@ local check_for_death = function(self, cause) set_animation(self, "die") minetest.after(2, function(self) + + if use_cmi then + cmi.notify_die(self.object, cmi_cause) + end + self.object:remove() end, self) else + + if use_cmi then + cmi.notify_die(self.object, cmi_cause) + end + self.object:remove() end @@ -499,15 +517,11 @@ local node_ok = function(pos, fallback) local node = minetest.get_node_or_nil(pos) - if not node then - return minetest.registered_nodes[fallback] - end - - if minetest.registered_nodes[node.name] then + if node and minetest.registered_nodes[node.name] then return node end - return minetest.registered_nodes[fallback] + return {name = fallback} end @@ -549,7 +563,7 @@ local do_env_damage = function(self) effect(pos, 5, "tnt_smoke.png") - if check_for_death(self, "light") then return end + if check_for_death(self, "light", {type = "light"}) then return end end -- what is mob standing in? @@ -577,7 +591,8 @@ local do_env_damage = function(self) effect(pos, 5, "bubble.png", nil, nil, 1, nil) - if check_for_death(self, "water") then return end + if check_for_death(self, "water", {type = "environment", + pos = pos, node = self.standing_in}) then return end end -- lava or fire @@ -592,7 +607,8 @@ local do_env_damage = function(self) effect(pos, 5, "fire_basic_flame.png", nil, nil, 1, nil) - if check_for_death(self, "lava") then return end + if check_for_death(self, "lava", {type = "environment", + pos = pos, node = self.standing_in}) then return end end -- damage_per_second node check @@ -602,7 +618,8 @@ local do_env_damage = function(self) effect(pos, 5, "tnt_smoke.png") - if check_for_death(self, "dps") then return end + if check_for_death(self, "dps", {type = "environment", + pos = pos, node = self.standing_in}) then return end end --- suffocation inside solid node @@ -613,10 +630,11 @@ local do_env_damage = function(self) self.health = self.health - self.suffocation - if check_for_death(self, "suffocation") then return end + if check_for_death(self, "suffocation", {type = "environment", + pos = pos, node = self.standing_in}) then return end end - check_for_death(self, "") + check_for_death(self, "", {type = "unknown"}) end @@ -1957,7 +1975,7 @@ local falling = function(self, pos) effect(pos, 5, "tnt_smoke.png", 1, 2, 2, nil) - if check_for_death(self, "fall") then + if check_for_death(self, "fall", {type = "fall"}) then return end end @@ -2004,18 +2022,23 @@ local mob_punch = function(self, hitter, tflp, tool_capabilities, dir) tflp = 0.2 end - for group,_ in pairs( (tool_capabilities.damage_groups or {}) ) do + if use_cmi then + damage = cmi.calculate_damage(self.object, hitter, tflp, tool_capabilities, dir) + else - tmp = tflp / (tool_capabilities.full_punch_interval or 1.4) + for group,_ in pairs( (tool_capabilities.damage_groups or {}) ) do - if tmp < 0 then - tmp = 0.0 - elseif tmp > 1 then - tmp = 1.0 + tmp = tflp / (tool_capabilities.full_punch_interval or 1.4) + + if tmp < 0 then + tmp = 0.0 + elseif tmp > 1 then + tmp = 1.0 + end + + damage = damage + (tool_capabilities.damage_groups[group] or 0) + * tmp * ((armor[group] or 0) / 100.0) end - - damage = damage + (tool_capabilities.damage_groups[group] or 0) - * tmp * ((armor[group] or 0) / 100.0) end -- check for tool immunity or special damage @@ -2036,6 +2059,13 @@ local mob_punch = function(self, hitter, tflp, tool_capabilities, dir) -- print ("Mob Damage is", damage) + if use_cmi then + + local cancel = cmi.notify_punch(self.object, hitter, tflp, tool_capabilities, dir, damage) + + if cancel then return end + end + -- add weapon wear if tool_capabilities then punch_interval = tool_capabilities.full_punch_interval or 1.4 @@ -2083,11 +2113,13 @@ local mob_punch = function(self, hitter, tflp, tool_capabilities, dir) -- exit here if dead, special item check if weapon:get_name() == "mobs:pick_lava" then - if check_for_death(self, "lava") then + if check_for_death(self, "lava", {type = "punch", + puncher = hitter}) then return end else - if check_for_death(self, "hit") then + if check_for_death(self, "hit", {type = "punch", + puncher = hitter}) then return end end @@ -2220,6 +2252,10 @@ local mob_staticdata = function(self) self.rotate = math.rad(90) end + if use_cmi then + self.serialized_cmi_components = cmi.serialize_components(self.cmi_components) + end + local tmp = {} for _,stat in pairs(self) do @@ -2228,7 +2264,8 @@ local mob_staticdata = function(self) if t ~= "function" and t ~= "nil" - and t ~= "userdata" then + and t ~= "userdata" + and _ ~= "cmi_components" then tmp[_] = self[_] end end @@ -2239,7 +2276,7 @@ end -- activate mob and reload settings -local mob_activate = function(self, staticdata, def) +local mob_activate = function(self, staticdata, def, dtime) -- remove monsters in peaceful mode, or when no data if (self.type == "monster" and peaceful_only) then @@ -2339,12 +2376,21 @@ local mob_activate = function(self, staticdata, def) self.object:set_properties(self) set_yaw(self.object, (random(0, 360) - 180) / 180 * pi) update_tag(self) + + if use_cmi then + self.cmi_components = cmi.activate_components(self.serialized_cmi_components) + cmi.notify_activate(self.object, dtime) + end end -- main mob function local mob_step = function(self, dtime) + if use_cmi then + cmi.notify_step(self.object, dtime) + end + local pos = self.object:getpos() local yaw = 0 @@ -2565,6 +2611,7 @@ minetest.register_entity(name, { attack_animals = def.attack_animals or false, specific_attack = def.specific_attack, owner_loyal = def.owner_loyal, + cmi_is_mob = true, on_blast = def.on_blast or do_tnt, @@ -2572,8 +2619,8 @@ minetest.register_entity(name, { on_punch = mob_punch, - on_activate = function(self, staticdata) - return mob_activate(self, staticdata, def) + on_activate = function(self, staticdata, dtime) + return mob_activate(self, staticdata, def, dtime) end, get_staticdata = function(self) diff --git a/depends.txt b/depends.txt index 5eb2f17..d03b035 100644 --- a/depends.txt +++ b/depends.txt @@ -2,3 +2,4 @@ default invisibility? intllib? lucky_block? +cmi? diff --git a/readme.MD b/readme.MD index 45c83e2..ae879e5 100644 --- a/readme.MD +++ b/readme.MD @@ -22,6 +22,7 @@ Lucky Blocks: 9 Changelog: +- 1.37- Added support for Raymoo's CMI (common mob interface) mod: https://forum.minetest.net/viewtopic.php?f=9&t=15448 - 1.36- Death check added, if mob dies in fire/lava/with lava pick then drops are cooked - 1.35- Added owner_loyal flag for owned mobs to attack player enemies, also fixed group_attack - 1.34- Added function to fly mob using directional movement (thanks D00Med for flying code)