diff --git a/mods/mobs/api.lua b/mods/mobs/api.lua index f4b05d7..35682a6 100644 --- a/mods/mobs/api.lua +++ b/mods/mobs/api.lua @@ -33,7 +33,7 @@ local use_mc2 = minetest.get_modpath("mcl_core") -- Global mobs = { mod = "redo", - version = "20231105", + version = "20231111", translate = S, intllib = S, invis = minetest.global_exists("invisibility") and invisibility or {}, node_ice = "default:ice", @@ -151,6 +151,7 @@ local creatura = minetest.get_modpath("creatura") and mobs.mob_class = { + state = "stand", stepheight = 1.1, fly_in = "air", owner = "", @@ -183,6 +184,7 @@ mobs.mob_class = { walk_chance = 50, stand_chance = 30, attack_chance = 5, + attack_patience = 11, passive = false, blood_amount = 5, blood_texture = "mobs_blood.png", @@ -226,7 +228,7 @@ local mob_class = mobs.mob_class -- Compatibility local mob_class_meta = {__index = mob_class} --- play sound +-- function mob_sound play sound function mob_class:mob_sound(sound) if not sound then return end @@ -246,7 +248,7 @@ function mob_class:mob_sound(sound) end --- attack player/mob +-- function do_class attack player/mob function mob_class:do_attack(player) if self.state == "attack" then @@ -282,7 +284,7 @@ local function is_player(player) end --- collision function based on jordan4ibanez' open_ai mod +-- function collision based on jordan4ibanez' open_ai mod function mob_class:collision() local pos = self.object:get_pos() ; if not pos then return {0, 0} end @@ -344,7 +346,7 @@ local function check_for(look_for, look_inside) end --- move mob in facing direction +-- function set_velocity move mob in facing direction function mob_class:set_velocity(v) -- halt mob if it has been ordered to stay @@ -389,13 +391,13 @@ function mob_class:set_velocity(v) self.object:set_velocity(new_vel) end --- global version of above function +-- global version of above function [deprecated] function mobs:set_velocity(entity, v) mob_class.set_velocity(entity, v) end --- calculate mob velocity +-- function get_velocity calculate mob velocity function mob_class:get_velocity() local v = self.object:get_velocity() @@ -406,7 +408,7 @@ function mob_class:get_velocity() end --- set and return valid yaw +-- function set_yaw set and return valid yaw function mob_class:set_yaw(yaw, delay) if not yaw or yaw ~= yaw then @@ -441,7 +443,7 @@ function mobs:yaw(entity, yaw, delay) end --- set defined animation +-- function set_animation set defined animation function mob_class:set_animation(anim, force) if not self.animation or not anim then return end @@ -486,6 +488,7 @@ function mob_class:set_animation(anim, force) 0, self.animation[anim .. "_loop"] ~= false) end +-- global function to set mob animation [deprecated function mobs:set_animation(entity, anim) entity.set_animation(entity, anim) end @@ -629,7 +632,7 @@ local function ray_line_of_sight(self, pos1, pos2) return true end - +-- function line_of_sight autodetectyion with raycasting support if any function mob_class:line_of_sight(pos1, pos2, stepsize) if minetest.raycast then -- only use if minetest 5.0 is detected @@ -639,12 +642,13 @@ function mob_class:line_of_sight(pos1, pos2, stepsize) return line_of_sight(self, pos1, pos2, stepsize) end --- global function +-- global function line of sight [deprecated] function mobs:line_of_sight(entity, pos1, pos2, stepsize) return entity:line_of_sight(pos1, pos2, stepsize) end +-- function attempt_flight_correction internal function mob_class:attempt_flight_correction(override) if self:flight_check() and override ~= true then return true end @@ -675,7 +679,7 @@ function mob_class:attempt_flight_correction(override) end --- are we flying in what we are suppose to? (taikedz) +-- function flight_check - are we flying in what we are suppose to? (taikedz) function mob_class:flight_check() local def = minetest.registered_nodes[self.standing_in] @@ -698,8 +702,8 @@ function mob_class:flight_check() end --- turn mob to face position -local function yaw_to_pos(self, target, rot) +-- function yaw_to_pos turn mob to face position +function mob_class:yaw_to_pos(target, rot) rot = rot or 0 @@ -716,12 +720,13 @@ local function yaw_to_pos(self, target, rot) return yaw end +-- global [deprecated] function mobs:yaw_to_pos(self, target, rot) - return yaw_to_pos(self, target, rot) + return self:yaw_to_pos(target, rot) end --- if stay near set then periodically check for nodes and turn towards them +-- function do_stay_near if stay near set then periodically check for nodes and turn towards them function mob_class:do_stay_near() if not self.stay_near then return false end @@ -747,7 +752,7 @@ function mob_class:do_stay_near() return false end - yaw_to_pos(self, nearby_nodes[random(#nearby_nodes)]) + self:yaw_to_pos(nearby_nodes[random(#nearby_nodes)]) self:set_animation("walk") @@ -793,6 +798,7 @@ local function effect( }) end +-- global function effect function mobs:effect( pos, amount, texture, min_size, max_size, radius, gravity, glow, fall) @@ -807,7 +813,7 @@ local HORNY_AGAIN_TIME = 60 * 5 -- 5 minutes local CHILD_GROW_TIME = 60 * 20 -- 20 minutes --- update nametag and infotext +-- function update_tag update nametag and infotext function mob_class:update_tag() local col @@ -857,7 +863,7 @@ function mob_class:update_tag() end --- drop items +-- function item_drop drop items function mob_class:item_drop() -- no drops if disabled by setting or mob is child @@ -940,7 +946,7 @@ function mob_class:item_drop() end --- remove mob and descrease counter +-- TODO make object class function - remove mob and descrease counter local function remove_mob(self, decrease) self.object:remove() @@ -961,7 +967,7 @@ function mobs:remove(self, decrease) end --- check if mob is dead or only hurt +-- function check_for_deathcheck if mob is dead or only hurt function mob_class:check_for_death(cmi_cause) -- We dead already @@ -1086,6 +1092,11 @@ local function node_ok(pos, fallback) return minetest.registered_nodes[(fallback or mobs.fallback_node)] end +-- global function node_ok +function mobs:node_ok(pos, fallback) + return node_ok(pos, fallback) +end + -- Returns true is node can deal damage to self function mobs:is_node_dangerous(mob_object, nodename) @@ -1117,7 +1128,7 @@ local function is_node_dangerous(mob_object, nodename) end --- is mob facing a cliff +-- function is_at_cliff is mob facing a cliff function mob_class:is_at_cliff() if self.driver or self.fear_height == 0 then -- 0 for no falling protection! @@ -1156,7 +1167,30 @@ function mob_class:is_at_cliff() end --- environmental damage (water, lava, fire, light etc.) +-- function is_inside check for nodes or groups inside mob +function mob_class:is_inside(itemtable) + + local cb + if not self.collisionbox then + if self.object:get_properties().collisionbox then + cb = self.object:get_properties().collisionbox + else + return false + end + else + cb = self.collisionbox + end + local pos = self.object:get_pos() + local vo1 = {} + local nn = minetest.find_nodes_in_area( + {x = pos.x + cb[1], y = pos.y + cb[2], z = pos.z + cb[3]}, + {x = pos.x + cb[4], y = pos.y + cb[5], z = pos.z + cb[6]}, itemtable) + + if nn and #nn > 0 then return true else return false end +end + + +-- function do_env_damage environmental damage (water, lava, fire, light etc.) function mob_class:do_env_damage() self:update_tag() @@ -1195,7 +1229,7 @@ function mob_class:do_env_damage() end -- lava damage - elseif self.lava_damage ~= 0 and nodef.groups.lava then + elseif self.lava_damage ~= 0 and self:is_inside("group:lava") then -- nodef.groups.lava then self.health = self.health - self.lava_damage @@ -1300,7 +1334,7 @@ function mob_class:do_env_damage() end --- jump if facing a solid node (not fences or gates) +-- function do_jump jump if facing a solid node (not fences or gates) function mob_class:do_jump() local vel = self.object:get_velocity() ; if not vel then return false end @@ -1416,7 +1450,7 @@ local function is_invisible(self, player_name) end --- should mob follow what I'm holding ? +-- function follow_holding should mob follow what I'm holding ? function mob_class:follow_holding(clicker) if is_invisible(self, clicker:get_player_name()) then @@ -1434,7 +1468,7 @@ function mob_class:follow_holding(clicker) end --- find two animals of same type and breed if nearby and horny +-- function breed find two animals of same type and breed if nearby and horny function mob_class:breed() -- child takes a long time before growing into adult @@ -1542,8 +1576,8 @@ function mob_class:breed() local pos2 = ent.object:get_pos() -- Have mobs face one another - yaw_to_pos(self, pos2) - yaw_to_pos(ent, self.object:get_pos()) + self:yaw_to_pos(pos2) + ent:yaw_to_pos(self.object:get_pos()) self.hornytimer = HORNY_TIME + 1 ent.hornytimer = HORNY_TIME + 1 @@ -1638,7 +1672,7 @@ function mob_class:breed() end --- find and replace what mob is looking for (grass, wheat etc.) +-- function replace find and replace what mob is looking for (grass, wheat etc.) function mob_class:replace(pos) local vel = self.object:get_velocity() @@ -1695,7 +1729,7 @@ function mob_class:replace(pos) end --- check if daytime and also if mob is docile during daylight hours +-- function day_docile check if daytime and also if mob is docile during daylight hours function mob_class:day_docile() if self.docile_by_day == false then @@ -1750,6 +1784,7 @@ end local pathfinder_mod = minetest.get_modpath("pathfinder") +-- function smart_mobs -- path finding and smart mob routine by rnd, -- line_of_sight and other edits by Elkien3 function mob_class:smart_mobs(s, p, dist, dtime) @@ -1859,7 +1894,9 @@ function mob_class:smart_mobs(s, p, dist, dtime) s.y = sground.y + 1 end - local p1 = self.attack:get_pos() + local p1 = self.attack and self.attack:get_pos() + + if not p1 then return end p1.x = floor(p1.x + 0.5) p1.y = floor(p1.y + 0.5) @@ -1998,12 +2035,12 @@ end local function is_peaceful_player(player) -- main setting enabled - if peaceful_player_enabled and player:is_player() then + if is_player(player) then local player_name = player:get_player_name() -- player priv enabled - if player_name and minetest.check_player_privs(player_name, "peaceful_player") then + if player_name and peaceful_player_enabled and minetest.check_player_privs(player_name, "peaceful_player") then return true end end @@ -2012,7 +2049,7 @@ local function is_peaceful_player(player) end --- general attack function for all mobs +-- function general_attack function for all mobs function mob_class:general_attack() -- return if already attacking, passive or docile during day @@ -2039,8 +2076,7 @@ function mob_class:general_attack() or self.attack_players == false or (self.owner and self.type ~= "monster") or is_invisible(self, objs[n]:get_player_name()) - or (self.specific_attack - and not check_for("player", self.specific_attack)) then + or (self.specific_attack and not check_for("player", self.specific_attack)) then objs[n] = nil --print("- pla", n) end @@ -2052,10 +2088,8 @@ function mob_class:general_attack() -- monsters attack all creatura mobs, npc and animals will only attack -- if the animal owner is currently being attacked by creatura mob if self.name == ent.name - or (self.type ~= "monster" - and self.owner ~= (ent._target and ent._target:get_player_name() or ".")) - or (self.specific_attack - and not check_for(ent.name, self.specific_attack)) then + or (self.type ~= "monster" and self.owner ~= (ent._target and ent._target:get_player_name() or ".")) + or (self.specific_attack and not check_for(ent.name, self.specific_attack)) then objs[n] = nil --print("-- creatura", ent.name) @@ -2069,8 +2103,7 @@ function mob_class:general_attack() or (not self.attack_animals and ent.type == "animal") or (not self.attack_monsters and ent.type == "monster") or (not self.attack_npcs and ent.type == "npc") - or (self.specific_attack - and not check_for(ent.name, self.specific_attack)) then + or (self.specific_attack and not check_for(ent.name, self.specific_attack)) then objs[n] = nil --print("- mob", n, self.name, ent.name) end @@ -2114,7 +2147,7 @@ function mob_class:general_attack() end --- find someone to runaway from +-- function do_runaway_from find someone to runaway from function mob_class:do_runaway_from() if not self.runaway_from then @@ -2174,7 +2207,7 @@ function mob_class:do_runaway_from() if min_player then - yaw_to_pos(self, min_player:get_pos(), 3) + self:yaw_to_pos(min_player:get_pos(), 3) self.state = "runaway" self.runaway_timer = 3 @@ -2188,7 +2221,7 @@ function mob_class:do_runaway_from() if objs then - yaw_to_pos(self, objs, 3) + self:yaw_to_pos(objs, 3) self.state = "runaway" self.runaway_timer = 3 @@ -2197,7 +2230,7 @@ function mob_class:do_runaway_from() end --- follow player if owner or holding item, if fish outta water then flop +-- function follow_flop follow player if owner or holding item, if fish outta water then flop function mob_class:follow_flop() -- find player to follow @@ -2212,7 +2245,7 @@ function mob_class:follow_flop() for n = 1, #players do if players[n] then - if players[n]:is_player() then + if is_player(players[n]) then if not is_invisible(self, players[n]:get_player_name()) and get_distance(players[n]:get_pos(), s) < self.view_range then self.following = players[n] @@ -2236,7 +2269,7 @@ function mob_class:follow_flop() else -- stop following player if not holding specific item or mob is horny if self.following and is_player(self.following) - and (self:follow_holding(self.following) == false or self.horny) then + and (self.horny or not self:follow_holding(self.following)) then self.following = nil end @@ -2262,7 +2295,7 @@ function mob_class:follow_flop() if dist > self.view_range then self.following = nil else - yaw_to_pos(self, p) + self:yaw_to_pos(p) -- anyone but standing npc's can move along if dist >= self.reach @@ -2313,7 +2346,7 @@ function mob_class:follow_flop() end --- dogshoot attack switch and counter function +-- function dogswitch dogshoot attack switch and counter function function mob_class:dogswitch(dtime) -- switch mode not activated @@ -2339,7 +2372,7 @@ function mob_class:dogswitch(dtime) end --- stop attack +-- function stop_attack function mob_class:stop_attack() self.attack = nil @@ -2354,7 +2387,7 @@ function mob_class:stop_attack() end --- execute current state (stand, walk, run, attacks) +-- function do_states execute current state (stand, walk, run, attacks) function mob_class:do_states(dtime) local yaw = self.object:get_yaw() ; if not yaw then return end @@ -2386,7 +2419,7 @@ function mob_class:do_states(dtime) -- select position of random block to climb onto lp = lp[random(#lp)] - yaw = yaw_to_pos(self, lp) + yaw = self:yaw_to_pos(lp) end self.pause_timer = 3 @@ -2418,7 +2451,7 @@ function mob_class:do_states(dtime) -- look at any players nearby, otherwise turn randomly if lp then - yaw = yaw_to_pos(self, lp) + yaw = self:yaw_to_pos(lp) else yaw = yaw + random(-0.5, 0.5) end @@ -2496,8 +2529,8 @@ function mob_class:do_states(dtime) self.runaway_timer = self.runaway_timer + 1 - -- stop after 5 seconds or when at cliff - if self.runaway_timer > 5 + -- stop early after 3 or 2 seconds or when at cliff cos defaults start at 0 but on some states is 3 + if self.runaway_timer > 4 or self.at_cliff or self.order == "stand" then self.runaway_timer = 0 @@ -2523,17 +2556,11 @@ function mob_class:do_states(dtime) local dist = p and get_distance(p, s) or 500 -- stop attacking if player out of range or invisible - if dist > self.view_range - or not self.attack - or not self.attack:get_pos() - or self.attack:get_hp() <= 0 - or (is_player(self.attack) - and is_invisible(self, self.attack:get_player_name())) then - + if dist > self.view_range and not self.attack and not is_player(self.attack) then + if not self.attack:get_pos() or self.attack:get_hp() <= 0 and is_invisible(self, self.attack:get_player_name()) then --print(" ** stop attacking **", self.name, self.health, dist, self.view_range) - - self:stop_attack() - + self:stop_attack() + end return end @@ -2556,7 +2583,7 @@ function mob_class:do_states(dtime) if self.attack_type == "explode" then - yaw_to_pos(self, p) + self:yaw_to_pos(p) local node_break_radius = self.explosion_radius or 1 local entity_damage_radius = self.explosion_damage_radius @@ -2707,7 +2734,7 @@ function mob_class:do_states(dtime) p = {x = p1.x, y = p1.y, z = p1.z} end - yaw_to_pos(self, p) + self:yaw_to_pos(p) -- move towards enemy if beyond mob reach if dist > (self.reach + (self.reach_ext or 0)) then @@ -2799,7 +2826,7 @@ function mob_class:do_states(dtime) local vec = {x = p.x - s.x, y = p.y - s.y, z = p.z - s.z} - yaw_to_pos(self, p) + self:yaw_to_pos(p) self:set_velocity(0) @@ -2846,7 +2873,7 @@ function mob_class:do_states(dtime) end --- falling and fall damage +-- function falling and fall damage function mob_class:falling(pos) if self.fly or self.disable_falling then @@ -2901,7 +2928,7 @@ end -- is Took Ranks mod active? local tr = minetest.get_modpath("toolranks") --- deal damage and effects when mob punched +-- function on_punch deal damage and effects when mob punched function mob_class:on_punch(hitter, tflp, tool_capabilities, dir, damage) -- mob health check @@ -3147,7 +3174,7 @@ function mob_class:on_punch(hitter, tflp, tool_capabilities, dir, damage) local lp = hitter:get_pos() - yaw_to_pos(self, lp, 3) + self:yaw_to_pos(lp, 3) self.state = "runaway" self.runaway_timer = 0 @@ -3222,7 +3249,7 @@ local function clean_staticdata(self) end --- get entity staticdata +-- function mob_staticdata get entity staticdata function mob_class:mob_staticdata() -- this handles mob count for mobs activated, unloaded, reloaded @@ -3287,7 +3314,7 @@ function mob_class:mob_staticdata() end --- activate mob and reload settings +-- function mob_activate activate mob and reload settings function mob_class:mob_activate(staticdata, def, dtime) -- if dtime == 0 then entity has just been created @@ -3459,7 +3486,7 @@ function mob_class:mob_activate(staticdata, def, dtime) end --- handle mob lifetimer and expiration +-- function mob_expire handle mob lifetimer and expiration function mob_class:mob_expire(pos, dtime) -- when lifetimer expires remove mob (except npc and tamed) @@ -3498,7 +3525,7 @@ function mob_class:mob_expire(pos, dtime) end --- get nodes mob is standing on/in, facing/above +-- function get_nodes get nodes mob is standing on/in, facing/above function mob_class:get_nodes() local pos = self.object:get_pos() @@ -3542,7 +3569,7 @@ print("on: " .. self.standing_on end --- main mob function +-- function on_step main mob function function mob_class:on_step(dtime, moveresult) if self.state == "die" then return end @@ -3698,7 +3725,7 @@ function mob_class:on_step(dtime, moveresult) end --- default function when mobs are blown up with TNT +-- function on_blast default function when mobs are blown up with TNT function mob_class:on_blast(damage) --print("-- blast damage", damage) @@ -3782,6 +3809,7 @@ minetest.register_entity(name, setmetatable({ walk_chance = def.walk_chance, stand_chance = def.stand_chance, attack_chance = def.attack_chance, + attack_patience = def.attack_patience, passive = def.passive, knock_back = def.knock_back, blood_amount = def.blood_amount, @@ -3985,8 +4013,13 @@ function mobs:add_mob(pos, def) effect(pos, 15, "tnt_smoke.png", 1, 2, 2, 15, 5) end + -- use new texture if found + local new_texture = def.texture or ent.base_texture + if def.child then + ent.mommy_tex = new_texture -- how baby looks when grown + ent.base_texture = new_texture local textures = ent.base_texture -- using specific child texture (if found) @@ -4020,6 +4053,12 @@ function mobs:add_mob(pos, def) }) ent.child = true + -- if not child set new texture + elseif def.texture then + + ent.base_texture = new_texture + + mob:set_properties({textures = new_texture}) end if def.owner then @@ -4085,7 +4124,7 @@ function mobs:spawn_specific(name, nodes, neighbors, min_light, max_light, inter pos, node, active_object_count, active_object_count_wider) -- use instead of abm's chance setting when using lbm - if map_load and random(max(1, (chance * mob_chance_multiplier))) > 1 then + if map_load and random(max(1, (chance * mob_chance_multiplier/10))) > 1 then return end @@ -4190,6 +4229,11 @@ function mobs:spawn_specific(name, nodes, neighbors, min_light, max_light, inter local ent = minetest.registered_entities[name] + if not ent or not ent.base_colbox then + print("[MOBS] Error spawning mob: " .. name) + return + end + -- should we check mob area for obstructions ? if mob_area_spawn ~= true then @@ -4257,7 +4301,7 @@ function mobs:spawn_specific(name, nodes, neighbors, min_light, max_light, inter nodenames = nodes, neighbors = neighbors, interval = interval, - chance = max(1, (chance * mob_chance_multiplier)), + chance = max(1, (chance * (mob_chance_multiplier/10))), catch_up = false, action = function(pos, node, active_object_count, active_object_count_wider) @@ -4492,6 +4536,16 @@ function mobs:register_egg(mob, desc, background, addegg, no_creative) "^[mask:mobs_chicken_egg_overlay.png)" end + -- does mob/entity exist + local is_mob = minetest.registered_entities[mob] + + if not is_mob then + print("[Mobs Redo] Spawn Egg cannot be created for " .. mob) + return + end + -- these are only created for animals and npc mobs, not monsters TODO + -- if is_mob.type ~= "monster" then return end + -- register new spawn egg containing mob information (cannot be stacked) minetest.register_craftitem(mob .. "_set", { @@ -4514,10 +4568,15 @@ function mobs:register_egg(mob, desc, background, addegg, no_creative) pointed_thing.under, under, placer, itemstack, pointed_thing) end - if pos - and not minetest.is_protected(pos, placer:get_player_name()) then + if pos and not minetest.is_protected(pos, placer:get_player_name()) then - if not minetest.registered_entities[mob] then + if active_limit > 0 and active_mobs >= active_limit then + if is_player(placer) then + minetest.chat_send_player(placer:get_player_name(), + S("Active Mob Limit Reached!") + .. " (" .. active_mobs + .. " / " .. active_limit .. ")") + end return end @@ -4567,16 +4626,14 @@ function mobs:register_egg(mob, desc, background, addegg, no_creative) if pos and not minetest.is_protected(pos, placer:get_player_name()) then - if not minetest.registered_entities[mob] then - return - end - -- have we reached active mob limit if active_limit > 0 and active_mobs >= active_limit then - minetest.chat_send_player(placer:get_player_name(), - S("Active Mob Limit Reached!") - .. " (" .. active_mobs - .. " / " .. active_limit .. ")") + if is_player(placer) then + minetest.chat_send_player(placer:get_player_name(), + S("Active Mob Limit Reached!") + .. " (" .. active_mobs + .. " / " .. active_limit .. ")") + end return end @@ -4786,7 +4843,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(pos, 25, "mobs_protect_particle.png", 0.5, 4, 2, 15) self:mob_sound("mobs_spell") diff --git a/mods/mobs/api.txt b/mods/mobs/api.txt index 53b5f08..023380c 100644 --- a/mods/mobs/api.txt +++ b/mods/mobs/api.txt @@ -104,6 +104,8 @@ functions needed for the mob to work properly which contains the following: hours and only attacking player at night or when provoked. 'attack_chance' 0 to 100 chance the mob will attack (default is 5). + 'attack_patience' Time in seconds before mob gives up attacking if + player isn't seen (Defaults to 11). 'attack_monsters' when true mob will attack monsters. 'attack_animals' when true mob will attack animals. 'attack_npcs' when true mob will attack npcs within range. @@ -386,14 +388,31 @@ for each mob. 'self.facing_fence' True if mob facing node containing "wall", "fence", "gate" in it's name. - Internal Functions ------------------ Each mob contains a set of functions that can be called for use internally or from another mod entirely, replace mob_class with the mob entity variable: +mob_class:mob_sound(sound) -- play sound at mob position +mob_class:do_attack(player) -- if not already attacking, attack object given mob_class:stop_attack() -- stops mob attacking +mob_class:collision() -- checks for player collision with mob and returns {x, z} vector +mob_class:set_velocity(velocity) -- move at velocity in the facing direction +mob_class:get_velocity() -- returns mob speed value +mob_class:set_yaw(yaw, delay) -- change mob yaw, delay is for smooth rotation (default:0) +mob_class:yaw_to_pos(pos, delay) -- rotates mod to look at position and returns new yaw +mob_class:set_animation(animation, force) -- set mob animation +mob_class:line_of_sight(pos1, pos2) -- internal line of sight function +mob_class:attempt_flight_correction(override) -- check for stuck flying mobs and fix +mob_class:update_tag(newname) -- update nametag or give new name +mob_class:do_jump() -- check if mob can jump then jump +mob_class:follow_holding(clicker) -- return True if mob likes what player is holding +mob_class:day_docile() -- return True if mob docile during current daytime +mob_class:mob_expire(pos, dtime) -- check if mob is to despawn +mob_class:get_nodes() -- get specific nodes around mob +mob_class:on_blast(damage) -- function called when mob in blast area +mob_class:is_inside(itemtable) -- returns True is mob collisionbox inside any node/group in table Adding Mobs in World diff --git a/mods/mobs/readme.MD b/mods/mobs/readme.MD index b51f05f..957e80f 100644 --- a/mods/mobs/readme.MD +++ b/mods/mobs/readme.MD @@ -32,6 +32,25 @@ the tenplus1 only works in last minetest, admins will not wants to constant upgr ## Changelog +### pending next + +* Added self.homing so that arrows follow player when visible +* Added support for Visual Harm 1ndicators mod to show health bars +* Move mob and arrow entities to use initial_properties +* Spawn eggs check if mob is available when creating +* Used get/set_properties() within API for mob properties +* Moved nametag variable to self._nametag + +### Version 1.60 + +* Updated api txt documentation +* Added entity:is_inside(itemtable) function (thx cora) +* Added self.attack_patience value so mobs stop attacking unseen players +* Tidied breeding function +* Better MineClone2 / MineClonia support added +* Tweaked and tidied code in places +* Added self.node_damage flag which is true by default to enable damage_per_second node damage + ### Version 1.57 * Added 'injured' animation when mob hurt diff --git a/mods/mobs/textures/mobs_net-fs8.png b/mods/mobs/textures/mobs_net-fs8.png deleted file mode 100644 index 24eb578..0000000 Binary files a/mods/mobs/textures/mobs_net-fs8.png and /dev/null differ