Tweak and Tidy code

master
TenPlus1 2015-07-10 19:09:08 +01:00
parent b353311995
commit 4f890f6a49
1 changed files with 289 additions and 127 deletions

416
api.lua
View File

@ -79,7 +79,8 @@ function mobs:register_mob(name, def)
do_attack = function(self, player, dist)
if self.state ~= "attack" then
if math.random(0,100) < 90 and self.sounds.war_cry 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
@ -92,8 +93,11 @@ function mobs:register_mob(name, def)
end,
set_velocity = function(self, v)
if not v then v = 0 end
if def.drawtype and def.drawtype == "side" then self.rotate = 1.5 end
v = (v or 0)
if def.drawtype
and def.drawtype == "side" then
self.rotate = 1.5
end
local yaw = self.object:getyaw() + self.rotate
local x = math.sin(yaw) * -v
local z = math.cos(yaw) * v
@ -132,28 +136,48 @@ function mobs:register_mob(name, def)
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)
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)
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)
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)
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
@ -161,15 +185,18 @@ function mobs:register_mob(name, def)
on_step = function(self, dtime)
if self.type == "monster" and peaceful_only then
if self.type == "monster"
and peaceful_only then
self.object:remove()
return
end
-- if lifetimer run out and not npc; tamed or attacking then remove mob
if self.type ~= "npc" and not self.tamed then
if self.type ~= "npc"
and not self.tamed then
self.lifetimer = self.lifetimer - dtime
if self.lifetimer <= 0 and self.state ~= "attack" then
if self.lifetimer <= 0
and self.state ~= "attack" then
minetest.log("action","lifetimer expired, removed "..self.name)
effect(self.object:getpos(), 15, "tnt_smoke.png")
self.object:remove()
@ -194,35 +221,38 @@ function mobs:register_mob(name, def)
local yaw = 0
-- jump direction (adapted from Carbone mobs), gravity, falling or floating in water
if not self.fly then
if self.object:getvelocity().y > 0.1 then
yaw = self.object:getyaw() + self.rotate
local x = math.sin(yaw) * -2
local z = math.cos(yaw) * 2
if minetest.get_item_group(minetest.get_node(self.object:getpos()).name, "water") ~= 0 then
if self.floats == 1 then self.object:setacceleration({x = x, y = 1.5, z = z}) end
else
self.object:setacceleration({x = x, y = self.fall_speed, z = z})
-- floating in water (or falling)
local pos = self.object:getpos()
local nod = minetest.get_node_or_nil(pos)
if nod then nod = nod.name else nod = "default:dirt" end
local nodef = minetest.registered_nodes[nod]
if nodef.groups.water then
if self.floats == 1 then
self.object:setacceleration({
x = 0,
y = 1.5,
z = 0
})
end
else
if minetest.get_item_group(minetest.get_node(self.object:getpos()).name, "water") ~= 0 then
if self.floats == 1 then self.object:setacceleration({x = 0, y = 1.5, z = 0}) end
else
self.object:setacceleration({x = 0, y = self.fall_speed, z = 0})
end
end
self.object:setacceleration({
x = 0,
y = self.fall_speed,
z = 0
})
-- fall damage
if self.fall_damage == 1 and self.object:getvelocity().y == 0 then
local d = self.old_y - self.object:getpos().y
if d > 5 then
self.object:set_hp(self.object:get_hp() - math.floor(d - 5))
effect(self.object:getpos(), 5, "tnt_smoke.png")
check_for_death(self)
-- fall damage
if self.fall_damage == 1
and self.object:getvelocity().y == 0 then
local d = self.old_y - self.object:getpos().y
if d > 5 then
self.object:set_hp(self.object:get_hp() - math.floor(d - 5))
effect(self.object:getpos(), 5, "tnt_smoke.png")
check_for_death(self)
end
self.old_y = self.object:getpos().y
end
self.old_y = self.object:getpos().y
end
end
@ -244,7 +274,8 @@ function mobs:register_mob(name, def)
self.timer = 0
end
if self.sounds.random and math.random(1, 100) <= 1 then
if self.sounds.random
and math.random(1, 100) <= 1 then
minetest.sound_play(self.sounds.random, {
object = self.object,
max_hear_distance = self.sounds.distance
@ -259,9 +290,10 @@ function mobs:register_mob(name, def)
-- daylight above ground
if self.light_damage ~= 0
and pos.y > 0
and tod > 0.2 and tod < 0.8
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)
self.object:set_hp(self.object:get_hp() - self.light_damage)
effect(pos, 5, "tnt_smoke.png")
check_for_death(self)
end
@ -275,7 +307,7 @@ function mobs:register_mob(name, def)
-- water
if self.water_damage ~= 0
and nodef.groups.water then
self.object:set_hp(self.object:get_hp()-self.water_damage)
self.object:set_hp(self.object:get_hp() - self.water_damage)
effect(pos, 5, "bubble.png")
check_for_death(self)
end
@ -283,7 +315,7 @@ function mobs:register_mob(name, def)
-- lava or fire
if self.lava_damage ~= 0
and (nodef.groups.lava or nod.name == "fire:basic_flame") then
self.object:set_hp(self.object:get_hp()-self.lava_damage)
self.object:set_hp(self.object:get_hp() - self.lava_damage)
effect(pos, 5, "fire_basic_flame.png")
check_for_death(self)
end
@ -291,7 +323,9 @@ function mobs:register_mob(name, def)
end
local do_jump = function(self)
if self.fly then return end
if self.fly then
return
end
self.jumptimer = (self.jumptimer or 0) + 1
if self.jumptimer < 3 then
@ -299,8 +333,11 @@ function mobs:register_mob(name, def)
pos.y = (pos.y + self.collisionbox[2]) - 0.2
local nod = minetest.get_node(pos)
--print ("standing on:", nod.name, pos.y)
if not nod or not minetest.registered_nodes[nod.name]
or minetest.registered_nodes[nod.name].walkable == false then return end
if not nod
or not minetest.registered_nodes[nod.name]
or minetest.registered_nodes[nod.name].walkable == false then
return
end
if self.direction then
pos.y = pos.y + 0.5
local nod = minetest.get_node_or_nil({
@ -309,9 +346,14 @@ function mobs:register_mob(name, def)
z = pos.z + self.direction.z
})
--print ("in front:", nod.name, pos.y)
if nod and nod.name and (nod.name ~= "air" or self.walk_chance == 0) then
if nod and nod.name and
(nod.name ~= "air"
or self.walk_chance == 0) then
local def = minetest.registered_items[nod.name]
if (def and def.walkable and not nod.name:find("fence")) or self.walk_chance == 0 then
if (def
and def.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
@ -333,7 +375,8 @@ function mobs:register_mob(name, def)
-- environmental damage timer
self.env_damage_timer = self.env_damage_timer + dtime
if self.state == "attack" and self.env_damage_timer > 1 then
if self.state == "attack"
and self.env_damage_timer > 1 then
self.env_damage_timer = 0
do_env_damage(self)
elseif self.state ~= "attack" then
@ -341,7 +384,9 @@ function mobs:register_mob(name, def)
end
-- find someone to attack
if self.type == "monster" and damage_enabled and self.state ~= "attack" then
if self.type == "monster"
and damage_enabled
and self.state ~= "attack" then
local s = self.object:getpos()
local p, sp, dist
@ -351,7 +396,7 @@ function mobs:register_mob(name, def)
local min_dist = self.view_range + 1
local min_player = nil
for _,oir in ipairs(minetest.get_objects_inside_radius(s,self.view_range)) do
for _,oir in ipairs(minetest.get_objects_inside_radius(s, self.view_range)) do
if oir:is_player() then
player = oir
@ -364,14 +409,16 @@ function mobs:register_mob(name, def)
end
end
if type == "player" or type == "npc" then
if type == "player"
or type == "npc" then
s = self.object:getpos()
p = player:getpos()
sp = s
p.y = p.y + 1
sp.y = sp.y + 1 -- aim higher to make looking up hills more realistic
dist = ((p.x - s.x) ^ 2 + (p.y - s.y) ^ 2 + (p.z - s.z) ^ 2) ^ 0.5
if dist < self.view_range then -- and self.in_fov(self,p) then
if dist < self.view_range then
-- and self.in_fov(self,p) then
-- choose closest player to attack
if minetest.line_of_sight(sp, p, 2) == true
and dist < min_dist then
@ -391,12 +438,15 @@ function mobs:register_mob(name, def)
local min_dist = self.view_range + 1
local min_player = nil
if self.type == "npc" and self.attacks_monsters and self.state ~= "attack" then
if self.type == "npc"
and self.attacks_monsters
and self.state ~= "attack" then
local s = self.object:getpos()
local obj = nil
for _, oir in pairs(minetest.get_objects_inside_radius(s,self.view_range)) do
obj = oir:get_luaentity()
if obj and obj.type == "monster" then
if obj
and obj.type == "monster" then
-- attack monster
p = obj.object:getpos()
dist = ((p.x - s.x) ^ 2 + (p.y - s.y) ^ 2 + (p.z - s.z) ^ 2) ^ 0.5
@ -412,7 +462,9 @@ function mobs:register_mob(name, def)
end
-- horny animal can mate for 40 seconds, afterwards horny animal cannot mate again for 200 seconds
if self.horny == true and self.hornytimer < 240 and self.child == false then
if self.horny == true
and self.hornytimer < 240
and self.child == false then
self.hornytimer = self.hornytimer + 1
if self.hornytimer >= 240 then
self.hornytimer = 0
@ -429,14 +481,18 @@ function mobs:register_mob(name, def)
self.object:set_properties({
textures = self.base_texture,
mesh = self.base_mesh,
visual_size = {x = self.visual_size.x, y = self.visual_size.y},
visual_size = {
x = self.visual_size.x,
y = self.visual_size.y
},
collisionbox = self.collisionbox,
})
end
end
-- if animal is horny, find another same animal who is horny and mate
if self.horny == true and self.hornytimer <= 40 then
if self.horny == true
and self.hornytimer <= 40 then
local pos = self.object:getpos()
effect({x = pos.x, y = pos.y + 1, z = pos.z}, 4, "heart.png")
local ents = minetest.get_objects_inside_radius(pos, self.view_range)
@ -444,7 +500,12 @@ function mobs:register_mob(name, def)
local ent = nil
for i,obj in ipairs(ents) do
ent = obj:get_luaentity()
if ent and ent.name == self.name and ent.horny == true and ent.hornytimer <= 40 then num = num + 1 end
if ent
and ent.name == self.name
and ent.horny == true
and ent.hornytimer <= 40 then
num = num + 1
end
if num > 1 then
self.hornytimer = 41
ent.hornytimer = 41
@ -457,7 +518,10 @@ function mobs:register_mob(name, def)
end
mob:set_properties({
textures = textures,
visual_size = {x = self.visual_size.x / 2, y = self.visual_size.y / 2},
visual_size = {
x = self.visual_size.x / 2,
y = self.visual_size.y / 2
},
collisionbox = {
self.collisionbox[1] / 2, self.collisionbox[2] / 2, self.collisionbox[3] / 2,
self.collisionbox[4] / 2, self.collisionbox[5] / 2, self.collisionbox[6] / 2
@ -474,7 +538,10 @@ function mobs:register_mob(name, def)
end
-- find player to follow
if (self.follow ~= "" or self.order == "follow") and not self.following and self.state ~= "attack" then
if (self.follow ~= ""
or self.order == "follow")
and not self.following
and self.state ~= "attack" then
local s, p, dist
for _,player in pairs(minetest.get_connected_players()) do
s = self.object:getpos()
@ -492,14 +559,21 @@ function mobs:register_mob(name, def)
self.do_custom(self)
end
if self.type == "npc" and self.order == "follow" and self.state ~= "attack" then
if self.type == "npc"
and self.order == "follow"
and self.state ~= "attack" then
-- npc stop following player if not owner
if self.following and self.type == "npc" and self.owner and self.owner ~= self.following:get_player_name() then
if self.following
and self.type == "npc"
and self.owner
and self.owner ~= self.following:get_player_name() then
self.following = nil
end
else
-- stop following player if not holding specific item
if self.following and self.following.is_player and self.following:get_wielded_item():get_name() ~= self.follow then
if self.following
and self.following.is_player
and self.following:get_wielded_item():get_name() ~= self.follow then
self.following = nil
end
end
@ -509,7 +583,8 @@ function mobs:register_mob(name, def)
local s = self.object:getpos()
local p
if self.following.is_player and self.following:is_player() then
if self.following.is_player
and self.following:is_player() then
p = self.following:getpos()
elseif self.following.object then
p = self.following.object:getpos()
@ -528,10 +603,18 @@ function mobs:register_mob(name, def)
self.object:setyaw(yaw)
-- anyone but standing npc's can move along
if dist > 2 and self.order ~= "stand" then
if (self.jump and self.get_velocity(self) <= 0.5 and self.object:getvelocity().y == 0)
or (self.object:getvelocity().y == 0 and self.jump_chance > 0) then
self.direction = {x = math.sin(yaw) * -1, y = -20, z = math.cos(yaw)}
if dist > 2
and self.order ~= "stand" then
if (self.jump
and self.get_velocity(self) <= 0.5
and self.object:getvelocity().y == 0)
or (self.object:getvelocity().y == 0
and self.jump_chance > 0) then
self.direction = {
x = math.sin(yaw) * -1,
y = -20,
z = math.cos(yaw)
}
do_jump(self)
end
self.set_velocity(self, self.walk_velocity)
@ -582,12 +665,14 @@ function mobs:register_mob(name, def)
self.set_animation(self, "stand")
-- npc's ordered to stand stay standing
if self.type == "npc" and self.order == "stand" then
if self.type == "npc"
and self.order == "stand" then
self.set_velocity(self, 0)
self.state = "stand"
self:set_animation("stand")
else
if self.walk_chance ~= 0 and math.random(1, 100) <= self.walk_chance then
if self.walk_chance ~= 0
and math.random(1, 100) <= self.walk_chance then
self.set_velocity(self, self.walk_velocity)
self.state = "walk"
self.set_animation(self, "walk")
@ -606,7 +691,9 @@ function mobs:register_mob(name, def)
local lp = minetest.find_node_near(s, 1, {"group:water"})
-- water swimmers cannot move out of water
if self.fly and self.fly_in == "default:water_source" and not lp then
if self.fly
and self.fly_in == "default:water_source"
and not lp then
print ("out of water")
self.set_velocity(self, 0)
self.state = "flop" -- change to undefined state so nothing more happens
@ -626,8 +713,13 @@ end
elseif math.random(1, 100) <= 30 then
self.object:setyaw(self.object:getyaw() + ((math.random(0, 360) - 180) / 180 * math.pi))
end
if self.jump and self.get_velocity(self) <= 0.5 and self.object:getvelocity().y == 0 then
self.direction = {x = math.sin(yaw) * -1, y = -20, z = math.cos(yaw)}
if self.jump and self.get_velocity(self) <= 0.5
and self.object:getvelocity().y == 0 then
self.direction = {
x = math.sin(yaw) * -1,
y = -20,
z = math.cos(yaw)
}
do_jump(self)
end
@ -641,7 +733,8 @@ end
-- exploding mobs
elseif self.state == "attack" and self.attack_type == "explode" then
if not self.attack.player or not self.attack.player:is_player() then
if not self.attack.player
or not self.attack.player:is_player() then
self.state = "stand"
self:set_animation("stand")
self.timer = 0
@ -680,7 +773,8 @@ end
else
self.timer = 0
self.blinktimer = 0
if self.get_velocity(self) <= 0.5 and self.object:getvelocity().y == 0 then
if self.get_velocity(self) <= 0.5
and self.object:getvelocity().y == 0 then
local v = self.object:getvelocity()
v.y = 5
self.object:setvelocity(v)
@ -724,8 +818,10 @@ end
end
-- end of exploding mobs
elseif self.state == "attack" and self.attack_type == "dogfight" then
if not self.attack.player or not self.attack.player:getpos() then
elseif self.state == "attack"
and self.attack_type == "dogfight" then
if not self.attack.player
or not self.attack.player:getpos() then
print("stop attacking")
self.state = "stand"
self:set_animation("stand")
@ -736,7 +832,8 @@ end
local dist = ((p.x - s.x) ^ 2 + (p.y - s.y) ^ 2 + (p.z - s.z) ^ 2) ^ 0.5
-- fly bit modified from BlockMens creatures mod
if self.fly and dist > 2 then
if self.fly
and dist > 2 then
local nod = minetest.get_node_or_nil(s)
local p1 = s
@ -744,27 +841,45 @@ end
local p2 = p
local p_y = math.floor(p2.y + 1)
local v = self.object:getvelocity()
if nod and nod.name == self.fly_in then
if nod
and nod.name == self.fly_in then
if me_y < p_y then
self.object:setvelocity({x = v.x, y = 1 * self.walk_velocity, z = v.z})
self.object:setvelocity({
x = v.x,
y = 1 * self.walk_velocity,
z = v.z
})
elseif me_y > p_y then
self.object:setvelocity({x = v.x, y = -1 * self.walk_velocity, z = v.z})
self.object:setvelocity({
x = v.x,
y = -1 * self.walk_velocity,
z = v.z
})
end
else
if me_y < p_y then
self.object:setvelocity({x = v.x, y = 0.01,z = v.z})
self.object:setvelocity({
x = v.x,
y = 0.01,
z = v.z
})
elseif me_y > p_y then
self.object:setvelocity({x = v.x, y = -0.01, z = v.z})
self.object:setvelocity({
x = v.x,
y = -0.01,
z = v.z
})
end
end
end
-- end fly bit
if dist > self.view_range or self.attack.player:get_hp() <= 0 then
if dist > self.view_range
or self.attack.player:get_hp() <= 0 then
self.state = "stand"
self.set_velocity(self, 0)
self.attack = {player=nil, dist=nil}
self.attack = {player = nil, dist = nil}
self:set_animation("stand")
return
else
@ -780,9 +895,16 @@ end
-- attack distance is 2 + half of mob width so the bigger mobs can attack (like slimes)
if self.attack.dist > ((-self.collisionbox[1] + self.collisionbox[4]) / 2) + 2 then
-- jump attack
if (self.jump and self.get_velocity(self) <= 0.5 and self.object:getvelocity().y == 0)
or (self.object:getvelocity().y == 0 and self.jump_chance > 0) then
self.direction = {x = math.sin(yaw) * -1, y = -20, z = math.cos(yaw)}
if (self.jump
and self.get_velocity(self) <= 0.5
and self.object:getvelocity().y == 0)
or (self.object:getvelocity().y == 0
and self.jump_chance > 0) then
self.direction = {
x = math.sin(yaw) * -1,
y = -20,
z = math.cos(yaw)
}
do_jump(self)
end
self.set_velocity(self, self.run_velocity)
@ -815,14 +937,16 @@ end
end
end
elseif self.state == "attack" and self.attack_type == "shoot" then
elseif self.state == "attack"
and self.attack_type == "shoot" then
local s = self.object:getpos()
local p = self.attack.player:getpos()
p.y = p.y - .5
s.y = s.y + .5
local dist = ((p.x - s.x) ^ 2 + (p.y - s.y) ^ 2 + (p.z - s.z) ^ 2) ^ 0.5
if dist > self.view_range or self.attack.player:get_hp() <= 0 then
if dist > self.view_range
or self.attack.player:get_hp() <= 0 then
self.state = "stand"
self.set_velocity(self, 0)
self:set_animation("stand")
@ -839,7 +963,9 @@ end
self.object:setyaw(yaw)
self.set_velocity(self, 0)
if self.shoot_interval and self.timer > self.shoot_interval and math.random(1, 100) <= 60 then
if self.shoot_interval
and self.timer > self.shoot_interval
and math.random(1, 100) <= 60 then
self.timer = 0
self:set_animation("punch")
@ -866,7 +992,8 @@ end
end,
on_activate = function(self, staticdata, dtime_s)
if self.type == "monster" and peaceful_only then
if self.type == "monster"
and peaceful_only then
self.object:remove()
end
@ -879,8 +1006,7 @@ end
self.object:setvelocity({x = 0, y = self.object:getvelocity().y, z = 0})
self.old_y = self.object:getpos().y
self.object:setyaw(math.random(1, 360) / 180 * math.pi)
if not self.sounds.distance then self.sounds.distance = 10 end
self.sounds.distance = (self.sounds.distance or 10)
if staticdata then
local tmp = minetest.deserialize(staticdata)
@ -938,11 +1064,13 @@ end
local vis_size = self.visual_size
local colbox = self.collisionbox
-- specific texture if gotten
if self.gotten == true and def.gotten_texture then
if self.gotten == true
and def.gotten_texture then
textures = def.gotten_texture
end
-- specific mesh if gotten
if self.gotten == true and def.gotten_mesh then
if self.gotten == true
and def.gotten_mesh then
mesh = def.gotten_mesh
end
-- if object is child then set half size
@ -1004,7 +1132,9 @@ end
-- blood_particles
local pos = self.object:getpos()
pos.y = pos.y + (-self.collisionbox[2] + self.collisionbox[5]) / 2
if self.blood_amount > 0 and pos and enable_blood == true then
if self.blood_amount > 0
--and pos
and enable_blood == true then
effect(pos, self.blood_amount, self.blood_texture)
end
@ -1020,7 +1150,8 @@ end
self.pause_timer = r
-- attack puncher and call other mobs for help
if self.passive == false and not self.tamed then
if self.passive == false
and not self.tamed then
if self.state ~= "attack" then
self.do_attack(self, hitter, 1)
end
@ -1029,7 +1160,8 @@ end
for _, oir in pairs(minetest.get_objects_inside_radius(hitter:getpos(), 5)) do
obj = oir:get_luaentity()
if obj then
if obj.group_attack == true and obj.state ~= "attack" then
if obj.group_attack == true
and obj.state ~= "attack" then
obj.do_attack(obj, hitter, 1)
end
end
@ -1049,7 +1181,7 @@ function mobs:spawn_specific(name, nodes, neighbors, min_light, max_light, inter
interval = interval,
chance = chance,
action = function(pos, node, _, active_object_count_wider)
-- do not spawn if too many active in area
-- do not spawn if too many active entities in area
if active_object_count_wider > active_object_count
or not mobs.spawning_mobs[name]
or not pos then
@ -1060,25 +1192,39 @@ function mobs:spawn_specific(name, nodes, neighbors, min_light, max_light, inter
pos.y = pos.y + 1
-- mobs cannot spawn inside protected areas if enabled
if mobs.protected == 1 and minetest.is_protected(pos, "") then
if mobs.protected == 1
and minetest.is_protected(pos, "") then
return
end
-- check if light and height levels are ok to spawn
local light = minetest.get_node_light(pos)
if not light or light > max_light or light < min_light
or pos.y > max_height or pos.y < min_height then
if not light
or light > max_light
or light < min_light
or pos.y > max_height
or pos.y < min_height then
return
end
-- are we spawning inside a solid node?
local nod = minetest.get_node_or_nil(pos)
if not nod or not nod.name or not minetest.registered_nodes[nod.name]
or minetest.registered_nodes[nod.name].walkable == true then return end
if not nod
or not nod.name
or not minetest.registered_nodes[nod.name]
or minetest.registered_nodes[nod.name].walkable == true then
return
end
pos.y = pos.y + 1
nod = minetest.get_node_or_nil(pos)
if not nod or not nod.name or not minetest.registered_nodes[nod.name]
or minetest.registered_nodes[nod.name].walkable == true then return end
if not nod
or not nod.name
or not minetest.registered_nodes[nod.name]
or minetest.registered_nodes[nod.name].walkable == true then
return
end
if minetest.setting_getbool("display_mob_spawn") then
minetest.chat_send_all("[mobs] Add "..name.." at "..minetest.pos_to_string(pos))
@ -1134,7 +1280,8 @@ function mobs:explosion(pos, radius, fire, smoke, sound)
local c_obsidian = minetest.get_content_id("default:obsidian")
local c_brick = minetest.get_content_id("default:obsidianbrick")
local c_chest = minetest.get_content_id("default:chest_locked")
if sound and sound ~= "" then
if sound
and sound ~= "" then
minetest.sound_play(sound, {
pos = pos,
gain = 1.0,
@ -1152,7 +1299,9 @@ function mobs:explosion(pos, radius, fire, smoke, sound)
p.x = pos.x + x
p.y = pos.y + y
p.z = pos.z + z
if data[vi] ~= c_air and data[vi] ~= c_ignore and data[vi] ~= c_obsidian and data[vi] ~= c_brick and data[vi] ~= c_chest then
if data[vi] ~= c_air and data[vi] ~= c_ignore
and data[vi] ~= c_obsidian and data[vi] ~= c_brick
and data[vi] ~= c_chest then
local n = minetest.get_node(p).name
if minetest.get_item_group(n, "unbreakable") ~= 1 then
-- if chest then drop items inside
@ -1167,8 +1316,10 @@ function mobs:explosion(pos, radius, fire, smoke, sound)
end
end
end
if fire > 0 and (minetest.registered_nodes[n].groups.flammable or math.random(1, 100) <= 30) then
minetest.set_node(p, {name="fire:basic_flame"})
if fire > 0
and (minetest.registered_nodes[n].groups.flammable
or math.random(1, 100) <= 30) then
minetest.set_node(p, {name = "fire:basic_flame"})
else
minetest.remove_node(p)
end
@ -1202,9 +1353,14 @@ function check_for_death(self)
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)))
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 = 5, z = math.random(-1, 1)})
obj:setvelocity({
x = math.random(-1, 1),
y = 5,
z = math.random(-1, 1)
})
end
end
end
@ -1286,7 +1442,8 @@ function mobs:register_arrow(name, def)
return
end
if (self.hit_player or self.hit_mob) and self.timer > engage then
if (self.hit_player or self.hit_mob)
and self.timer > engage then
for _,player in pairs(minetest.get_objects_inside_radius(pos, 1.0)) do
if self.hit_player
and player:is_player() then
@ -1319,7 +1476,8 @@ function mobs:register_egg(mob, desc, background, addegg)
inventory_image = invimg,
on_place = function(itemstack, placer, pointed_thing)
local pos = pointed_thing.above
if pointed_thing.above and not minetest.is_protected(pos, placer:get_player_name()) then
if pointed_thing.above
and not minetest.is_protected(pos, placer:get_player_name()) then
pos.y = pos.y + 0.5
local mob = minetest.add_entity(pos, mob)
local ent = mob:get_luaentity()
@ -1337,7 +1495,9 @@ end
-- capture critter (thanks to blert2112 for idea)
function mobs:capture_mob(self, clicker, chance_hand, chance_net, chance_lasso, force_take, replacewith)
if clicker:is_player() and clicker:get_inventory() and not self.child then
if clicker:is_player()
and clicker:get_inventory()
and not self.child then
-- get name of clicked mob
local mobname = self.name
-- if not nil change what will be added to inventory
@ -1346,11 +1506,13 @@ function mobs:capture_mob(self, clicker, chance_hand, chance_net, chance_lasso,
end
--print ("taking by force is", force_take)
local name = clicker:get_player_name()
if self.owner == "" and force_take == false then
if self.owner == ""
and force_take == false then
minetest.chat_send_player(name, "Not tamed!")
return
-- cannot pick up if not owner
elseif self.owner ~= name and force_take == false then
elseif self.owner ~= name
and force_take == false then
minetest.chat_send_player(name, "Not owner!")
return
end