mod - mobs_redo - update 20231111 minetest.org best compatible, works with multicraft
* make api compatible with minetesty 0.4 and 5.0 and also multicraft 2.0.3 fix offset vector and upgrade api issue * stupid tenplus1 does not care others only him. so i sustitute the crap of modernish using equivalent to vector.offset that is just movement to the collisionbox offset * closes minenux/minetest-mod-mobs_redo#108 * Updated api txt documentation * Added entity:is_inside(itemtable) function (thx cora) and also check for fire/lava in mob collisionbox area * 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 * mobs:add_mob() can now set mob texture * do not regiter mobs if there is not a mob * property check player object as must be cos engine returns false positives
This commit is contained in:
parent
841133e4ad
commit
e19cb34416
@ -33,7 +33,7 @@ local use_mc2 = minetest.get_modpath("mcl_core")
|
|||||||
-- Global
|
-- Global
|
||||||
mobs = {
|
mobs = {
|
||||||
mod = "redo",
|
mod = "redo",
|
||||||
version = "20231105",
|
version = "20231111",
|
||||||
translate = S, intllib = S,
|
translate = S, intllib = S,
|
||||||
invis = minetest.global_exists("invisibility") and invisibility or {},
|
invis = minetest.global_exists("invisibility") and invisibility or {},
|
||||||
node_ice = "default:ice",
|
node_ice = "default:ice",
|
||||||
@ -151,6 +151,7 @@ local creatura = minetest.get_modpath("creatura") and
|
|||||||
|
|
||||||
|
|
||||||
mobs.mob_class = {
|
mobs.mob_class = {
|
||||||
|
state = "stand",
|
||||||
stepheight = 1.1,
|
stepheight = 1.1,
|
||||||
fly_in = "air",
|
fly_in = "air",
|
||||||
owner = "",
|
owner = "",
|
||||||
@ -183,6 +184,7 @@ mobs.mob_class = {
|
|||||||
walk_chance = 50,
|
walk_chance = 50,
|
||||||
stand_chance = 30,
|
stand_chance = 30,
|
||||||
attack_chance = 5,
|
attack_chance = 5,
|
||||||
|
attack_patience = 11,
|
||||||
passive = false,
|
passive = false,
|
||||||
blood_amount = 5,
|
blood_amount = 5,
|
||||||
blood_texture = "mobs_blood.png",
|
blood_texture = "mobs_blood.png",
|
||||||
@ -226,7 +228,7 @@ local mob_class = mobs.mob_class -- Compatibility
|
|||||||
local mob_class_meta = {__index = mob_class}
|
local mob_class_meta = {__index = mob_class}
|
||||||
|
|
||||||
|
|
||||||
-- play sound
|
-- function mob_sound play sound
|
||||||
function mob_class:mob_sound(sound)
|
function mob_class:mob_sound(sound)
|
||||||
|
|
||||||
if not sound then return end
|
if not sound then return end
|
||||||
@ -246,7 +248,7 @@ function mob_class:mob_sound(sound)
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
-- attack player/mob
|
-- function do_class attack player/mob
|
||||||
function mob_class:do_attack(player)
|
function mob_class:do_attack(player)
|
||||||
|
|
||||||
if self.state == "attack" then
|
if self.state == "attack" then
|
||||||
@ -282,7 +284,7 @@ local function is_player(player)
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
-- collision function based on jordan4ibanez' open_ai mod
|
-- function collision based on jordan4ibanez' open_ai mod
|
||||||
function mob_class:collision()
|
function mob_class:collision()
|
||||||
|
|
||||||
local pos = self.object:get_pos() ; if not pos then return {0, 0} end
|
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
|
end
|
||||||
|
|
||||||
|
|
||||||
-- move mob in facing direction
|
-- function set_velocity move mob in facing direction
|
||||||
function mob_class:set_velocity(v)
|
function mob_class:set_velocity(v)
|
||||||
|
|
||||||
-- halt mob if it has been ordered to stay
|
-- 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)
|
self.object:set_velocity(new_vel)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- global version of above function
|
-- global version of above function [deprecated]
|
||||||
function mobs:set_velocity(entity, v)
|
function mobs:set_velocity(entity, v)
|
||||||
mob_class.set_velocity(entity, v)
|
mob_class.set_velocity(entity, v)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
-- calculate mob velocity
|
-- function get_velocity calculate mob velocity
|
||||||
function mob_class:get_velocity()
|
function mob_class:get_velocity()
|
||||||
|
|
||||||
local v = self.object:get_velocity()
|
local v = self.object:get_velocity()
|
||||||
@ -406,7 +408,7 @@ function mob_class:get_velocity()
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
-- set and return valid yaw
|
-- function set_yaw set and return valid yaw
|
||||||
function mob_class:set_yaw(yaw, delay)
|
function mob_class:set_yaw(yaw, delay)
|
||||||
|
|
||||||
if not yaw or yaw ~= yaw then
|
if not yaw or yaw ~= yaw then
|
||||||
@ -441,7 +443,7 @@ function mobs:yaw(entity, yaw, delay)
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
-- set defined animation
|
-- function set_animation set defined animation
|
||||||
function mob_class:set_animation(anim, force)
|
function mob_class:set_animation(anim, force)
|
||||||
|
|
||||||
if not self.animation or not anim then return end
|
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)
|
0, self.animation[anim .. "_loop"] ~= false)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- global function to set mob animation [deprecated
|
||||||
function mobs:set_animation(entity, anim)
|
function mobs:set_animation(entity, anim)
|
||||||
entity.set_animation(entity, anim)
|
entity.set_animation(entity, anim)
|
||||||
end
|
end
|
||||||
@ -629,7 +632,7 @@ local function ray_line_of_sight(self, pos1, pos2)
|
|||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- function line_of_sight autodetectyion with raycasting support if any
|
||||||
function mob_class:line_of_sight(pos1, pos2, stepsize)
|
function mob_class:line_of_sight(pos1, pos2, stepsize)
|
||||||
|
|
||||||
if minetest.raycast then -- only use if minetest 5.0 is detected
|
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)
|
return line_of_sight(self, pos1, pos2, stepsize)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- global function
|
-- global function line of sight [deprecated]
|
||||||
function mobs:line_of_sight(entity, pos1, pos2, stepsize)
|
function mobs:line_of_sight(entity, pos1, pos2, stepsize)
|
||||||
return entity:line_of_sight(pos1, pos2, stepsize)
|
return entity:line_of_sight(pos1, pos2, stepsize)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
-- function attempt_flight_correction internal
|
||||||
function mob_class:attempt_flight_correction(override)
|
function mob_class:attempt_flight_correction(override)
|
||||||
|
|
||||||
if self:flight_check() and override ~= true then return true end
|
if self:flight_check() and override ~= true then return true end
|
||||||
@ -675,7 +679,7 @@ function mob_class:attempt_flight_correction(override)
|
|||||||
end
|
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()
|
function mob_class:flight_check()
|
||||||
|
|
||||||
local def = minetest.registered_nodes[self.standing_in]
|
local def = minetest.registered_nodes[self.standing_in]
|
||||||
@ -698,8 +702,8 @@ function mob_class:flight_check()
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
-- turn mob to face position
|
-- function yaw_to_pos turn mob to face position
|
||||||
local function yaw_to_pos(self, target, rot)
|
function mob_class:yaw_to_pos(target, rot)
|
||||||
|
|
||||||
rot = rot or 0
|
rot = rot or 0
|
||||||
|
|
||||||
@ -716,12 +720,13 @@ local function yaw_to_pos(self, target, rot)
|
|||||||
return yaw
|
return yaw
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- global [deprecated]
|
||||||
function mobs:yaw_to_pos(self, target, rot)
|
function mobs:yaw_to_pos(self, target, rot)
|
||||||
return yaw_to_pos(self, target, rot)
|
return self:yaw_to_pos(target, rot)
|
||||||
end
|
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()
|
function mob_class:do_stay_near()
|
||||||
|
|
||||||
if not self.stay_near then return false end
|
if not self.stay_near then return false end
|
||||||
@ -747,7 +752,7 @@ function mob_class:do_stay_near()
|
|||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
yaw_to_pos(self, nearby_nodes[random(#nearby_nodes)])
|
self:yaw_to_pos(nearby_nodes[random(#nearby_nodes)])
|
||||||
|
|
||||||
self:set_animation("walk")
|
self:set_animation("walk")
|
||||||
|
|
||||||
@ -793,6 +798,7 @@ local function effect(
|
|||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- global function effect
|
||||||
function mobs:effect(
|
function mobs:effect(
|
||||||
pos, amount, texture, min_size, max_size, radius, gravity, glow, fall)
|
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
|
local CHILD_GROW_TIME = 60 * 20 -- 20 minutes
|
||||||
|
|
||||||
|
|
||||||
-- update nametag and infotext
|
-- function update_tag update nametag and infotext
|
||||||
function mob_class:update_tag()
|
function mob_class:update_tag()
|
||||||
|
|
||||||
local col
|
local col
|
||||||
@ -857,7 +863,7 @@ function mob_class:update_tag()
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
-- drop items
|
-- function item_drop drop items
|
||||||
function mob_class:item_drop()
|
function mob_class:item_drop()
|
||||||
|
|
||||||
-- no drops if disabled by setting or mob is child
|
-- no drops if disabled by setting or mob is child
|
||||||
@ -940,7 +946,7 @@ function mob_class:item_drop()
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
-- remove mob and descrease counter
|
-- TODO make object class function - remove mob and descrease counter
|
||||||
local function remove_mob(self, decrease)
|
local function remove_mob(self, decrease)
|
||||||
|
|
||||||
self.object:remove()
|
self.object:remove()
|
||||||
@ -961,7 +967,7 @@ function mobs:remove(self, decrease)
|
|||||||
end
|
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)
|
function mob_class:check_for_death(cmi_cause)
|
||||||
|
|
||||||
-- We dead already
|
-- We dead already
|
||||||
@ -1086,6 +1092,11 @@ local function node_ok(pos, fallback)
|
|||||||
return minetest.registered_nodes[(fallback or mobs.fallback_node)]
|
return minetest.registered_nodes[(fallback or mobs.fallback_node)]
|
||||||
end
|
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
|
-- Returns true is node can deal damage to self
|
||||||
function mobs:is_node_dangerous(mob_object, nodename)
|
function mobs:is_node_dangerous(mob_object, nodename)
|
||||||
@ -1117,7 +1128,7 @@ local function is_node_dangerous(mob_object, nodename)
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
-- is mob facing a cliff
|
-- function is_at_cliff is mob facing a cliff
|
||||||
function mob_class:is_at_cliff()
|
function mob_class:is_at_cliff()
|
||||||
|
|
||||||
if self.driver or self.fear_height == 0 then -- 0 for no falling protection!
|
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
|
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()
|
function mob_class:do_env_damage()
|
||||||
|
|
||||||
self:update_tag()
|
self:update_tag()
|
||||||
@ -1195,7 +1229,7 @@ function mob_class:do_env_damage()
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- lava damage
|
-- 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
|
self.health = self.health - self.lava_damage
|
||||||
|
|
||||||
@ -1300,7 +1334,7 @@ function mob_class:do_env_damage()
|
|||||||
end
|
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()
|
function mob_class:do_jump()
|
||||||
|
|
||||||
local vel = self.object:get_velocity() ; if not vel then return false end
|
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
|
end
|
||||||
|
|
||||||
|
|
||||||
-- should mob follow what I'm holding ?
|
-- function follow_holding should mob follow what I'm holding ?
|
||||||
function mob_class:follow_holding(clicker)
|
function mob_class:follow_holding(clicker)
|
||||||
|
|
||||||
if is_invisible(self, clicker:get_player_name()) then
|
if is_invisible(self, clicker:get_player_name()) then
|
||||||
@ -1434,7 +1468,7 @@ function mob_class:follow_holding(clicker)
|
|||||||
end
|
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()
|
function mob_class:breed()
|
||||||
|
|
||||||
-- child takes a long time before growing into adult
|
-- child takes a long time before growing into adult
|
||||||
@ -1542,8 +1576,8 @@ function mob_class:breed()
|
|||||||
local pos2 = ent.object:get_pos()
|
local pos2 = ent.object:get_pos()
|
||||||
|
|
||||||
-- Have mobs face one another
|
-- Have mobs face one another
|
||||||
yaw_to_pos(self, pos2)
|
self:yaw_to_pos(pos2)
|
||||||
yaw_to_pos(ent, self.object:get_pos())
|
ent:yaw_to_pos(self.object:get_pos())
|
||||||
|
|
||||||
self.hornytimer = HORNY_TIME + 1
|
self.hornytimer = HORNY_TIME + 1
|
||||||
ent.hornytimer = HORNY_TIME + 1
|
ent.hornytimer = HORNY_TIME + 1
|
||||||
@ -1638,7 +1672,7 @@ function mob_class:breed()
|
|||||||
end
|
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)
|
function mob_class:replace(pos)
|
||||||
|
|
||||||
local vel = self.object:get_velocity()
|
local vel = self.object:get_velocity()
|
||||||
@ -1695,7 +1729,7 @@ function mob_class:replace(pos)
|
|||||||
end
|
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()
|
function mob_class:day_docile()
|
||||||
|
|
||||||
if self.docile_by_day == false then
|
if self.docile_by_day == false then
|
||||||
@ -1750,6 +1784,7 @@ end
|
|||||||
|
|
||||||
local pathfinder_mod = minetest.get_modpath("pathfinder")
|
local pathfinder_mod = minetest.get_modpath("pathfinder")
|
||||||
|
|
||||||
|
-- function smart_mobs
|
||||||
-- path finding and smart mob routine by rnd,
|
-- path finding and smart mob routine by rnd,
|
||||||
-- line_of_sight and other edits by Elkien3
|
-- line_of_sight and other edits by Elkien3
|
||||||
function mob_class:smart_mobs(s, p, dist, dtime)
|
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
|
s.y = sground.y + 1
|
||||||
end
|
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.x = floor(p1.x + 0.5)
|
||||||
p1.y = floor(p1.y + 0.5)
|
p1.y = floor(p1.y + 0.5)
|
||||||
@ -1998,12 +2035,12 @@ end
|
|||||||
local function is_peaceful_player(player)
|
local function is_peaceful_player(player)
|
||||||
|
|
||||||
-- main setting enabled
|
-- main setting enabled
|
||||||
if peaceful_player_enabled and player:is_player() then
|
if is_player(player) then
|
||||||
|
|
||||||
local player_name = player:get_player_name()
|
local player_name = player:get_player_name()
|
||||||
|
|
||||||
-- player priv enabled
|
-- 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
|
return true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -2012,7 +2049,7 @@ local function is_peaceful_player(player)
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
-- general attack function for all mobs
|
-- function general_attack function for all mobs
|
||||||
function mob_class:general_attack()
|
function mob_class:general_attack()
|
||||||
|
|
||||||
-- return if already attacking, passive or docile during day
|
-- 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.attack_players == false
|
||||||
or (self.owner and self.type ~= "monster")
|
or (self.owner and self.type ~= "monster")
|
||||||
or is_invisible(self, objs[n]:get_player_name())
|
or is_invisible(self, objs[n]:get_player_name())
|
||||||
or (self.specific_attack
|
or (self.specific_attack and not check_for("player", self.specific_attack)) then
|
||||||
and not check_for("player", self.specific_attack)) then
|
|
||||||
objs[n] = nil
|
objs[n] = nil
|
||||||
--print("- pla", n)
|
--print("- pla", n)
|
||||||
end
|
end
|
||||||
@ -2052,10 +2088,8 @@ function mob_class:general_attack()
|
|||||||
-- monsters attack all creatura mobs, npc and animals will only attack
|
-- monsters attack all creatura mobs, npc and animals will only attack
|
||||||
-- if the animal owner is currently being attacked by creatura mob
|
-- if the animal owner is currently being attacked by creatura mob
|
||||||
if self.name == ent.name
|
if self.name == ent.name
|
||||||
or (self.type ~= "monster"
|
or (self.type ~= "monster" and self.owner ~= (ent._target and ent._target:get_player_name() or "."))
|
||||||
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.specific_attack
|
|
||||||
and not check_for(ent.name, self.specific_attack)) then
|
|
||||||
|
|
||||||
objs[n] = nil
|
objs[n] = nil
|
||||||
--print("-- creatura", ent.name)
|
--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_animals and ent.type == "animal")
|
||||||
or (not self.attack_monsters and ent.type == "monster")
|
or (not self.attack_monsters and ent.type == "monster")
|
||||||
or (not self.attack_npcs and ent.type == "npc")
|
or (not self.attack_npcs and ent.type == "npc")
|
||||||
or (self.specific_attack
|
or (self.specific_attack and not check_for(ent.name, self.specific_attack)) then
|
||||||
and not check_for(ent.name, self.specific_attack)) then
|
|
||||||
objs[n] = nil
|
objs[n] = nil
|
||||||
--print("- mob", n, self.name, ent.name)
|
--print("- mob", n, self.name, ent.name)
|
||||||
end
|
end
|
||||||
@ -2114,7 +2147,7 @@ function mob_class:general_attack()
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
-- find someone to runaway from
|
-- function do_runaway_from find someone to runaway from
|
||||||
function mob_class:do_runaway_from()
|
function mob_class:do_runaway_from()
|
||||||
|
|
||||||
if not self.runaway_from then
|
if not self.runaway_from then
|
||||||
@ -2174,7 +2207,7 @@ function mob_class:do_runaway_from()
|
|||||||
|
|
||||||
if min_player then
|
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.state = "runaway"
|
||||||
self.runaway_timer = 3
|
self.runaway_timer = 3
|
||||||
@ -2188,7 +2221,7 @@ function mob_class:do_runaway_from()
|
|||||||
|
|
||||||
if objs then
|
if objs then
|
||||||
|
|
||||||
yaw_to_pos(self, objs, 3)
|
self:yaw_to_pos(objs, 3)
|
||||||
|
|
||||||
self.state = "runaway"
|
self.state = "runaway"
|
||||||
self.runaway_timer = 3
|
self.runaway_timer = 3
|
||||||
@ -2197,7 +2230,7 @@ function mob_class:do_runaway_from()
|
|||||||
end
|
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()
|
function mob_class:follow_flop()
|
||||||
|
|
||||||
-- find player to follow
|
-- find player to follow
|
||||||
@ -2212,7 +2245,7 @@ function mob_class:follow_flop()
|
|||||||
for n = 1, #players do
|
for n = 1, #players do
|
||||||
|
|
||||||
if players[n] then
|
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())
|
if not is_invisible(self, players[n]:get_player_name())
|
||||||
and get_distance(players[n]:get_pos(), s) < self.view_range then
|
and get_distance(players[n]:get_pos(), s) < self.view_range then
|
||||||
self.following = players[n]
|
self.following = players[n]
|
||||||
@ -2236,7 +2269,7 @@ function mob_class:follow_flop()
|
|||||||
else
|
else
|
||||||
-- stop following player if not holding specific item or mob is horny
|
-- stop following player if not holding specific item or mob is horny
|
||||||
if self.following and is_player(self.following)
|
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
|
self.following = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -2262,7 +2295,7 @@ function mob_class:follow_flop()
|
|||||||
if dist > self.view_range then
|
if dist > self.view_range then
|
||||||
self.following = nil
|
self.following = nil
|
||||||
else
|
else
|
||||||
yaw_to_pos(self, p)
|
self:yaw_to_pos(p)
|
||||||
|
|
||||||
-- anyone but standing npc's can move along
|
-- anyone but standing npc's can move along
|
||||||
if dist >= self.reach
|
if dist >= self.reach
|
||||||
@ -2313,7 +2346,7 @@ function mob_class:follow_flop()
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
-- dogshoot attack switch and counter function
|
-- function dogswitch dogshoot attack switch and counter function
|
||||||
function mob_class:dogswitch(dtime)
|
function mob_class:dogswitch(dtime)
|
||||||
|
|
||||||
-- switch mode not activated
|
-- switch mode not activated
|
||||||
@ -2339,7 +2372,7 @@ function mob_class:dogswitch(dtime)
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
-- stop attack
|
-- function stop_attack
|
||||||
function mob_class:stop_attack()
|
function mob_class:stop_attack()
|
||||||
|
|
||||||
self.attack = nil
|
self.attack = nil
|
||||||
@ -2354,7 +2387,7 @@ function mob_class:stop_attack()
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
-- execute current state (stand, walk, run, attacks)
|
-- function do_states execute current state (stand, walk, run, attacks)
|
||||||
function mob_class:do_states(dtime)
|
function mob_class:do_states(dtime)
|
||||||
|
|
||||||
local yaw = self.object:get_yaw() ; if not yaw then return end
|
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
|
-- select position of random block to climb onto
|
||||||
lp = lp[random(#lp)]
|
lp = lp[random(#lp)]
|
||||||
|
|
||||||
yaw = yaw_to_pos(self, lp)
|
yaw = self:yaw_to_pos(lp)
|
||||||
end
|
end
|
||||||
|
|
||||||
self.pause_timer = 3
|
self.pause_timer = 3
|
||||||
@ -2418,7 +2451,7 @@ function mob_class:do_states(dtime)
|
|||||||
|
|
||||||
-- look at any players nearby, otherwise turn randomly
|
-- look at any players nearby, otherwise turn randomly
|
||||||
if lp then
|
if lp then
|
||||||
yaw = yaw_to_pos(self, lp)
|
yaw = self:yaw_to_pos(lp)
|
||||||
else
|
else
|
||||||
yaw = yaw + random(-0.5, 0.5)
|
yaw = yaw + random(-0.5, 0.5)
|
||||||
end
|
end
|
||||||
@ -2496,8 +2529,8 @@ function mob_class:do_states(dtime)
|
|||||||
|
|
||||||
self.runaway_timer = self.runaway_timer + 1
|
self.runaway_timer = self.runaway_timer + 1
|
||||||
|
|
||||||
-- stop after 5 seconds or when at cliff
|
-- 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 > 5
|
if self.runaway_timer > 4
|
||||||
or self.at_cliff
|
or self.at_cliff
|
||||||
or self.order == "stand" then
|
or self.order == "stand" then
|
||||||
self.runaway_timer = 0
|
self.runaway_timer = 0
|
||||||
@ -2523,17 +2556,11 @@ function mob_class:do_states(dtime)
|
|||||||
local dist = p and get_distance(p, s) or 500
|
local dist = p and get_distance(p, s) or 500
|
||||||
|
|
||||||
-- stop attacking if player out of range or invisible
|
-- stop attacking if player out of range or invisible
|
||||||
if dist > self.view_range
|
if dist > self.view_range and not self.attack and not is_player(self.attack) then
|
||||||
or not self.attack
|
if not self.attack:get_pos() or self.attack:get_hp() <= 0 and is_invisible(self, self.attack:get_player_name()) then
|
||||||
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
|
|
||||||
|
|
||||||
--print(" ** stop attacking **", self.name, self.health, dist, self.view_range)
|
--print(" ** stop attacking **", self.name, self.health, dist, self.view_range)
|
||||||
|
self:stop_attack()
|
||||||
self:stop_attack()
|
end
|
||||||
|
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -2556,7 +2583,7 @@ function mob_class:do_states(dtime)
|
|||||||
|
|
||||||
if self.attack_type == "explode" then
|
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 node_break_radius = self.explosion_radius or 1
|
||||||
local entity_damage_radius = self.explosion_damage_radius
|
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}
|
p = {x = p1.x, y = p1.y, z = p1.z}
|
||||||
end
|
end
|
||||||
|
|
||||||
yaw_to_pos(self, p)
|
self:yaw_to_pos(p)
|
||||||
|
|
||||||
-- move towards enemy if beyond mob reach
|
-- move towards enemy if beyond mob reach
|
||||||
if dist > (self.reach + (self.reach_ext or 0)) then
|
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}
|
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)
|
self:set_velocity(0)
|
||||||
|
|
||||||
@ -2846,7 +2873,7 @@ function mob_class:do_states(dtime)
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
-- falling and fall damage
|
-- function falling and fall damage
|
||||||
function mob_class:falling(pos)
|
function mob_class:falling(pos)
|
||||||
|
|
||||||
if self.fly or self.disable_falling then
|
if self.fly or self.disable_falling then
|
||||||
@ -2901,7 +2928,7 @@ end
|
|||||||
-- is Took Ranks mod active?
|
-- is Took Ranks mod active?
|
||||||
local tr = minetest.get_modpath("toolranks")
|
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)
|
function mob_class:on_punch(hitter, tflp, tool_capabilities, dir, damage)
|
||||||
|
|
||||||
-- mob health check
|
-- mob health check
|
||||||
@ -3147,7 +3174,7 @@ function mob_class:on_punch(hitter, tflp, tool_capabilities, dir, damage)
|
|||||||
|
|
||||||
local lp = hitter:get_pos()
|
local lp = hitter:get_pos()
|
||||||
|
|
||||||
yaw_to_pos(self, lp, 3)
|
self:yaw_to_pos(lp, 3)
|
||||||
|
|
||||||
self.state = "runaway"
|
self.state = "runaway"
|
||||||
self.runaway_timer = 0
|
self.runaway_timer = 0
|
||||||
@ -3222,7 +3249,7 @@ local function clean_staticdata(self)
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
-- get entity staticdata
|
-- function mob_staticdata get entity staticdata
|
||||||
function mob_class:mob_staticdata()
|
function mob_class:mob_staticdata()
|
||||||
|
|
||||||
-- this handles mob count for mobs activated, unloaded, reloaded
|
-- this handles mob count for mobs activated, unloaded, reloaded
|
||||||
@ -3287,7 +3314,7 @@ function mob_class:mob_staticdata()
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
-- activate mob and reload settings
|
-- function mob_activate activate mob and reload settings
|
||||||
function mob_class:mob_activate(staticdata, def, dtime)
|
function mob_class:mob_activate(staticdata, def, dtime)
|
||||||
|
|
||||||
-- if dtime == 0 then entity has just been created
|
-- if dtime == 0 then entity has just been created
|
||||||
@ -3459,7 +3486,7 @@ function mob_class:mob_activate(staticdata, def, dtime)
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
-- handle mob lifetimer and expiration
|
-- function mob_expire handle mob lifetimer and expiration
|
||||||
function mob_class:mob_expire(pos, dtime)
|
function mob_class:mob_expire(pos, dtime)
|
||||||
|
|
||||||
-- when lifetimer expires remove mob (except npc and tamed)
|
-- when lifetimer expires remove mob (except npc and tamed)
|
||||||
@ -3498,7 +3525,7 @@ function mob_class:mob_expire(pos, dtime)
|
|||||||
end
|
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()
|
function mob_class:get_nodes()
|
||||||
|
|
||||||
local pos = self.object:get_pos()
|
local pos = self.object:get_pos()
|
||||||
@ -3542,7 +3569,7 @@ print("on: " .. self.standing_on
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
-- main mob function
|
-- function on_step main mob function
|
||||||
function mob_class:on_step(dtime, moveresult)
|
function mob_class:on_step(dtime, moveresult)
|
||||||
|
|
||||||
if self.state == "die" then return end
|
if self.state == "die" then return end
|
||||||
@ -3698,7 +3725,7 @@ function mob_class:on_step(dtime, moveresult)
|
|||||||
end
|
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)
|
function mob_class:on_blast(damage)
|
||||||
|
|
||||||
--print("-- blast damage", damage)
|
--print("-- blast damage", damage)
|
||||||
@ -3782,6 +3809,7 @@ minetest.register_entity(name, setmetatable({
|
|||||||
walk_chance = def.walk_chance,
|
walk_chance = def.walk_chance,
|
||||||
stand_chance = def.stand_chance,
|
stand_chance = def.stand_chance,
|
||||||
attack_chance = def.attack_chance,
|
attack_chance = def.attack_chance,
|
||||||
|
attack_patience = def.attack_patience,
|
||||||
passive = def.passive,
|
passive = def.passive,
|
||||||
knock_back = def.knock_back,
|
knock_back = def.knock_back,
|
||||||
blood_amount = def.blood_amount,
|
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)
|
effect(pos, 15, "tnt_smoke.png", 1, 2, 2, 15, 5)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- use new texture if found
|
||||||
|
local new_texture = def.texture or ent.base_texture
|
||||||
|
|
||||||
if def.child then
|
if def.child then
|
||||||
|
|
||||||
|
ent.mommy_tex = new_texture -- how baby looks when grown
|
||||||
|
ent.base_texture = new_texture
|
||||||
local textures = ent.base_texture
|
local textures = ent.base_texture
|
||||||
|
|
||||||
-- using specific child texture (if found)
|
-- using specific child texture (if found)
|
||||||
@ -4020,6 +4053,12 @@ function mobs:add_mob(pos, def)
|
|||||||
})
|
})
|
||||||
|
|
||||||
ent.child = true
|
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
|
end
|
||||||
|
|
||||||
if def.owner then
|
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)
|
pos, node, active_object_count, active_object_count_wider)
|
||||||
|
|
||||||
-- use instead of abm's chance setting when using lbm
|
-- 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
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -4190,6 +4229,11 @@ function mobs:spawn_specific(name, nodes, neighbors, min_light, max_light, inter
|
|||||||
|
|
||||||
local ent = minetest.registered_entities[name]
|
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 ?
|
-- should we check mob area for obstructions ?
|
||||||
if mob_area_spawn ~= true then
|
if mob_area_spawn ~= true then
|
||||||
|
|
||||||
@ -4257,7 +4301,7 @@ function mobs:spawn_specific(name, nodes, neighbors, min_light, max_light, inter
|
|||||||
nodenames = nodes,
|
nodenames = nodes,
|
||||||
neighbors = neighbors,
|
neighbors = neighbors,
|
||||||
interval = interval,
|
interval = interval,
|
||||||
chance = max(1, (chance * mob_chance_multiplier)),
|
chance = max(1, (chance * (mob_chance_multiplier/10))),
|
||||||
catch_up = false,
|
catch_up = false,
|
||||||
|
|
||||||
action = function(pos, node, active_object_count, active_object_count_wider)
|
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)"
|
"^[mask:mobs_chicken_egg_overlay.png)"
|
||||||
end
|
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)
|
-- register new spawn egg containing mob information (cannot be stacked)
|
||||||
minetest.register_craftitem(mob .. "_set", {
|
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)
|
pointed_thing.under, under, placer, itemstack, pointed_thing)
|
||||||
end
|
end
|
||||||
|
|
||||||
if pos
|
if pos and not minetest.is_protected(pos, placer:get_player_name()) then
|
||||||
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
|
return
|
||||||
end
|
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 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
|
-- have we reached active mob limit
|
||||||
if active_limit > 0 and active_mobs >= active_limit then
|
if active_limit > 0 and active_mobs >= active_limit then
|
||||||
minetest.chat_send_player(placer:get_player_name(),
|
if is_player(placer) then
|
||||||
S("Active Mob Limit Reached!")
|
minetest.chat_send_player(placer:get_player_name(),
|
||||||
.. " (" .. active_mobs
|
S("Active Mob Limit Reached!")
|
||||||
.. " / " .. active_limit .. ")")
|
.. " (" .. active_mobs
|
||||||
|
.. " / " .. active_limit .. ")")
|
||||||
|
end
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -4786,7 +4843,7 @@ function mobs:protect(self, clicker)
|
|||||||
|
|
||||||
pos.y = pos.y + self.collisionbox[2] + 0.5
|
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")
|
self:mob_sound("mobs_spell")
|
||||||
|
|
||||||
|
@ -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
|
hours and only attacking player at night or when
|
||||||
provoked.
|
provoked.
|
||||||
'attack_chance' 0 to 100 chance the mob will attack (default is 5).
|
'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_monsters' when true mob will attack monsters.
|
||||||
'attack_animals' when true mob will attack animals.
|
'attack_animals' when true mob will attack animals.
|
||||||
'attack_npcs' when true mob will attack npcs within range.
|
'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"
|
'self.facing_fence' True if mob facing node containing "wall", "fence", "gate"
|
||||||
in it's name.
|
in it's name.
|
||||||
|
|
||||||
|
|
||||||
Internal Functions
|
Internal Functions
|
||||||
------------------
|
------------------
|
||||||
|
|
||||||
Each mob contains a set of functions that can be called for use internally or from
|
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:
|
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: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
|
Adding Mobs in World
|
||||||
|
@ -32,6 +32,25 @@ the tenplus1 only works in last minetest, admins will not wants to constant upgr
|
|||||||
|
|
||||||
## Changelog
|
## 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
|
### Version 1.57
|
||||||
|
|
||||||
* Added 'injured' animation when mob hurt
|
* Added 'injured' animation when mob hurt
|
||||||
|
Binary file not shown.
Before Width: | Height: | Size: 184 B |
Loading…
x
Reference in New Issue
Block a user