added new textures inventory
update api.lua move menu spawner code from api.lua to mff_menu.lua
@ -1,15 +1,13 @@
|
|||||||
-- Mobs Api (15th July 2015)
|
-- Mobs Api (18th August 2015)
|
||||||
mobs = {}
|
mobs = {}
|
||||||
mobs.mod = "redo"
|
mobs.mod = "redo"
|
||||||
|
|
||||||
-- Do mobs spawn in protected areas (0=yes, 1=no)
|
-- Load settings
|
||||||
mobs.protected = 1
|
|
||||||
|
|
||||||
-- Initial settings check
|
|
||||||
local damage_enabled = minetest.setting_getbool("enable_damage")
|
local damage_enabled = minetest.setting_getbool("enable_damage")
|
||||||
local peaceful_only = minetest.setting_getbool("only_peaceful_mobs")
|
local peaceful_only = minetest.setting_getbool("only_peaceful_mobs")
|
||||||
local enable_blood = minetest.setting_getbool("mobs_enable_blood") or true
|
local disable_blood = minetest.setting_getbool("mobs_disable_blood")
|
||||||
mobs.protected = tonumber(minetest.setting_get("mobs_spawn_protected")) or mobs.protected
|
mobs.protected = tonumber(minetest.setting_get("mobs_spawn_protected")) or 1
|
||||||
|
mobs.remove = minetest.setting_getbool("remove_far_mobs")
|
||||||
|
|
||||||
function mobs:register_mob(name, def)
|
function mobs:register_mob(name, def)
|
||||||
minetest.register_entity(name, {
|
minetest.register_entity(name, {
|
||||||
@ -23,14 +21,14 @@ function mobs:register_mob(name, def)
|
|||||||
do_custom = def.do_custom,
|
do_custom = def.do_custom,
|
||||||
jump_height = def.jump_height or 6,
|
jump_height = def.jump_height or 6,
|
||||||
jump_chance = def.jump_chance or 0,
|
jump_chance = def.jump_chance or 0,
|
||||||
rotate = def.rotate or 0, -- 0=front, 1.5=side, 3.0=back, 4.5=side2
|
rotate = math.rad(def.rotate or 0), -- 0=front, 90=side, 180=back, 270=side2
|
||||||
lifetimer = def.lifetimer or 600, -- default is 180 now
|
lifetimer = def.lifetimer or 180, -- 3 minutes
|
||||||
hp_min = def.hp_min or 5,
|
hp_min = def.hp_min or 5,
|
||||||
hp_max = def.hp_max or 10,
|
hp_max = def.hp_max or 10,
|
||||||
physical = true,
|
physical = true,
|
||||||
collisionbox = def.collisionbox,
|
collisionbox = def.collisionbox,
|
||||||
visual = def.visual,
|
visual = def.visual,
|
||||||
visual_size = def.visual_size or {x=1, y=1},
|
visual_size = def.visual_size or {x = 1, y = 1},
|
||||||
mesh = def.mesh,
|
mesh = def.mesh,
|
||||||
makes_footstep_sound = def.makes_footstep_sound or false,
|
makes_footstep_sound = def.makes_footstep_sound or false,
|
||||||
view_range = def.view_range or 5,
|
view_range = def.view_range or 5,
|
||||||
@ -51,7 +49,7 @@ function mobs:register_mob(name, def)
|
|||||||
shoot_interval = def.shoot_interval,
|
shoot_interval = def.shoot_interval,
|
||||||
sounds = def.sounds or {},
|
sounds = def.sounds or {},
|
||||||
animation = def.animation,
|
animation = def.animation,
|
||||||
follow = def.follow or "",
|
follow = def.follow, -- or "",
|
||||||
jump = def.jump or true,
|
jump = def.jump or true,
|
||||||
walk_chance = def.walk_chance or 50,
|
walk_chance = def.walk_chance or 50,
|
||||||
attacks_monsters = def.attacks_monsters or false,
|
attacks_monsters = def.attacks_monsters or false,
|
||||||
@ -70,7 +68,7 @@ function mobs:register_mob(name, def)
|
|||||||
replace_offset = def.replace_offset or 0,
|
replace_offset = def.replace_offset or 0,
|
||||||
timer = 0,
|
timer = 0,
|
||||||
env_damage_timer = 0, -- only if state = "attack"
|
env_damage_timer = 0, -- only if state = "attack"
|
||||||
attack = {player=nil, dist=nil},
|
attack = {player = nil, dist = nil},
|
||||||
state = "stand",
|
state = "stand",
|
||||||
tamed = false,
|
tamed = false,
|
||||||
pause_timer = 0,
|
pause_timer = 0,
|
||||||
@ -99,7 +97,7 @@ function mobs:register_mob(name, def)
|
|||||||
v = (v or 0)
|
v = (v or 0)
|
||||||
if def.drawtype
|
if def.drawtype
|
||||||
and def.drawtype == "side" then
|
and def.drawtype == "side" then
|
||||||
self.rotate = 1.5
|
self.rotate = math.rad(90)
|
||||||
end
|
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
|
||||||
@ -212,13 +210,13 @@ function mobs:register_mob(name, def)
|
|||||||
and self.child == false
|
and self.child == false
|
||||||
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()
|
||||||
local nodeunder = minetest.get_node_or_nil({x=pos.x, y=pos.y-1, z=pos.z})
|
local nodeunder = minetest.get_node_or_nil({x=pos.x, y=pos.y-1, z=pos.z}) --MFF (Mg egg not in air)
|
||||||
pos.y = pos.y + self.replace_offset
|
pos.y = pos.y + self.replace_offset
|
||||||
-- print ("replace node = ".. minetest.get_node(pos).name, pos.y)
|
-- 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
|
||||||
and nodeunder and nodeunder.name ~= "air" then
|
and nodeunder and nodeunder.name ~= "air" then --MFF (Mg egg not in air)
|
||||||
--and self.state == "stand" then
|
--and self.state == "stand" then
|
||||||
minetest.set_node(pos, {name = self.replace_with})
|
minetest.set_node(pos, {name = self.replace_with})
|
||||||
end
|
end
|
||||||
@ -226,7 +224,6 @@ function mobs:register_mob(name, def)
|
|||||||
|
|
||||||
local yaw = 0
|
local yaw = 0
|
||||||
|
|
||||||
-- jump direction (adapted from Carbone mobs), gravity, falling or floating in water
|
|
||||||
if not self.fly then
|
if not self.fly then
|
||||||
-- floating in water (or falling)
|
-- floating in water (or falling)
|
||||||
local pos = self.object:getpos()
|
local pos = self.object:getpos()
|
||||||
@ -263,7 +260,7 @@ function mobs:register_mob(name, def)
|
|||||||
-- fall damage
|
-- fall damage
|
||||||
if self.fall_damage == 1
|
if self.fall_damage == 1
|
||||||
and self.object:getvelocity().y == 0 then
|
and self.object:getvelocity().y == 0 then
|
||||||
local d = self.old_y - self.object:getpos().y
|
local d = (self.old_y or 0) - 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))
|
||||||
effect(self.object:getpos(), 5, "tnt_smoke.png")
|
effect(self.object:getpos(), 5, "tnt_smoke.png")
|
||||||
@ -313,7 +310,7 @@ function mobs:register_mob(name, def)
|
|||||||
and (minetest.get_node_light(pos) or 0) > 12 then
|
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)
|
if check_for_death(self) then return end
|
||||||
end
|
end
|
||||||
|
|
||||||
pos.y = pos.y + self.collisionbox[2] -- foot level
|
pos.y = pos.y + self.collisionbox[2] -- foot level
|
||||||
@ -328,7 +325,7 @@ function mobs:register_mob(name, def)
|
|||||||
and nodef.groups.water then
|
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)
|
if check_for_death(self) then return end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- lava or fire
|
-- lava or fire
|
||||||
@ -336,7 +333,7 @@ function mobs:register_mob(name, def)
|
|||||||
and (nodef.groups.lava or nod.name == "fire:basic_flame") then
|
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)
|
if check_for_death(self) then return end
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
@ -391,15 +388,23 @@ function mobs:register_mob(name, def)
|
|||||||
self.jumptimer = 0
|
self.jumptimer = 0
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- environmental damage timer
|
-- environmental damage timer (every 1 second)
|
||||||
self.env_damage_timer = self.env_damage_timer + dtime
|
self.env_damage_timer = self.env_damage_timer + dtime
|
||||||
if self.state == "attack"
|
if self.state == "attack"
|
||||||
and self.env_damage_timer > 1 then
|
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)
|
||||||
|
-- custom function (defined in mob lua file)
|
||||||
|
if self.do_custom then
|
||||||
|
self.do_custom(self)
|
||||||
|
end
|
||||||
elseif self.state ~= "attack" then
|
elseif self.state ~= "attack" then
|
||||||
do_env_damage(self)
|
do_env_damage(self)
|
||||||
|
-- custom function
|
||||||
|
if self.do_custom then
|
||||||
|
self.do_custom(self)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- find someone to attack
|
-- find someone to attack
|
||||||
@ -461,7 +466,7 @@ function mobs:register_mob(name, def)
|
|||||||
and self.attacks_monsters
|
and self.attacks_monsters
|
||||||
and self.state ~= "attack" then
|
and self.state ~= "attack" then
|
||||||
local s = self.object:getpos()
|
local s = self.object:getpos()
|
||||||
local p, dist
|
local p, dist --MFF
|
||||||
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()
|
||||||
@ -501,12 +506,14 @@ 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 = {
|
visual_size = self.base_size,
|
||||||
x = self.visual_size.x,
|
collisionbox = self.base_colbox,
|
||||||
y = self.visual_size.y
|
|
||||||
},
|
|
||||||
collisionbox = self.collisionbox,
|
|
||||||
})
|
})
|
||||||
|
-- jump when grown to now fall into ground
|
||||||
|
local v = self.object:getvelocity()
|
||||||
|
v.y = self.jump_height
|
||||||
|
v.x = 0 ; v.z = 0
|
||||||
|
self.object:setvelocity(v)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -521,13 +528,26 @@ function mobs:register_mob(name, def)
|
|||||||
for i,obj in ipairs(ents) do
|
for i,obj in ipairs(ents) do
|
||||||
ent = obj:get_luaentity()
|
ent = obj:get_luaentity()
|
||||||
|
|
||||||
-- quick fix for racist sheep
|
-- check for same animal with different colour
|
||||||
if ent
|
local canmate = false
|
||||||
and string.find(ent.name, "mobs:sheep_") then
|
if ent then
|
||||||
ent.name = "mobs:sheep"
|
if ent.name == self.name then
|
||||||
|
canmate = true
|
||||||
|
else
|
||||||
|
local entname = string.split(ent.name,":")
|
||||||
|
local selfname = string.split(self.name,":")
|
||||||
|
if entname[1] == selfname[1] then
|
||||||
|
entname = string.split(entname[2],"_")
|
||||||
|
selfname = string.split(selfname[2],"_")
|
||||||
|
if entname[1] == selfname[1] then
|
||||||
|
canmate = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if ent
|
if ent
|
||||||
and ent.name == self.name
|
and canmate == true
|
||||||
and ent.horny == true
|
and ent.horny == true
|
||||||
and ent.hornytimer <= 40 then
|
and ent.hornytimer <= 40 then
|
||||||
num = num + 1
|
num = num + 1
|
||||||
@ -545,17 +565,21 @@ function mobs:register_mob(name, def)
|
|||||||
mob:set_properties({
|
mob:set_properties({
|
||||||
textures = textures,
|
textures = textures,
|
||||||
visual_size = {
|
visual_size = {
|
||||||
x = self.visual_size.x / 2,
|
x = self.base_size.x / 2,
|
||||||
y = self.visual_size.y / 2
|
y = self.base_size.y / 2
|
||||||
},
|
},
|
||||||
collisionbox = {
|
collisionbox = {
|
||||||
self.collisionbox[1] / 2, self.collisionbox[2] / 2, self.collisionbox[3] / 2,
|
self.base_colbox[1] / 2,
|
||||||
self.collisionbox[4] / 2, self.collisionbox[5] / 2, self.collisionbox[6] / 2
|
self.base_colbox[2] / 2,
|
||||||
|
self.base_colbox[3] / 2,
|
||||||
|
self.base_colbox[4] / 2,
|
||||||
|
self.base_colbox[5] / 2,
|
||||||
|
self.base_colbox[6] / 2
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
ent2.child = true
|
ent2.child = true
|
||||||
ent2.tamed = true
|
ent2.tamed = true
|
||||||
ent2.following = ent -- follow mother
|
ent2.owner = self.owner
|
||||||
end)
|
end)
|
||||||
num = 0
|
num = 0
|
||||||
break
|
break
|
||||||
@ -580,11 +604,6 @@ function mobs:register_mob(name, def)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- custom function (defined in mob lua file)
|
|
||||||
if self.do_custom then
|
|
||||||
self.do_custom(self)
|
|
||||||
end
|
|
||||||
|
|
||||||
if self.type == "npc"
|
if self.type == "npc"
|
||||||
and self.order == "follow"
|
and self.order == "follow"
|
||||||
and self.state ~= "attack" then
|
and self.state ~= "attack" then
|
||||||
@ -599,7 +618,8 @@ function mobs:register_mob(name, def)
|
|||||||
-- stop following player if not holding specific item
|
-- stop following player if not holding specific item
|
||||||
if self.following
|
if self.following
|
||||||
and self.following.is_player
|
and self.following.is_player
|
||||||
and self.following:get_wielded_item():get_name() ~= self.follow then
|
--and self.following:get_wielded_item():get_name() ~= self.follow then
|
||||||
|
and follow_holding(self, self.following) == false then
|
||||||
self.following = nil
|
self.following = nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -622,7 +642,7 @@ 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
|
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
|
||||||
@ -677,7 +697,7 @@ function mobs:register_mob(name, def)
|
|||||||
|
|
||||||
if lp ~= nil then
|
if lp ~= nil then
|
||||||
local vec = {x = lp.x - s.x, y = lp.y - s.y, z = lp.z - s.z}
|
local vec = {x = lp.x - s.x, y = lp.y - s.y, z = lp.z - s.z}
|
||||||
yaw = (math.atan(vec.z / vec.x) + math.pi / 2) + self.rotate
|
yaw = (math.atan(vec.z / vec.x) + math.pi / 2) - self.rotate
|
||||||
if lp.x > s.x then
|
if lp.x > s.x then
|
||||||
yaw = yaw + math.pi
|
yaw = yaw + math.pi
|
||||||
end
|
end
|
||||||
@ -729,7 +749,7 @@ end
|
|||||||
-- if water nearby then turn away
|
-- if water nearby then turn away
|
||||||
if lp then
|
if lp then
|
||||||
local vec = {x = lp.x - s.x, y = lp.y - s.y, z = lp.z - s.z}
|
local vec = {x = lp.x - s.x, y = lp.y - s.y, z = lp.z - s.z}
|
||||||
yaw = math.atan(vec.z / vec.x) + 3 * math.pi / 2 + self.rotate
|
yaw = math.atan(vec.z / vec.x) + 3 * math.pi / 2 - self.rotate
|
||||||
if lp.x > s.x then
|
if lp.x > s.x then
|
||||||
yaw = yaw + math.pi
|
yaw = yaw + math.pi
|
||||||
end
|
end
|
||||||
@ -785,9 +805,9 @@ 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)
|
||||||
if self.attack.dist > 3 then
|
if self.attack.dist > 3 then
|
||||||
@ -797,8 +817,8 @@ end
|
|||||||
self.timer = 0
|
self.timer = 0
|
||||||
self.blinktimer = 0
|
self.blinktimer = 0
|
||||||
else
|
else
|
||||||
self.timer = 0
|
self.timer = 0
|
||||||
self.blinktimer = 0
|
self.blinktimer = 0
|
||||||
if self.get_velocity(self) <= 0.5
|
if self.get_velocity(self) <= 0.5
|
||||||
and self.object:getvelocity().y == 0 then
|
and self.object:getvelocity().y == 0 then
|
||||||
local v = self.object:getvelocity()
|
local v = self.object:getvelocity()
|
||||||
@ -913,9 +933,9 @@ 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)
|
||||||
-- 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)
|
||||||
@ -986,7 +1006,7 @@ 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
|
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
|
||||||
@ -1022,115 +1042,109 @@ end
|
|||||||
end,
|
end,
|
||||||
|
|
||||||
on_activate = function(self, staticdata, dtime_s)
|
on_activate = function(self, staticdata, dtime_s)
|
||||||
|
|
||||||
if self.type == "monster"
|
if self.type == "monster"
|
||||||
and peaceful_only then
|
and peaceful_only then
|
||||||
self.object:remove()
|
self.object:remove()
|
||||||
end
|
end
|
||||||
|
|
||||||
self.health = math.random (self.hp_min, self.hp_max) -- set initial HP
|
-- load entity variables
|
||||||
self.object:set_hp( self.health )
|
|
||||||
self.health = self.object:get_hp()
|
|
||||||
self.object:set_armor_groups({fleshy = self.armor})
|
|
||||||
self.object:setacceleration({x = 0, y = self.fall_speed, z = 0})
|
|
||||||
self.state = "stand"
|
|
||||||
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)
|
|
||||||
self.sounds.distance = (self.sounds.distance or 10)
|
|
||||||
|
|
||||||
if staticdata then
|
if staticdata then
|
||||||
local tmp = minetest.deserialize(staticdata)
|
local tmp = minetest.deserialize(staticdata)
|
||||||
if tmp then
|
if tmp then
|
||||||
if tmp.lifetimer then
|
for _,stat in pairs(tmp) do
|
||||||
self.lifetimer = tmp.lifetimer
|
self[_] = stat
|
||||||
end
|
|
||||||
if tmp.tamed then
|
|
||||||
self.tamed = tmp.tamed
|
|
||||||
end
|
|
||||||
if tmp.gotten then
|
|
||||||
self.gotten = tmp.gotten
|
|
||||||
end
|
|
||||||
if tmp.child then
|
|
||||||
self.child = tmp.child
|
|
||||||
end
|
|
||||||
if tmp.horny then
|
|
||||||
self.horny = tmp.horny
|
|
||||||
end
|
|
||||||
if tmp.hornytimer then
|
|
||||||
self.hornytimer = tmp.hornytimer
|
|
||||||
end
|
|
||||||
if tmp.textures then
|
|
||||||
self.textures = tmp.textures
|
|
||||||
end
|
|
||||||
if tmp.mesh then
|
|
||||||
self.mesh = tmp.mesh
|
|
||||||
end
|
|
||||||
if tmp.base_texture then
|
|
||||||
self.base_texture = tmp.base_texture
|
|
||||||
end
|
|
||||||
if tmp.base_mesh then
|
|
||||||
self.base_mesh = tmp.base_mesh
|
|
||||||
end
|
|
||||||
if tmp.owner then
|
|
||||||
self.owner = tmp.owner
|
|
||||||
end
|
|
||||||
if tmp.health then
|
|
||||||
self.health = tmp.health
|
|
||||||
self.object:set_hp( self.health )
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end,
|
|
||||||
|
|
||||||
get_staticdata = function(self)
|
-- select random texture, set model and size
|
||||||
-- select random texture, set model
|
|
||||||
if not self.base_texture then
|
if not self.base_texture then
|
||||||
self.base_texture = def.textures[math.random(1, #def.textures)]
|
self.base_texture = def.textures[math.random(1, #def.textures)]
|
||||||
self.base_mesh = def.mesh
|
self.base_mesh = def.mesh
|
||||||
|
self.base_size = self.visual_size
|
||||||
|
self.base_colbox = self.collisionbox
|
||||||
end
|
end
|
||||||
|
|
||||||
-- set texture, model and size
|
-- set texture, model and size
|
||||||
local textures = self.base_texture
|
local textures = self.base_texture
|
||||||
local mesh = self.base_mesh
|
local mesh = self.base_mesh
|
||||||
local vis_size = self.visual_size
|
local vis_size = self.base_size
|
||||||
local colbox = self.collisionbox
|
local colbox = self.base_colbox
|
||||||
|
|
||||||
-- specific texture if gotten
|
-- specific texture if gotten
|
||||||
if self.gotten == true
|
if self.gotten == true
|
||||||
and def.gotten_texture then
|
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
|
if self.gotten == true
|
||||||
and def.gotten_mesh then
|
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
|
||||||
if self.child == true then
|
if self.child == true then
|
||||||
vis_size = {x = self.visual_size.x / 2, y = self.visual_size.y / 2}
|
vis_size = {
|
||||||
|
x = self.base_size.x / 2,
|
||||||
|
y = self.base_size.y / 2
|
||||||
|
}
|
||||||
if def.child_texture then
|
if def.child_texture then
|
||||||
textures = def.child_texture[1]
|
textures = def.child_texture[1]
|
||||||
end
|
end
|
||||||
colbox = {
|
colbox = {
|
||||||
self.collisionbox[1] / 2, self.collisionbox[2] / 2, self.collisionbox[3] / 2,
|
self.base_colbox[1] / 2,
|
||||||
self.collisionbox[4] / 2, self.collisionbox[5] / 2, self.collisionbox[6] / 2
|
self.base_colbox[2] / 2,
|
||||||
|
self.base_colbox[3] / 2,
|
||||||
|
self.base_colbox[4] / 2,
|
||||||
|
self.base_colbox[5] / 2,
|
||||||
|
self.base_colbox[6] / 2
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
-- remember settings
|
|
||||||
local tmp = {
|
if self.health == 0 then
|
||||||
lifetimer = self.lifetimer,
|
self.health = math.random (self.hp_min, self.hp_max)
|
||||||
tamed = self.tamed,
|
end
|
||||||
gotten = self.gotten,
|
|
||||||
child = self.child,
|
self.object:set_hp( self.health )
|
||||||
horny = self.horny,
|
self.object:set_armor_groups({fleshy = self.armor})
|
||||||
hornytimer = self.hornytimer,
|
self.state = "stand"
|
||||||
mesh = mesh,
|
self.order = "stand"
|
||||||
textures = textures,
|
self.following = nil
|
||||||
visual_size = vis_size,
|
self.old_y = self.object:getpos().y
|
||||||
base_texture = self.base_texture,
|
self.object:setyaw(math.random(1, 360) / 180 * math.pi)
|
||||||
collisionbox = colbox,
|
self.sounds.distance = (self.sounds.distance or 10)
|
||||||
owner = self.owner,
|
self.textures = textures
|
||||||
health = self.health,
|
self.mesh = mesh
|
||||||
}
|
self.collisionbox = colbox
|
||||||
self.object:set_properties(tmp)
|
self.visual_size = vis_size
|
||||||
|
-- set anything changed above
|
||||||
|
self.object:set_properties(self)
|
||||||
|
|
||||||
|
end,
|
||||||
|
|
||||||
|
get_staticdata = function(self)
|
||||||
|
|
||||||
|
-- remove mob when out of range unless tamed
|
||||||
|
if mobs.remove and self.remove_ok and not self.tamed then
|
||||||
|
print ("REMOVED", self.remove_ok, self.name)
|
||||||
|
self.object:remove()
|
||||||
|
end
|
||||||
|
self.remove_ok = true
|
||||||
|
self.attack = nil
|
||||||
|
self.following = nil
|
||||||
|
|
||||||
|
local tmp = {}
|
||||||
|
for _,stat in pairs(self) do
|
||||||
|
local t = type(stat)
|
||||||
|
if t ~= 'function'
|
||||||
|
and t ~= 'nil'
|
||||||
|
and t ~= 'userdata' then
|
||||||
|
tmp[_] = self[_]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
-- print('===== '..self.name..'\n'.. dump(tmp)..'\n=====\n')
|
||||||
return minetest.serialize(tmp)
|
return minetest.serialize(tmp)
|
||||||
end,
|
end,
|
||||||
|
|
||||||
@ -1158,27 +1172,33 @@ end
|
|||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
check_for_death(self)
|
-- exit here if dead
|
||||||
|
if check_for_death(self) then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
-- blood_particles
|
-- blood_particles
|
||||||
local pos = self.object:getpos()
|
|
||||||
pos.y = pos.y + (-self.collisionbox[2] + self.collisionbox[5]) / 2
|
|
||||||
if self.blood_amount > 0
|
if self.blood_amount > 0
|
||||||
--and pos
|
and not disable_blood then
|
||||||
and enable_blood == true then
|
local pos = self.object:getpos()
|
||||||
|
pos.y = pos.y + (-self.collisionbox[2] + self.collisionbox[5]) / 2
|
||||||
effect(pos, self.blood_amount, self.blood_texture)
|
effect(pos, self.blood_amount, self.blood_texture)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- knock back effect, adapted from blockmen's pyramids mod
|
-- knock back effect
|
||||||
local kb = self.knock_back
|
if self.knock_back > 0 then
|
||||||
local r = self.recovery_time
|
local kb = self.knock_back
|
||||||
local v = self.object:getvelocity()
|
local r = self.recovery_time
|
||||||
if tflp < tool_capabilities.full_punch_interval then
|
local v = self.object:getvelocity()
|
||||||
kb = kb * ( tflp / tool_capabilities.full_punch_interval )
|
if tflp < tool_capabilities.full_punch_interval then
|
||||||
r = r * ( tflp / tool_capabilities.full_punch_interval )
|
if kb > 0 then
|
||||||
|
kb = kb * ( tflp / tool_capabilities.full_punch_interval )
|
||||||
|
end
|
||||||
|
r = r * ( tflp / tool_capabilities.full_punch_interval )
|
||||||
|
end
|
||||||
|
self.object:setvelocity({x = dir.x * kb,y = 0,z = dir.z * kb})
|
||||||
|
self.pause_timer = r
|
||||||
end
|
end
|
||||||
self.object:setvelocity({x = dir.x * kb,y = 0,z = dir.z * kb})
|
|
||||||
self.pause_timer = r
|
|
||||||
|
|
||||||
-- attack puncher and call other mobs for help
|
-- attack puncher and call other mobs for help
|
||||||
if self.passive == false
|
if self.passive == false
|
||||||
@ -1190,10 +1210,9 @@ end
|
|||||||
local obj = nil
|
local obj = nil
|
||||||
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
|
if obj then
|
||||||
and obj.name == self.name then
|
|
||||||
if obj.group_attack == true
|
if obj.group_attack == true
|
||||||
and not obj.tamed
|
and not obj.tamed --MFF(crabman) group tamed don't attack
|
||||||
and obj.state ~= "attack" then
|
and obj.state ~= "attack" then
|
||||||
obj.do_attack(obj, hitter, 1)
|
obj.do_attack(obj, hitter, 1)
|
||||||
end
|
end
|
||||||
@ -1299,7 +1318,7 @@ end
|
|||||||
|
|
||||||
-- explosion
|
-- explosion
|
||||||
function mobs:explosion(pos, radius, fire, smoke, sound)
|
function mobs:explosion(pos, radius, fire, smoke, sound)
|
||||||
-- node hit, bursts into flame (cannot blast through obsidian or protection redo mod items)
|
-- node hit, bursts into flame (cannot blast through unbreakable/specific nodes)
|
||||||
if not fire then fire = 0 end
|
if not fire then fire = 0 end
|
||||||
if not smoke then smoke = 0 end
|
if not smoke then smoke = 0 end
|
||||||
local pos = vector.round(pos)
|
local pos = vector.round(pos)
|
||||||
@ -1333,14 +1352,12 @@ 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 p.y >= 19600
|
if p.y >= 19600 --MFF
|
||||||
and data[vi] ~= c_air and data[vi] ~= c_ignore
|
and data[vi] ~= c_air and data[vi] ~= c_ignore
|
||||||
and data[vi] ~= c_obsidian and data[vi] ~= c_brick
|
and data[vi] ~= c_obsidian and data[vi] ~= c_brick
|
||||||
and data[vi] ~= c_chest then
|
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
|
if not minetest.is_protected(p, "") --/MFF (Crabman|06/23/2015) re-added node protected in areas
|
||||||
if not n:find("protector:")
|
|
||||||
and not minetest.is_protected(p, "") --/MFF (Crabman|06/23/2015) re-added node protected in areas
|
|
||||||
and minetest.get_item_group(n, "unbreakable") ~= 1 then
|
and minetest.get_item_group(n, "unbreakable") ~= 1 then
|
||||||
-- if chest then drop items inside
|
-- if chest then drop items inside
|
||||||
if n == "default:chest" or n == "3dchest:chest" then
|
if n == "default:chest" or n == "3dchest:chest" then
|
||||||
@ -1376,14 +1393,14 @@ end
|
|||||||
function check_for_death(self)
|
function check_for_death(self)
|
||||||
local hp = self.object:get_hp()
|
local hp = self.object:get_hp()
|
||||||
if hp > 0 then
|
if hp > 0 then
|
||||||
|
self.health = hp
|
||||||
if self.sounds.damage ~= nil then
|
if self.sounds.damage ~= nil then
|
||||||
minetest.sound_play(self.sounds.damage,{
|
minetest.sound_play(self.sounds.damage,{
|
||||||
object = self.object,
|
object = self.object,
|
||||||
max_hear_distance = self.sounds.distance
|
max_hear_distance = self.sounds.distance
|
||||||
})
|
})
|
||||||
self.health = hp
|
|
||||||
end
|
end
|
||||||
return
|
return false
|
||||||
end
|
end
|
||||||
local pos = self.object:getpos()
|
local pos = self.object:getpos()
|
||||||
pos.y = pos.y + 0.5 -- drop items half a block higher
|
pos.y = pos.y + 0.5 -- drop items half a block higher
|
||||||
@ -1409,9 +1426,9 @@ function check_for_death(self)
|
|||||||
})
|
})
|
||||||
end
|
end
|
||||||
if self.on_die then
|
if self.on_die then
|
||||||
pos.y = pos.y - 0.5
|
|
||||||
self.on_die(self, pos)
|
self.on_die(self, pos)
|
||||||
end
|
end
|
||||||
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
-- from TNT mod
|
-- from TNT mod
|
||||||
@ -1467,7 +1484,7 @@ function mobs:register_arrow(name, def)
|
|||||||
local pos = self.object:getpos()
|
local pos = self.object:getpos()
|
||||||
local node = minetest.get_node_or_nil(self.object:getpos())
|
local node = minetest.get_node_or_nil(self.object:getpos())
|
||||||
if node then node = node.name else node = "air" end
|
if node then node = node.name else node = "air" end
|
||||||
-- hit node you can walk on
|
|
||||||
if self.hit_node
|
if self.hit_node
|
||||||
and minetest.registered_nodes[node]
|
and minetest.registered_nodes[node]
|
||||||
and minetest.registered_nodes[node].walkable then
|
and minetest.registered_nodes[node].walkable then
|
||||||
@ -1490,7 +1507,6 @@ function mobs:register_arrow(name, def)
|
|||||||
self.object:remove() ; -- print ("hit player")
|
self.object:remove() ; -- print ("hit player")
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
-- hit mob
|
|
||||||
if self.hit_mob
|
if self.hit_mob
|
||||||
and player:get_luaentity().name ~= self.object:get_luaentity().name
|
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
|
||||||
@ -1544,16 +1560,17 @@ function mobs:capture_mob(self, clicker, chance_hand, chance_net, chance_lasso,
|
|||||||
if replacewith then
|
if replacewith then
|
||||||
mobname = replacewith
|
mobname = replacewith
|
||||||
end
|
end
|
||||||
--print ("taking by force is", force_take)
|
|
||||||
local name = clicker:get_player_name()
|
local name = clicker:get_player_name()
|
||||||
if self.owner == ""
|
-- is mob tamed?
|
||||||
|
if self.tamed == false
|
||||||
and force_take == false then
|
and force_take == false then
|
||||||
minetest.chat_send_player(name, "Not tamed!")
|
minetest.chat_send_player(name, "Not tamed!")
|
||||||
return
|
return
|
||||||
|
end
|
||||||
-- cannot pick up if not owner
|
-- cannot pick up if not owner
|
||||||
elseif self.owner ~= name
|
if self.owner ~= name
|
||||||
and force_take == false then
|
and force_take == false then
|
||||||
minetest.chat_send_player(name, "Not owner!")
|
minetest.chat_send_player(name, self.owner.." is owner!")
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -1587,63 +1604,101 @@ function mobs:capture_mob(self, clicker, chance_hand, chance_net, chance_lasso,
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- follow what I'm holding ?
|
||||||
|
function follow_holding(self, clicker)
|
||||||
|
local item = clicker:get_wielded_item()
|
||||||
|
local follow_item = false
|
||||||
|
local t = type(self.follow)
|
||||||
|
|
||||||
--Menu mobs spawner
|
-- single item
|
||||||
mobs.shown_spawner_menu = function(player_name)
|
if t == "string"
|
||||||
local formspec = {"size[7,9]label[2.7,0;Mobs Spawner]"}
|
and item:get_name() == self.follow then
|
||||||
if mobs["spawning_mobs"] ~= nil then
|
follow_item = true
|
||||||
local Y = 1
|
|
||||||
local X = 1
|
-- multiple items
|
||||||
for name, etat in pairs(mobs["spawning_mobs"]) do
|
elseif t == "table" then
|
||||||
table.insert(formspec, "item_image_button["..X..","..Y..";1,1;"..name..";"..name..";]")
|
for no = 1, #self.follow do
|
||||||
X = X+1
|
if self.follow[no] == item:get_name() then
|
||||||
if X > 5 then
|
follow_item = true
|
||||||
X = 1
|
|
||||||
Y = Y+1.2
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
table.insert(formspec, "button_exit[2.9,8.5;1.2,1;close;Close]")
|
|
||||||
minetest.show_formspec(player_name, "mobs:spawner", table.concat(formspec))
|
-- true if can eat/tame with item
|
||||||
|
if follow_item == true then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
minetest.register_on_player_receive_fields(function(player, formname, fields)
|
-- feeding, taming and breeding (thanks blert2112)
|
||||||
local player_name = player:get_player_name()
|
function mobs:feed_tame(self, clicker, feed_count, breed)
|
||||||
if not player_name then return end
|
|
||||||
if formname == "mobs:spawner" then
|
if not self.follow then return false end
|
||||||
for f in pairs(fields) do
|
|
||||||
if string.find(f, "mobs:") then
|
local item = clicker:get_wielded_item()
|
||||||
local pos = player:getpos()
|
local follow_item = false
|
||||||
pos.y = pos.y+0.5
|
local t = type(self.follow)
|
||||||
minetest.add_entity(pos, f)
|
|
||||||
return
|
-- single item
|
||||||
end
|
if t == "string"
|
||||||
|
and item:get_name() == self.follow then
|
||||||
|
follow_item = true
|
||||||
|
|
||||||
|
-- multiple items
|
||||||
|
elseif t == "table" then
|
||||||
|
for no = 1, #self.follow do
|
||||||
|
if self.follow[no] == item:get_name() then
|
||||||
|
follow_item = true
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end)
|
|
||||||
|
|
||||||
|
-- can eat/tame with item in hand
|
||||||
|
if follow_holding(self, clicker) then
|
||||||
|
--print ("mmm, tasty")
|
||||||
|
-- take item
|
||||||
|
if not minetest.setting_getbool("creative_mode") then
|
||||||
|
item:take_item()
|
||||||
|
clicker:set_wielded_item(item)
|
||||||
|
end
|
||||||
|
|
||||||
if (minetest.get_modpath("unified_inventory")) ~= nil then
|
-- heal health
|
||||||
unified_inventory.register_button("menu_mobs", {
|
local hp = self.object:get_hp()
|
||||||
type = "image",
|
hp = math.min(hp + 4, self.hp_max)
|
||||||
image = "mobs_dungeon_master_fireball.png",
|
self.object:set_hp(hp)
|
||||||
tooltip = "Mobs Spawner Menu",
|
self.health = hp
|
||||||
show_with = "server",
|
|
||||||
action = function(player)
|
-- make children grow quicker
|
||||||
local player_name = player:get_player_name()
|
if self.child == true then
|
||||||
if not player_name then return end
|
self.hornytimer = self.hornytimer + 20
|
||||||
if minetest.check_player_privs(player_name, {server=true}) then
|
return true
|
||||||
mobs.shown_spawner_menu(player_name)
|
end
|
||||||
|
|
||||||
|
-- feed and tame
|
||||||
|
self.food = (self.food or 0) + 1
|
||||||
|
if self.food == feed_count then
|
||||||
|
self.food = 0
|
||||||
|
if breed and self.hornytimer == 0 then
|
||||||
|
self.horny = true
|
||||||
end
|
end
|
||||||
end,
|
self.gotten = false
|
||||||
})
|
self.tamed = true
|
||||||
else
|
if not self.owner or self.owner == "" then
|
||||||
minetest.register_chatcommand("mobs_spawner", {
|
self.owner = clicker:get_player_name()
|
||||||
params = "",
|
end
|
||||||
description = "Spawn entity at given (or your) position",
|
|
||||||
privs = {server=true},
|
-- make sound when fed so many times
|
||||||
func = function(name, param)
|
if self.sounds.random then
|
||||||
mobs.shown_spawner_menu(name)
|
minetest.sound_play(self.sounds.random, {
|
||||||
end,
|
object = self.object,
|
||||||
})
|
max_hear_distance = self.sounds.distance
|
||||||
end
|
})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return true
|
||||||
|
else
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
@ -52,7 +52,7 @@ mobs:register_mob("mobs:bee", {
|
|||||||
-- spawn on group:flowers between 4 and 20 light, 1 in 5000 chance, 1 bee in area up to 31000 in height
|
-- spawn on group:flowers between 4 and 20 light, 1 in 5000 chance, 1 bee in area up to 31000 in height
|
||||||
mobs:spawn_specific("mobs:bee", {"group:flower"}, {"air"}, 4, 20, 30, 5000, 1, -31000, 31000, true)
|
mobs:spawn_specific("mobs:bee", {"group:flower"}, {"air"}, 4, 20, 30, 5000, 1, -31000, 31000, true)
|
||||||
-- register spawn egg
|
-- register spawn egg
|
||||||
mobs:register_egg("mobs:bee", "Bee", "mobs_bee_inv.png", 0)
|
mobs:register_egg("mobs:bee", "Bee", "mobs_bee_inv.png", 1)
|
||||||
|
|
||||||
-- honey
|
-- honey
|
||||||
minetest.register_craftitem("mobs:honey", {
|
minetest.register_craftitem("mobs:honey", {
|
||||||
@ -112,4 +112,4 @@ minetest.register_craft({
|
|||||||
recipe = {
|
recipe = {
|
||||||
{"mobs:honey_block"},
|
{"mobs:honey_block"},
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -74,4 +74,4 @@ mobs:register_mob("mobs:bunny", {
|
|||||||
damage = 5,
|
damage = 5,
|
||||||
})
|
})
|
||||||
mobs:spawn_specific("mobs:bunny", {"default:dirt_with_grass"}, {"air"}, 8, 20, 30, 10000, 1, -31000, 31000, true)
|
mobs:spawn_specific("mobs:bunny", {"default:dirt_with_grass"}, {"air"}, 8, 20, 30, 10000, 1, -31000, 31000, true)
|
||||||
mobs:register_egg("mobs:bunny", "Bunny", "mobs_bunny_inv.png", 0)
|
mobs:register_egg("mobs:bunny", "Bunny", "mobs_bunny_inv.png", 1)
|
||||||
|
@ -65,7 +65,7 @@ mobs:register_mob("mobs:chicken", {
|
|||||||
-- spawn on default or bamboo grass between 8 and 20 light, 1 in 10000 change, 1 chicken in area up to 31000 in height
|
-- spawn on default or bamboo grass between 8 and 20 light, 1 in 10000 change, 1 chicken in area up to 31000 in height
|
||||||
mobs:spawn_specific("mobs:chicken", {"default:dirt_with_grass"}, {"air"}, 8, 20, 30, 10000, 1, -31000, 31000, true)
|
mobs:spawn_specific("mobs:chicken", {"default:dirt_with_grass"}, {"air"}, 8, 20, 30, 10000, 1, -31000, 31000, true)
|
||||||
-- register spawn egg
|
-- register spawn egg
|
||||||
mobs:register_egg("mobs:chicken", "Chicken", "mobs_chicken_inv.png", 0)
|
mobs:register_egg("mobs:chicken", "Chicken", "mobs_chicken_inv.png", 1)
|
||||||
|
|
||||||
-- egg
|
-- egg
|
||||||
minetest.register_node("mobs:egg", {
|
minetest.register_node("mobs:egg", {
|
||||||
@ -122,4 +122,4 @@ minetest.register_craft({
|
|||||||
type = "cooking",
|
type = "cooking",
|
||||||
recipe = "mobs:chicken_raw",
|
recipe = "mobs:chicken_raw",
|
||||||
output = "mobs:chicken_cooked",
|
output = "mobs:chicken_cooked",
|
||||||
})
|
})
|
||||||
|
@ -86,4 +86,4 @@ mobs:register_mob("mobs:dog", {
|
|||||||
speed_normal = 15, speed_run = 15,
|
speed_normal = 15, speed_run = 15,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
mobs:register_egg("mobs:dog", "Dog", "wool_brown.png", 1)
|
mobs:register_egg("mobs:dog", "Dog", "mobs_dog_inv.png", 1)
|
||||||
|
@ -56,7 +56,7 @@ mobs:register_mob("mobs:greensmall", {
|
|||||||
-- model animation
|
-- model animation
|
||||||
-- no model animation
|
-- no model animation
|
||||||
})
|
})
|
||||||
mobs:register_egg("mobs:greensmall", "Small Green Slime", "mobs_green_slime_egg.png", 1)
|
mobs:register_egg("mobs:greensmall", "Small Green Slime", "mobs_green_slime_medium_inv.png", 1)
|
||||||
|
|
||||||
-- register medium green slime
|
-- register medium green slime
|
||||||
mobs:register_mob("mobs:greenmedium", {
|
mobs:register_mob("mobs:greenmedium", {
|
||||||
@ -105,7 +105,7 @@ mobs:register_mob("mobs:greenmedium", {
|
|||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
mobs:register_egg("mobs:greenmedium", "Medium Green Slime", "mobs_green_slime_egg.png", 1)
|
mobs:register_egg("mobs:greenmedium", "Medium Green Slime", "mobs_green_slime_medium_inv.png", 1)
|
||||||
|
|
||||||
-- register big green slime
|
-- register big green slime
|
||||||
mobs:register_mob("mobs:greenbig", {
|
mobs:register_mob("mobs:greenbig", {
|
||||||
@ -155,7 +155,7 @@ mobs:register_mob("mobs:greenbig", {
|
|||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
mobs:register_egg("mobs:greenbig", "Big Green Slime", "mobs_green_slime_egg.png", 1)
|
mobs:register_egg("mobs:greenbig", "Big Green Slime", "mobs_green_slime_big_inv.png", 1)
|
||||||
|
|
||||||
--mobs:spawn_specific(name, nodes, neighbors, min_light, max_light, interval, chance, active_object_count, min_height, max_height)
|
--mobs:spawn_specific(name, nodes, neighbors, min_light, max_light, interval, chance, active_object_count, min_height, max_height)
|
||||||
mobs:spawn_specific("mobs:greenbig", {"default:acid_source"},{"default:acid_flowing"}, -1, 20, 30, 4000, 1, -32000, 32000, false)
|
mobs:spawn_specific("mobs:greenbig", {"default:acid_source"},{"default:acid_flowing"}, -1, 20, 30, 4000, 1, -32000, 32000, false)
|
||||||
|
@ -57,6 +57,9 @@ dofile(path.."/creeper.lua")
|
|||||||
-- Mob Items
|
-- Mob Items
|
||||||
dofile(path.."/crafts.lua")
|
dofile(path.."/crafts.lua")
|
||||||
|
|
||||||
|
-- Mob menu spawner special MFF
|
||||||
|
dofile(path.."/mff_menu.lua")
|
||||||
|
|
||||||
if minetest.setting_get("log_mods") then
|
if minetest.setting_get("log_mods") then
|
||||||
minetest.log("action", "mobs loaded")
|
minetest.log("action", "mobs loaded")
|
||||||
end
|
end
|
||||||
|
@ -58,7 +58,7 @@ mobs:register_mob("mobs:lavasmall", {
|
|||||||
-- model animation
|
-- model animation
|
||||||
-- no model animation
|
-- no model animation
|
||||||
})
|
})
|
||||||
mobs:register_egg("mobs:lavasmall", "Small Lava Slime", "mobs_lava_slime_egg.png", 1)
|
mobs:register_egg("mobs:lavasmall", "Small Lava Slime", "mobs_lava_slime_medium_inv.png", 1)
|
||||||
|
|
||||||
-- register medium lava slime
|
-- register medium lava slime
|
||||||
mobs:register_mob("mobs:lavamedium", {
|
mobs:register_mob("mobs:lavamedium", {
|
||||||
@ -109,7 +109,7 @@ mobs:register_mob("mobs:lavamedium", {
|
|||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
mobs:register_egg("mobs:lavamedium", "Medium Lava Slime", "mobs_lava_slime_egg.png", 1)
|
mobs:register_egg("mobs:lavamedium", "Medium Lava Slime", "mobs_lava_slime_medium_inv.png", 1)
|
||||||
|
|
||||||
-- register big lava slime
|
-- register big lava slime
|
||||||
mobs:register_mob("mobs:lavabig", {
|
mobs:register_mob("mobs:lavabig", {
|
||||||
@ -162,7 +162,7 @@ mobs:register_mob("mobs:lavabig", {
|
|||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
mobs:register_egg("mobs:lavabig", "Big Lava Slime", "mobs_lava_slime_egg.png", 1)
|
mobs:register_egg("mobs:lavabig", "Big Lava Slime", "mobs_lava_slime_big_inv.png", 1)
|
||||||
|
|
||||||
--mobs:spawn_specific(name, nodes, neighbors, min_light, max_light, interval, chance, active_object_count, min_height, max_height)
|
--mobs:spawn_specific(name, nodes, neighbors, min_light, max_light, interval, chance, active_object_count, min_height, max_height)
|
||||||
mobs:spawn_specific("mobs:lavabig", {"default:lava_source"},{"default:lava_flowing"}, -1, 20, 30, 4000, 1, -32000, 32000, false)
|
mobs:spawn_specific("mobs:lavabig", {"default:lava_source"},{"default:lava_flowing"}, -1, 20, 30, 4000, 1, -32000, 32000, false)
|
||||||
|
@ -64,7 +64,7 @@ mobs:register_mob("mobs:mese_monster", {
|
|||||||
-- spawn on stone between 20 and -1 light, 1 in 7000 chance, 1 in area below -25
|
-- spawn on stone between 20 and -1 light, 1 in 7000 chance, 1 in area below -25
|
||||||
mobs:spawn_specific("mobs:mese_monster", {"default:stone", "default:sandstone"}, {"air"}, -1, 20, 30, 7000, 1, -31000, -125, false)
|
mobs:spawn_specific("mobs:mese_monster", {"default:stone", "default:sandstone"}, {"air"}, -1, 20, 30, 7000, 1, -31000, -125, false)
|
||||||
-- register spawn egg
|
-- register spawn egg
|
||||||
mobs:register_egg("mobs:mese_monster", "Mese Monster", "default_mese_block.png", 1)
|
mobs:register_egg("mobs:mese_monster", "Mese Monster", "mobs_mese_monster_inv.png", 1)
|
||||||
|
|
||||||
-- mese arrow (weapon)
|
-- mese arrow (weapon)
|
||||||
mobs:register_arrow("mobs:mese_arrow", {
|
mobs:register_arrow("mobs:mese_arrow", {
|
||||||
@ -99,4 +99,4 @@ minetest.register_craft({
|
|||||||
{"default:mese_crystal_fragment", "default:mese_crystal_fragment", "default:mese_crystal_fragment"},
|
{"default:mese_crystal_fragment", "default:mese_crystal_fragment", "default:mese_crystal_fragment"},
|
||||||
{"default:mese_crystal_fragment", "default:mese_crystal_fragment", "default:mese_crystal_fragment"},
|
{"default:mese_crystal_fragment", "default:mese_crystal_fragment", "default:mese_crystal_fragment"},
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
58
mods/mobs/mff_menu.lua
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
--Menu mobs spawner
|
||||||
|
mobs.shown_spawner_menu = function(player_name)
|
||||||
|
local formspec = {"size[7,9]label[2.7,0;Mobs Spawner]"}
|
||||||
|
if mobs["spawning_mobs"] ~= nil then
|
||||||
|
local Y = 1
|
||||||
|
local X = 1
|
||||||
|
for name, etat in pairs(mobs["spawning_mobs"]) do
|
||||||
|
table.insert(formspec, "item_image_button["..X..","..Y..";1,1;"..name..";"..name..";]")
|
||||||
|
X = X+1
|
||||||
|
if X > 5 then
|
||||||
|
X = 1
|
||||||
|
Y = Y+1.2
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
table.insert(formspec, "button_exit[2.9,8.5;1.2,1;close;Close]")
|
||||||
|
minetest.show_formspec(player_name, "mobs:spawner", table.concat(formspec))
|
||||||
|
end
|
||||||
|
|
||||||
|
minetest.register_on_player_receive_fields(function(player, formname, fields)
|
||||||
|
local player_name = player:get_player_name()
|
||||||
|
if not player_name then return end
|
||||||
|
if formname == "mobs:spawner" then
|
||||||
|
for f in pairs(fields) do
|
||||||
|
if string.find(f, "mobs:") then
|
||||||
|
local pos = player:getpos()
|
||||||
|
minetest.add_entity(pos, f)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
|
||||||
|
if (minetest.get_modpath("unified_inventory")) ~= nil then
|
||||||
|
unified_inventory.register_button("menu_mobs", {
|
||||||
|
type = "image",
|
||||||
|
image = "mobs_dungeon_master_fireball.png",
|
||||||
|
tooltip = "Mobs Spawner Menu",
|
||||||
|
show_with = "server",
|
||||||
|
action = function(player)
|
||||||
|
local player_name = player:get_player_name()
|
||||||
|
if not player_name then return end
|
||||||
|
if minetest.check_player_privs(player_name, {server=true}) then
|
||||||
|
mobs.shown_spawner_menu(player_name)
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
else
|
||||||
|
minetest.register_chatcommand("mobs_spawner", {
|
||||||
|
params = "",
|
||||||
|
description = "Spawn entity at given (or your) position",
|
||||||
|
privs = {server=true},
|
||||||
|
func = function(name, param)
|
||||||
|
mobs.shown_spawner_menu(name)
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
end
|
@ -47,7 +47,7 @@ mobs:register_mob("mobs:rat", {
|
|||||||
-- spawn on stone between 1 and 20 light, 1 in 7000 chance, 1 per area up to 31000 in height
|
-- spawn on stone between 1 and 20 light, 1 in 7000 chance, 1 per area up to 31000 in height
|
||||||
mobs:spawn_specific("mobs:rat", {"default:stone", "default:sandstone"}, {"air"}, 0, 20, 30, 10000, 1, -31000, 31000, true)
|
mobs:spawn_specific("mobs:rat", {"default:stone", "default:sandstone"}, {"air"}, 0, 20, 30, 10000, 1, -31000, 31000, true)
|
||||||
-- register spawn egg
|
-- register spawn egg
|
||||||
mobs:register_egg("mobs:rat", "Rat", "mobs_rat_inv.png", 0)
|
mobs:register_egg("mobs:rat", "Rat", "mobs_rat_inv.png", 1)
|
||||||
|
|
||||||
-- cooked rat, yummy!
|
-- cooked rat, yummy!
|
||||||
minetest.register_craftitem("mobs:rat_cooked", {
|
minetest.register_craftitem("mobs:rat_cooked", {
|
||||||
@ -61,4 +61,4 @@ minetest.register_craft({
|
|||||||
output = "mobs:rat_cooked",
|
output = "mobs:rat_cooked",
|
||||||
recipe = "mobs:rat",
|
recipe = "mobs:rat",
|
||||||
cooktime = 5,
|
cooktime = 5,
|
||||||
})
|
})
|
||||||
|
@ -139,11 +139,11 @@ for _, col in ipairs(all_colours) do
|
|||||||
end
|
end
|
||||||
})
|
})
|
||||||
|
|
||||||
mobs:register_egg("mobs:sheep_"..col, "Sheep ("..col..")", "wool_"..col..".png", 1)
|
mobs:register_egg("mobs:sheep_"..col, "Sheep ("..col..")", "mobs_sheep_"..col.."_inv.png", 1)
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
mobs:register_spawn("mobs:sheep_white", {"default:dirt_with_grass", "ethereal:green_dirt"}, 20, 10, 15000, 1, 31000)
|
mobs:spawn_specific("mobs:sheep", {"default:dirt_with_grass"}, {"air"}, 8, 20, 30, 10000, 1, -31000, 31000, true)
|
||||||
|
|
||||||
-- compatibility (item and entity)
|
-- compatibility (item and entity)
|
||||||
minetest.register_alias("mobs:sheep", "mobs:sheep_white")
|
minetest.register_alias("mobs:sheep", "mobs:sheep_white")
|
||||||
|
@ -60,7 +60,7 @@ mobs:register_mob("mobs:spider", {
|
|||||||
-- spawn on jungleleaves/jungletree, between 0 and 5 light, 1 in 10000 chance, 1 in area up to 31000 in height
|
-- spawn on jungleleaves/jungletree, between 0 and 5 light, 1 in 10000 chance, 1 in area up to 31000 in height
|
||||||
mobs:spawn_specific("mobs:spider", {"default:jungleleaves", "default:jungletree"}, {"air"}, -1, 20, 30, 7500, 1, -31000, 31000, false)
|
mobs:spawn_specific("mobs:spider", {"default:jungleleaves", "default:jungletree"}, {"air"}, -1, 20, 30, 7500, 1, -31000, 31000, false)
|
||||||
-- register spawn egg
|
-- register spawn egg
|
||||||
mobs:register_egg("mobs:spider", "Spider", "mobs_cobweb.png", 1)
|
mobs:register_egg("mobs:spider", "Spider", "mobs_spider_inv.png", 1)
|
||||||
|
|
||||||
-- ethereal crystal spike compatibility
|
-- ethereal crystal spike compatibility
|
||||||
if not minetest.get_modpath("ethereal") then
|
if not minetest.get_modpath("ethereal") then
|
||||||
@ -96,4 +96,4 @@ minetest.register_craft( {
|
|||||||
{ "farming:string", "", "" },
|
{ "farming:string", "", "" },
|
||||||
{ "", "", "farming:string"}
|
{ "", "", "farming:string"}
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
Before Width: | Height: | Size: 934 B After Width: | Height: | Size: 599 B |
Before Width: | Height: | Size: 457 B After Width: | Height: | Size: 668 B |
Before Width: | Height: | Size: 357 B After Width: | Height: | Size: 537 B |
BIN
mods/mobs/textures/mobs_dog_inv.png
Normal file
After Width: | Height: | Size: 2.8 KiB |
BIN
mods/mobs/textures/mobs_green_slime_big_inv.png
Normal file
After Width: | Height: | Size: 2.4 KiB |
BIN
mods/mobs/textures/mobs_green_slime_medium_inv.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 361 B After Width: | Height: | Size: 524 B |
BIN
mods/mobs/textures/mobs_lava_slime_big_inv.png
Normal file
After Width: | Height: | Size: 2.6 KiB |
BIN
mods/mobs/textures/mobs_lava_slime_medium_inv.png
Normal file
After Width: | Height: | Size: 1.9 KiB |
BIN
mods/mobs/textures/mobs_mese_monster_inv.png
Normal file
After Width: | Height: | Size: 1.8 KiB |
BIN
mods/mobs/textures/mobs_sheep_black_inv.png
Normal file
After Width: | Height: | Size: 3.9 KiB |
BIN
mods/mobs/textures/mobs_sheep_blue_inv.png
Normal file
After Width: | Height: | Size: 4.0 KiB |
BIN
mods/mobs/textures/mobs_sheep_brown_inv.png
Normal file
After Width: | Height: | Size: 3.9 KiB |
BIN
mods/mobs/textures/mobs_sheep_cyan_inv.png
Normal file
After Width: | Height: | Size: 4.0 KiB |
BIN
mods/mobs/textures/mobs_sheep_dark_green_inv.png
Normal file
After Width: | Height: | Size: 4.0 KiB |
BIN
mods/mobs/textures/mobs_sheep_dark_grey_inv.png
Normal file
After Width: | Height: | Size: 4.0 KiB |
BIN
mods/mobs/textures/mobs_sheep_green_inv.png
Normal file
After Width: | Height: | Size: 3.9 KiB |
BIN
mods/mobs/textures/mobs_sheep_grey_inv.png
Normal file
After Width: | Height: | Size: 3.9 KiB |
BIN
mods/mobs/textures/mobs_sheep_magenta_inv.png
Normal file
After Width: | Height: | Size: 4.0 KiB |
BIN
mods/mobs/textures/mobs_sheep_orange_inv.png
Normal file
After Width: | Height: | Size: 4.0 KiB |
BIN
mods/mobs/textures/mobs_sheep_pink_inv.png
Normal file
After Width: | Height: | Size: 3.9 KiB |
BIN
mods/mobs/textures/mobs_sheep_red_inv.png
Normal file
After Width: | Height: | Size: 4.0 KiB |
BIN
mods/mobs/textures/mobs_sheep_shaved_inv.png
Normal file
After Width: | Height: | Size: 4.3 KiB |
BIN
mods/mobs/textures/mobs_sheep_violet_inv.png
Normal file
After Width: | Height: | Size: 4.0 KiB |
BIN
mods/mobs/textures/mobs_sheep_white_inv.png
Normal file
After Width: | Height: | Size: 2.3 KiB |
BIN
mods/mobs/textures/mobs_sheep_yellow_inv.png
Normal file
After Width: | Height: | Size: 4.0 KiB |
BIN
mods/mobs/textures/mobs_spider_inv.png
Normal file
After Width: | Height: | Size: 1.9 KiB |
BIN
mods/mobs/textures/mobs_wolf_inv.png
Executable file → Normal file
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.8 KiB |