diff --git a/README.md b/README.md index 52e259d2..73609a00 100644 --- a/README.md +++ b/README.md @@ -67,7 +67,7 @@ The game includes the mods from the default [minetest_game](https://github.com/m * [mobs_monster][] ([MIT][lic.mobs_monster]) -- version: [e6f77e1 Git][ver.mobs_monster] *2017-05-28* ([patched][patch.mobs_monster]) * [sneeker][] ([WTFPL][lic.wtfpl] / [CC0][lic.cc0]) -- version: [a56b9c2 Git][ver.sneeker] *2017-06-07* * mobiles/engine/ - * [mobs_redo][] ([MIT][lic.mobs_redo]) -- version: [4eb1c93 Git][ver.mobs_redo] *2017-06-04* ([patched][patch.mobs_redo]) ***UPDATE*** + * [mobs_redo][] ([MIT][lic.mobs_redo] / Unspecified Creative Commons license) -- version: [7b02fef Git][ver.mobs_redo] *2017-07-08* ([patched][patch.mobs_redo]) ***UPDATE*** * mobiles/general/ * [mobs_animal][] ([MIT][lic.mobs_animal]) -- version: [ebc2e3a Git][ver.mobs_animal] *2017-05-27* ([patched][patch.mobs_animal]) * mobiles/passive/ @@ -474,7 +474,7 @@ The game includes the mods from the default [minetest_game](https://github.com/m [ver.mobs_animal]: https://github.com/tenplus1/mobs_animal/tree/ebc2e3a [ver.mobs_goblins]: https://github.com/FreeLikeGNU/mobs_goblins/tree/acabe4d [ver.mobs_monster]: https://github.com/tenplus1/mobs_monster/tree/e6f77e1 -[ver.mobs_redo]: https://github.com/tenplus1/mobs_redo/tree/4eb1c93 +[ver.mobs_redo]: https://github.com/tenplus1/mobs_redo/tree/7b02fef [ver.more_chests]: https://github.com/minetest-mods/more_chests/tree/c597779 [ver.moreblocks]: https://github.com/minetest-mods/moreblocks/tree/fbfb079 [ver.moremesecons]: https://github.com/minetest-mods/MoreMesecons/tree/aa2ae82 @@ -564,7 +564,7 @@ The game includes the mods from the default [minetest_game](https://github.com/m [patch.mobs_animal]: https://github.com/AntumMT/mtmod-mobs_animal/tree/3f3249e [patch.mobs_goblins]: https://github.com/AntumMT/mod-mobs_goblins/tree/b5cee44 [patch.mobs_monster]: https://github.com/AntumMT/mtmod-mobs_monster/tree/71d3e0c -[patch.mobs_redo]: https://github.com/AntumMT/mtmod-mobs_redo/tree/3a82320 +[patch.mobs_redo]: https://github.com/AntumMT/mod-mobs_redo/tree/5f4c18f [patch.moreblocks]: https://github.com/AntumMT/mod-moreblocks/tree/e5d5449 [patch.moreores]: https://github.com/AntumMT/mtmod-moreores/tree/e5abf12 [patch.mydoors]: https://github.com/AntumMT/mtmp-mydoors/tree/e36c9d1 diff --git a/mods/mobiles/engine/mobs_redo/api.lua b/mods/mobiles/engine/mobs_redo/api.lua index 56937e3c..28c03d0f 100644 --- a/mods/mobiles/engine/mobs_redo/api.lua +++ b/mods/mobiles/engine/mobs_redo/api.lua @@ -1,28 +1,20 @@ --- Mobs Api (4th June 2017) +-- Mobs Api (8th July 2017) mobs = {} mobs.mod = "redo" -mobs.version = "20170604" +mobs.version = "20170708" -- Intllib -local S - -if minetest.get_modpath("intllib") then - S = intllib.Getter() -else - S = function(s, a, ...) a = {a, ...} - return s:gsub("@(%d+)", function(n) - return a[tonumber(n)] - end) - end - -end - +local MP = minetest.get_modpath(minetest.get_current_modname()) +local S, NS = dofile(MP .. "/intllib.lua") mobs.intllib = S +-- CMI support check +local use_cmi = minetest.global_exists("cmi") + -- Invisibility mod check mobs.invis = {} if rawget(_G, "invisibility") then @@ -72,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 = "fire:basic_flame" +local node_permanent_flame = "fire:permanent_flame" +local node_ice = "default:ice" +local node_snowblock = "default:snowblock" +local node_snow = "default:snow" +mobs.fallback_node = minetest.registered_aliases["mapgen_dirt"] or "default:dirt" -- play sound local mob_sound = function(self, sound) @@ -154,9 +153,9 @@ local set_animation = function(self, anim) self.object:set_animation({ x = self.animation[anim .. "_start"], - y = self.animation[anim .. "_end"] - }, self.animation[anim .. "_speed"] or self.animation.speed_normal or 15) - + y = self.animation[anim .. "_end"]}, + self.animation[anim .. "_speed"] or self.animation.speed_normal or 15, + 0, self.animation[anim .. "_loop"] ~= false) end @@ -250,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 @@ -260,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 @@ -272,12 +272,13 @@ end -- particle effects -local effect = function(pos, amount, texture, min_size, max_size, radius, gravity) +local effect = function(pos, amount, texture, min_size, max_size, radius, gravity, glow) 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 minetest.add_particlespawner({ amount = amount, @@ -293,6 +294,7 @@ local effect = function(pos, amount, texture, min_size, max_size, radius, gravit minsize = min_size, maxsize = max_size, texture = texture, + glow = glow, }) end @@ -326,6 +328,9 @@ end -- drop items local item_drop = function(self, cooked) + -- no drops for child mobs + if self.child then return end + local obj, item, num local pos = self.object:getpos() @@ -370,7 +375,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 +424,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 +449,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 @@ -495,23 +515,19 @@ end -- get node but use fallback for nil or unknown local node_ok = function(pos, fallback) - fallback = fallback or "default:dirt" + fallback = fallback or mobs.fallback_node 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 --- environmental damage (water, lava, fire, light) +-- environmental damage (water, lava, fire, light etc.) local do_env_damage = function(self) -- feed/tame text timer (so mob 'full' messages dont spam chat) @@ -549,11 +565,17 @@ 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 + + local y_level = self.collisionbox[2] + + if self.child then + y_level = self.collisionbox[2] * 0.5 end -- what is mob standing in? - pos.y = pos.y + self.collisionbox[2] + 0.1 -- foot level + pos.y = pos.y + y_level + 0.25 -- foot level self.standing_in = node_ok(pos, "air").name -- print ("standing in " .. self.standing_in) @@ -563,51 +585,64 @@ local do_env_damage = function(self) --print ("--- stopping on ignore") end - if self.water_damage ~= 0 - or self.lava_damage ~= 0 then + local nodef = minetest.registered_nodes[self.standing_in] - local nodef = minetest.registered_nodes[self.standing_in] + pos.y = pos.y + 1 -- for particle effect position - pos.y = pos.y + 1 + -- water + if self.water_damage + and nodef.groups.water then - -- water - if nodef.groups.water then + if self.water_damage ~= 0 then - if self.water_damage ~= 0 then + self.health = self.health - self.water_damage - self.health = self.health - self.water_damage + effect(pos, 5, "bubble.png", nil, nil, 1, nil) - effect(pos, 5, "bubble.png", nil, nil, 1, nil) - - if check_for_death(self, "water") then return end - end - - -- lava or fire - elseif (nodef.groups.lava - or self.standing_in == "fire:basic_flame" - or self.standing_in == "fire:permanent_flame") then - - if self.lava_damage ~= 0 then - - self.health = self.health - self.lava_damage - - effect(pos, 5, "fire_basic_flame.png", nil, nil, 1, nil) - - if check_for_death(self, "lava") then return end - end - - -- damage_per_second node check - elseif minetest.registered_nodes[self.standing_in].damage_per_second ~= 0 then - - local dps = minetest.registered_nodes[self.standing_in].damage_per_second - - self.health = self.health - dps - - effect(pos, 5, "tnt_smoke.png") + if check_for_death(self, "water", {type = "environment", + pos = pos, node = self.standing_in}) then return end end + + -- lava or fire + elseif self.lava_damage + and (nodef.groups.lava + or self.standing_in == node_fire + or self.standing_in == node_permanent_flame) then + + if self.lava_damage ~= 0 then + + self.health = self.health - self.lava_damage + + effect(pos, 5, "fire_basic_flame.png", nil, nil, 1, nil) + + if check_for_death(self, "lava", {type = "environment", + pos = pos, node = self.standing_in}) then return end + end + + -- damage_per_second node check + elseif nodef.damage_per_second ~= 0 then + + self.health = self.health - nodef.damage_per_second + + effect(pos, 5, "tnt_smoke.png") + + if check_for_death(self, "dps", {type = "environment", + pos = pos, node = self.standing_in}) then return end end - check_for_death(self, "") + --- suffocation inside solid node + if self.suffocation ~= 0 + and nodef.walkable == true + and nodef.groups.disable_suffocation ~= 1 + and nodef.drawtype == "normal" then + + self.health = self.health - self.suffocation + + if check_for_death(self, "suffocation", {type = "environment", + pos = pos, node = self.standing_in}) then return end + end + + check_for_death(self, "", {type = "unknown"}) end @@ -654,7 +689,7 @@ local do_jump = function(self) }) -- thin blocks that do not need to be jumped - if nod.name == "default:snow" then + if nod.name == node_snow then return false end @@ -704,7 +739,7 @@ local entity_physics = function(pos, radius) objs[n]:punch(objs[n], 1.0, { full_punch_interval = 1.0, damage_groups = {fleshy = damage}, - }, nil) + }, pos) -- was nil end end @@ -906,12 +941,23 @@ local replace = function(self, pos) -- print ("replace node = ".. minetest.get_node(pos).name, pos.y) - minetest.set_node(pos, {name = with}) + local oldnode = {name = what} + local newnode = {name = with} + local on_replace_return - -- when cow/sheep eats grass, replace wool and milk - if self.gotten == true then - self.gotten = false - self.object:set_properties(self) + if self.on_replace then + on_replace_return = self.on_replace(self, pos, oldnode, newnode) + end + + if on_replace_return ~= false then + + minetest.set_node(pos, {name = with}) + + -- when cow/sheep eats grass, replace wool and milk + if self.gotten == true then + self.gotten = false + self.object:set_properties(self) + end end end end @@ -1011,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 = "default:dirt"}) + minetest.set_node(s, {name = mobs.fallback_node}) end end @@ -1109,7 +1155,7 @@ local specific_attack = function(list, what) return true end - -- is found entity on list to attack? + -- found entity on list to attack? for no = 1, #list do if list[no] == what then @@ -1126,6 +1172,7 @@ local monster_attack = function(self) if self.type ~= "monster" or not damage_enabled + or creative or self.state == "attack" or day_docile(self) then return @@ -1432,7 +1479,7 @@ local do_states = function(self, dtime) self.state = "walk" set_animation(self, "walk") - -- fly up/down randombly for flying mobs + -- fly up/down randomly for flying mobs if self.fly and random(1, 100) <= self.walk_chance then local v = self.object:getvelocity() @@ -1472,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", "default:ice", "default:snowblock"}) + "group:sand", node_ice, node_snowblock}) -- did we find land? if lp then @@ -1511,7 +1558,8 @@ local do_states = function(self, dtime) -- otherwise randomly turn elseif random(1, 100) <= 30 then - yaw = random() * 2 * pi + --yaw = random() * 2 * pi + yaw = (random(0, 360) - 180) / 180 * pi yaw = set_yaw(self.object, yaw) end @@ -1635,30 +1683,26 @@ 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, 1, 1, self.sounds.explode) - self.object:remove() - entity_physics(pos, radius) + if minetest.get_modpath("tnt") then + + tnt.boom(pos, { + radius = radius, + damage_radius = damage_radius, + }) + else + entity_physics(pos, damage_radius) + end return end @@ -1905,14 +1949,26 @@ local falling = function(self, pos) -- floating in water (or falling) local v = self.object:getvelocity() - -- going up then apply gravity - if v.y > 0.1 then + if v.y > 0 then + -- apply gravity when moving up + self.object:setacceleration({ + x = 0, + y = -10, + z = 0 + }) + + elseif v.y <= 0 and v.y > self.fall_speed then + + -- fall downwards at set speed self.object:setacceleration({ x = 0, y = self.fall_speed, z = 0 }) + else + -- stop accelerating once max fall speed hit + self.object:setacceleration({x = 0, y = 0, z = 0}) end -- in water then float up @@ -1928,14 +1984,8 @@ local falling = function(self, pos) }) end else - -- fall downwards - self.object:setacceleration({ - x = 0, - y = self.fall_speed, - z = 0 - }) - -- fall damage + -- fall damage onto solid ground if self.fall_damage == 1 and self.object:getvelocity().y == 0 then @@ -1947,7 +1997,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 @@ -1968,14 +2018,14 @@ local mob_punch = function(self, hitter, tflp, tool_capabilities, dir) -- error checking when mod profiling is enabled if not tool_capabilities then - print (S("[MOBS] mod profiling enabled, damage not enabled")) + minetest.log("warning", "[mobs] Mod profiling enabled, damage not enabled") return end -- is mob protected? if self.protected and hitter:is_player() and minetest.is_protected(self.object:getpos(), hitter:get_player_name()) then - minetest.chat_send_player(hitter:get_player_name(), "Mob has been protected!") + minetest.chat_send_player(hitter:get_player_name(), S("Mob has been protected!")) return end @@ -1994,18 +2044,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 @@ -2026,6 +2081,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 @@ -2073,11 +2135,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 @@ -2124,14 +2188,13 @@ local mob_punch = function(self, hitter, tflp, tool_capabilities, dir) local lp = hitter:getpos() local s = self.object:getpos() - local vec = { x = lp.x - s.x, y = lp.y - s.y, z = lp.z - s.z } - local yaw = atan(vec.z / vec.x) + 3 * pi / 2 + local yaw = (atan(vec.z / vec.x) + 3 * pi / 2) - self.rotate if lp.x > s.x then yaw = yaw + pi @@ -2211,6 +2274,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 @@ -2219,7 +2286,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 @@ -2230,7 +2298,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 @@ -2330,12 +2398,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 @@ -2501,10 +2578,11 @@ minetest.register_entity(name, { view_range = def.view_range or 5, walk_velocity = def.walk_velocity or 1, run_velocity = def.run_velocity or 2, - damage = max(1, (def.damage or 0) * difficulty), + damage = max(0, (def.damage or 0) * difficulty), light_damage = def.light_damage or 0, water_damage = def.water_damage or 0, lava_damage = def.lava_damage or 0, + suffocation = def.suffocation or 2, fall_damage = def.fall_damage or 1, fall_speed = def.fall_speed or -10, -- must be lower than -2 (default: -10) drops = def.drops or {}, @@ -2530,6 +2608,7 @@ minetest.register_entity(name, { replace_what = def.replace_what, replace_with = def.replace_with, replace_offset = def.replace_offset or 0, + on_replace = def.on_replace, timer = 0, env_damage_timer = 0, -- only used when state = "attack" tamed = false, @@ -2560,6 +2639,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, @@ -2567,8 +2647,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) @@ -2625,12 +2705,12 @@ function mobs:spawn_specific(name, nodes, neighbors, min_light, max_light, aoc = tonumber(numbers[2]) or aoc if chance == 0 then - print(S("[Mobs Redo] @1 has spawning disabled", name)) + minetest.log("warning", string.format("[mobs] %s has spawning disabled", name)) return end - print (S("[Mobs Redo] Chance setting for @1 changed to @2", name, chance) - .. " (total: " .. aoc .. ")") + minetest.log("action", + string.format("[mobs] Chance setting for %s changed to %s (total: %s)", name, chance, aoc)) end @@ -2741,8 +2821,8 @@ function mobs:spawn_specific(name, nodes, neighbors, min_light, max_light, return end else - print (S("[mobs] @1 failed to spawn at @2", - name, minetest.pos_to_string(pos))) + minetest.log("warning", string.format("[mobs] %s failed to spawn at %s", + name, minetest.pos_to_string(pos))) end end @@ -2779,100 +2859,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("default:obsidian") -local c_brick = minetest.get_content_id("default:obsidianbrick") -local c_chest = minetest.get_content_id("default:chest_locked") -local c_fire = minetest.get_content_id("fire:basic_flame") - --- 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_brick - and data[vi] ~= c_chest - 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 = "fire:basic_flame"}) - else - minetest.set_node(p, {name = "air"}) - - if smoke > 0 then - effect(p, 2, "tnt_smoke.png") - end - end - end - end - - vi = vi + 1 - - end - end - end -end - - -- register arrow for shoot attack function mobs:register_arrow(name, def) @@ -2967,16 +2953,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 ~= "signs:text" - and entity ~= "itemframes:item" then + and entity.name ~= self.object:get_luaentity().name then self.hit_mob(self, player) @@ -2993,14 +2975,18 @@ function mobs:register_arrow(name, def) end --- register spawn eggs +-- Register spawn eggs + +-- Note: This also introduces the “spawn_egg” group: +-- * spawn_egg=1: Spawn egg (generic mob, no metadata) +-- * spawn_egg=2: Spawn egg (captured/tamed mob, metadata) function mobs:register_egg(mob, desc, background, addegg, no_creative) - local grp = {} + local grp = {spawn_egg = 1} -- do NOT add this egg to creative inventory (e.g. dungeon master) if creative and no_creative == true then - grp = {not_in_creative_inventory = 1} + grp.not_in_creative_inventory = 1 end local invimg = background @@ -3013,9 +2999,9 @@ function mobs:register_egg(mob, desc, background, addegg, no_creative) -- register new spawn egg containing mob information minetest.register_craftitem(mob .. "_set", { - description = desc .. " (Tamed)", + description = S("@1 (Tamed)", desc), inventory_image = invimg, - groups = {not_in_creative_inventory = 1}, + groups = {spawn_egg = 2, not_in_creative_inventory = 1}, stack_max = 1, on_place = function(itemstack, placer, pointed_thing) @@ -3091,7 +3077,8 @@ function mobs:register_egg(mob, desc, background, addegg, no_creative) return end - if ent.type ~= "monster" then + if ent.type ~= "monster" + and not placer:get_player_control().sneak then -- set owner and tame if not monster ent.owner = placer:get_player_name() ent.tamed = true @@ -3133,7 +3120,7 @@ function mobs:capture_mob(self, clicker, chance_hand, chance_net, chance_lasso, -- are we using hand, net or lasso to pick up mob? if tool:get_name() ~= "" and tool:get_name() ~= "mobs:net" - and tool:get_name() ~= "mobs:magic_lasso" then + and tool:get_name() ~= "mobs:lasso" then return false end @@ -3171,7 +3158,7 @@ function mobs:capture_mob(self, clicker, chance_hand, chance_net, chance_lasso, clicker:set_wielded_item(tool) - elseif tool:get_name() == "mobs:magic_lasso" then + elseif tool:get_name() == "mobs:lasso" then chance = chance_lasso @@ -3219,8 +3206,13 @@ function mobs:capture_mob(self, clicker, chance_hand, chance_net, chance_lasso, self.object:remove() + mob_sound(self, "default_place_node_hard") + + else minetest.chat_send_player(name, S("Missed!")) + + mob_sound(self, "mobs_swing") end end @@ -3248,11 +3240,20 @@ function mobs:protect(self, clicker) return true -- false end - tool:take_item() -- take 1 protection rune - clicker:set_wielded_item(tool) + if not creative then + tool:take_item() -- take 1 protection rune + clicker:set_wielded_item(tool) + end self.protected = true - minetest.chat_send_player(name, S("Protected!")) +-- minetest.chat_send_player(name, S("Protected!")) + + local pos = self.object:getpos() + pos.y = pos.y + self.collisionbox[2] + 0.5 + + effect(self.object:getpos(), 25, "mobs_protect_particle.png", 0.5, 4, 2, 15) + + mob_sound(self, "mobs_spell") return true end @@ -3361,8 +3362,8 @@ function mobs:feed_tame(self, clicker, feed_count, breed, tame) minetest.show_formspec(name, "mobs_nametag", "size[8,4]" .. default.gui_bg .. default.gui_bg_img - .. "field[0.5,1;7.5,0;name;" .. S("Enter name:") .. ";" .. tag .. "]" - .. "button_exit[2.5,3.5;3,1;mob_rename;" .. S("Rename") .. "]") + .. "field[0.5,1;7.5,0;name;" .. minetest.formspec_escape(S("Enter name:")) .. ";" .. tag .. "]" + .. "button_exit[2.5,3.5;3,1;mob_rename;" .. minetest.formspec_escape(S("Rename")) .. "]") end diff --git a/mods/mobiles/engine/mobs_redo/api.txt b/mods/mobiles/engine/mobs_redo/api.txt index dd567481..fab62ca2 100644 --- a/mods/mobiles/engine/mobs_redo/api.txt +++ b/mods/mobiles/engine/mobs_redo/api.txt @@ -1,5 +1,5 @@ -MOB API (12th May 2017) +MOB API (8th July 2017) The mob api is a function that can be called on by other mods to add new animals or monsters into minetest. @@ -20,7 +20,7 @@ This functions registers a new mob as a Minetest entity. 'name' is the name of the mob (e.g. "mobs:dirt_monster") definition is a table with the following fields - 'type' the type of the mob ("monster", "animal" or "npc") + 'type' the type of the mob ("monster", "animal" or "npc") where monsters attack players and npc's, animals and npc's tend to wander around and can attack when hit 1st. 'passive' will mob defend itself, set to false to attack 'docile_by_day' when true, mob will not attack during daylight hours unless provoked 'attacks_monsters' usually for npc's to attack monsters in area @@ -41,9 +41,9 @@ This functions registers a new mob as a Minetest entity. 'mesh' same is in minetest.register_entity() 'gotten_mesh' alternative mesh for when self.gotten is true (used for sheep) 'makes_footstep_sound' same is in minetest.register_entity() - 'follow' item when held will cause mob to follow player, can be single string "default:apple" or table {"default:apple", "default:diamond"} - 'view_range' the range in that the monster will see the playerand follow him - 'walk_chance' chance of mob walking around, set above to 0 for jumping mob only + 'follow' item when held will cause mob to follow player, can be single string "default:apple" or table {"default:apple", "default:diamond"}. These are also items that are used to feed and tame mob. + 'view_range' the range in which the mob will follow or attack player + 'walk_chance' chance of mob walking around (0 to 100), set to 0 for jumping mob only 'walk_velocity' the velocity when the monster is walking around 'run_velocity' the velocity when the monster is attacking a player 'runaway' when true mob will turn and run away when punched @@ -52,8 +52,8 @@ This functions registers a new mob as a Minetest entity. 'jump_height' height mob can jump, default is 6 (0 to disable jump) 'fly' can mob fly, true or false (used for swimming mobs also) 'fly_in' node name that mob flys inside, e.g "air", "default:water_source" for fish - 'damage' the damage per second - 'recovery_time' how much time from when mob is hit to recovery (default: 0.5) + 'damage' the damage mobs inflict per melee attack. + 'recovery_time' how much time from when mob is hit to recovery (default: 0.5 seconds) 'knock_back' strength of knock-back when mob hit (default: 3) 'immune_to' table holding special tool/item names and damage the incur e.g. {"default:sword_wood", 0}, {"default:gold_lump", -10} immune to sword, gold lump heals @@ -64,14 +64,15 @@ This functions registers a new mob as a Minetest entity. 'chance' the inverted chance (same as in abm) to get the item 'min' the minimum number of items 'max' the maximum number of items - 'armor' the armor (integer)(3=lowest; 1=highest)(fleshy group is used) + 'armor' this integer holds armor strength with 100 being normal, with lower numbers hardening the armor and higher numbers making it weaker (weird I know but compatible with simple mobs) 'drawtype' "front" or "side" (DEPRECATED, replaced with below) 'rotate' set mob rotation, 0=front, 90=side, 180=back, 270=other side 'water_damage' the damage per second if the mob is in water 'lava_damage' the damage per second if the mob is in lava 'light_damage' the damage per second if the mob is in light + 'suffocation' health value mob loses when inside a solid node 'fall_damage' will mob be hurt when falling from height - 'fall_speed' speed mob falls (default: -10 and has to be lower than -2) + 'fall_speed' maximum falling velocity of mob (default is -10 and must be below -2) 'fear_height' when mob walks near a drop then anything over this value makes it stop and turn back (default is 0 to disable) 'on_die' a function that is called when the mob is killed the parameters are (self, pos) 'floats' 1 to float in water, 0 to sink @@ -85,11 +86,11 @@ This functions registers a new mob as a Minetest entity. 'dogshoot_switch' allows switching between shoot and dogfight modes inside dogshoot using timer (1 = shoot, 2 = dogfight) 'dogshoot_count_max' number of seconds before switching to dogfight mode. 'dogshoot_count2_max' number of seconds before switching back to shoot mode. - 'custom_attack' is a function that is called when mob is in range to attack player, parameters are (self, to_attack) + 'custom_attack' when set this function is called instead of the normal mob melee attack, parameters are (self, to_attack) 'double_melee_attack' if false then api will choose randomly between 'punch' and 'punch2' attack animations - 'on_blast' is called when TNT explodes near mob, function uses (object, damage) and returns (do_damage, do_knockback, drops) + 'on_blast' is called when an explosion happens near mob when using TNT functions, parameters are (object, damage) and returns (do_damage, do_knockback, drops) 'explosion_radius' radius of explosion attack (defaults to 1) - 'arrow' if the attack_type is "shoot" or "dogshoot" then the entity name of the arrow is required + 'arrow' if the attack_type is "shoot" or "dogshoot" then the entity name of a pre-defined arrow is required, see below for arrow definition. 'shoot_interval' the minimum shoot interval 'shoot_offset' +/- value to position arrow/fireball when fired 'reach' how far a reach this mob has, default is 3 @@ -104,12 +105,21 @@ This functions registers a new mob as a Minetest entity. 'explode' sound when exploding 'distance' maximum distance sounds are heard from (default is 10) -Mobs can look for specific nodes as they walk and replace them to mimic eating +Mobs can look for specific nodes as they walk and replace them to mimic eating. 'replace_what' group if items to replace e.g. {"farming:wheat_8", "farming:carrot_8"} 'replace_with' replace with what e.g. "air" or in chickens case "mobs:egg" 'replace_rate' how random should the replace rate be (typically 10) 'replace_offset' +/- value to check specific node to replace + 'on_replace(self, pos, oldnode, newnode)' gets called when mob is about to replace a node + self: ObjectRef of mob + pos: Position of node to replace + oldnode: Current node + newnode: What the node will become after replacing + + If false is returned, the mob will not replace the node. + + By default, replacing sets self.gotten to true and resets the object properties. The 'replace_what' has been updated to use tables for what, with and y_offset e.g. @@ -126,13 +136,20 @@ can be added to the mob definition under pre-defined mob animation names like: 'punch_start', 'punch_end', 'punch_speed' when mob attacks 'punch2_start', 'punch2_end', 'punch2_speed' when mob attacks (alternative) 'die_start', 'die_end', 'die_speed' when mob dies + '*_loop' bool value to determine if any set animation loops e.g (die_loop = false) + defaults to true if not set also 'speed_normal' for compatibility with older mobs for animation speed (deprecated) The mob api also has some preset variables and functions that it will remember for each mob + 'self.health' contains current health of mob (cannot exceed self.hp_max) + 'self.texture_list' contains list of all mob textures + 'self.child_texture' contains mob child texture when growing up + 'self.base_texture' contains current skin texture which was randomly selected from textures list 'self.gotten' this is used for obtaining milk from cow and wool from sheep 'self.horny' when animal fed enough it is set to true and animal can breed with same animal + 'self.hornytimer' background timer that controls breeding functions and mob childhood timings 'self.child' used for when breeding animals have child, will use child_texture and be half size 'self.owner' string used to set owner of npc mobs, typically used for dogs 'self.order' set to "follow" or "stand" so that npc will follow owner or stand it's ground @@ -201,7 +218,7 @@ This function registers a arrow for mobs with the attack type shoot. 'on_step' is a custom function when arrow is active, nil for default. -mobs:register_egg(name, description, background, addegg) +mobs:register_egg(name, description, background, addegg, no_creative) This function registers a spawn egg which can be used by admin to properly spawn in a mob. @@ -236,7 +253,7 @@ This function is generally called inside the on_rightclick section of the mob ap 'replacewith' once captured replace mob with this item instead (overrides new mob eggs with saved information) -mobs:feed_tame(self, clicker, feed_count, breed) +mobs:feed_tame(self, clicker, feed_count, breed, tame) This function allows the mob to be fed the item inside self.follow be it apple, wheat or whatever a set number of times and be tamed or bred as a result. Will return true when mob is fed with item it likes. @@ -255,17 +272,6 @@ This function can be used to right-click any tamed mob with mobs:protector item, 'clicker' player information -Useful Internal Variables - - 'self.health' contains current health of mob - 'self.texture_list' contains list of all mob textures - 'self.child_texture' contains mob child texture when growing up - 'self.base_texture' contains current skin texture which was randomly selected from textures list - 'self.gotten' true when sheep have been sheared or cows have been milked, a toggle switch which can be used for many functions - 'self.child' true when mob is currently a child (when two mobs have bred and current mob is the outcome) - 'self.hornytimer' background timer that controls breeding functions and mob childhood timings - - Mobs can now be ridden by players and the following shows the functions and usage: @@ -305,8 +311,10 @@ This function allows an attached player to fly the mob around using directional 'speed' speed of flight 'can_shoot' true if mob can fire arrow (sneak and left mouse button fires) 'arrow_entity' name of arrow entity used for firing - 'move_animation' string containing movement animation e.g. "walk" - 'stand_animation' string containing movement animation e.g. "stand" + 'move_animation' string containing name of pre-defined animation e.g. "walk" or "fly" etc. + 'stand_animation' string containing name of pre-defined animation e.g. "stand" or "blink" etc. + + Note: animation names above are from the pre-defined animation lists inside mob registry without extensions. mobs:set_animation(self, name) @@ -319,7 +327,7 @@ This function sets the current animation for mob, defaulting to "stand" if not f Certain variables need to be set before using the above functions: - 'self.v2' toggle switch + 'self.v2' toggle switch used to define below values for the first time 'self.max_speed_forward' max speed mob can move forward 'self.max_speed_reverse' max speed mob can move backwards 'self.accel' acceleration speed diff --git a/mods/mobiles/engine/mobs_redo/crafts.lua b/mods/mobiles/engine/mobs_redo/crafts.lua index be416878..263829e1 100644 --- a/mods/mobiles/engine/mobs_redo/crafts.lua +++ b/mods/mobiles/engine/mobs_redo/crafts.lua @@ -3,15 +3,17 @@ local S = mobs.intllib -- name tag minetest.register_craftitem("mobs:nametag", { - description = S("Nametag"), + description = S("Name Tag"), inventory_image = "mobs_nametag.png", }) -core.register_craft({ - type = "shapeless", - output = "mobs:nametag", - recipe = {"default:paper", "dye:black", "farming:string"}, -}) +if minetest.get_modpath("dye") and minetest.get_modpath("farming") then + minetest.register_craft({ + type = "shapeless", + output = "mobs:nametag", + recipe = {"default:paper", "dye:black", "farming:string"}, + }) +end -- leather minetest.register_craftitem("mobs:leather", { @@ -40,22 +42,26 @@ minetest.register_craft({ cooktime = 5, }) --- magic lasso -minetest.register_tool("mobs:magic_lasso", { - description = S("Magic Lasso (right-click animal to put in inventory)"), +-- lasso +minetest.register_tool("mobs:lasso", { + description = S("Lasso (right-click animal to put in inventory)"), inventory_image = "mobs_magic_lasso.png", }) minetest.register_alias("mobs:lasso", "mobs:magic_lasso") minetest.register_alias("lasso", "mobs:magic_lasso") -minetest.register_craft({ - output = "mobs:magic_lasso", - recipe = { - {"farming:string", "default:gold_lump", "farming:string"}, - {"default:gold_lump", "default:diamondblock", "default:gold_lump"}, - {"farming:string", "default:gold_lump", "farming:string"}, - } -}) +if minetest.get_modpath("farming") then + minetest.register_craft({ + output = "mobs:lasso", + recipe = { + {"farming:string", "", "farming:string"}, + {"", "default:diamond", ""}, + {"farming:string", "", "farming:string"}, + } + }) +end + +minetest.register_alias("mobs:magic_lasso", "mobs:lasso") -- net minetest.register_tool("mobs:net", { @@ -63,14 +69,16 @@ minetest.register_tool("mobs:net", { inventory_image = "mobs_net.png", }) -minetest.register_craft({ - output = "mobs:net", - recipe = { - {"default:stick", "", "default:stick"}, - {"default:stick", "", "default:stick"}, - {"farming:string", "default:stick", "farming:string"}, - } -}) +if minetest.get_modpath("farming") then + minetest.register_craft({ + output = "mobs:net", + recipe = { + {"group:stick", "", "group:stick"}, + {"group:stick", "", "group:stick"}, + {"farming:string", "group:stick", "farming:string"}, + } + }) +end -- shears (right click to shear animal) minetest.register_tool("mobs:shears", { @@ -103,7 +111,7 @@ minetest.register_craft({ -- saddle minetest.register_craftitem("mobs:saddle", { - description = "Saddle", + description = S("Saddle"), inventory_image = "mobs_saddle.png" }) diff --git a/mods/mobiles/engine/mobs_redo/depends.txt b/mods/mobiles/engine/mobs_redo/depends.txt index 5eb2f179..258743b0 100644 --- a/mods/mobiles/engine/mobs_redo/depends.txt +++ b/mods/mobiles/engine/mobs_redo/depends.txt @@ -1,4 +1,8 @@ default +tnt? +dye? +farming? invisibility? intllib? lucky_block? +cmi? \ No newline at end of file diff --git a/mods/mobiles/engine/mobs_redo/init.lua b/mods/mobiles/engine/mobs_redo/init.lua index 8a625b62..f63fb164 100644 --- a/mods/mobiles/engine/mobs_redo/init.lua +++ b/mods/mobiles/engine/mobs_redo/init.lua @@ -16,4 +16,4 @@ dofile(path .. "/spawner.lua") -- Lucky Blocks dofile(path .. "/lucky_block.lua") -print ("[MOD] Mobs Redo loaded") +minetest.log("action", "[MOD] Mobs Redo loaded") diff --git a/mods/mobiles/engine/mobs_redo/intllib.lua b/mods/mobiles/engine/mobs_redo/intllib.lua new file mode 100644 index 00000000..70c5f3cc --- /dev/null +++ b/mods/mobiles/engine/mobs_redo/intllib.lua @@ -0,0 +1,45 @@ + +-- Fallback functions for when `intllib` is not installed. +-- Code released under Unlicense . + +-- Get the latest version of this file at: +-- https://raw.githubusercontent.com/minetest-mods/intllib/master/lib/intllib.lua + +local function format(str, ...) + local args = { ... } + local function repl(escape, open, num, close) + if escape == "" then + local replacement = tostring(args[tonumber(num)]) + if open == "" then + replacement = replacement..close + end + return replacement + else + return "@"..open..num..close + end + end + return (str:gsub("(@?)@(%(?)(%d+)(%)?)", repl)) +end + +local gettext, ngettext +if minetest.global_exists("intllib") then + if intllib.make_gettext_pair then + -- New method using gettext. + gettext, ngettext = intllib.make_gettext_pair() + else + -- Old method using text files. + gettext = intllib.Getter() + end +end + +-- Fill in missing functions. + +gettext = gettext or function(msgid, ...) + return format(msgid, ...) +end + +ngettext = ngettext or function(msgid, msgid_plural, n, ...) + return format(n==1 and msgid or msgid_plural, ...) +end + +return gettext, ngettext diff --git a/mods/mobiles/engine/mobs_redo/locale/de_DE.po b/mods/mobiles/engine/mobs_redo/locale/de_DE.po new file mode 100644 index 00000000..d627dfde --- /dev/null +++ b/mods/mobiles/engine/mobs_redo/locale/de_DE.po @@ -0,0 +1,127 @@ +# Mobs Redo translation. +# Copyright (C) 2017 TenPlus1 +# This file is distributed under the same license as the mobs package. +# Wuzzy , 2017 +# +msgid "" +msgstr "" +"Project-Id-Version: mobs\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2017-07-02 16:48+0200\n" +"PO-Revision-Date: 2017-07-02 14:27+0200\n" +"Last-Translator: Wuzzy \n" +"Language-Team: \n" +"Language: de_DE\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 2.0.2\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: api.lua +msgid "Mob has been protected!" +msgstr "Kreatur wurde geschützt!" + +#: api.lua +msgid "@1 (Tamed)" +msgstr "@1 (Gezähmt)" + +#: api.lua +msgid "Not tamed!" +msgstr "Nicht gezähmt!" + +#: api.lua +msgid "@1 is owner!" +msgstr "@1 ist der Besitzer!" + +#: api.lua +msgid "Missed!" +msgstr "Daneben!" + +#: api.lua +msgid "Already protected!" +msgstr "Bereits geschützt!" + +#: api.lua +msgid "Protected!" +msgstr "Geschützt!" + +#: api.lua +msgid "@1 at full health (@2)" +msgstr "@1 bei voller Gesundheit (@2)" + +#: api.lua +msgid "@1 has been tamed!" +msgstr "@1 wurde gezähmt!" + +#: api.lua +msgid "Enter name:" +msgstr "Namen eingeben:" + +#: api.lua +msgid "Rename" +msgstr "Umbenennen" + +#: crafts.lua +msgid "Name Tag" +msgstr "Namensschild" + +#: crafts.lua +msgid "Leather" +msgstr "Leder" + +#: crafts.lua +msgid "Raw Meat" +msgstr "Rohes Fleisch" + +#: crafts.lua +msgid "Meat" +msgstr "Fleisch" + +#: crafts.lua +msgid "Lasso (right-click animal to put in inventory)" +msgstr "Lasso (Rechtsklick auf Tier, um es zu nehmen)" + +#: crafts.lua +msgid "Net (right-click animal to put in inventory)" +msgstr "Netz (Rechtsklick auf Tier, um es zu nehmen)" + +#: crafts.lua +msgid "Steel Shears (right-click to shear)" +msgstr "Stahlschere (Rechtsklick zum Scheren)" + +#: crafts.lua +msgid "Mob Protection Rune" +msgstr "Kreaturschutzrune" + +#: crafts.lua +msgid "Saddle" +msgstr "Sattel" + +#: spawner.lua +msgid "Mob Spawner" +msgstr "Kreaturenspawner" + +#: spawner.lua +msgid "Mob MinLight MaxLight Amount PlayerDist" +msgstr "Kreatur MinLicht MaxLicht Menge SpielerEntfng" + +#: spawner.lua +msgid "Spawner Not Active (enter settings)" +msgstr "Nicht aktiv (Einstellungen eingeben)" + +#: spawner.lua +msgid "Spawner Active (@1)" +msgstr "Spawner aktiv (@1)" + +#: spawner.lua +msgid "Mob Spawner settings failed!" +msgstr "Kreaturenspawner-Einstellungen gescheitert!" + +#: spawner.lua +msgid "" +"Syntax: “name min_light[0-14] max_light[0-14] max_mobs_in_area[0 to disable] " +"distance[1-20] y_offset[-10 to 10]”" +msgstr "" +"Syntax: „name min_licht[0-14] max_licht[0-14] max_mobs_im_gebiet[0 zum " +"Deaktivieren] distanz[1-20] y_versatz[-10 bis 10]“" \ No newline at end of file diff --git a/mods/mobiles/engine/mobs_redo/locale/pt.po b/mods/mobiles/engine/mobs_redo/locale/pt.po new file mode 100644 index 00000000..05c3ae3d --- /dev/null +++ b/mods/mobiles/engine/mobs_redo/locale/pt.po @@ -0,0 +1,129 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: mobs\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2017-07-02 16:48+0200\n" +"PO-Revision-Date: 2017-07-02 14:55+0200\n" +"Last-Translator: Wuzzy \n" +"Language-Team: \n" +"Language: pt\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 2.0.2\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: api.lua +msgid "Mob has been protected!" +msgstr "" + +#: api.lua +msgid "@1 (Tamed)" +msgstr "" + +#: api.lua +msgid "Not tamed!" +msgstr "Indomesticado!" + +#: api.lua +msgid "@1 is owner!" +msgstr "Dono @1!" + +#: api.lua +msgid "Missed!" +msgstr "Faltou!" + +#: api.lua +msgid "Already protected!" +msgstr "" + +#: api.lua +msgid "Protected!" +msgstr "" + +#: api.lua +msgid "@1 at full health (@2)" +msgstr "@1 em plena saude (@2)" + +#: api.lua +msgid "@1 has been tamed!" +msgstr "@1 foi domesticado!" + +#: api.lua +msgid "Enter name:" +msgstr "Insira um nome:" + +#: api.lua +msgid "Rename" +msgstr "Renomear" + +#: crafts.lua +msgid "Name Tag" +msgstr "Etiqueta" + +#: crafts.lua +msgid "Leather" +msgstr "Couro" + +#: crafts.lua +msgid "Raw Meat" +msgstr "Carne crua" + +#: crafts.lua +msgid "Meat" +msgstr "Carne" + +#: crafts.lua +#, fuzzy +msgid "Lasso (right-click animal to put in inventory)" +msgstr "Laço (clique-direito no animal para por no inventario)" + +#: crafts.lua +msgid "Net (right-click animal to put in inventory)" +msgstr "Net (clique-direito no animal para por no inventario)" + +#: crafts.lua +msgid "Steel Shears (right-click to shear)" +msgstr "Tesoura de Aço (clique-direito para tosquiar)" + +#: crafts.lua +msgid "Mob Protection Rune" +msgstr "" + +#: crafts.lua +msgid "Saddle" +msgstr "" + +#: spawner.lua +msgid "Mob Spawner" +msgstr "Spawnador de Mob" + +#: spawner.lua +msgid "Mob MinLight MaxLight Amount PlayerDist" +msgstr "Mob LuzMinima LuzMaxima Valor DistJogador" + +#: spawner.lua +msgid "Spawner Not Active (enter settings)" +msgstr "Spawnador Inativo (configurar)" + +#: spawner.lua +msgid "Spawner Active (@1)" +msgstr "Spawnador Ativo (@1)" + +#: spawner.lua +msgid "Mob Spawner settings failed!" +msgstr "Configuraçao de Spawnador do Mob falhou!" + +#: spawner.lua +#, fuzzy +msgid "" +"Syntax: “name min_light[0-14] max_light[0-14] max_mobs_in_area[0 to disable] " +"distance[1-20] y_offset[-10 to 10]”" +msgstr "" +"> nome luz_min[0-14] luz_max[0-14] max_mobs_na_area[0 para desabilitar] " +"distancia[1-20] y_offset[-10 a 10]" \ No newline at end of file diff --git a/mods/mobiles/engine/mobs_redo/locale/template.pot b/mods/mobiles/engine/mobs_redo/locale/template.pot new file mode 100644 index 00000000..90e52416 --- /dev/null +++ b/mods/mobiles/engine/mobs_redo/locale/template.pot @@ -0,0 +1,124 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2017-07-02 16:48+0200\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: api.lua +msgid "Mob has been protected!" +msgstr "" + +#: api.lua +msgid "@1 (Tamed)" +msgstr "" + +#: api.lua +msgid "Not tamed!" +msgstr "" + +#: api.lua +msgid "@1 is owner!" +msgstr "" + +#: api.lua +msgid "Missed!" +msgstr "" + +#: api.lua +msgid "Already protected!" +msgstr "" + +#: api.lua +msgid "Protected!" +msgstr "" + +#: api.lua +msgid "@1 at full health (@2)" +msgstr "" + +#: api.lua +msgid "@1 has been tamed!" +msgstr "" + +#: api.lua +msgid "Enter name:" +msgstr "" + +#: api.lua +msgid "Rename" +msgstr "" + +#: crafts.lua +msgid "Name Tag" +msgstr "" + +#: crafts.lua +msgid "Leather" +msgstr "" + +#: crafts.lua +msgid "Raw Meat" +msgstr "" + +#: crafts.lua +msgid "Meat" +msgstr "" + +#: crafts.lua +msgid "Lasso (right-click animal to put in inventory)" +msgstr "" + +#: crafts.lua +msgid "Net (right-click animal to put in inventory)" +msgstr "" + +#: crafts.lua +msgid "Steel Shears (right-click to shear)" +msgstr "" + +#: crafts.lua +msgid "Mob Protection Rune" +msgstr "" + +#: crafts.lua +msgid "Saddle" +msgstr "" + +#: spawner.lua +msgid "Mob Spawner" +msgstr "" + +#: spawner.lua +msgid "Mob MinLight MaxLight Amount PlayerDist" +msgstr "" + +#: spawner.lua +msgid "Spawner Not Active (enter settings)" +msgstr "" + +#: spawner.lua +msgid "Spawner Active (@1)" +msgstr "" + +#: spawner.lua +msgid "Mob Spawner settings failed!" +msgstr "" + +#: spawner.lua +msgid "" +"Syntax: “name min_light[0-14] max_light[0-14] max_mobs_in_area[0 to disable] " +"distance[1-20] y_offset[-10 to 10]”" +msgstr "" \ No newline at end of file diff --git a/mods/mobiles/engine/mobs_redo/locale/tr.po b/mods/mobiles/engine/mobs_redo/locale/tr.po new file mode 100644 index 00000000..b9c06d58 --- /dev/null +++ b/mods/mobiles/engine/mobs_redo/locale/tr.po @@ -0,0 +1,129 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: mobs\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2017-07-02 16:48+0200\n" +"PO-Revision-Date: 2017-07-02 14:56+0200\n" +"Last-Translator: Wuzzy \n" +"Language-Team: \n" +"Language: tr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 2.0.2\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: api.lua +msgid "Mob has been protected!" +msgstr "" + +#: api.lua +msgid "@1 (Tamed)" +msgstr "" + +#: api.lua +msgid "Not tamed!" +msgstr "Evcil değil!" + +#: api.lua +msgid "@1 is owner!" +msgstr "Sahibi @1!" + +#: api.lua +msgid "Missed!" +msgstr "Kaçırdın!" + +#: api.lua +msgid "Already protected!" +msgstr "" + +#: api.lua +msgid "Protected!" +msgstr "" + +#: api.lua +msgid "@1 at full health (@2)" +msgstr "@1 tam canında (@2)" + +#: api.lua +msgid "@1 has been tamed!" +msgstr "@1 tamamen evcilleştirilmiştir!" + +#: api.lua +msgid "Enter name:" +msgstr "İsim gir:" + +#: api.lua +msgid "Rename" +msgstr "Yeniden adlandır" + +#: crafts.lua +msgid "Name Tag" +msgstr "İsim etiketi" + +#: crafts.lua +msgid "Leather" +msgstr "Deri" + +#: crafts.lua +msgid "Raw Meat" +msgstr "Çiğ et" + +#: crafts.lua +msgid "Meat" +msgstr "Et" + +#: crafts.lua +#, fuzzy +msgid "Lasso (right-click animal to put in inventory)" +msgstr "Kement (hayvana sağ tıklayarak envantere koy)" + +#: crafts.lua +msgid "Net (right-click animal to put in inventory)" +msgstr "Ağ (hayvana sağ tıklayarak envantere koy)" + +#: crafts.lua +msgid "Steel Shears (right-click to shear)" +msgstr "Çelik makas (sağ tıklayarak kes)" + +#: crafts.lua +msgid "Mob Protection Rune" +msgstr "" + +#: crafts.lua +msgid "Saddle" +msgstr "" + +#: spawner.lua +msgid "Mob Spawner" +msgstr "Canavar Yaratıcı" + +#: spawner.lua +msgid "Mob MinLight MaxLight Amount PlayerDist" +msgstr "Mob MinIşık MaxIşık Miktar OyuncuMesafesi" + +#: spawner.lua +msgid "Spawner Not Active (enter settings)" +msgstr "Yaratıcı aktif değil (ayarlara gir)" + +#: spawner.lua +msgid "Spawner Active (@1)" +msgstr "Yaratıcı aktif (@1)" + +#: spawner.lua +msgid "Mob Spawner settings failed!" +msgstr "Yaratıcı ayarları uygulanamadı." + +#: spawner.lua +#, fuzzy +msgid "" +"Syntax: “name min_light[0-14] max_light[0-14] max_mobs_in_area[0 to disable] " +"distance[1-20] y_offset[-10 to 10]”" +msgstr "" +"> isim min_isik[0-14] max_isik[0-14] alandaki_max_canavar_sayisi[kapatmak " +"icin 0] mesafe[1-20] y_cikinti[-10 ve 10 arası]" \ No newline at end of file diff --git a/mods/mobiles/engine/mobs_redo/mount.lua b/mods/mobiles/engine/mobs_redo/mount.lua index b26f8ac4..d574293b 100644 --- a/mods/mobiles/engine/mobs_redo/mount.lua +++ b/mods/mobiles/engine/mobs_redo/mount.lua @@ -1,7 +1,7 @@ -- lib_mount by Blert2112 (edited by TenPlus1) -local enable_crash = true +local enable_crash = false local crash_threshold = 6.5 -- ignored if enable_crash=false ------------------------------------------------------------------------------ @@ -10,9 +10,23 @@ local crash_threshold = 6.5 -- ignored if enable_crash=false -- Helper functions -- +local node_ok = function(pos, fallback) + + fallback = fallback or mobs.fallback_node + + local node = minetest.get_node_or_nil(pos) + + if node and minetest.registered_nodes[node.name] then + return node + end + + return {name = fallback} +end + + local function node_is(pos) - local node = minetest.get_node(pos) + local node = node_ok(pos) if node.name == "air" then return "air" @@ -26,7 +40,7 @@ local function node_is(pos) return "liquid" end - if minetest.get_item_group(node.name, "walkable") ~= 0 then + if minetest.registered_nodes[node.name].walkable == true then return "walkable" end diff --git a/mods/mobiles/engine/mobs_redo/readme.MD b/mods/mobiles/engine/mobs_redo/readme.MD index 45c83e28..ae879e56 100644 --- a/mods/mobiles/engine/mobs_redo/readme.MD +++ b/mods/mobiles/engine/mobs_redo/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) diff --git a/mods/mobiles/engine/mobs_redo/sounds/license.txt b/mods/mobiles/engine/mobs_redo/sounds/license.txt new file mode 100644 index 00000000..e055c477 --- /dev/null +++ b/mods/mobiles/engine/mobs_redo/sounds/license.txt @@ -0,0 +1,4 @@ +Creative Commons sounds from Freesound.org + +mobs_swing.ogg by qubodup +mobs_spell.ogg by littletobotsoundfactory diff --git a/mods/mobiles/engine/mobs_redo/sounds/mobs_spell.ogg b/mods/mobiles/engine/mobs_redo/sounds/mobs_spell.ogg new file mode 100644 index 00000000..455b54f5 Binary files /dev/null and b/mods/mobiles/engine/mobs_redo/sounds/mobs_spell.ogg differ diff --git a/mods/mobiles/engine/mobs_redo/sounds/mobs_swing.ogg b/mods/mobiles/engine/mobs_redo/sounds/mobs_swing.ogg new file mode 100644 index 00000000..ffe6a9ce Binary files /dev/null and b/mods/mobiles/engine/mobs_redo/sounds/mobs_swing.ogg differ diff --git a/mods/mobiles/engine/mobs_redo/spawner.lua b/mods/mobiles/engine/mobs_redo/spawner.lua index a54663df..0c198842 100644 --- a/mods/mobiles/engine/mobs_redo/spawner.lua +++ b/mods/mobiles/engine/mobs_redo/spawner.lua @@ -1,5 +1,7 @@ -local S = mobs.intllib +-- intllib +local MP = minetest.get_modpath(minetest.get_current_modname()) +local S, NS = dofile(MP .. "/intllib.lua") -- mob spawner @@ -66,7 +68,7 @@ minetest.register_node("mobs:spawner", { else minetest.chat_send_player(name, S("Mob Spawner settings failed!")) minetest.chat_send_player(name, - S("> name min_light[0-14] max_light[0-14] max_mobs_in_area[0 to disable] distance[1-20] y_offset[-10 to 10]")) + S("Syntax: “name min_light[0-14] max_light[0-14] max_mobs_in_area[0 to disable] distance[1-20] y_offset[-10 to 10]”")) end end, }) diff --git a/mods/mobiles/engine/mobs_redo/textures/mobs_noentry_particle.png b/mods/mobiles/engine/mobs_redo/textures/mobs_noentry_particle.png new file mode 100644 index 00000000..87938ff4 Binary files /dev/null and b/mods/mobiles/engine/mobs_redo/textures/mobs_noentry_particle.png differ diff --git a/mods/mobiles/engine/mobs_redo/textures/mobs_protect_particle.png b/mods/mobiles/engine/mobs_redo/textures/mobs_protect_particle.png new file mode 100644 index 00000000..debe20cb Binary files /dev/null and b/mods/mobiles/engine/mobs_redo/textures/mobs_protect_particle.png differ