Optimized code

master
TenPlus1 2015-10-12 19:14:36 +01:00
parent 8c57ef83c3
commit 7b868a73ed
2 changed files with 379 additions and 366 deletions

744
api.lua
View File

@ -2,8 +2,6 @@
mobs = {}
mobs.mod = "redo"
local pi = math.pi
-- Load settings
local damage_enabled = minetest.setting_getbool("enable_damage")
local peaceful_only = minetest.setting_getbool("only_peaceful_mobs")
@ -11,9 +9,345 @@ local disable_blood = minetest.setting_getbool("mobs_disable_blood")
mobs.protected = tonumber(minetest.setting_get("mobs_spawn_protected")) or 1
mobs.remove = minetest.setting_getbool("remove_far_mobs")
-- internal functions
local pi = math.pi
local do_attack = function(self, player)
if self.state ~= "attack" then
if math.random(0,100) < 90
and self.sounds.war_cry then
minetest.sound_play(self.sounds.war_cry,{
object = self.object,
max_hear_distance = self.sounds.distance
})
end
self.state = "attack"
self.attack = player
end
end
local set_velocity = function(self, v)
v = (v or 0)
if self.drawtype
and self.drawtype == "side" then
self.rotate = math.rad(90)
end
local yaw = self.object:getyaw() + self.rotate
local x = math.sin(yaw) * -v
local z = math.cos(yaw) * v
self.object:setvelocity({
x = x,
y = self.object:getvelocity().y,
z = z
})
end
local get_velocity = function(self)
local v = self.object:getvelocity()
return (v.x ^ 2 + v.z ^ 2) ^ (0.5)
end
local set_animation2 = function(self, type)
if not self.animation then
return
end
if not self.animation.current then
self.animation.current = ""
end
if type == "stand"
and self.animation.current ~= "stand" then
if self.animation.stand_start
and self.animation.stand_end
and self.animation.speed_normal then
self.object:set_animation({
x = self.animation.stand_start,
y = self.animation.stand_end},
self.animation.speed_normal, 0)
self.animation.current = "stand"
end
elseif type == "walk"
and self.animation.current ~= "walk" then
if self.animation.walk_start
and self.animation.walk_end
and self.animation.speed_normal then
self.object:set_animation({
x = self.animation.walk_start,
y = self.animation.walk_end},
self.animation.speed_normal, 0)
self.animation.current = "walk"
end
elseif type == "run"
and self.animation.current ~= "run" then
if self.animation.run_start
and self.animation.run_end
and self.animation.speed_run then
self.object:set_animation({
x = self.animation.run_start,
y = self.animation.run_end},
self.animation.speed_run, 0)
self.animation.current = "run"
end
elseif type == "punch"
and self.animation.current ~= "punch" then
if self.animation.punch_start
and self.animation.punch_end
and self.animation.speed_normal then
self.object:set_animation({
x = self.animation.punch_start,
y = self.animation.punch_end},
self.animation.speed_normal, 0)
self.animation.current = "punch"
end
end
end
local do_env_damage = function(self)
-- feed/tame text timer
if self.htimer > 0 then
self.htimer = self.htimer - 1
end
local pos = self.object:getpos()
local tod = minetest.get_timeofday()
-- daylight above ground
if self.light_damage ~= 0
and pos.y > 0
and tod > 0.2
and tod < 0.8
and (minetest.get_node_light(pos) or 0) > 12 then
self.object:set_hp(self.object:get_hp() - self.light_damage)
effect(pos, 5, "tnt_smoke.png")
if check_for_death(self) then return end
end
if self.water_damage ~= 0 or self.lava_damage ~= 0 then
pos.y = (pos.y + self.collisionbox[2]) + 0.1 -- foot level
local nod = node_ok(pos, "air") ; -- print ("standing in "..nod.name)
local nodef = minetest.registered_nodes[nod.name]
pos.y = pos.y + 1
-- water
if self.water_damage ~= 0
and nodef.groups.water then
self.object:set_hp(self.object:get_hp() - self.water_damage)
effect(pos, 5, "bubble.png")
if check_for_death(self) then return end
end
-- lava or fire
if self.lava_damage ~= 0
and (nodef.groups.lava
or nod.name == "fire:basic_flame"
or nod.name == "fire:eternal_flame") then
self.object:set_hp(self.object:get_hp() - self.lava_damage)
effect(pos, 5, "fire_basic_flame.png")
if check_for_death(self) then return end
end
end
end
local do_jump = function(self)
if self.fly then
return
end
local pos = self.object:getpos()
pos.y = (pos.y + self.collisionbox[2]) - 0.2
local nod = node_ok(pos)
--print ("standing on:", nod.name, pos.y)
if minetest.registered_nodes[nod.name].walkable == false then
return
end
if self.direction then
pos.y = pos.y + 0.5
local nod = node_ok({
x = pos.x + self.direction.x,
y = pos.y,
z = pos.z + self.direction.z
})
--print ("in front:", nod.name, pos.y)
if nod.name ~= "air"
and minetest.registered_items[nod.name].walkable
and not nod.name:find("fence")
or self.walk_chance == 0 then
local v = self.object:getvelocity()
v.y = self.jump_height + 1
v.x = v.x * 2.2
v.z = v.z * 2.2
self.object:setvelocity(v)
if self.sounds.jump then
minetest.sound_play(self.sounds.jump, {
object = self.object,
max_hear_distance = self.sounds.distance
})
end
end
end
end
local in_fov = function(self, pos)
-- checks if POS is in mobs field of view
local yaw = self.object:getyaw() + self.rotate
local vx = math.sin(yaw)
local vz = math.cos(yaw)
local ds = math.sqrt(vx ^ 2 + vz ^ 2)
local ps = math.sqrt(pos.x ^ 2 + pos.z ^ 2)
local d = {x = vx / ds, z = vz / ds}
local p = {x = pos.x / ps, z = pos.z / ps}
local an = (d.x * p.x) + (d.z * p.z)
if math.deg(math.acos(an)) > (self.fov / 2) then
return false
end
return true
end
-- particle effects
function effect(pos, amount, texture, max_size)
minetest.add_particlespawner({
amount = amount,
time = 0.25,
minpos = pos,
maxpos = pos,
minvel = {x = -0, y = -2, z = -0},
maxvel = {x = 2, y = 2, z = 2},
minacc = {x = -4, y = -4, z = -4},
maxacc = {x = 4, y = 4, z = 4},
minexptime = 0.1,
maxexptime = 1,
minsize = 0.5,
maxsize = (max_size or 1),
texture = texture,
})
end
-- on mob death drop items
function check_for_death(self)
local hp = self.object:get_hp()
if hp > 0 then
self.health = hp
if self.sounds.damage ~= nil then
minetest.sound_play(self.sounds.damage,{
object = self.object,
max_hear_distance = self.sounds.distance
})
end
return false
end
local pos = self.object:getpos()
local obj = nil
for _,drop in ipairs(self.drops) do
if math.random(1, drop.chance) == 1 then
obj = minetest.add_item(pos,
ItemStack(drop.name.." "..math.random(drop.min, drop.max)))
if obj then
obj:setvelocity({
x = math.random(-1, 1),
y = 6,
z = math.random(-1, 1)
})
end
end
end
if self.sounds.death ~= nil then
minetest.sound_play(self.sounds.death,{
object = self.object,
max_hear_distance = self.sounds.distance
})
end
if self.on_die then
self.on_die(self, pos)
end
self.object:remove()
return true
end
-- from TNT mod
function calc_velocity(pos1, pos2, old_vel, power)
local vel = vector.direction(pos1, pos2)
vel = vector.normalize(vel)
vel = vector.multiply(vel, power)
local dist = vector.distance(pos1, pos2)
dist = math.max(dist, 1)
vel = vector.divide(vel, dist)
vel = vector.add(vel, old_vel)
return vel
end
-- modified from TNT mod
function entity_physics(pos, radius)
radius = radius * 2
local objs = minetest.get_objects_inside_radius(pos, radius)
local obj_pos, obj_vel, dist
for _, obj in pairs(objs) do
obj_pos = obj:getpos()
obj_vel = obj:getvelocity()
dist = math.max(1, vector.distance(pos, obj_pos))
if obj_vel ~= nil then
obj:setvelocity(calc_velocity(pos, obj_pos, obj_vel, radius * 10))
end
local damage = math.floor((4 / dist) * radius)
obj:set_hp(obj:get_hp() - damage)
end
end
-- check if within map limits (-30911 to 30927)
function within_limits(pos, radius)
if (pos.x - radius) > -30913
and (pos.x + radius) < 30928
and (pos.y - radius) > -30913
and (pos.y + radius) < 30928
and (pos.z - radius) > -30913
and (pos.z + radius) < 30928 then
return true -- within limits
end
return false -- beyond limits
end
-- get node at location but with fallback for nil or unknown
function node_ok(pos, fallback)
fallback = fallback or "default:dirt"
local node = minetest.get_node_or_nil(pos)
if not node then
return minetest.registered_nodes[fallback]
end
local nodef = minetest.registered_nodes[node.name]
if nodef then
return node
end
return minetest.registered_nodes[fallback]
end
-- should mob follow what I'm holding ?
function follow_holding(self, clicker)
local item = clicker:get_wielded_item()
local t = type(self.follow)
-- single item
if t == "string"
and item:get_name() == self.follow then
return true
-- multiple items
elseif t == "table" then
for no = 1, #self.follow do
if self.follow[no] == item:get_name() then
return true
end
end
end
return false
end
-- register mob function
function mobs:register_mob(name, def)
minetest.register_entity(name, {
stepheight = def.stepheight or 0.6,
name = name,
fly = def.fly,
@ -24,6 +358,7 @@ minetest.register_entity(name, {
do_custom = def.do_custom,
jump_height = def.jump_height or 6,
jump_chance = def.jump_chance or 0,
drawtype = def.drawtype, -- DEPRECATED, use rotate instead
rotate = math.rad(def.rotate or 0), -- 0=front, 90=side, 180=back, 270=side2
lifetimer = def.lifetimer or 180, -- 3 minutes
hp_min = def.hp_min or 5,
@ -83,111 +418,6 @@ minetest.register_entity(name, {
reach = def.reach or 3,
htimer = 0,
do_attack = function(self, player)
if self.state ~= "attack" then
if math.random(0,100) < 90
and self.sounds.war_cry then
minetest.sound_play(self.sounds.war_cry,{
object = self.object,
max_hear_distance = self.sounds.distance
})
end
self.state = "attack"
self.attack = player
end
end,
set_velocity = function(self, v)
v = (v or 0)
if def.drawtype
and def.drawtype == "side" then
self.rotate = math.rad(90)
end
local yaw = self.object:getyaw() + self.rotate
local x = math.sin(yaw) * -v
local z = math.cos(yaw) * v
self.object:setvelocity({
x = x,
y = self.object:getvelocity().y,
z = z}
)
end,
get_velocity = function(self)
local v = self.object:getvelocity()
return (v.x ^ 2 + v.z ^ 2) ^ (0.5)
end,
--[[
in_fov = function(self, pos)
-- checks if POS is in self's FOV
local yaw = self.object:getyaw() + self.rotate
local vx = math.sin(yaw)
local vz = math.cos(yaw)
local ds = math.sqrt(vx ^ 2 + vz ^ 2)
local ps = math.sqrt(pos.x ^ 2 + pos.z ^ 2)
local d = {x = vx / ds, z = vz / ds}
local p = {x = pos.x / ps, z = pos.z / ps}
local an = (d.x * p.x) + (d.z * p.z)
if math.deg(math.acos(an)) > (self.fov / 2) then
return false
end
return true
end,
]]
set_animation = function(self, type)
if not self.animation then
return
end
if not self.animation.current then
self.animation.current = ""
end
if type == "stand"
and self.animation.current ~= "stand" then
if self.animation.stand_start
and self.animation.stand_end
and self.animation.speed_normal then
self.object:set_animation({
x = self.animation.stand_start,
y = self.animation.stand_end},
self.animation.speed_normal, 0)
self.animation.current = "stand"
end
elseif type == "walk"
and self.animation.current ~= "walk" then
if self.animation.walk_start
and self.animation.walk_end
and self.animation.speed_normal then
self.object:set_animation({
x = self.animation.walk_start,
y = self.animation.walk_end},
self.animation.speed_normal, 0)
self.animation.current = "walk"
end
elseif type == "run"
and self.animation.current ~= "run" then
if self.animation.run_start
and self.animation.run_end
and self.animation.speed_run then
self.object:set_animation({
x = self.animation.run_start,
y = self.animation.run_end},
self.animation.speed_run, 0)
self.animation.current = "run"
end
elseif type == "punch"
and self.animation.current ~= "punch" then
if self.animation.punch_start
and self.animation.punch_end
and self.animation.speed_normal then
self.object:set_animation({
x = self.animation.punch_start,
y = self.animation.punch_end},
self.animation.speed_normal, 0)
self.animation.current = "punch"
end
end
end,
on_step = function(self, dtime)
-- remove monsters if playing on peaceful
@ -301,89 +531,6 @@ minetest.register_entity(name, {
})
end
local do_env_damage = function(self)
if self.htimer > 0 then
self.htimer = self.htimer - 1
end
local pos = self.object:getpos()
local tod = minetest.get_timeofday()
-- daylight above ground
if self.light_damage ~= 0
and pos.y > 0
and tod > 0.2
and tod < 0.8
and (minetest.get_node_light(pos) or 0) > 12 then
self.object:set_hp(self.object:get_hp() - self.light_damage)
effect(pos, 5, "tnt_smoke.png")
if check_for_death(self) then return end
end
if self.water_damage ~= 0 or self.lava_damage ~= 0 then
pos.y = (pos.y + self.collisionbox[2]) + 0.1 -- foot level
local nod = node_ok(pos, "air") ; -- print ("standing in "..nod.name)
local nodef = minetest.registered_nodes[nod.name]
pos.y = pos.y + 1
-- water
if self.water_damage ~= 0
and nodef.groups.water then
self.object:set_hp(self.object:get_hp() - self.water_damage)
effect(pos, 5, "bubble.png")
if check_for_death(self) then return end
end
-- lava or fire
if self.lava_damage ~= 0
and (nodef.groups.lava
or nod.name == "fire:basic_flame"
or nod.name == "fire:eternal_flame") then
self.object:set_hp(self.object:get_hp() - self.lava_damage)
effect(pos, 5, "fire_basic_flame.png")
if check_for_death(self) then return end
end
end
end
local do_jump = function(self)
if self.fly then
return
end
local pos = self.object:getpos()
pos.y = (pos.y + self.collisionbox[2]) - 0.2
local nod = node_ok(pos)
--print ("standing on:", nod.name, pos.y)
if minetest.registered_nodes[nod.name].walkable == false then
return
end
if self.direction then
pos.y = pos.y + 0.5
local nod = node_ok({
x = pos.x + self.direction.x,
y = pos.y,
z = pos.z + self.direction.z
})
--print ("in front:", nod.name, pos.y)
if nod.name ~= "air"
and minetest.registered_items[nod.name].walkable
and not nod.name:find("fence")
or self.walk_chance == 0 then
local v = self.object:getvelocity()
v.y = self.jump_height + 1
v.x = v.x * 2.2
v.z = v.z * 2.2
self.object:setvelocity(v)
if self.sounds.jump then
minetest.sound_play(self.sounds.jump, {
object = self.object,
max_hear_distance = self.sounds.distance
})
end
end
end
end
-- environmental damage timer (every 1 second)
self.env_damage_timer = self.env_damage_timer + dtime
if self.state == "attack"
@ -449,7 +596,7 @@ end
end
-- attack player
if min_player then
self.do_attack(self, min_player)
do_attack(self, min_player)
end
end
@ -476,7 +623,7 @@ end
end
end
if min_player then
self.do_attack(self, min_player)
do_attack(self, min_player)
end
end
@ -506,8 +653,9 @@ end
})
-- jump when grown so not to fall into ground
local v = self.object:getvelocity()
v.x = 0
v.y = self.jump_height
v.x = 0 ; v.z = 0
v.z = 0
self.object:setvelocity(v)
end
end
@ -650,7 +798,7 @@ end
if dist > self.reach
and self.order ~= "stand" then
if (self.jump
and self.get_velocity(self) <= 0.5
and get_velocity(self) <= 0.5
and self.object:getvelocity().y == 0)
or (self.object:getvelocity().y == 0
and self.jump_chance > 0) then
@ -661,13 +809,14 @@ end
}
do_jump(self)
end
self.set_velocity(self, self.walk_velocity)
set_velocity(self, self.walk_velocity)
if self.walk_chance ~= 0 then
self:set_animation("walk")
--self:set_animation("walk")
set_animation2(self, "walk")
end
else
self.set_velocity(self, 0)
self:set_animation("stand")
set_velocity(self, 0)
set_animation2(self, "stand")
end
return
end
@ -704,21 +853,21 @@ end
self.object:setyaw(yaw)
end
self.set_velocity(self, 0)
self.set_animation(self, "stand")
set_velocity(self, 0)
set_animation2(self, "stand")
-- npc's ordered to stand stay standing
if self.type == "npc"
and self.order == "stand" then
self.set_velocity(self, 0)
set_velocity(self, 0)
self.state = "stand"
self:set_animation("stand")
set_animation2(self, "stand")
else
if self.walk_chance ~= 0
and math.random(1, 100) <= self.walk_chance then
self.set_velocity(self, self.walk_velocity)
set_velocity(self, self.walk_velocity)
self.state = "walk"
self.set_animation(self, "walk")
set_animation2(self, "walk")
end
end
@ -731,10 +880,10 @@ end
and self.fly_in == "default:water_source"
and not lp then
print ("out of water")
self.set_velocity(self, 0)
set_velocity(self, 0)
-- change to undefined state so nothing more happens
self.state = "flop"
self:set_animation("stand")
set_animation2(self, "stand")
return
end
@ -752,7 +901,7 @@ end
end
-- jump when walking comes to a halt
if self.jump and self.get_velocity(self) <= 0.5
if self.jump and get_velocity(self) <= 0.5
and self.object:getvelocity().y == 0 then
self.direction = {
x = math.sin(yaw) * -1,
@ -762,12 +911,12 @@ end
do_jump(self)
end
self:set_animation("walk")
self.set_velocity(self, self.walk_velocity)
set_velocity(self, self.walk_velocity)
set_animation2(self, "walk")
if math.random(1, 100) <= 30 then
self.set_velocity(self, 0)
set_velocity(self, 0)
self.state = "stand"
self:set_animation("stand")
set_animation2(self, "stand")
end
-- attack routines (explode, dogfight, shoot, dogshoot)
@ -785,8 +934,8 @@ end
or self.attack:get_hp() <= 0 then
--print(" ** stop attacking **", dist, self.view_range)
self.state = "stand"
self.set_velocity(self, 0)
self:set_animation("stand")
set_velocity(self, 0)
set_animation2(self, "stand")
self.attack = nil
self.v_start = false
self.timer = 0
@ -806,23 +955,23 @@ end
if dist > self.reach then
if not self.v_start then
self.v_start = true
self.set_velocity(self, self.run_velocity)
set_velocity(self, self.run_velocity)
self.timer = 0
self.blinktimer = 0
else
self.timer = 0
self.blinktimer = 0
if self.get_velocity(self) <= 0.5
if get_velocity(self) <= 0.5
and self.object:getvelocity().y == 0 then
local v = self.object:getvelocity()
v.y = 5
self.object:setvelocity(v)
end
self.set_velocity(self, self.run_velocity)
set_velocity(self, self.run_velocity)
end
self:set_animation("run")
set_animation2(self, "run")
else
self.set_velocity(self, 0)
set_velocity(self, 0)
self.timer = self.timer + dtime
self.blinktimer = (self.blinktimer or 0) + dtime
if self.blinktimer > 0.2 then
@ -916,7 +1065,7 @@ end
if dist > self.reach then
-- jump attack
if (self.jump
and self.get_velocity(self) <= 0.5
and get_velocity(self) <= 0.5
and self.object:getvelocity().y == 0)
or (self.object:getvelocity().y == 0
and self.jump_chance > 0) then
@ -927,11 +1076,11 @@ end
}
do_jump(self)
end
self.set_velocity(self, self.run_velocity)
self:set_animation("run")
set_velocity(self, self.run_velocity)
set_animation2(self, "run")
else
self.set_velocity(self, 0)
self:set_animation("punch")
set_velocity(self, 0)
set_animation2(self, "punch")
if self.timer > 1 then
self.timer = 0
local p2 = p
@ -968,13 +1117,13 @@ end
yaw = yaw + pi
end
self.object:setyaw(yaw)
self.set_velocity(self, 0)
set_velocity(self, 0)
if self.shoot_interval
and self.timer > self.shoot_interval
and math.random(1, 100) <= 60 then
self.timer = 0
self:set_animation("punch")
set_animation2(self, "punch")
-- play shoot attack sound
if self.sounds.shoot_attack then
@ -1072,8 +1221,6 @@ end
self.object:set_hp(self.health)
self.object:set_armor_groups({fleshy = self.armor})
--self.state = "stand"
--self.following = nil
self.old_y = self.object:getpos().y
self.object:setyaw(math.random(1, 360) / 180 * pi)
self.sounds.distance = (self.sounds.distance or 10)
@ -1171,7 +1318,7 @@ end
if self.passive == false
and not self.tamed then
if self.state ~= "attack" then
self.do_attack(self, hitter)
do_attack(self, hitter)
end
-- alert others to the attack
local obj = nil
@ -1180,7 +1327,7 @@ end
if obj then
if obj.group_attack == true
and obj.state ~= "attack" then
obj.do_attack(obj, hitter)
do_attack(obj, hitter)
end
end
end
@ -1190,6 +1337,8 @@ end
end -- END mobs:register_mob function
-- global functions
mobs.spawning_mobs = {}
function mobs:spawn_specific(name, nodes, neighbors, min_light, max_light, interval, chance, active_object_count, min_height, max_height)
@ -1252,25 +1401,6 @@ function mobs:register_spawn(name, nodes, max_light, min_light, chance, active_o
mobs:spawn_specific(name, nodes, {"air"}, min_light, max_light, 30, chance, active_object_count, -31000, max_height)
end
-- particle effects
function effect(pos, amount, texture, max_size)
minetest.add_particlespawner({
amount = amount,
time = 0.25,
minpos = pos,
maxpos = pos,
minvel = {x = -0, y = -2, z = -0},
maxvel = {x = 2, y = 2, z = 2},
minacc = {x = -4, y = -4, z = -4},
maxacc = {x = 4, y = 4, z = 4},
minexptime = 0.1,
maxexptime = 1,
minsize = 0.5,
maxsize = (max_size or 1),
texture = texture,
})
end
-- explosion
function mobs:explosion(pos, radius, fire, smoke, sound)
-- node hit, bursts into flame (cannot blast through unbreakable/specific nodes)
@ -1349,76 +1479,6 @@ function mobs:explosion(pos, radius, fire, smoke, sound)
end
end
-- on mob death drop items
function check_for_death(self)
local hp = self.object:get_hp()
if hp > 0 then
self.health = hp
if self.sounds.damage ~= nil then
minetest.sound_play(self.sounds.damage,{
object = self.object,
max_hear_distance = self.sounds.distance
})
end
return false
end
local pos = self.object:getpos()
local obj = nil
for _,drop in ipairs(self.drops) do
if math.random(1, drop.chance) == 1 then
obj = minetest.add_item(pos,
ItemStack(drop.name.." "..math.random(drop.min, drop.max)))
if obj then
obj:setvelocity({
x = math.random(-1, 1),
y = 6,
z = math.random(-1, 1)
})
end
end
end
if self.sounds.death ~= nil then
minetest.sound_play(self.sounds.death,{
object = self.object,
max_hear_distance = self.sounds.distance
})
end
if self.on_die then
self.on_die(self, pos)
end
self.object:remove()
return true
end
-- from TNT mod
function calc_velocity(pos1, pos2, old_vel, power)
local vel = vector.direction(pos1, pos2)
vel = vector.normalize(vel)
vel = vector.multiply(vel, power)
local dist = vector.distance(pos1, pos2)
dist = math.max(dist, 1)
vel = vector.divide(vel, dist)
vel = vector.add(vel, old_vel)
return vel
end
-- modified from TNT mod
function entity_physics(pos, radius)
radius = radius * 2
local objs = minetest.get_objects_inside_radius(pos, radius)
local obj_pos, obj_vel, dist
for _, obj in pairs(objs) do
obj_pos = obj:getpos()
obj_vel = obj:getvelocity()
dist = math.max(1, vector.distance(pos, obj_pos))
if obj_vel ~= nil then
obj:setvelocity(calc_velocity(pos, obj_pos, obj_vel, radius * 10))
end
local damage = math.floor((4 / dist) * radius)
obj:set_hp(obj:get_hp() - damage)
end
end
-- register arrow for shoot attack
function mobs:register_arrow(name, def)
if not name or not def then return end -- errorcheck
@ -1569,28 +1629,6 @@ function mobs:capture_mob(self, clicker, chance_hand, chance_net, chance_lasso,
end
end
-- should mob follow what I'm holding ?
function follow_holding(self, clicker)
local item = clicker:get_wielded_item()
local t = type(self.follow)
-- single item
if t == "string"
and item:get_name() == self.follow then
return true
-- multiple items
elseif t == "table" then
for no = 1, #self.follow do
if self.follow[no] == item:get_name() then
return true
end
end
end
return false
end
-- feeding, taming and breeding (thanks blert2112)
function mobs:feed_tame(self, clicker, feed_count, breed, tame)
@ -1654,29 +1692,3 @@ function mobs:feed_tame(self, clicker, feed_count, breed, tame)
return false
end
end
-- check if within map limits (-30911 to 30927)
function within_limits(pos, radius)
if (pos.x - radius) > -30913
and (pos.x + radius) < 30928
and (pos.y - radius) > -30913
and (pos.y + radius) < 30928
and (pos.z - radius) > -30913
and (pos.z + radius) < 30928 then
return true -- within limits
end
return false -- beyond limits
end
function node_ok(pos, fallback)
fallback = fallback or "default:dirt"
local node = minetest.get_node_or_nil(pos)
if not node then
return minetest.registered_nodes[fallback]
end
local nodef = minetest.registered_nodes[node.name]
if nodef then
return node
end
return minetest.registered_nodes[fallback]
end

View File

@ -5,6 +5,7 @@ mobs:register_mob("mobs:pumba", {
type = "animal",
passive = false,
attack_type = "dogfight",
group_attack = true,
reach = 2,
damage = 2,
hp_min = 5,