mirror of
https://github.com/sys4-fr/server-nalc.git
synced 2025-04-03 19:20:35 +02:00
Mobd update second part
This commit is contained in:
parent
c93567ef87
commit
744ccb7bee
@ -28,7 +28,7 @@ This mod contains the following additions:
|
|||||||
|
|
||||||
Changelog:
|
Changelog:
|
||||||
|
|
||||||
1.13- Added capture function (thanks blert2112) chance of picking up mob with hand, net and magic lasso
|
1.13- Added capture function (thanks blert2112) chance of picking up mob with hand; net; magic lasso, replaced some .x models with newer .b3d one's
|
||||||
1.12- Added animal ownership so that players cannot steal your tamed animals
|
1.12- Added animal ownership so that players cannot steal your tamed animals
|
||||||
1.11- Added flying mobs (and swimming), fly=true and fly_in="air" or "deafult:water_source" for fishy
|
1.11- Added flying mobs (and swimming), fly=true and fly_in="air" or "deafult:water_source" for fishy
|
||||||
1,10- Footstep removed (use replace), explosion routine added for exploding mobs.
|
1,10- Footstep removed (use replace), explosion routine added for exploding mobs.
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
-- Mobs Api (29th June 2015)
|
-- Mobs Api (15th July 2015)
|
||||||
mobs = {}
|
mobs = {}
|
||||||
mobs.mod = "redo"
|
mobs.mod = "redo"
|
||||||
|
|
||||||
@ -37,9 +37,9 @@ function mobs:register_mob(name, def)
|
|||||||
walk_velocity = def.walk_velocity or 1,
|
walk_velocity = def.walk_velocity or 1,
|
||||||
run_velocity = def.run_velocity or 2,
|
run_velocity = def.run_velocity or 2,
|
||||||
damage = def.damage,
|
damage = def.damage,
|
||||||
light_damage = def.light_damage,
|
light_damage = def.light_damage or 0,
|
||||||
water_damage = def.water_damage,
|
water_damage = def.water_damage or 0,
|
||||||
lava_damage = def.lava_damage,
|
lava_damage = def.lava_damage or 0,
|
||||||
fall_damage = def.fall_damage or 1,
|
fall_damage = def.fall_damage or 1,
|
||||||
fall_speed = def.fall_speed or -10, -- must be lower than -2 (default: -10)
|
fall_speed = def.fall_speed or -10, -- must be lower than -2 (default: -10)
|
||||||
drops = def.drops or {},
|
drops = def.drops or {},
|
||||||
@ -82,7 +82,8 @@ function mobs:register_mob(name, def)
|
|||||||
|
|
||||||
do_attack = function(self, player, dist)
|
do_attack = function(self, player, dist)
|
||||||
if self.state ~= "attack" then
|
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,{
|
minetest.sound_play(self.sounds.war_cry,{
|
||||||
object = self.object,
|
object = self.object,
|
||||||
max_hear_distance = self.sounds.distance
|
max_hear_distance = self.sounds.distance
|
||||||
@ -95,8 +96,11 @@ function mobs:register_mob(name, def)
|
|||||||
end,
|
end,
|
||||||
|
|
||||||
set_velocity = function(self, v)
|
set_velocity = function(self, v)
|
||||||
if not v then v = 0 end
|
v = (v or 0)
|
||||||
if def.drawtype and def.drawtype == "side" then self.rotate = 1.5 end
|
if def.drawtype
|
||||||
|
and def.drawtype == "side" then
|
||||||
|
self.rotate = 1.5
|
||||||
|
end
|
||||||
local yaw = self.object:getyaw() + self.rotate
|
local yaw = self.object:getyaw() + self.rotate
|
||||||
local x = math.sin(yaw) * -v
|
local x = math.sin(yaw) * -v
|
||||||
local z = math.cos(yaw) * v
|
local z = math.cos(yaw) * v
|
||||||
@ -117,7 +121,6 @@ function mobs:register_mob(name, def)
|
|||||||
local ps = math.sqrt(pos.x ^ 2 + pos.z ^ 2)
|
local ps = math.sqrt(pos.x ^ 2 + pos.z ^ 2)
|
||||||
local d = { x = vx / ds, z = vz / ds }
|
local d = { x = vx / ds, z = vz / ds }
|
||||||
local p = { x = pos.x / ps, z = pos.z / ps }
|
local p = { x = pos.x / ps, z = pos.z / ps }
|
||||||
|
|
||||||
local an = ( d.x * p.x ) + ( d.z * p.z )
|
local an = ( d.x * p.x ) + ( d.z * p.z )
|
||||||
|
|
||||||
a = math.deg( math.acos( an ) )
|
a = math.deg( math.acos( an ) )
|
||||||
@ -136,27 +139,47 @@ function mobs:register_mob(name, def)
|
|||||||
if not self.animation.current then
|
if not self.animation.current then
|
||||||
self.animation.current = ""
|
self.animation.current = ""
|
||||||
end
|
end
|
||||||
if type == "stand" and self.animation.current ~= "stand" then
|
if type == "stand"
|
||||||
if self.animation.stand_start and self.animation.stand_end and self.animation.speed_normal then
|
and self.animation.current ~= "stand" then
|
||||||
self.object:set_animation({x=self.animation.stand_start,
|
if self.animation.stand_start
|
||||||
y=self.animation.stand_end},self.animation.speed_normal, 0)
|
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"
|
self.animation.current = "stand"
|
||||||
end
|
end
|
||||||
elseif type == "walk" and self.animation.current ~= "walk" then
|
elseif type == "walk"
|
||||||
if self.animation.walk_start and self.animation.walk_end and self.animation.speed_normal then
|
and self.animation.current ~= "walk" then
|
||||||
self.object:set_animation({x=self.animation.walk_start,y=self.animation.walk_end},
|
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.speed_normal, 0)
|
||||||
self.animation.current = "walk"
|
self.animation.current = "walk"
|
||||||
end
|
end
|
||||||
elseif type == "run" and self.animation.current ~= "run" then
|
elseif type == "run"
|
||||||
if self.animation.run_start and self.animation.run_end and self.animation.speed_run then
|
and self.animation.current ~= "run" then
|
||||||
self.object:set_animation({x=self.animation.run_start,y=self.animation.run_end},
|
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.speed_run, 0)
|
||||||
self.animation.current = "run"
|
self.animation.current = "run"
|
||||||
end
|
end
|
||||||
elseif type == "punch" and self.animation.current ~= "punch" then
|
elseif type == "punch"
|
||||||
if self.animation.punch_start and self.animation.punch_end and self.animation.speed_normal then
|
and self.animation.current ~= "punch" then
|
||||||
self.object:set_animation({x=self.animation.punch_start,y=self.animation.punch_end},
|
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.speed_normal, 0)
|
||||||
self.animation.current = "punch"
|
self.animation.current = "punch"
|
||||||
end
|
end
|
||||||
@ -165,15 +188,18 @@ function mobs:register_mob(name, def)
|
|||||||
|
|
||||||
on_step = function(self, dtime)
|
on_step = function(self, dtime)
|
||||||
|
|
||||||
if self.type == "monster" and peaceful_only then
|
if self.type == "monster"
|
||||||
|
and peaceful_only then
|
||||||
self.object:remove()
|
self.object:remove()
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
-- if lifetimer run out and not npc; tamed or attacking then remove mob
|
-- 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
|
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)
|
minetest.log("action","lifetimer expired, removed "..self.name)
|
||||||
effect(self.object:getpos(), 15, "tnt_smoke.png")
|
effect(self.object:getpos(), 15, "tnt_smoke.png")
|
||||||
self.object:remove()
|
self.object:remove()
|
||||||
@ -187,6 +213,7 @@ function mobs:register_mob(name, def)
|
|||||||
and math.random(1,self.replace_rate) == 1 then
|
and math.random(1,self.replace_rate) == 1 then
|
||||||
local pos = self.object:getpos()
|
local pos = self.object:getpos()
|
||||||
pos.y = pos.y + self.replace_offset
|
pos.y = pos.y + self.replace_offset
|
||||||
|
-- print ("replace node = ".. minetest.get_node(pos).name, pos.y)
|
||||||
if self.replace_what
|
if self.replace_what
|
||||||
and self.object:getvelocity().y == 0
|
and self.object:getvelocity().y == 0
|
||||||
and #minetest.find_nodes_in_area(pos, pos, self.replace_what) > 0 then
|
and #minetest.find_nodes_in_area(pos, pos, self.replace_what) > 0 then
|
||||||
@ -199,26 +226,38 @@ function mobs:register_mob(name, def)
|
|||||||
|
|
||||||
-- jump direction (adapted from Carbone mobs), gravity, falling or floating in water
|
-- jump direction (adapted from Carbone mobs), gravity, falling or floating in water
|
||||||
if not self.fly then
|
if not self.fly then
|
||||||
if self.object:getvelocity().y > 0.1 then
|
-- floating in water (or falling)
|
||||||
yaw = self.object:getyaw() + self.rotate
|
local pos = self.object:getpos()
|
||||||
local x = math.sin(yaw) * -2
|
local nod = minetest.get_node_or_nil(pos)
|
||||||
local z = math.cos(yaw) * 2
|
if nod then nod = nod.name else nod = "default:dirt" end
|
||||||
|
local nodef = minetest.registered_nodes[nod]
|
||||||
|
|
||||||
if minetest.get_item_group(minetest.get_node(self.object:getpos()).name, "water") ~= 0 then
|
local v = self.object:getvelocity()
|
||||||
if self.floats == 1 then self.object:setacceleration({x = x, y = 1.5, z = z}) end
|
if v.y > 0.1 then
|
||||||
else
|
self.object:setacceleration({
|
||||||
self.object:setacceleration({x = x, y = self.fall_speed, z = z})
|
x = 0,
|
||||||
|
y= self.fall_speed,
|
||||||
|
z = 0
|
||||||
|
})
|
||||||
|
end
|
||||||
|
if nodef.groups.water then
|
||||||
|
if self.floats == 1 then
|
||||||
|
self.object:setacceleration({
|
||||||
|
x = 0,
|
||||||
|
y = -self.fall_speed / (math.max(1, v.y) ^ 2),
|
||||||
|
z = 0
|
||||||
|
})
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
if minetest.get_item_group(minetest.get_node(self.object:getpos()).name, "water") ~= 0 then
|
self.object:setacceleration({
|
||||||
if self.floats == 1 then self.object:setacceleration({x = 0, y = 1.5, z = 0}) end
|
x = 0,
|
||||||
else
|
y = self.fall_speed,
|
||||||
self.object:setacceleration({x = 0, y = self.fall_speed, z = 0})
|
z = 0
|
||||||
end
|
})
|
||||||
end
|
|
||||||
|
|
||||||
-- fall damage
|
-- fall damage
|
||||||
if self.fall_damage == 1 and self.object:getvelocity().y == 0 then
|
if self.fall_damage == 1
|
||||||
|
and self.object:getvelocity().y == 0 then
|
||||||
local d = self.old_y - self.object:getpos().y
|
local d = self.old_y - self.object:getpos().y
|
||||||
if d > 5 then
|
if d > 5 then
|
||||||
self.object:set_hp(self.object:get_hp() - math.floor(d - 5))
|
self.object:set_hp(self.object:get_hp() - math.floor(d - 5))
|
||||||
@ -228,6 +267,7 @@ function mobs:register_mob(name, def)
|
|||||||
self.old_y = self.object:getpos().y
|
self.old_y = self.object:getpos().y
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
-- knockback timer
|
-- knockback timer
|
||||||
if self.pause_timer > 0 then
|
if self.pause_timer > 0 then
|
||||||
@ -247,7 +287,8 @@ function mobs:register_mob(name, def)
|
|||||||
self.timer = 0
|
self.timer = 0
|
||||||
end
|
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, {
|
minetest.sound_play(self.sounds.random, {
|
||||||
object = self.object,
|
object = self.object,
|
||||||
max_hear_distance = self.sounds.distance
|
max_hear_distance = self.sounds.distance
|
||||||
@ -257,28 +298,36 @@ function mobs:register_mob(name, def)
|
|||||||
local do_env_damage = function(self)
|
local do_env_damage = function(self)
|
||||||
|
|
||||||
local pos = self.object:getpos()
|
local pos = self.object:getpos()
|
||||||
local n = minetest.get_node(pos)
|
|
||||||
local tod = minetest.get_timeofday()
|
local tod = minetest.get_timeofday()
|
||||||
pos.y = (pos.y + self.collisionbox[2]) -- foot level
|
|
||||||
--print ("standing on:", minetest.get_node(pos).name)
|
-- daylight above ground
|
||||||
if self.light_damage and self.light_damage ~= 0
|
if self.light_damage ~= 0
|
||||||
and pos.y > 0
|
and pos.y > 0
|
||||||
and tod > 0.2 and tod < 0.8
|
and tod > 0.2
|
||||||
and (minetest.get_node_light(pos) or 0) > 10 then
|
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")
|
effect(pos, 5, "tnt_smoke.png")
|
||||||
check_for_death(self)
|
check_for_death(self)
|
||||||
end
|
end
|
||||||
|
|
||||||
if self.water_damage and self.water_damage ~= 0
|
pos.y = pos.y + self.collisionbox[2] -- foot level
|
||||||
and minetest.get_item_group(n.name, "water") ~= 0 then
|
local nod = minetest.get_node_or_nil(pos)
|
||||||
|
if not nod then return end ; -- 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)
|
self.object:set_hp(self.object:get_hp() - self.water_damage)
|
||||||
effect(pos, 5, "bubble.png")
|
effect(pos, 5, "bubble.png")
|
||||||
check_for_death(self)
|
check_for_death(self)
|
||||||
end
|
end
|
||||||
|
|
||||||
if self.lava_damage and self.lava_damage ~= 0
|
-- lava or fire
|
||||||
and minetest.get_item_group(n.name, "lava") ~= 0 then
|
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")
|
effect(pos, 5, "fire_basic_flame.png")
|
||||||
check_for_death(self)
|
check_for_death(self)
|
||||||
@ -287,7 +336,9 @@ function mobs:register_mob(name, def)
|
|||||||
end
|
end
|
||||||
|
|
||||||
local do_jump = function(self)
|
local do_jump = function(self)
|
||||||
if self.fly then return end
|
if self.fly then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
self.jumptimer = (self.jumptimer or 0) + 1
|
self.jumptimer = (self.jumptimer or 0) + 1
|
||||||
if self.jumptimer < 3 then
|
if self.jumptimer < 3 then
|
||||||
@ -295,15 +346,27 @@ function mobs:register_mob(name, def)
|
|||||||
pos.y = (pos.y + self.collisionbox[2]) - 0.2
|
pos.y = (pos.y + self.collisionbox[2]) - 0.2
|
||||||
local nod = minetest.get_node(pos)
|
local nod = minetest.get_node(pos)
|
||||||
--print ("standing on:", nod.name, pos.y)
|
--print ("standing on:", nod.name, pos.y)
|
||||||
if not nod or not minetest.registered_nodes[nod.name]
|
if not nod
|
||||||
or minetest.registered_nodes[nod.name].walkable == false then return end
|
or not minetest.registered_nodes[nod.name]
|
||||||
|
or minetest.registered_nodes[nod.name].walkable == false then
|
||||||
|
return
|
||||||
|
end
|
||||||
if self.direction then
|
if self.direction then
|
||||||
pos.y = pos.y + 0.5
|
pos.y = pos.y + 0.5
|
||||||
local nod = minetest.get_node_or_nil({x=pos.x + self.direction.x,y=pos.y,z=pos.z + self.direction.z})
|
local nod = minetest.get_node_or_nil({
|
||||||
|
x = pos.x + self.direction.x,
|
||||||
|
y = pos.y,
|
||||||
|
z = pos.z + self.direction.z
|
||||||
|
})
|
||||||
--print ("in front:", nod.name, pos.y)
|
--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]
|
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()
|
local v = self.object:getvelocity()
|
||||||
v.y = self.jump_height + 1
|
v.y = self.jump_height + 1
|
||||||
v.x = v.x * 2.2
|
v.x = v.x * 2.2
|
||||||
@ -325,7 +388,8 @@ function mobs:register_mob(name, def)
|
|||||||
|
|
||||||
-- environmental damage timer
|
-- environmental damage timer
|
||||||
self.env_damage_timer = self.env_damage_timer + dtime
|
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
|
self.env_damage_timer = 0
|
||||||
do_env_damage(self)
|
do_env_damage(self)
|
||||||
elseif self.state ~= "attack" then
|
elseif self.state ~= "attack" then
|
||||||
@ -333,7 +397,9 @@ function mobs:register_mob(name, def)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- find someone to attack
|
-- 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 s = self.object:getpos()
|
||||||
local p, sp, dist
|
local p, sp, dist
|
||||||
@ -356,14 +422,16 @@ function mobs:register_mob(name, def)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if type == "player" or type == "npc" then
|
if type == "player"
|
||||||
|
or type == "npc" then
|
||||||
s = self.object:getpos()
|
s = self.object:getpos()
|
||||||
p = player:getpos()
|
p = player:getpos()
|
||||||
sp = s
|
sp = s
|
||||||
p.y = p.y + 1
|
p.y = p.y + 1
|
||||||
sp.y = sp.y + 1 -- aim higher to make looking up hills more realistic
|
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
|
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
|
-- choose closest player to attack
|
||||||
if minetest.line_of_sight(sp, p, 2) == true
|
if minetest.line_of_sight(sp, p, 2) == true
|
||||||
and dist < min_dist then
|
and dist < min_dist then
|
||||||
@ -383,15 +451,18 @@ function mobs:register_mob(name, def)
|
|||||||
local min_dist = self.view_range + 1
|
local min_dist = self.view_range + 1
|
||||||
local min_player = nil
|
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 s = self.object:getpos()
|
||||||
local obj = nil
|
local obj = nil
|
||||||
for _, oir in pairs(minetest.get_objects_inside_radius(s,self.view_range)) do
|
for _, oir in pairs(minetest.get_objects_inside_radius(s,self.view_range)) do
|
||||||
obj = oir:get_luaentity()
|
obj = oir:get_luaentity()
|
||||||
if obj and obj.type == "monster" then
|
if obj
|
||||||
|
and obj.type == "monster" then
|
||||||
-- attack monster
|
-- attack monster
|
||||||
local p = obj.object:getpos()
|
p = obj.object:getpos()
|
||||||
local dist = ((p.x-s.x)^2 + (p.y-s.y)^2 + (p.z-s.z)^2)^0.5
|
dist = ((p.x - s.x) ^ 2 + (p.y - s.y) ^ 2 + (p.z - s.z) ^ 2) ^ 0.5
|
||||||
if dist < min_dist then
|
if dist < min_dist then
|
||||||
min_dist = dist
|
min_dist = dist
|
||||||
min_player = obj.object
|
min_player = obj.object
|
||||||
@ -404,7 +475,9 @@ function mobs:register_mob(name, def)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- horny animal can mate for 40 seconds, afterwards horny animal cannot mate again for 200 seconds
|
-- 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
|
self.hornytimer = self.hornytimer + 1
|
||||||
if self.hornytimer >= 240 then
|
if self.hornytimer >= 240 then
|
||||||
self.hornytimer = 0
|
self.hornytimer = 0
|
||||||
@ -421,14 +494,18 @@ function mobs:register_mob(name, def)
|
|||||||
self.object:set_properties({
|
self.object:set_properties({
|
||||||
textures = self.base_texture,
|
textures = self.base_texture,
|
||||||
mesh = self.base_mesh,
|
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,
|
collisionbox = self.collisionbox,
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- if animal is horny, find another same animal who is horny and mate
|
-- 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()
|
local pos = self.object:getpos()
|
||||||
effect({x = pos.x, y = pos.y + 1, z = pos.z}, 4, "heart.png")
|
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)
|
local ents = minetest.get_objects_inside_radius(pos, self.view_range)
|
||||||
@ -436,7 +513,18 @@ function mobs:register_mob(name, def)
|
|||||||
local ent = nil
|
local ent = nil
|
||||||
for i,obj in ipairs(ents) do
|
for i,obj in ipairs(ents) do
|
||||||
ent = obj:get_luaentity()
|
ent = obj:get_luaentity()
|
||||||
if ent and ent.name == self.name and ent.horny == true and ent.hornytimer <= 40 then num = num + 1 end
|
|
||||||
|
-- quick fix for racist sheep
|
||||||
|
if ent
|
||||||
|
and string.find(ent.name, "mobs:sheep_") then
|
||||||
|
ent.name = "mobs:sheep"
|
||||||
|
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
|
if num > 1 then
|
||||||
self.hornytimer = 41
|
self.hornytimer = 41
|
||||||
ent.hornytimer = 41
|
ent.hornytimer = 41
|
||||||
@ -449,9 +537,14 @@ function mobs:register_mob(name, def)
|
|||||||
end
|
end
|
||||||
mob:set_properties({
|
mob:set_properties({
|
||||||
textures = textures,
|
textures = textures,
|
||||||
visual_size = {x=self.visual_size.x/2,y=self.visual_size.y/2},
|
visual_size = {
|
||||||
collisionbox = {self.collisionbox[1]/2, self.collisionbox[2]/2, self.collisionbox[3]/2,
|
x = self.visual_size.x / 2,
|
||||||
self.collisionbox[4]/2, self.collisionbox[5]/2, self.collisionbox[6]/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
|
||||||
|
},
|
||||||
})
|
})
|
||||||
ent2.child = true
|
ent2.child = true
|
||||||
ent2.tamed = true
|
ent2.tamed = true
|
||||||
@ -464,7 +557,10 @@ function mobs:register_mob(name, def)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- find player to follow
|
-- 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
|
local s, p, dist
|
||||||
for _,player in pairs(minetest.get_connected_players()) do
|
for _,player in pairs(minetest.get_connected_players()) do
|
||||||
s = self.object:getpos()
|
s = self.object:getpos()
|
||||||
@ -482,14 +578,21 @@ function mobs:register_mob(name, def)
|
|||||||
self.do_custom(self)
|
self.do_custom(self)
|
||||||
end
|
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
|
-- 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
|
self.following = nil
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
-- stop following player if not holding specific item
|
-- 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
|
self.following = nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -499,7 +602,8 @@ function mobs:register_mob(name, def)
|
|||||||
local s = self.object:getpos()
|
local s = self.object:getpos()
|
||||||
local p
|
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()
|
p = self.following:getpos()
|
||||||
elseif self.following.object then
|
elseif self.following.object then
|
||||||
p = self.following.object:getpos()
|
p = self.following.object:getpos()
|
||||||
@ -511,17 +615,25 @@ function mobs:register_mob(name, def)
|
|||||||
self.following = nil
|
self.following = nil
|
||||||
else
|
else
|
||||||
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 = (math.atan(vec.z/vec.x)+math.pi/2) + self.rotate -- local
|
yaw = (math.atan(vec.z / vec.x) + math.pi / 2) + self.rotate
|
||||||
if p.x > s.x then
|
if p.x > s.x then
|
||||||
yaw = yaw + math.pi
|
yaw = yaw + math.pi
|
||||||
end
|
end
|
||||||
self.object:setyaw(yaw)
|
self.object:setyaw(yaw)
|
||||||
|
|
||||||
-- anyone but standing npc's can move along
|
-- anyone but standing npc's can move along
|
||||||
if dist > 4 and self.order ~= "stand" then --/MFF (Crabman|07/14/2015) follow but at distance, default value is 2
|
if dist > 4 --/MFF (Crabman|07/14/2015) follow but at distance, default value is 2
|
||||||
if (self.jump and self.get_velocity(self) <= 0.5 and self.object:getvelocity().y == 0)
|
and self.order ~= "stand" then
|
||||||
or (self.object:getvelocity().y == 0 and self.jump_chance > 0) then
|
if (self.jump
|
||||||
self.direction = {x = math.sin(yaw)*-1, y = -20, z = math.cos(yaw)}
|
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)
|
do_jump(self)
|
||||||
end
|
end
|
||||||
self.set_velocity(self, self.walk_velocity)
|
self.set_velocity(self, self.walk_velocity)
|
||||||
@ -572,12 +684,14 @@ function mobs:register_mob(name, def)
|
|||||||
self.set_animation(self, "stand")
|
self.set_animation(self, "stand")
|
||||||
|
|
||||||
-- npc's ordered to stand stay standing
|
-- 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.set_velocity(self, 0)
|
||||||
self.state = "stand"
|
self.state = "stand"
|
||||||
self:set_animation("stand")
|
self:set_animation("stand")
|
||||||
else
|
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.set_velocity(self, self.walk_velocity)
|
||||||
self.state = "walk"
|
self.state = "walk"
|
||||||
self.set_animation(self, "walk")
|
self.set_animation(self, "walk")
|
||||||
@ -596,7 +710,9 @@ function mobs:register_mob(name, def)
|
|||||||
local lp = minetest.find_node_near(s, 1, {"group:water"})
|
local lp = minetest.find_node_near(s, 1, {"group:water"})
|
||||||
|
|
||||||
-- water swimmers cannot move out of 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")
|
print ("out of water")
|
||||||
self.set_velocity(self, 0)
|
self.set_velocity(self, 0)
|
||||||
self.state = "flop" -- change to undefined state so nothing more happens
|
self.state = "flop" -- change to undefined state so nothing more happens
|
||||||
@ -616,8 +732,13 @@ end
|
|||||||
elseif math.random(1, 100) <= 30 then
|
elseif math.random(1, 100) <= 30 then
|
||||||
self.object:setyaw(self.object:getyaw() + ((math.random(0, 360) - 180) / 180 * math.pi))
|
self.object:setyaw(self.object:getyaw() + ((math.random(0, 360) - 180) / 180 * math.pi))
|
||||||
end
|
end
|
||||||
if self.jump and self.get_velocity(self) <= 0.5 and self.object:getvelocity().y == 0 then
|
if self.jump and self.get_velocity(self) <= 0.5
|
||||||
self.direction = {x = math.sin(yaw)*-1, y = -20, z = math.cos(yaw)}
|
and self.object:getvelocity().y == 0 then
|
||||||
|
self.direction = {
|
||||||
|
x = math.sin(yaw) * -1,
|
||||||
|
y = -20,
|
||||||
|
z = math.cos(yaw)
|
||||||
|
}
|
||||||
do_jump(self)
|
do_jump(self)
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -631,7 +752,8 @@ end
|
|||||||
|
|
||||||
-- exploding mobs
|
-- exploding mobs
|
||||||
elseif self.state == "attack" and self.attack_type == "explode" then
|
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.state = "stand"
|
||||||
self:set_animation("stand")
|
self:set_animation("stand")
|
||||||
self.timer = 0
|
self.timer = 0
|
||||||
@ -670,7 +792,8 @@ end
|
|||||||
else
|
else
|
||||||
self.timer = 0
|
self.timer = 0
|
||||||
self.blinktimer = 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()
|
local v = self.object:getvelocity()
|
||||||
v.y = 5
|
v.y = 5
|
||||||
self.object:setvelocity(v)
|
self.object:setvelocity(v)
|
||||||
@ -704,18 +827,20 @@ end
|
|||||||
max_hear_distance = 16
|
max_hear_distance = 16
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
pos.y = pos.y + 1
|
|
||||||
effect(pos, 15, "tnt_smoke.png", 5)
|
effect(pos, 15, "tnt_smoke.png", 5)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
self.object:remove()
|
self.object:remove()
|
||||||
mobs:explosion(pos, 2, 0, 1, "tnt_explode", self.sounds.explode)
|
pos.y = pos.y - 1
|
||||||
|
mobs:explosion(pos, 2, 0, 1, self.sounds.explode)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
-- end of exploding mobs
|
-- end of exploding mobs
|
||||||
|
|
||||||
elseif self.state == "attack" and self.attack_type == "dogfight" then
|
elseif self.state == "attack"
|
||||||
if not self.attack.player or not self.attack.player:getpos() then
|
and self.attack_type == "dogfight" then
|
||||||
|
if not self.attack.player
|
||||||
|
or not self.attack.player:getpos() then
|
||||||
print("stop attacking")
|
print("stop attacking")
|
||||||
self.state = "stand"
|
self.state = "stand"
|
||||||
self:set_animation("stand")
|
self:set_animation("stand")
|
||||||
@ -726,7 +851,8 @@ end
|
|||||||
local dist = ((p.x - s.x) ^ 2 + (p.y - s.y) ^ 2 + (p.z - s.z) ^ 2) ^ 0.5
|
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
|
-- 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 nod = minetest.get_node_or_nil(s)
|
||||||
local p1 = s
|
local p1 = s
|
||||||
@ -734,24 +860,42 @@ end
|
|||||||
local p2 = p
|
local p2 = p
|
||||||
local p_y = math.floor(p2.y + 1)
|
local p_y = math.floor(p2.y + 1)
|
||||||
local v = self.object:getvelocity()
|
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
|
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
|
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
|
end
|
||||||
else
|
else
|
||||||
if me_y < p_y then
|
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
|
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
|
||||||
|
|
||||||
end
|
end
|
||||||
-- end fly bit
|
-- 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.state = "stand"
|
||||||
self.set_velocity(self, 0)
|
self.set_velocity(self, 0)
|
||||||
self.attack = {player = nil, dist = nil}
|
self.attack = {player = nil, dist = nil}
|
||||||
@ -770,9 +914,16 @@ end
|
|||||||
-- attack distance is 2 + half of mob width so the bigger mobs can attack (like slimes)
|
-- 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
|
if self.attack.dist > ((-self.collisionbox[1] + self.collisionbox[4]) / 2) + 2 then
|
||||||
-- jump attack
|
-- jump attack
|
||||||
if (self.jump and self.get_velocity(self) <= 0.5 and self.object:getvelocity().y == 0)
|
if (self.jump
|
||||||
or (self.object:getvelocity().y == 0 and self.jump_chance > 0) then
|
and self.get_velocity(self) <= 0.5
|
||||||
self.direction = {x = math.sin(yaw)*-1, y = -20, z = math.cos(yaw)}
|
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)
|
do_jump(self)
|
||||||
end
|
end
|
||||||
self.set_velocity(self, self.run_velocity)
|
self.set_velocity(self, self.run_velocity)
|
||||||
@ -805,14 +956,16 @@ end
|
|||||||
end
|
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 s = self.object:getpos()
|
||||||
local p = self.attack.player:getpos()
|
local p = self.attack.player:getpos()
|
||||||
p.y = p.y - .5
|
p.y = p.y - .5
|
||||||
s.y = s.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
|
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.state = "stand"
|
||||||
self.set_velocity(self, 0)
|
self.set_velocity(self, 0)
|
||||||
self:set_animation("stand")
|
self:set_animation("stand")
|
||||||
@ -822,14 +975,16 @@ end
|
|||||||
end
|
end
|
||||||
|
|
||||||
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 = (math.atan(vec.z/vec.x)+math.pi/2) + self.rotate -- local
|
yaw = (math.atan(vec.z/vec.x)+math.pi/2) + self.rotate
|
||||||
if p.x > s.x then
|
if p.x > s.x then
|
||||||
yaw = yaw + math.pi
|
yaw = yaw + math.pi
|
||||||
end
|
end
|
||||||
self.object:setyaw(yaw)
|
self.object:setyaw(yaw)
|
||||||
self.set_velocity(self, 0)
|
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.timer = 0
|
||||||
|
|
||||||
self:set_animation("punch")
|
self:set_animation("punch")
|
||||||
@ -856,7 +1011,8 @@ end
|
|||||||
end,
|
end,
|
||||||
|
|
||||||
on_activate = function(self, staticdata, dtime_s)
|
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()
|
self.object:remove()
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -869,8 +1025,7 @@ end
|
|||||||
self.object:setvelocity({x = 0, y = self.object:getvelocity().y, z = 0})
|
self.object:setvelocity({x = 0, y = self.object:getvelocity().y, z = 0})
|
||||||
self.old_y = self.object:getpos().y
|
self.old_y = self.object:getpos().y
|
||||||
self.object:setyaw(math.random(1, 360) / 180 * math.pi)
|
self.object:setyaw(math.random(1, 360) / 180 * math.pi)
|
||||||
|
self.sounds.distance = (self.sounds.distance or 10)
|
||||||
if not self.sounds.distance then self.sounds.distance = 10 end
|
|
||||||
|
|
||||||
if staticdata then
|
if staticdata then
|
||||||
local tmp = minetest.deserialize(staticdata)
|
local tmp = minetest.deserialize(staticdata)
|
||||||
@ -928,11 +1083,13 @@ end
|
|||||||
local vis_size = self.visual_size
|
local vis_size = self.visual_size
|
||||||
local colbox = self.collisionbox
|
local colbox = self.collisionbox
|
||||||
-- specific texture if gotten
|
-- 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
|
textures = def.gotten_texture
|
||||||
end
|
end
|
||||||
-- specific mesh if gotten
|
-- 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
|
mesh = def.gotten_mesh
|
||||||
end
|
end
|
||||||
-- if object is child then set half size
|
-- if object is child then set half size
|
||||||
@ -941,8 +1098,10 @@ end
|
|||||||
if def.child_texture then
|
if def.child_texture then
|
||||||
textures = def.child_texture[1]
|
textures = def.child_texture[1]
|
||||||
end
|
end
|
||||||
colbox = {self.collisionbox[1]/2, self.collisionbox[2]/2, self.collisionbox[3]/2,
|
colbox = {
|
||||||
self.collisionbox[4]/2, self.collisionbox[5]/2, self.collisionbox[6]/2}
|
self.collisionbox[1] / 2, self.collisionbox[2] / 2, self.collisionbox[3] / 2,
|
||||||
|
self.collisionbox[4] / 2, self.collisionbox[5] / 2, self.collisionbox[6] / 2
|
||||||
|
}
|
||||||
end
|
end
|
||||||
-- remember settings
|
-- remember settings
|
||||||
local tmp = {
|
local tmp = {
|
||||||
@ -992,7 +1151,9 @@ end
|
|||||||
-- blood_particles
|
-- blood_particles
|
||||||
local pos = self.object:getpos()
|
local pos = self.object:getpos()
|
||||||
pos.y = pos.y + (-self.collisionbox[2] + self.collisionbox[5]) / 2
|
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)
|
effect(pos, self.blood_amount, self.blood_texture)
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -1008,7 +1169,8 @@ end
|
|||||||
self.pause_timer = r
|
self.pause_timer = r
|
||||||
|
|
||||||
-- attack puncher and call other mobs for help
|
-- 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
|
if self.state ~= "attack" then
|
||||||
self.do_attack(self, hitter, 1)
|
self.do_attack(self, hitter, 1)
|
||||||
end
|
end
|
||||||
@ -1017,7 +1179,8 @@ end
|
|||||||
for _, oir in pairs(minetest.get_objects_inside_radius(hitter:getpos(), 5)) do
|
for _, oir in pairs(minetest.get_objects_inside_radius(hitter:getpos(), 5)) do
|
||||||
obj = oir:get_luaentity()
|
obj = oir:get_luaentity()
|
||||||
if obj then
|
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)
|
obj.do_attack(obj, hitter, 1)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -1037,7 +1200,7 @@ function mobs:spawn_specific(name, nodes, neighbors, min_light, max_light, inter
|
|||||||
interval = interval,
|
interval = interval,
|
||||||
chance = chance,
|
chance = chance,
|
||||||
action = function(pos, node, _, active_object_count_wider)
|
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
|
if active_object_count_wider > active_object_count
|
||||||
or not mobs.spawning_mobs[name]
|
or not mobs.spawning_mobs[name]
|
||||||
or not pos then
|
or not pos then
|
||||||
@ -1048,25 +1211,39 @@ function mobs:spawn_specific(name, nodes, neighbors, min_light, max_light, inter
|
|||||||
pos.y = pos.y + 1
|
pos.y = pos.y + 1
|
||||||
|
|
||||||
-- mobs cannot spawn inside protected areas if enabled
|
-- 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
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
-- check if light and height levels are ok to spawn
|
-- check if light and height levels are ok to spawn
|
||||||
local light = minetest.get_node_light(pos)
|
local light = minetest.get_node_light(pos)
|
||||||
if not light or light > max_light or light < min_light
|
if not light
|
||||||
or pos.y > max_height or pos.y < min_height then
|
or light > max_light
|
||||||
|
or light < min_light
|
||||||
|
or pos.y > max_height
|
||||||
|
or pos.y < min_height then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
-- are we spawning inside a solid node?
|
-- are we spawning inside a solid node?
|
||||||
local nod = minetest.get_node_or_nil(pos)
|
local nod = minetest.get_node_or_nil(pos)
|
||||||
if not nod or not nod.name or not minetest.registered_nodes[nod.name]
|
if not nod
|
||||||
or minetest.registered_nodes[nod.name].walkable == true then return end
|
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
|
pos.y = pos.y + 1
|
||||||
|
|
||||||
nod = minetest.get_node_or_nil(pos)
|
nod = minetest.get_node_or_nil(pos)
|
||||||
if not nod or not nod.name or not minetest.registered_nodes[nod.name]
|
if not nod
|
||||||
or minetest.registered_nodes[nod.name].walkable == true then return end
|
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
|
if minetest.setting_getbool("display_mob_spawn") then
|
||||||
minetest.chat_send_all("[mobs] Add "..name.." at "..minetest.pos_to_string(pos))
|
minetest.chat_send_all("[mobs] Add "..name.." at "..minetest.pos_to_string(pos))
|
||||||
@ -1122,7 +1299,8 @@ function mobs:explosion(pos, radius, fire, smoke, sound)
|
|||||||
local c_obsidian = minetest.get_content_id("default:obsidian")
|
local c_obsidian = minetest.get_content_id("default:obsidian")
|
||||||
local c_brick = minetest.get_content_id("default:obsidianbrick")
|
local c_brick = minetest.get_content_id("default:obsidianbrick")
|
||||||
local c_chest = minetest.get_content_id("default:chest_locked")
|
local c_chest = minetest.get_content_id("default:chest_locked")
|
||||||
if sound and sound ~= "" then
|
if sound
|
||||||
|
and sound ~= "" then
|
||||||
minetest.sound_play(sound, {
|
minetest.sound_play(sound, {
|
||||||
pos = pos,
|
pos = pos,
|
||||||
gain = 1.0,
|
gain = 1.0,
|
||||||
@ -1140,7 +1318,9 @@ function mobs:explosion(pos, radius, fire, smoke, sound)
|
|||||||
p.x = pos.x + x
|
p.x = pos.x + x
|
||||||
p.y = pos.y + y
|
p.y = pos.y + y
|
||||||
p.z = pos.z + z
|
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
|
local n = minetest.get_node(p).name
|
||||||
-- do NOT destroy protection nodes but DO destroy nodes in protected area
|
-- do NOT destroy protection nodes but DO destroy nodes in protected area
|
||||||
if not n:find("protector:")
|
if not n:find("protector:")
|
||||||
@ -1158,7 +1338,9 @@ function mobs:explosion(pos, radius, fire, smoke, sound)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if fire > 0 and (minetest.registered_nodes[n].groups.flammable or math.random(1, 100) <= 30) then
|
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"})
|
minetest.set_node(p, {name = "fire:basic_flame"})
|
||||||
else
|
else
|
||||||
minetest.remove_node(p)
|
minetest.remove_node(p)
|
||||||
@ -1193,9 +1375,14 @@ function check_for_death(self)
|
|||||||
local obj = nil
|
local obj = nil
|
||||||
for _,drop in ipairs(self.drops) do
|
for _,drop in ipairs(self.drops) do
|
||||||
if math.random(1, drop.chance) == 1 then
|
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
|
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
|
end
|
||||||
end
|
end
|
||||||
@ -1259,38 +1446,45 @@ function mobs:register_arrow(name, def)
|
|||||||
on_step = function(self, dtime)
|
on_step = function(self, dtime)
|
||||||
self.timer = (self.timer or 0) + 1
|
self.timer = (self.timer or 0) + 1
|
||||||
if self.timer > 150 then self.object:remove() return end
|
if self.timer > 150 then self.object:remove() return end
|
||||||
|
|
||||||
local engage = 10 - (self.velocity / 2) -- clear entity before arrow becomes active
|
local engage = 10 - (self.velocity / 2) -- clear entity before arrow becomes active
|
||||||
local pos = self.object:getpos()
|
local pos = self.object:getpos()
|
||||||
local node = minetest.get_node(self.object:getpos()).name
|
local node = minetest.get_node_or_nil(self.object:getpos())
|
||||||
|
if node then node = node.name else node = "air" end
|
||||||
-- hit node you can walk on
|
-- hit node you can walk on
|
||||||
if self.hit_node and node and minetest.registered_nodes[node] and minetest.registered_nodes[node].walkable then
|
if self.hit_node
|
||||||
|
and minetest.registered_nodes[node]
|
||||||
|
and minetest.registered_nodes[node].walkable then
|
||||||
self.hit_node(self, pos, node)
|
self.hit_node(self, pos, node)
|
||||||
if self.drop == true then
|
if self.drop == true then
|
||||||
pos.y = pos.y + 1 ; self.lastpos = (self.lastpos or pos)
|
pos.y = pos.y + 1
|
||||||
|
self.lastpos = (self.lastpos or pos)
|
||||||
minetest.add_item(self.lastpos, self.object:get_luaentity().name)
|
minetest.add_item(self.lastpos, self.object:get_luaentity().name)
|
||||||
end
|
end
|
||||||
self.object:remove()
|
self.object:remove() ; -- print ("hit node")
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
if self.hit_player or self.hit_mob then
|
if (self.hit_player or self.hit_mob)
|
||||||
for _,player in pairs(minetest.get_objects_inside_radius(pos, 1)) do
|
and self.timer > engage then
|
||||||
-- hit player
|
for _,player in pairs(minetest.get_objects_inside_radius(pos, 1.0)) do
|
||||||
if self.hit_player and self.timer > engage and player:is_player() then
|
if self.hit_player
|
||||||
|
and player:is_player() then
|
||||||
self.hit_player(self, player)
|
self.hit_player(self, player)
|
||||||
self.object:remove()
|
self.object:remove() ; -- print ("hit player")
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
-- hit mob
|
-- hit mob
|
||||||
if self.hit_mob and self.timer > engage and player:get_luaentity().name ~= self.object:get_luaentity().name
|
if self.hit_mob
|
||||||
|
and player:get_luaentity().name ~= self.object:get_luaentity().name
|
||||||
and player:get_luaentity().name ~= "__builtin:item" then
|
and player:get_luaentity().name ~= "__builtin:item" then
|
||||||
self.hit_mob(self, player)
|
self.hit_mob(self, player)
|
||||||
self.object:remove()
|
self.object:remove() ; -- print ("hit mob")
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
self.lastpos = pos
|
|
||||||
end
|
end
|
||||||
|
self.lastpos = pos
|
||||||
end
|
end
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
@ -1306,7 +1500,8 @@ function mobs:register_egg(mob, desc, background, addegg)
|
|||||||
inventory_image = invimg,
|
inventory_image = invimg,
|
||||||
on_place = function(itemstack, placer, pointed_thing)
|
on_place = function(itemstack, placer, pointed_thing)
|
||||||
local pos = pointed_thing.above
|
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
|
pos.y = pos.y + 0.5
|
||||||
local mob = minetest.add_entity(pos, mob)
|
local mob = minetest.add_entity(pos, mob)
|
||||||
local ent = mob:get_luaentity()
|
local ent = mob:get_luaentity()
|
||||||
@ -1324,7 +1519,9 @@ end
|
|||||||
|
|
||||||
-- capture critter (thanks to blert2112 for idea)
|
-- capture critter (thanks to blert2112 for idea)
|
||||||
function mobs:capture_mob(self, clicker, chance_hand, chance_net, chance_lasso, force_take, replacewith)
|
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
|
-- get name of clicked mob
|
||||||
local mobname = self.name
|
local mobname = self.name
|
||||||
-- if not nil change what will be added to inventory
|
-- if not nil change what will be added to inventory
|
||||||
@ -1333,11 +1530,13 @@ function mobs:capture_mob(self, clicker, chance_hand, chance_net, chance_lasso,
|
|||||||
end
|
end
|
||||||
--print ("taking by force is", force_take)
|
--print ("taking by force is", force_take)
|
||||||
local name = clicker:get_player_name()
|
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!")
|
minetest.chat_send_player(name, "Not tamed!")
|
||||||
return
|
return
|
||||||
-- cannot pick up if not owner
|
-- 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!")
|
minetest.chat_send_player(name, "Not owner!")
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
@ -12,6 +12,7 @@ mobs:register_mob("mobs:chicken", {
|
|||||||
collisionbox = {-0.3, -0.75, -0.3, 0.3, 0.1, 0.3},
|
collisionbox = {-0.3, -0.75, -0.3, 0.3, 0.1, 0.3},
|
||||||
visual = "mesh",
|
visual = "mesh",
|
||||||
mesh = "mobs_chicken.x",
|
mesh = "mobs_chicken.x",
|
||||||
|
-- seems a lot of textures but this fixes the problem with the model
|
||||||
textures = {
|
textures = {
|
||||||
{"mobs_chicken.png", "mobs_chicken.png", "mobs_chicken.png", "mobs_chicken.png",
|
{"mobs_chicken.png", "mobs_chicken.png", "mobs_chicken.png", "mobs_chicken.png",
|
||||||
"mobs_chicken.png", "mobs_chicken.png", "mobs_chicken.png", "mobs_chicken.png", "mobs_chicken.png"},
|
"mobs_chicken.png", "mobs_chicken.png", "mobs_chicken.png", "mobs_chicken.png", "mobs_chicken.png"},
|
||||||
@ -84,7 +85,8 @@ mobs:register_mob("mobs:chicken", {
|
|||||||
self.owner = name
|
self.owner = name
|
||||||
end
|
end
|
||||||
minetest.sound_play("mobs_chicken", {
|
minetest.sound_play("mobs_chicken", {
|
||||||
object = self.object,gain = 1.0,
|
object = self.object,
|
||||||
|
gain = 1.0,
|
||||||
max_hear_distance = 15,
|
max_hear_distance = 15,
|
||||||
loop = false,
|
loop = false,
|
||||||
})
|
})
|
||||||
|
@ -21,7 +21,6 @@ mobs:register_mob("mobs:cow", {
|
|||||||
--{"mobs_cow_brown.png"}, -- dé-commenter quand "mobs_cow_brown.png" sera compatible
|
--{"mobs_cow_brown.png"}, -- dé-commenter quand "mobs_cow_brown.png" sera compatible
|
||||||
},
|
},
|
||||||
blood_texture = "mobs_blood.png",
|
blood_texture = "mobs_blood.png",
|
||||||
visual_size = {x=1,y=1},
|
|
||||||
-- sounds
|
-- sounds
|
||||||
makes_footstep_sound = true,
|
makes_footstep_sound = true,
|
||||||
sounds = {
|
sounds = {
|
||||||
@ -107,7 +106,7 @@ mobs:register_mob("mobs:cow", {
|
|||||||
minetest.sound_play("mobs_cow", {
|
minetest.sound_play("mobs_cow", {
|
||||||
object = self.object,
|
object = self.object,
|
||||||
gain = 1.0,
|
gain = 1.0,
|
||||||
max_hear_distance = 32,
|
max_hear_distance = 16,
|
||||||
loop = false,
|
loop = false,
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
@ -131,10 +130,10 @@ mobs:register_mob("mobs:cow", {
|
|||||||
elseif self.owner ~= name then
|
elseif self.owner ~= name then
|
||||||
minetest.chat_send_player(name, "Not owner!")
|
minetest.chat_send_player(name, "Not owner!")
|
||||||
end
|
end
|
||||||
|
--]]
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
})--]]
|
})
|
||||||
-- spawn on default;green;prairie grass between 0 and 20 light, 1 in 11000 chance, 1 cow in area up to 31000 in height
|
-- spawn on default;green;prairie grass between 0 and 20 light, 1 in 11000 chance, 1 cow in area up to 31000 in height
|
||||||
mobs:register_spawn("mobs:cow", {"default:dirt_with_grass"}, 20, 8, 10000, 1, 31000)
|
mobs:register_spawn("mobs:cow", {"default:dirt_with_grass"}, 20, 8, 10000, 1, 31000)
|
||||||
-- register spawn egg
|
-- register spawn egg
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
|
|
||||||
-- Meat & Cooked Meat
|
-- raw meat
|
||||||
|
|
||||||
minetest.register_craftitem("mobs:meat_raw", {
|
minetest.register_craftitem("mobs:meat_raw", {
|
||||||
description = "Raw Meat",
|
description = "Raw Meat",
|
||||||
inventory_image = "mobs_meat_raw.png",
|
inventory_image = "mobs_meat_raw.png",
|
||||||
on_use = minetest.item_eat(3),
|
on_use = minetest.item_eat(3),
|
||||||
})
|
})
|
||||||
|
|
||||||
|
-- cooked meat
|
||||||
minetest.register_craftitem("mobs:meat", {
|
minetest.register_craftitem("mobs:meat", {
|
||||||
description = "Meat",
|
description = "Meat",
|
||||||
inventory_image = "mobs_meat.png",
|
inventory_image = "mobs_meat.png",
|
||||||
@ -20,8 +20,7 @@ minetest.register_craft({
|
|||||||
cooktime = 5,
|
cooktime = 5,
|
||||||
})
|
})
|
||||||
|
|
||||||
-- Golden Lasso
|
-- golden lasso
|
||||||
|
|
||||||
minetest.register_tool("mobs:magic_lasso", {
|
minetest.register_tool("mobs:magic_lasso", {
|
||||||
description = "Magic Lasso (right-click animal to put in inventory)",
|
description = "Magic Lasso (right-click animal to put in inventory)",
|
||||||
inventory_image = "mobs_magic_lasso.png",
|
inventory_image = "mobs_magic_lasso.png",
|
||||||
@ -36,8 +35,7 @@ minetest.register_craft({
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
-- Net
|
-- net
|
||||||
|
|
||||||
minetest.register_tool("mobs:net", {
|
minetest.register_tool("mobs:net", {
|
||||||
description = "Net (right-click animal to put in inventory)",
|
description = "Net (right-click animal to put in inventory)",
|
||||||
inventory_image = "mobs_net.png",
|
inventory_image = "mobs_net.png",
|
||||||
|
@ -13,13 +13,12 @@ mobs:register_mob("mobs:dirt_monster", {
|
|||||||
hp_max = 30,
|
hp_max = 30,
|
||||||
armor = 90,
|
armor = 90,
|
||||||
-- textures and model
|
-- textures and model
|
||||||
collisionbox = {-0.4, -0.01, -0.4, 0.4, 1.9, 0.4},
|
collisionbox = {-0.4, -1, -0.4, 0.4, 0.8, 0.4},
|
||||||
visual = "mesh",
|
visual = "mesh",
|
||||||
mesh = "mobs_stone_monster.x",
|
mesh = "mobs_stone_monster.b3d",
|
||||||
textures = {
|
textures = {
|
||||||
{"mobs_dirt_monster.png"},
|
{"mobs_dirt_monster.png"},
|
||||||
},
|
},
|
||||||
visual_size = {x=3, y=2.6},
|
|
||||||
blood_texture = "default_dirt.png",
|
blood_texture = "default_dirt.png",
|
||||||
-- sounds
|
-- sounds
|
||||||
makes_footstep_sound = true,
|
makes_footstep_sound = true,
|
||||||
|
@ -13,13 +13,13 @@ mobs:register_mob("mobs:dungeon_master", {
|
|||||||
attack_type = "shoot",
|
attack_type = "shoot",
|
||||||
shoot_interval = 2.5,
|
shoot_interval = 2.5,
|
||||||
arrow = "mobs:fireball",
|
arrow = "mobs:fireball",
|
||||||
shoot_offset = 0,
|
shoot_offset = 1,
|
||||||
-- health & armor
|
-- health & armor
|
||||||
hp_min = 60,
|
hp_min = 60,
|
||||||
hp_max = 80,
|
hp_max = 80,
|
||||||
armor = 70,
|
armor = 70,
|
||||||
-- textures and model
|
-- textures and model
|
||||||
collisionbox = {-0.7, -0.01, -0.7, 0.7, 2.6, 0.7},
|
collisionbox = {-0.7, -1, -0.7, 0.7, 1.6, 0.7},
|
||||||
visual = "mesh",
|
visual = "mesh",
|
||||||
mesh = "mobs_dungeon_master.b3d",
|
mesh = "mobs_dungeon_master.b3d",
|
||||||
textures = {
|
textures = {
|
||||||
@ -27,7 +27,6 @@ mobs:register_mob("mobs:dungeon_master", {
|
|||||||
{"mobs_dungeon_master_cobblestone.png"},
|
{"mobs_dungeon_master_cobblestone.png"},
|
||||||
{"mobs_dungeon_master_strangewhite.png"},
|
{"mobs_dungeon_master_strangewhite.png"},
|
||||||
},
|
},
|
||||||
visual_size = {x=8, y=8},
|
|
||||||
blood_texture = "mobs_blood.png",
|
blood_texture = "mobs_blood.png",
|
||||||
-- sounds
|
-- sounds
|
||||||
makes_footstep_sound = true,
|
makes_footstep_sound = true,
|
||||||
|
@ -20,7 +20,6 @@ mobs:register_mob("mobs:lava_flan", {
|
|||||||
{"zmobs_lava_flan.png"},
|
{"zmobs_lava_flan.png"},
|
||||||
},
|
},
|
||||||
blood_texture = "fire_basic_flame.png",
|
blood_texture = "fire_basic_flame.png",
|
||||||
visual_size = {x=1, y=1},
|
|
||||||
-- sounds
|
-- sounds
|
||||||
makes_footstep_sound = false,
|
makes_footstep_sound = false,
|
||||||
sounds = {
|
sounds = {
|
||||||
|
@ -69,7 +69,7 @@ mobs:register_egg("mobs:mese_monster", "Mese Monster", "default_mese_block.png",
|
|||||||
-- mese arrow (weapon)
|
-- mese arrow (weapon)
|
||||||
mobs:register_arrow("mobs:mese_arrow", {
|
mobs:register_arrow("mobs:mese_arrow", {
|
||||||
visual = "sprite",
|
visual = "sprite",
|
||||||
visual_size = {x=.5, y=.5},
|
visual_size = {x = 0.5, y = 0.5},
|
||||||
textures = {"default_mese_crystal_fragment.png"},
|
textures = {"default_mese_crystal_fragment.png"},
|
||||||
velocity = 6,
|
velocity = 6,
|
||||||
|
|
||||||
|
@ -27,7 +27,6 @@ mobs:register_mob("mobs:npc", {
|
|||||||
{"mobs_npc.png"},
|
{"mobs_npc.png"},
|
||||||
{"mobs_npc2.png"}, -- female by nuttmeg20
|
{"mobs_npc2.png"}, -- female by nuttmeg20
|
||||||
},
|
},
|
||||||
visual_size = {x=1, y=1},
|
|
||||||
-- sounds
|
-- sounds
|
||||||
makes_footstep_sound = true,
|
makes_footstep_sound = true,
|
||||||
sounds = {},
|
sounds = {},
|
||||||
@ -69,7 +68,7 @@ mobs:register_mob("mobs:npc", {
|
|||||||
local item = clicker:get_wielded_item()
|
local item = clicker:get_wielded_item()
|
||||||
local name = clicker:get_player_name()
|
local name = clicker:get_player_name()
|
||||||
if not name then return end
|
if not name then return end
|
||||||
-- heal npc
|
-- feed toheal npc
|
||||||
if item:get_name() == "mobs:meat"
|
if item:get_name() == "mobs:meat"
|
||||||
or item:get_name() == "farming:bread" then
|
or item:get_name() == "farming:bread" then
|
||||||
-- feed and add health
|
-- feed and add health
|
||||||
@ -80,7 +79,6 @@ mobs:register_mob("mobs:npc", {
|
|||||||
return
|
return
|
||||||
end
|
end
|
||||||
hp = hp + 4 -- add restorative value
|
hp = hp + 4 -- add restorative value
|
||||||
-- new health shouldn't exceed self.hp_max
|
|
||||||
if hp > self.hp_max then hp = self.hp_max end
|
if hp > self.hp_max then hp = self.hp_max end
|
||||||
self.object:set_hp(hp)
|
self.object:set_hp(hp)
|
||||||
-- take item
|
-- take item
|
||||||
|
@ -13,14 +13,13 @@ mobs:register_mob("mobs:oerkki", {
|
|||||||
hp_max = 50,
|
hp_max = 50,
|
||||||
armor = 90,
|
armor = 90,
|
||||||
-- textures and model
|
-- textures and model
|
||||||
collisionbox = {-0.4, -0.01, -0.4, 0.4, 1.9, 0.4},
|
collisionbox = {-0.4, -1, -0.4, 0.4, 0.9, 0.4},
|
||||||
visual = "mesh",
|
visual = "mesh",
|
||||||
mesh = "mobs_oerkki.b3d",
|
mesh = "mobs_oerkki.b3d",
|
||||||
textures = {
|
textures = {
|
||||||
{"mobs_oerkki.png"},
|
{"mobs_oerkki.png"},
|
||||||
{"mobs_oerkki2.png"},
|
{"mobs_oerkki2.png"},
|
||||||
},
|
},
|
||||||
visual_size = {x=5, y=5},
|
|
||||||
blood_texture = "mobs_blood.png",
|
blood_texture = "mobs_blood.png",
|
||||||
-- sounds
|
-- sounds
|
||||||
makes_footstep_sound = false,
|
makes_footstep_sound = false,
|
||||||
|
@ -11,7 +11,7 @@ mobs:register_mob("mobs:rat", {
|
|||||||
hp_max = 4,
|
hp_max = 4,
|
||||||
armor = 200,
|
armor = 200,
|
||||||
-- textures and model
|
-- textures and model
|
||||||
collisionbox = {-0.2, -0.01, -0.2, 0.2, 0.2, 0.2},
|
collisionbox = {-0.2, -1, -0.2, 0.2, -0.8, 0.2},
|
||||||
visual = "mesh",
|
visual = "mesh",
|
||||||
mesh = "mobs_rat.b3d",
|
mesh = "mobs_rat.b3d",
|
||||||
textures = {
|
textures = {
|
||||||
|
@ -13,7 +13,7 @@ mobs:register_mob("mobs:sand_monster", {
|
|||||||
hp_max = 20,
|
hp_max = 20,
|
||||||
armor = 100,
|
armor = 100,
|
||||||
-- textures and model
|
-- textures and model
|
||||||
collisionbox = {-0.4, -0.01, -0.4, 0.4, 1.9, 0.4},
|
collisionbox = {-0.4, -1, -0.4, 0.4, 0.8, 0.4},
|
||||||
visual = "mesh",
|
visual = "mesh",
|
||||||
mesh = "mobs_sand_monster.b3d",
|
mesh = "mobs_sand_monster.b3d",
|
||||||
textures = {
|
textures = {
|
||||||
|
@ -1,4 +1,9 @@
|
|||||||
|
|
||||||
|
local all_colours = {
|
||||||
|
"grey", "black", "red", "yellow", "green", "cyan", "blue", "magenta",
|
||||||
|
"orange", "violet", "brown", "pink", "dark_grey", "dark_green"
|
||||||
|
}
|
||||||
|
|
||||||
-- Sheep by PilzAdam
|
-- Sheep by PilzAdam
|
||||||
|
|
||||||
mobs:register_mob("mobs:sheep", {
|
mobs:register_mob("mobs:sheep", {
|
||||||
@ -11,7 +16,7 @@ mobs:register_mob("mobs:sheep", {
|
|||||||
hp_max = 15,
|
hp_max = 15,
|
||||||
armor = 200,
|
armor = 200,
|
||||||
-- textures and model
|
-- textures and model
|
||||||
collisionbox = {-0.4, -0.01, -0.4, 0.4, 1, 0.4},
|
collisionbox = {-0.4, -1, -0.4, 0.4, 0.3, 0.4},
|
||||||
visual = "mesh",
|
visual = "mesh",
|
||||||
mesh = "mobs_sheep.b3d",
|
mesh = "mobs_sheep.b3d",
|
||||||
textures = {
|
textures = {
|
||||||
@ -56,6 +61,7 @@ mobs:register_mob("mobs:sheep", {
|
|||||||
replace_what = {"default:grass_3", "default:grass_4", "default:grass_5", "farming:wheat_8"},
|
replace_what = {"default:grass_3", "default:grass_4", "default:grass_5", "farming:wheat_8"},
|
||||||
replace_with = "air",
|
replace_with = "air",
|
||||||
-- right click sheep to shear sheep and get wood, feed 8 wheat for wool to grow back
|
-- right click sheep to shear sheep and get wood, feed 8 wheat for wool to grow back
|
||||||
|
replace_offset = -1,
|
||||||
on_rightclick = function(self, clicker)
|
on_rightclick = function(self, clicker)
|
||||||
local item = clicker:get_wielded_item()
|
local item = clicker:get_wielded_item()
|
||||||
local name = clicker:get_player_name()
|
local name = clicker:get_player_name()
|
||||||
@ -86,12 +92,12 @@ mobs:register_mob("mobs:sheep", {
|
|||||||
end
|
end
|
||||||
self.object:set_properties({
|
self.object:set_properties({
|
||||||
textures = {"mobs_sheep.png"},
|
textures = {"mobs_sheep.png"},
|
||||||
mesh = "mobs_sheep.x",
|
mesh = "mobs_sheep.b3d",
|
||||||
})
|
})
|
||||||
minetest.sound_play("mobs_sheep", {
|
minetest.sound_play("mobs_sheep", {
|
||||||
object = self.object,
|
object = self.object,
|
||||||
gain = 1.0,
|
gain = 1.0,
|
||||||
max_hear_distance = 20,
|
max_hear_distance = 10,
|
||||||
loop = false,
|
loop = false,
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
@ -119,6 +125,29 @@ mobs:register_mob("mobs:sheep", {
|
|||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
for _, col in ipairs(all_colours) do
|
||||||
|
if item:get_name() == "dye:"..col
|
||||||
|
and self.gotten == false
|
||||||
|
and self.child == false
|
||||||
|
and self.tamed == true
|
||||||
|
and name == self.owner then
|
||||||
|
local pos = self.object:getpos()
|
||||||
|
self.object:remove()
|
||||||
|
local mob = minetest.add_entity(pos, "mobs:sheep_"..col)
|
||||||
|
local ent = mob:get_luaentity()
|
||||||
|
ent.owner = clicker:get_player_name()
|
||||||
|
ent.tamed = true
|
||||||
|
-- take item
|
||||||
|
if not minetest.setting_getbool("creative_mode") then
|
||||||
|
item:take_item()
|
||||||
|
clicker:set_wielded_item(item)
|
||||||
|
end
|
||||||
|
break
|
||||||
|
else
|
||||||
|
print ("not owner/tamed, cant dye sheep")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
mobs:capture_mob(self, clicker, 0, 5, 60, false, nil)
|
mobs:capture_mob(self, clicker, 0, 5, 60, false, nil)
|
||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
@ -148,3 +177,122 @@ minetest.register_craft({
|
|||||||
{'', 'group:stick', 'default:steel_ingot'},
|
{'', 'group:stick', 'default:steel_ingot'},
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
-- Coloured sheep
|
||||||
|
|
||||||
|
for _, col in ipairs(all_colours) do
|
||||||
|
|
||||||
|
mobs:register_mob("mobs:sheep_"..col, {
|
||||||
|
type = "animal",
|
||||||
|
passive = true,
|
||||||
|
hp_min = 8,
|
||||||
|
hp_max = 10,
|
||||||
|
armor = 200,
|
||||||
|
collisionbox = {-0.4, -1, -0.4, 0.4, 0.3, 0.4},
|
||||||
|
visual = "mesh",
|
||||||
|
mesh = "mobs_sheep.b3d",
|
||||||
|
textures = {
|
||||||
|
{"mobs_sheep_"..col..".png"},
|
||||||
|
},
|
||||||
|
gotten_texture = {"mobs_sheep_shaved.png"},
|
||||||
|
gotten_mesh = "mobs_sheep_shaved.b3d",
|
||||||
|
makes_footstep_sound = true,
|
||||||
|
sounds = {
|
||||||
|
random = "mobs_sheep",
|
||||||
|
},
|
||||||
|
walk_velocity = 1,
|
||||||
|
jump = true,
|
||||||
|
drops = {
|
||||||
|
{name = "mobs:meat_raw",
|
||||||
|
chance = 1, min = 2, max = 3},
|
||||||
|
{name = "wool:"..col,
|
||||||
|
chance = 1, min = 1, max = 1},
|
||||||
|
},
|
||||||
|
water_damage = 1,
|
||||||
|
lava_damage = 5,
|
||||||
|
light_damage = 0,
|
||||||
|
animation = {
|
||||||
|
speed_normal = 15,
|
||||||
|
speed_run = 15,
|
||||||
|
stand_start = 0,
|
||||||
|
stand_end = 80,
|
||||||
|
walk_start = 81,
|
||||||
|
walk_end = 100,
|
||||||
|
},
|
||||||
|
follow = "farming:wheat",
|
||||||
|
view_range = 5,
|
||||||
|
replace_rate = 50,
|
||||||
|
replace_what = {"default:grass_3", "default:grass_4", "default:grass_5", "farming:wheat_8"},
|
||||||
|
replace_with = "air",
|
||||||
|
replace_offset = -1,
|
||||||
|
on_rightclick = function(self, clicker)
|
||||||
|
local item = clicker:get_wielded_item()
|
||||||
|
local name = clicker:get_player_name()
|
||||||
|
|
||||||
|
if item:get_name() == "farming:wheat" then
|
||||||
|
-- take item
|
||||||
|
if not minetest.setting_getbool("creative_mode") then
|
||||||
|
item:take_item()
|
||||||
|
clicker:set_wielded_item(item)
|
||||||
|
end
|
||||||
|
-- make child grow quicker
|
||||||
|
if self.child == true then
|
||||||
|
self.hornytimer = self.hornytimer + 10
|
||||||
|
return
|
||||||
|
end
|
||||||
|
-- feed and tame
|
||||||
|
self.food = (self.food or 0) + 1
|
||||||
|
if self.food > 7 then
|
||||||
|
self.food = 0
|
||||||
|
if self.hornytimer == 0 then
|
||||||
|
self.horny = true
|
||||||
|
end
|
||||||
|
self.gotten = false -- can be shaved again
|
||||||
|
self.tamed = true
|
||||||
|
-- make owner
|
||||||
|
if self.owner == "" then
|
||||||
|
self.owner = name
|
||||||
|
end
|
||||||
|
self.object:set_properties({
|
||||||
|
textures = {"mobs_sheep_"..col..".png"},
|
||||||
|
mesh = "mobs_sheep.b3d",
|
||||||
|
})
|
||||||
|
minetest.sound_play("mobs_sheep", {
|
||||||
|
object = self.object,
|
||||||
|
gain = 1.0,
|
||||||
|
max_hear_distance = 10,
|
||||||
|
loop = false,
|
||||||
|
})
|
||||||
|
end
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
if item:get_name() == "mobs:shears"
|
||||||
|
and self.gotten == false
|
||||||
|
and self.child == false then
|
||||||
|
self.gotten = true -- shaved
|
||||||
|
if minetest.registered_items["wool:"..col] then
|
||||||
|
local pos = self.object:getpos()
|
||||||
|
pos.y = pos.y + 0.5
|
||||||
|
local obj = minetest.add_item(pos, ItemStack("wool:"..col.." "..math.random(2,3)))
|
||||||
|
if obj then
|
||||||
|
obj:setvelocity({x = math.random(-1,1), y = 5, z = math.random(-1,1)})
|
||||||
|
end
|
||||||
|
item:add_wear(650) -- 100 uses
|
||||||
|
clicker:set_wielded_item(item)
|
||||||
|
end
|
||||||
|
self.object:set_properties({
|
||||||
|
textures = {"mobs_sheep_shaved.png"},
|
||||||
|
mesh = "mobs_sheep_shaved.b3d",
|
||||||
|
})
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
mobs:capture_mob(self, clicker, 0, 5, 60, false, nil)
|
||||||
|
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
|
||||||
|
mobs:register_egg("mobs:sheep_"..col, "Sheep ("..col..")", "wool_"..col..".png", 1)
|
||||||
|
|
||||||
|
end
|
@ -19,7 +19,6 @@ mobs:register_mob("mobs:stone_monster", {
|
|||||||
textures = {
|
textures = {
|
||||||
{"mobs_stone_monster.png"},
|
{"mobs_stone_monster.png"},
|
||||||
},
|
},
|
||||||
visual_size = {x=3, y=2.6},
|
|
||||||
blood_texture = "default_stone.png",
|
blood_texture = "default_stone.png",
|
||||||
-- sounds
|
-- sounds
|
||||||
makes_footstep_sound = true,
|
makes_footstep_sound = true,
|
||||||
|
@ -13,13 +13,12 @@ mobs:register_mob("mobs:tree_monster", {
|
|||||||
hp_max = 50,
|
hp_max = 50,
|
||||||
armor = 80,
|
armor = 80,
|
||||||
-- textures and model
|
-- textures and model
|
||||||
collisionbox = {-0.4, -0.01, -0.4, 0.4, 1.9, 0.4},
|
collisionbox = {-0.4, -1, -0.4, 0.4, 0.8, 0.4},
|
||||||
visual = "mesh",
|
visual = "mesh",
|
||||||
mesh = "mobs_tree_monster.b3d",
|
mesh = "mobs_tree_monster.b3d",
|
||||||
textures = {
|
textures = {
|
||||||
{"mobs_tree_monster.png"},
|
{"mobs_tree_monster.png"},
|
||||||
},
|
},
|
||||||
visual_size = {x=4.5,y=4.5},
|
|
||||||
blood_texture = "default_wood.png",
|
blood_texture = "default_wood.png",
|
||||||
-- sounds
|
-- sounds
|
||||||
makes_footstep_sound = true,
|
makes_footstep_sound = true,
|
||||||
|
@ -105,6 +105,7 @@ minetest.register_craftitem("mobs:pork_raw", {
|
|||||||
on_use = minetest.item_eat(4),
|
on_use = minetest.item_eat(4),
|
||||||
})
|
})
|
||||||
|
|
||||||
|
-- cooked porkchop
|
||||||
minetest.register_craftitem("mobs:pork_cooked", {
|
minetest.register_craftitem("mobs:pork_cooked", {
|
||||||
description = "Cooked Porkchop",
|
description = "Cooked Porkchop",
|
||||||
inventory_image = "mobs_pork_cooked.png",
|
inventory_image = "mobs_pork_cooked.png",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user