diff --git a/mods/ENTITIES/mobs/api.lua b/mods/ENTITIES/mobs/api.lua index 620ed1a90..2fe40fbbe 100644 --- a/mods/ENTITIES/mobs/api.lua +++ b/mods/ENTITIES/mobs/api.lua @@ -1,27 +1,20 @@ --- Mobs Api (12th May 2017) +-- Mobs Api (4th July 2017) mobs = {} mobs.mod = "redo" +mobs.version = "20170704" -- 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 @@ -73,7 +66,7 @@ local stuck_path_timeout = 10 -- how long will mob follow path before giving up -- play sound -mob_sound = function(self, sound) +local mob_sound = function(self, sound) if sound then minetest.sound_play(sound, { @@ -86,7 +79,7 @@ end -- attack player/mob -do_attack = function(self, player) +local do_attack = function(self, player) if self.state == "attack" then return @@ -102,7 +95,7 @@ end -- move mob in facing direction -set_velocity = function(self, v) +local set_velocity = function(self, v) local yaw = (self.object:getyaw() or 0) + self.rotate @@ -115,7 +108,7 @@ end -- get overall speed of mob -get_velocity = function(self) +local get_velocity = function(self) local v = self.object:getvelocity() @@ -124,7 +117,7 @@ end -- set yaw -set_yaw = function(self, yaw) +local set_yaw = function(self, yaw) if not yaw or yaw ~= yaw then yaw = 0 @@ -137,7 +130,7 @@ end -- set defined animation -set_animation = function(self, anim) +local set_animation = function(self, anim) if not self.animation then return end @@ -153,9 +146,15 @@ 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 + +-- above function exported for mount.lua +function mobs:set_animation(anim) + set_animation(self, anim) end @@ -169,7 +168,7 @@ end -- check line of sight (BrunoMine) -function line_of_sight(self, pos1, pos2, stepsize) +local line_of_sight = function(self, pos1, pos2, stepsize) stepsize = stepsize or 1 @@ -240,7 +239,7 @@ end -- are we flying in what we are suppose to? (taikedz) -local function flight_check(self, pos_w) +local flight_check = function(self, pos_w) local nod = self.standing_in @@ -265,12 +264,13 @@ end -- particle effects -function effect(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, @@ -286,12 +286,13 @@ function effect(pos, amount, texture, min_size, max_size, radius, gravity) minsize = min_size, maxsize = max_size, texture = texture, + glow = glow, }) end -- update nametag colour -function update_tag(self) +local update_tag = function(self) local col = "#00FF00" local qua = self.hp_max / 4 @@ -316,11 +317,60 @@ function update_tag(self) 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() + + self.drops = self.drops or {} -- nil check + + for n = 1, #self.drops do + + if random(1, self.drops[n].chance) == 1 then + + num = random(self.drops[n].min, self.drops[n].max) + item = self.drops[n].name + + -- cook items when true + if cooked then + + local output = minetest.get_craft_result({ + method = "cooking", width = 1, items = {item}}) + + if output and output.item and not output.item:is_empty() then + item = output.item:get_name() + end + end + + -- add item if it exists + obj = minetest.add_item(pos, ItemStack(item .. " " .. num)) + + if obj and obj:get_luaentity() then + + obj:setvelocity({ + x = random(-10, 10) / 9, + y = 6, + z = random(-10, 10) / 9, + }) + elseif obj then + obj:remove() -- item does not exist + end + end + end + + self.drops = {} +end + + -- check if mob is dead or only hurt -function check_for_death(self) +local check_for_death = function(self, cause, cmi_cause) -- has health actually changed? - if self.health == self.old_health then + if self.health == self.old_health and self.health > 0 then return end @@ -352,36 +402,25 @@ function check_for_death(self) return false end - -- drop items when dead - local obj - local pos = self.object:getpos() - self.drops = self.drops or {} -- nil check - - for n = 1, #self.drops do - - if random(1, self.drops[n].chance) == 1 then - - obj = minetest.add_item(pos, - ItemStack(self.drops[n].name .. " " - .. random(self.drops[n].min, self.drops[n].max))) - - if obj then - - obj:setvelocity({ - x = random(-10, 10) / 9, - y = 6, - z = random(-10, 10) / 9, - }) - end - end + if cause == "lava" then + item_drop(self, true) + else + item_drop(self, nil) end mob_sound(self, self.sounds.death) + local pos = self.object:getpos() + -- execute custom death function 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 @@ -402,9 +441,19 @@ function check_for_death(self) 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 @@ -415,7 +464,7 @@ end -- check if within physical map limits (-30911 to 30927) -function within_limits(pos, radius) +local within_limits = function(pos, radius) if (pos.x - radius) > -30913 and (pos.x + radius) < 30928 @@ -431,7 +480,7 @@ end -- is mob facing a cliff -local function is_at_cliff(self) +local is_at_cliff = function(self) if self.fear_height == 0 then -- 0 for no falling protection! return false @@ -456,26 +505,22 @@ end -- get node but use fallback for nil or unknown -local function node_ok(pos, fallback) +local node_ok = function(pos, fallback) fallback = fallback or "mcl_core:dirt" 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) -do_env_damage = function(self) +-- environmental damage (water, lava, fire, light etc.) +local do_env_damage = function(self) -- feed/tame text timer (so mob 'full' messages dont spam chat) if self.htimer > 0 then @@ -511,12 +556,20 @@ do_env_damage = function(self) self.health = self.health - self.light_damage effect(pos, 5, "tnt_smoke.png") + + 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) +-- print ("standing in " .. self.standing_in) -- don't fall when on ignore, just stand still if self.standing_in == "ignore" then @@ -524,48 +577,69 @@ 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 self.water_damage ~= 0 - and nodef.groups.water then + if self.water_damage ~= 0 then self.health = self.health - self.water_damage effect(pos, 5, "bubble.png", nil, nil, 1, nil) - -- lava or fire - elseif self.lava_damage ~= 0 - and (nodef.groups.lava - or self.standing_in == "mcl_fire:fire" - or self.standing_in == "mcl_fire:eternal_fire") then + 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 == "mcl_fire:fire" + or self.standing_in == "mcl_fire:eternal_fire") 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) - -- 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, "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 -- jump if facing a solid node (not fences or gates) -do_jump = function(self) +local do_jump = function(self) if not self.jump or self.jump_height == 0 @@ -636,7 +710,7 @@ end -- blast damage to entities nearby (modified from TNT mod) -function entity_physics(pos, radius) +local entity_physics = function(pos, radius) radius = radius * 2 @@ -657,13 +731,13 @@ function entity_physics(pos, radius) objs[n]:punch(objs[n], 1.0, { full_punch_interval = 1.0, damage_groups = {fleshy = damage}, - }, nil) + }, pos) -- was nil end end -- should mob follow what I'm holding ? -function follow_holding(self, clicker) +local follow_holding = function(self, clicker) if mobs.invis[clicker:get_player_name()] then return false @@ -693,7 +767,7 @@ end -- find two animals of same type and breed if nearby and horny -local function breed(self) +local breed = function(self) -- child takes 240 seconds before growing into adult if self.child == true then @@ -828,7 +902,7 @@ end -- find and replace what mob is looking for (grass, wheat etc.) -function replace(self, pos) +local replace = function(self, pos) if not self.replace_rate or not self.replace_what @@ -859,19 +933,30 @@ function replace(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 -- check if daytime and also if mob is docile during daylight hours -function day_docile(self) +local day_docile = function(self) if self.docile_by_day == false then @@ -887,7 +972,7 @@ end -- path finding and smart mob routine by rnd -function smart_mobs(self, s, p, dist, dtime) +local smart_mobs = function(self, s, p, dist, dtime) local s1 = self.path.lastpos @@ -930,17 +1015,11 @@ function smart_mobs(self, s, p, dist, dtime) p1.y = floor(p1.y + 0.5) p1.z = floor(p1.z + 0.5) - local drop_height = self.fear_height - if not drop_height then - drop_height = 4 - end - local jump_height - if self.jump_height then - jump_height = math.max(1, self.jump_height/3) - else - jump_height = 1 - end - self.path.way = minetest.find_path(s, p1, self.view_range + 1, jump_height, drop_height, "A*_noprefetch") + local dropheight = 10 + if self.fear_height ~= 0 then dropheight = self.fear_height end + +-- self.path.way = minetest.find_path(s, p1, 16, 2, 6, "Dijkstra") -- "A*_noprefetch" + self.path.way = minetest.find_path(s, p1, 16, self.stepheight, dropheight, "A*_noprefetch") -- attempt to unstick mob that is "daydreaming" self.object:setpos({ @@ -1068,7 +1147,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 @@ -1085,6 +1164,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 @@ -1174,7 +1254,7 @@ local npc_attack = function(self) if obj and obj.type == "monster" then - p = obj.object:getpos() + local p = obj.object:getpos() dist = get_distance(p, s) @@ -1391,7 +1471,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() @@ -1470,7 +1550,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 @@ -1845,6 +1926,8 @@ local do_states = function(self, dtime) vec.z = vec.z * (v / amount) obj:setvelocity(vec) + else + obj:remove() -- arrow entity does not exist end end end @@ -1862,18 +1945,31 @@ 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 - if minetest.registered_nodes[node_ok(pos).name].groups.liquid then +-- if minetest.registered_nodes[node_ok(pos).name].groups.liquid then + if minetest.registered_nodes[node_ok(pos).name].groups.water then if self.floats == 1 then @@ -1884,14 +1980,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 @@ -1903,7 +1993,7 @@ local falling = function(self, pos) effect(pos, 5, "tnt_smoke.png", 1, 2, 2, nil) - if check_for_death(self) then + if check_for_death(self, "fall", {type = "fall"}) then return end end @@ -1924,14 +2014,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 @@ -1950,18 +2040,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 @@ -1982,6 +2077,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 @@ -2027,9 +2129,17 @@ local mob_punch = function(self, hitter, tflp, tool_capabilities, dir) -- do damage self.health = self.health - floor(damage) - -- exit here if dead - if check_for_death(self) then - return + -- exit here if dead, special item check + if weapon:get_name() == "mobs:pick_lava" then + if check_for_death(self, "lava", {type = "punch", + puncher = hitter}) then + return + end + else + if check_for_death(self, "hit", {type = "punch", + puncher = hitter}) then + return + end end --[[ add healthy afterglow when hit (can cause hit lag with larger textures) @@ -2074,14 +2184,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 @@ -2161,6 +2270,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 @@ -2169,7 +2282,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 @@ -2180,7 +2294,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 @@ -2280,12 +2394,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 @@ -2446,10 +2569,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 {}, @@ -2475,6 +2599,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, @@ -2505,6 +2630,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, @@ -2512,8 +2638,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) @@ -2570,12 +2696,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 @@ -2686,8 +2812,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 @@ -2728,8 +2854,6 @@ end 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_brick = minetest.get_content_id("mcl_core:obsidian") -local c_chest = minetest.get_content_id("mcl_core:chest") local c_fire = minetest.get_content_id("mcl_fire:fire") -- explosion (cannot break protected or unbreakable nodes) @@ -2778,8 +2902,6 @@ function mobs:explosion(pos, radius, fire, smoke, sound) 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 @@ -2842,6 +2964,8 @@ function mobs:register_arrow(name, def) automatic_face_movement_dir = def.rotate and (def.rotate - (pi / 180)) or false, + on_activate = def.on_activate or nil, + on_step = def.on_step or function(self, dtime) self.timer = self.timer + 1 @@ -2936,14 +3060,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 @@ -2985,7 +3113,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 @@ -3027,7 +3156,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 @@ -3035,6 +3164,8 @@ function mobs:capture_mob(self, clicker, chance_hand, chance_net, chance_lasso, if self.tamed == false and force_take == false then + minetest.chat_send_player(name, S("Not tamed!")) + return true -- false end @@ -3063,7 +3194,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 @@ -3111,7 +3242,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 @@ -3130,6 +3267,7 @@ function mobs:protect(self, clicker) end if self.tamed == false then + minetest.chat_send_player(name, S("Not tamed!")) return true -- false end @@ -3138,11 +3276,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 @@ -3180,6 +3327,10 @@ function mobs:feed_tame(self, clicker, feed_count, breed, tame) if self.htimer < 1 then + minetest.chat_send_player(clicker:get_player_name(), + S("@1 at full health (@2)", + self.name:split(":")[2], tostring(self.health))) + self.htimer = 5 end end @@ -3210,6 +3361,12 @@ function mobs:feed_tame(self, clicker, feed_count, breed, tame) if tame then + if self.tamed == false then + minetest.chat_send_player(clicker:get_player_name(), + S("@1 has been tamed!", + self.name:split(":")[2])) + end + self.tamed = true if not self.owner or self.owner == "" then @@ -3241,8 +3398,8 @@ function mobs:feed_tame(self, clicker, feed_count, breed, tame) minetest.show_formspec(name, "mobs_nametag", "size[8,4]" .. mcl_vars.gui_bg .. mcl_vars.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/ENTITIES/mobs/api.txt b/mods/ENTITIES/mobs/api.txt index 43d0db72f..e8a4df067 100644 --- a/mods/ENTITIES/mobs/api.txt +++ b/mods/ENTITIES/mobs/api.txt @@ -1,5 +1,5 @@ -MOB API (12th May 2017) +MOB API (4th 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,13 +311,23 @@ 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) + +This function sets the current animation for mob, defaulting to "stand" if not found. + + 'self' mob information + 'name' name of animation 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/ENTITIES/mobs/depends.txt b/mods/ENTITIES/mobs/depends.txt index de61bea55..6b6d81582 100644 --- a/mods/ENTITIES/mobs/depends.txt +++ b/mods/ENTITIES/mobs/depends.txt @@ -4,3 +4,4 @@ mcl_sounds invisibility? intllib? lucky_block? +cmi? diff --git a/mods/ENTITIES/mobs/init.lua b/mods/ENTITIES/mobs/init.lua index 2d8d01c6d..24c981f8d 100644 --- a/mods/ENTITIES/mobs/init.lua +++ b/mods/ENTITIES/mobs/init.lua @@ -16,4 +16,4 @@ dofile(path .. "/crafts.lua") -- Lucky Blocks dofile(path .. "/lucky_block.lua") -print ("[MOD] Mobs Redo loaded") +minetest.log("action", "[MOD] Mobs Redo loaded") diff --git a/mods/ENTITIES/mobs/intllib.lua b/mods/ENTITIES/mobs/intllib.lua new file mode 100644 index 000000000..6669d7202 --- /dev/null +++ b/mods/ENTITIES/mobs/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.get_modpath("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/ENTITIES/mobs/locale/de.txt b/mods/ENTITIES/mobs/locale/de.txt deleted file mode 100644 index aa7a7a7a9..000000000 --- a/mods/ENTITIES/mobs/locale/de.txt +++ /dev/null @@ -1,38 +0,0 @@ -# German Translation for mobs_redo mod -# Deutsche Übersetzung der mobs_redo Mod -# last update: 2016/June/10 -# Author: Xanthin - -#init.lua -[MOD] Mobs Redo loaded = [MOD] Mobs Redo geladen - -#api.lua -[MOBS] mod profiling enabled, damage not enabled = [MOBS] Modanalyse aktiviert, Schaden deaktiviert -lifetimer expired, removed @1 = Lebensdauer abgelaufen, @1 wurde entfernt -[Mobs Redo] @1 has spawning disabled = [Mobs Redo] Spawnen von @1 ist deaktiviert -[Mobs Redo] Chance setting for @1 is now @2 = [Mobs Redo] Wahrscheinlichkeitswert für @1 ist jetzt @2 -[mobs] @1 failed to spawn at @2 = [mobs] @1 konnte nicht bei @2 spawnen -Not tamed! = Nicht gezähmt! -@1 is owner! = @1 ist Besitzer! -Missed! = Verfehlt! -@1 at full health (@2) = @1 bei voller Gesundheit (@2) -@1 has been tamed! = @1 ist gezähmt worden! -Enter name: = Namen eingeben: -Rename = Umbenennen - -#crafts.lua -Nametag = Namensschild -Leather = Leder -Raw Meat = Rohes Fleisch -Meat = Fleisch -Magic Lasso (right-click animal to put in inventory) = Magisches Lasso (Rechtsklick auf Tier,\num es ins Inventar zu legen) -Net (right-click animal to put in inventory) = Netz (Rechtsklick auf Tier,\num es ins Inventar zu legen) -Steel Shears (right-click to shear) = Stahlschere (Rechtsklick zum Scheren) - -#spawner.lua -Mob Spawner = Mobspawner -Mob MinLight MaxLight Amount PlayerDist = Mob MinLicht MaxLicht Menge SpielerEntfng -Spawner Not Active (enter settings) = Spawner nicht aktiv (Einstellungen eintragen) -Spawner Active (@1) = Spawner aktiv (@1) -Mob Spawner settings failed! = Mobspawnereinstellungen gescheitert! -> name min_light[0-14] max_light[0-14] max_mobs_in_area[0 to disable] distance[1-20] y_offset[-10 to 10] = Name min. Licht[0-14] max. Licht[0-14] max. Mobs in Gebiet[0 zum deaktivieren] Entfernung zum Spieler[1-20] Höhe[-10 bis 10] \ No newline at end of file diff --git a/mods/ENTITIES/mobs/locale/de_DE.po b/mods/ENTITIES/mobs/locale/de_DE.po new file mode 100644 index 000000000..d627dfde9 --- /dev/null +++ b/mods/ENTITIES/mobs/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/ENTITIES/mobs/locale/pt.po b/mods/ENTITIES/mobs/locale/pt.po new file mode 100644 index 000000000..05c3ae3d6 --- /dev/null +++ b/mods/ENTITIES/mobs/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/ENTITIES/mobs/locale/pt.txt b/mods/ENTITIES/mobs/locale/pt.txt deleted file mode 100644 index 064631fe3..000000000 --- a/mods/ENTITIES/mobs/locale/pt.txt +++ /dev/null @@ -1,38 +0,0 @@ -# Portuguese Translation for mobs_redo mod -# Tradução em Portugues do mod mobs_redo -# Ultima revisao: 30/Ago/2016 -# Autor: BrunoMine - -#init.lua -[MOD] Mobs Redo loaded = [MOD] Mobs Redo carregado - -#api.lua -[MOBS] mod profiling enabled, damage not enabled = [MOBS] Mod criador de perfis ativado, dano desabilitado -lifetimer expired, removed @1 = tempo de vida expirado, @1 removido -[Mobs Redo] @1 has spawning disabled = [Mobs Redo] @1 teve spawn desabilitado -[Mobs Redo] Chance setting for @1 is now @2 = [Mobs Redo] Chances para @1 agora vai ser @2 -[mobs] @1 failed to spawn at @2 = [mobs] @1 falhou ao spawnar em @2 -Not tamed! = Indomesticado! -@1 is owner! = Dono @1! -Missed! = Faltou! -@1 at full health (@2) = @1 em plena saude (@2) -@1 has been tamed! = @1 foi domesticado! -Enter name: = Insira um nome: -Rename = Renomear - -#crafts.lua -Nametag = Etiqueta -Leather = Couro -Raw Meat = Carne crua -Meat = Carne -Magic Lasso (right-click animal to put in inventory) = Laço Magico (clique-direito no animal para por no inventario) -Net (right-click animal to put in inventory) = Net (clique-direito no animal para por no inventario) -Steel Shears (right-click to shear) = Tesoura de Aço (clique-direito para tosquiar) - -#spawner.lua -Mob Spawner = Spawnador de Mob -Mob MinLight MaxLight Amount PlayerDist = Mob LuzMinima LuzMaxima Valor DistJogador -Spawner Not Active (enter settings) = Spawnador Inativo (configurar) -Spawner Active (@1) = Spawnador Ativo (@1) -Mob Spawner settings failed! = Configuraçao de Spawnador do Mob falhou! -> name min_light[0-14] max_light[0-14] max_mobs_in_area[0 to disable] distance[1-20] y_offset[-10 to 10] = > nome luz_min[0-14] luz_max[0-14] max_mobs_na_area[0 para desabilitar] distancia[1-20] y_offset[-10 a 10] diff --git a/mods/ENTITIES/mobs/locale/template.pot b/mods/ENTITIES/mobs/locale/template.pot new file mode 100644 index 000000000..90e524164 --- /dev/null +++ b/mods/ENTITIES/mobs/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/ENTITIES/mobs/locale/template.txt b/mods/ENTITIES/mobs/locale/template.txt deleted file mode 100644 index c263ce97d..000000000 --- a/mods/ENTITIES/mobs/locale/template.txt +++ /dev/null @@ -1,36 +0,0 @@ -# Template for translations of mobs_redo mod -# last update: 2016/June/10 - -#init.lua -[MOD] Mobs Redo loaded = - -#api.lua -[MOBS] mod profiling enabled, damage not enabled = -lifetimer expired, removed @1 = -[Mobs Redo] @1 has spawning disabled = -[Mobs Redo] Chance setting for @1 is now @2 = -[mobs] @1 failed to spawn at @2 = -Not tamed! = -@1 is owner! = -Missed! = -@1 at full health (@2) = -@1 has been tamed! = -Enter name: = -Rename = - -#crafts.lua -Nametag = -Leather = -Raw Meat = -Meat = -Magic Lasso (right-click animal to put in inventory) = -Net (right-click animal to put in inventory) = -Steel Shears (right-click to shear) = - -#spawner.lua -Mob Spawner = -Mob MinLight MaxLight Amount PlayerDist = -Spawner Not Active (enter settings) = -Spawner Active (@1) = -Mob Spawner settings failed! = -> name min_light[0-14] max_light[0-14] max_mobs_in_area[0 to disable] distance[1-20] y_offset[-10 to 10] = \ No newline at end of file diff --git a/mods/ENTITIES/mobs/locale/tr.po b/mods/ENTITIES/mobs/locale/tr.po new file mode 100644 index 000000000..b9c06d58a --- /dev/null +++ b/mods/ENTITIES/mobs/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/ENTITIES/mobs/locale/tr.txt b/mods/ENTITIES/mobs/locale/tr.txt deleted file mode 100644 index 3f2833e23..000000000 --- a/mods/ENTITIES/mobs/locale/tr.txt +++ /dev/null @@ -1,39 +0,0 @@ -# Türkçe çeviri by Admicos -# Turkish translation by Admicos - -# Son düzenleme: 26 Nisan 2017 -# Last edit: 26 April 2017 - -#init.lua -[MOD] Mobs Redo loaded = [MOD] Mobs Red yüklendi - -#api.lua -[MOBS] mod profiling enabled, damage not enabled = [MOBS] profilleme açık, zarar kapalı -lifetimer expired, removed @1 = Can zamanlayıcısı bitti, @1 silindi -[Mobs Redo] @1 has spawning disabled = @1 yaratılması kapandı -[Mobs Redo] Chance setting for @1 is now @2 = [Mobs Redo] @1'in şans ayarı şimdi @2 -[mobs] @1 failed to spawn at @2 = @1, @2'de yaratılamadı -Not tamed! = Evcil değil! -@1 is owner! = Sahibi @1! -Missed! = Kaçırdın! -@1 at full health (@2) = @1 tam canında (@2) -@1 has been tamed! = @1 tamamen evcilleştirilmiştir! -Enter name: = İsim gir: -Rename = Yeniden adlandır - -#crafts.lua -Nametag = İsim etiketi -Leather = Deri -Raw Meat = Çiğ et -Meat = Et -Magic Lasso (right-click animal to put in inventory) = Sihirli kement (hayvana sağ tıklayarak envantere koy) -Net (right-click animal to put in inventory) = Ağ (hayvana sağ tıklayarak envantere koy) -Steel Shears (right-click to shear) = Çelik makas (sağ tıklayarak kes) - -#spawner.lua -Mob Spawner = Canavar Yaratıcı -Mob MinLight MaxLight Amount PlayerDist = Mob MinIşık MaxIşık Miktar OyuncuMesafesi -Spawner Not Active (enter settings) = Yaratıcı aktif değil (ayarlara gir) -Spawner Active (@1) = Yaratıcı aktif (@1) -Mob Spawner settings failed! = Yaratıcı ayarları uygulanamadı. -> name min_light[0-14] max_light[0-14] max_mobs_in_area[0 to disable] distance[1-20] y_offset[-10 to 10] = > 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/ENTITIES/mobs/mount.lua b/mods/ENTITIES/mobs/mount.lua index 0482dfca6..67ad40648 100644 --- a/mods/ENTITIES/mobs/mount.lua +++ b/mods/ENTITIES/mobs/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 "mcl_core:dirt" + + 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 @@ -241,7 +255,7 @@ function mobs.drive(entity, moving_anim, stand_anim, can_fly, dtime) if entity.v == 0 and velo.x == 0 and velo.y == 0 and velo.z == 0 then if stand_anim then - set_animation(entity, stand_anim) + mobs:set_animation(entity, stand_anim) end return @@ -249,7 +263,7 @@ function mobs.drive(entity, moving_anim, stand_anim, can_fly, dtime) -- set moving animation if moving_anim then - set_animation(entity, moving_anim) + mobs:set_animation(entity, moving_anim) end -- Stop! @@ -429,9 +443,9 @@ function mobs.fly(entity, dtime, speed, shoots, arrow, moving_anim, stand_anim) -- change animation if stopped if velo.x == 0 and velo.y == 0 and velo.z == 0 then - set_animation(entity, stand_anim) + mobs:set_animation(entity, stand_anim) else -- moving animation - set_animation(entity, moving_anim) + mobs:set_animation(entity, moving_anim) end end diff --git a/mods/ENTITIES/mobs/readme.MD b/mods/ENTITIES/mobs/readme.MD index 7eae00751..ae879e562 100644 --- a/mods/ENTITIES/mobs/readme.MD +++ b/mods/ENTITIES/mobs/readme.MD @@ -22,6 +22,8 @@ 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) - 1.33- Added functions to mount ride mobs (mobs.attach, mobs.detach, mobs.drive) many thanks to Blert2112