diff --git a/api.lua b/api.lua index 1910237..e5c5844 100644 --- a/api.lua +++ b/api.lua @@ -28,7 +28,7 @@ local use_cmi = minetest.global_exists("cmi") mobs = { mod = "redo", - version = "20220514", + version = "20220722", intllib = S, invis = minetest.global_exists("invisibility") and invisibility or {} } @@ -106,8 +106,8 @@ local stuck_timeout = 3 -- how long before stuck mod starts searching local stuck_path_timeout = 5 -- 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_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" @@ -425,8 +425,7 @@ function mob_class:set_animation(anim, force) 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, + self.animation[anim .. "_speed"] or self.animation.speed_normal or 15, 0, self.animation[anim .. "_loop"] ~= false) end @@ -1261,15 +1260,9 @@ function mob_class:do_jump() -- set y_pos to base of mob pos.y = pos.y + self.collisionbox[2] - -- what is in front of mob? - local nod = node_ok({ - x = pos.x + dir_x, y = pos.y + 0.5, z = pos.z + dir_z - }) - - -- what is above and in front? - local nodt = node_ok({ - x = pos.x + dir_x, y = pos.y + 1.5, z = pos.z + dir_z - }) + -- what is in front of mob and above? + local nod = node_ok({x = pos.x + dir_x, y = pos.y + 0.5, z = pos.z + dir_z}) + local nodt = node_ok({x = pos.x + dir_x, y = pos.y + 1.5, z = pos.z + dir_z}) local blocked = minetest.registered_nodes[nodt.name].walkable @@ -1277,6 +1270,7 @@ function mob_class:do_jump() if nod.name:find("fence") or nod.name:find("gate") or nod.name:find("wall") then self.facing_fence = true end + --[[ print("on: " .. self.standing_on .. ", front: " .. nod.name @@ -1285,6 +1279,13 @@ print("on: " .. self.standing_on .. ", fence: " .. (self.facing_fence and "yes" or "no") ) ]] + + -- if mob can leap then remove blockages and let them try + if self.can_leap == true then + blocked = false + self.facing_fence = false + end + -- jump if standing on solid node (not snow) and not blocked if (self.walk_chance == 0 or minetest.registered_items[nod.name].walkable) and not blocked and not self.facing_fence and nod.name ~= node_snow then @@ -1455,8 +1456,7 @@ function mob_class:breed() local pos = self.object:get_pos() - effect({x = pos.x, y = pos.y + 1, z = pos.z}, 8, - "heart.png", 3, 4, 1, 0.1) + effect({x = pos.x, y = pos.y + 1, z = pos.z}, 8, "heart.png", 3, 4, 1, 0.1) local objs = minetest.get_objects_inside_radius(pos, 3) local ent @@ -1477,6 +1477,7 @@ function mob_class:breed() local selfname = self.name:split(":") if entname[1] == selfname[1] then + entname = entname[2]:split("_") selfname = selfname[2]:split("_") @@ -1564,7 +1565,7 @@ function mob_class:breed() self.base_selbox[4] * .5, self.base_selbox[5] * .5, self.base_selbox[6] * .5 - }, + } }) -- tamed and owned by parents' owner ent2.child = true @@ -1640,13 +1641,10 @@ end function mob_class:day_docile() if self.docile_by_day == false then - return false - elseif self.docile_by_day == true and self.time_of_day > 0.2 and self.time_of_day < 0.8 then - return true end end @@ -2641,7 +2639,7 @@ function mob_class:do_states(dtime) yaw = yaw_to_pos(self, p) -- move towards enemy if beyond mob reach - if dist > self.reach then + if dist > (self.reach + (self.reach_ext or 0)) then -- path finding by rnd if self.pathfinding -- only if mob has pathfinding enabled @@ -2653,8 +2651,13 @@ function mob_class:do_states(dtime) -- distance padding to stop spinning mob local pad = abs(p.x - s.x) + abs(p.z - s.z) + self.reach_ext = 0 -- extended ready off by default + if self.at_cliff or pad < 0.2 then + -- when on top of player extend reach slightly so player can + -- still be attacked. + self.reach_ext = 0.8 self:set_velocity(0) self:set_animation("stand") else @@ -3283,7 +3286,7 @@ function mob_class:mob_activate(staticdata, def, dtime) if type(self.armor) == "table" then armor = table_copy(self.armor) else - armor = {fleshy = self.armor} -- immortal = 1 + armor = {fleshy = self.armor, immortal = 1} end self.object:set_armor_groups(armor) @@ -3416,8 +3419,7 @@ function mob_class:on_step(dtime, moveresult) -- if standing inside solid block then jump to escape if minetest.registered_nodes[self.standing_in].walkable - and minetest.registered_nodes[self.standing_in].drawtype - == "normal" then + and minetest.registered_nodes[self.standing_in].drawtype == "normal" then self.object:set_velocity({ x = 0, @@ -3591,6 +3593,7 @@ minetest.register_entity(name, setmetatable({ on_flop = def.on_flop, do_custom = def.do_custom, jump_height = def.jump_height, + can_leap = def.can_leap, drawtype = def.drawtype, -- DEPRECATED, use rotate instead rotate = rad(def.rotate or 0), -- 0=front 90=side 180=back 270=side2 glow = def.glow, @@ -3861,7 +3864,7 @@ function mobs:add_mob(pos, def) ent.base_selbox[4] * .5, ent.base_selbox[5] * .5, ent.base_selbox[6] * .5 - }, + } }) ent.child = true @@ -4663,8 +4666,7 @@ function mobs:protect(self, clicker) pos.y = pos.y + self.collisionbox[2] + 0.5 - effect(self.object:get_pos(), 25, "mobs_protect_particle.png", - 0.5, 4, 2, 15) + effect(self.object:get_pos(), 25, "mobs_protect_particle.png", 0.5, 4, 2, 15) self:mob_sound("mobs_spell") @@ -4843,7 +4845,7 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) end) --- compatibility function for old entities to new modpack entities +-- compatibility function for old mobs entities to new mobs_redo modpack function mobs:alias_mob(old_name, new_name) -- check old_name entity doesnt already exist @@ -4874,3 +4876,44 @@ function mobs:alias_mob(old_name, new_name) end }) end + + +-- admin command to remove untamed mobs around players +minetest.register_chatcommand("clear_mobs", { + params = "", + description = "Remove untamed mobs from around players.", + privs = {server = true}, + + func = function (name, param) + + local count = 0 + + for _, player in pairs(minetest.get_connected_players()) do + + if player then + + local pos = player:get_pos() + + local objs = minetest.get_objects_inside_radius(pos, 28) + + for _, obj in pairs(objs) do + + if obj then + + local ent = obj:get_luaentity() + + -- only remove mobs redo mobs that are not tamed + if ent and ent._cmi_is_mob and ent.tamed ~= true then + + remove_mob(ent, true) + + count = count + 1 + end + end + end + end + end + + minetest.chat_send_player(name, S("@1 mobs removed.", count)) + end +}) diff --git a/api.txt b/api.txt index cef228a..30bb2a3 100644 --- a/api.txt +++ b/api.txt @@ -42,6 +42,8 @@ functions needed for the mob to work properly which contains the following: randomly turn while walking or standing. 'jump' when true allows your mob to jump updwards. 'jump_height' holds the height your mob can jump, 0 to disable jumping. + 'can_leap' when true obstacles like fences or pits wont stop a mob + from trying to jump out. 'stepheight' height of a block that your mob can easily walk up onto, defaults to 1.1. 'fly' when true allows your mob to fly around instead of walking. @@ -223,6 +225,9 @@ functions needed for the mob to work properly which contains the following: 'fly_start' when a mob is flying. 'fly_end' 'fly_speed' + 'jump_start' when a mob is jumping + 'jump_end' + 'jump_speed' 'punch_start' when a mob melee attacks. 'punch_end' 'punch_speed'