beginning to sort out a huge mess
parent
d7d6b01049
commit
7e50b30d80
30
api.lua
30
api.lua
|
@ -177,20 +177,25 @@ function update_tag(self)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- check if mob is dead or only hurt
|
-- check if mob is dead or only hurt
|
||||||
function check_for_death(self)
|
function check_for_death(self, pos2)
|
||||||
|
|
||||||
-- return if no change
|
-- return if no change
|
||||||
local hp = self.object:get_hp()
|
local hp = self.object:get_hp()
|
||||||
|
hp.foo.bar(x)
|
||||||
if hp == self.health then
|
if pos2 == nil then
|
||||||
return false
|
print("pos2 is nil. api.lua:185")
|
||||||
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if hp == self.health then
|
||||||
|
--print("no damage")
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
print("got damage")
|
||||||
local pos = self.object:getpos()
|
local pos = self.object:getpos()
|
||||||
|
|
||||||
-- still got some health? play hurt sound
|
-- still got some health? play hurt sound
|
||||||
if hp > 0 then
|
if hp > 0 then
|
||||||
|
print("not dead: " .. hp)
|
||||||
self.health = hp
|
self.health = hp
|
||||||
|
|
||||||
if self.sounds.damage then
|
if self.sounds.damage then
|
||||||
|
@ -209,22 +214,25 @@ function check_for_death(self)
|
||||||
|
|
||||||
-- drop items when dead
|
-- drop items when dead
|
||||||
local obj
|
local obj
|
||||||
|
print("mob died")
|
||||||
for _,drop in pairs(self.drops) do
|
for _,drop in pairs(self.drops) do
|
||||||
|
print("dropping: " .. drop.name)
|
||||||
if math.random(1, drop.chance) == 1 then
|
if math.random(1, drop.chance) == 1 then
|
||||||
|
print("doing drop at "..pos.x..", "..pos.y..", "..pos.z)
|
||||||
obj = minetest.add_item(pos,
|
print("doing drop2 at "..pos2.x..", "..pos2.y..", "..pos2.z)
|
||||||
|
obj = minetest.add_item(pos2,
|
||||||
ItemStack(drop.name .. " "
|
ItemStack(drop.name .. " "
|
||||||
.. math.random(drop.min, drop.max)))
|
.. math.random(drop.min, drop.max)))
|
||||||
|
|
||||||
if obj then
|
if obj then
|
||||||
|
print("drop successful")
|
||||||
obj:setvelocity({
|
obj:setvelocity({
|
||||||
x = math.random(-1, 1),
|
x = math.random(-1, 1),
|
||||||
y = 6,
|
y = 6,
|
||||||
z = math.random(-1, 1)
|
z = math.random(-1, 1)
|
||||||
})
|
})
|
||||||
|
else
|
||||||
|
print("failed to add item")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,340 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function mobehavior:register_mob_fast(name, def)
|
||||||
|
|
||||||
|
local mdef = {
|
||||||
|
hp_max = 1,
|
||||||
|
health = 1,
|
||||||
|
rotate = 0,
|
||||||
|
physical = true,
|
||||||
|
weight = 5,
|
||||||
|
collisionbox = {-0.5,-0.5,-0.5, 0.5,0.5,0.5},
|
||||||
|
visual = "mesh",
|
||||||
|
visual_size = {x=1, y=1},
|
||||||
|
mesh = "model",
|
||||||
|
fall_speed = -9.81,
|
||||||
|
textures = {}, -- number of required textures depends on visual
|
||||||
|
colors = {}, -- number of required colors depends on visual
|
||||||
|
spritediv = {x=1, y=1},
|
||||||
|
initial_sprite_basepos = {x=0, y=0},
|
||||||
|
is_visible = true,
|
||||||
|
makes_footstep_sound = false,
|
||||||
|
automatic_rotate = false,
|
||||||
|
|
||||||
|
bt_timer = 0,
|
||||||
|
bt = nil,
|
||||||
|
btData = nil,
|
||||||
|
|
||||||
|
|
||||||
|
on_step = function(self, dtime)
|
||||||
|
local btdata = self.btData
|
||||||
|
-- print('newstep')
|
||||||
|
local pos = self.object:getpos()
|
||||||
|
local yaw = self.object:getyaw() or 0
|
||||||
|
|
||||||
|
self.bt_timer = self.bt_timer + dtime
|
||||||
|
|
||||||
|
-- run the behavior tree every two seconds
|
||||||
|
if self.bt_timer > 2 then
|
||||||
|
|
||||||
|
btdata.pos = pos
|
||||||
|
btdata.yaw = yaw
|
||||||
|
btdata.mob = self
|
||||||
|
|
||||||
|
print("\n<<< start >>>")
|
||||||
|
|
||||||
|
-- inventories cannot be serialized and cause the game to crash if
|
||||||
|
-- placed in the entity's table
|
||||||
|
local inv = minetest.get_inventory({type="detached", name=self.inv_id})
|
||||||
|
btdata.inv = inv
|
||||||
|
|
||||||
|
bt.tick(self.bt, btdata)
|
||||||
|
print("<<< end >>>\n")
|
||||||
|
|
||||||
|
-- so clear it out after running the behavior trees
|
||||||
|
btdata.inv = nil
|
||||||
|
-- the inventory exists on its own
|
||||||
|
|
||||||
|
self.bt_timer = 0
|
||||||
|
end
|
||||||
|
|
||||||
|
btdata.lastpos = pos
|
||||||
|
|
||||||
|
|
||||||
|
-- handle movement
|
||||||
|
|
||||||
|
local v = self.object:getvelocity()
|
||||||
|
|
||||||
|
-- TODO: floating
|
||||||
|
|
||||||
|
-- going up then apply gravity
|
||||||
|
-- if v.y > 0.1 then
|
||||||
|
|
||||||
|
self.object:setacceleration({
|
||||||
|
x = 0,
|
||||||
|
y = self.fall_speed,
|
||||||
|
z = 0
|
||||||
|
})
|
||||||
|
-- end
|
||||||
|
|
||||||
|
-- TODO: fall damage
|
||||||
|
|
||||||
|
|
||||||
|
if self.destination ~= nil then
|
||||||
|
|
||||||
|
--print("destination ")
|
||||||
|
|
||||||
|
local dist = distance(pos, self.destination)
|
||||||
|
-- print("walk dist ".. dist)
|
||||||
|
local s = self.destination
|
||||||
|
local vec = {
|
||||||
|
x = pos.x - s.x,
|
||||||
|
y = pos.y - s.y,
|
||||||
|
z = pos.z - s.z
|
||||||
|
}
|
||||||
|
|
||||||
|
if vec.x ~= 0 or vec.z ~= 0 then
|
||||||
|
|
||||||
|
yaw = (math.atan(vec.z / vec.x) + math.pi / 2) - self.rotate
|
||||||
|
|
||||||
|
if s.x > pos.x then
|
||||||
|
yaw = yaw + math.pi
|
||||||
|
end
|
||||||
|
|
||||||
|
-- print("yaw " .. yaw)
|
||||||
|
|
||||||
|
self.object:setyaw(yaw)
|
||||||
|
end
|
||||||
|
|
||||||
|
if dist > (self.approachDistance or .1) then
|
||||||
|
--[[
|
||||||
|
if (self.jump
|
||||||
|
and get_velocity(self) <= 0.5
|
||||||
|
and self.object:getvelocity().y == 0)
|
||||||
|
or (self.object:getvelocity().y == 0
|
||||||
|
and self.jump_chance > 0) then
|
||||||
|
do_jump(self)
|
||||||
|
end]]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
set_velocity(self, self.walk_velocity)
|
||||||
|
set_animation(self, "walk")
|
||||||
|
else
|
||||||
|
-- we have arrived
|
||||||
|
self.destination = nil
|
||||||
|
|
||||||
|
-- TODO: bump bttimer to get new directions
|
||||||
|
|
||||||
|
set_velocity(self, 0)
|
||||||
|
set_animation(self, "stand")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
|
||||||
|
|
||||||
|
on_activate = function(self, staticdata, dtime_s)
|
||||||
|
self.btData = {
|
||||||
|
groupID = "default",
|
||||||
|
|
||||||
|
waypoints= {},
|
||||||
|
paths= {},
|
||||||
|
counters={},
|
||||||
|
|
||||||
|
history={},
|
||||||
|
history_queue={},
|
||||||
|
history_depth=20,
|
||||||
|
|
||||||
|
posStack={},
|
||||||
|
}
|
||||||
|
|
||||||
|
local btdata = self.btData
|
||||||
|
|
||||||
|
self.inv_id= name..":"..math.random(1, 2000000000)
|
||||||
|
--print(btdata.id)
|
||||||
|
|
||||||
|
btdata.lastpos = self.object:getpos()
|
||||||
|
|
||||||
|
if type(def.pre_activate) == "function" then
|
||||||
|
def.pre_activate(self, static_data, dtime_s)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- load entity variables
|
||||||
|
if staticdata then
|
||||||
|
|
||||||
|
local tmp = minetest.deserialize(staticdata)
|
||||||
|
|
||||||
|
if tmp then
|
||||||
|
|
||||||
|
for _,stat in pairs(tmp) do
|
||||||
|
self[_] = stat
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
self.object:remove()
|
||||||
|
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local inventory = minetest.create_detached_inventory(self.inv_id, {})
|
||||||
|
inventory:set_size("main", 9)
|
||||||
|
|
||||||
|
|
||||||
|
-- select random texture, set model and size
|
||||||
|
if not self.base_texture then
|
||||||
|
|
||||||
|
self.base_texture = def.textures[math.random(1, #def.textures)]
|
||||||
|
self.base_mesh = def.mesh
|
||||||
|
self.base_size = self.visual_size
|
||||||
|
self.base_colbox = self.collisionbox
|
||||||
|
end
|
||||||
|
|
||||||
|
-- set texture, model and size
|
||||||
|
local textures = self.base_texture
|
||||||
|
local mesh = self.base_mesh
|
||||||
|
local vis_size = self.base_size
|
||||||
|
local colbox = self.base_colbox
|
||||||
|
|
||||||
|
-- specific texture if gotten
|
||||||
|
if self.gotten == true
|
||||||
|
and def.gotten_texture then
|
||||||
|
textures = def.gotten_texture
|
||||||
|
end
|
||||||
|
|
||||||
|
-- specific mesh if gotten
|
||||||
|
if self.gotten == true
|
||||||
|
and def.gotten_mesh then
|
||||||
|
mesh = def.gotten_mesh
|
||||||
|
end
|
||||||
|
|
||||||
|
-- set child objects to half size
|
||||||
|
if self.child == true then
|
||||||
|
|
||||||
|
vis_size = {
|
||||||
|
x = self.base_size.x / 2,
|
||||||
|
y = self.base_size.y / 2
|
||||||
|
}
|
||||||
|
|
||||||
|
if def.child_texture then
|
||||||
|
textures = def.child_texture[1]
|
||||||
|
end
|
||||||
|
|
||||||
|
colbox = {
|
||||||
|
self.base_colbox[1] / 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
|
||||||
|
|
||||||
|
if self.health == 0 then
|
||||||
|
self.health = math.random (self.hp_min, self.hp_max)
|
||||||
|
end
|
||||||
|
|
||||||
|
self.object:set_hp(self.health)
|
||||||
|
self.object:set_armor_groups({fleshy = self.armor})
|
||||||
|
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)
|
||||||
|
self.textures = textures
|
||||||
|
self.mesh = mesh
|
||||||
|
self.collisionbox = colbox
|
||||||
|
self.visual_size = vis_size
|
||||||
|
|
||||||
|
-- set anything changed above
|
||||||
|
self.object:set_properties(self)
|
||||||
|
update_tag(self)
|
||||||
|
|
||||||
|
if type(def.post_activate) == "function" then
|
||||||
|
def.post_activate(self, static_data, dtime_s)
|
||||||
|
end
|
||||||
|
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()
|
||||||
|
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
self.remove_ok = true
|
||||||
|
self.attack = nil
|
||||||
|
self.following = nil
|
||||||
|
self.state = "stand"
|
||||||
|
|
||||||
|
if self.btData ~= nil then
|
||||||
|
self.btData.inv = nil -- just in case
|
||||||
|
self.btData.mob = nil -- just in case
|
||||||
|
end
|
||||||
|
|
||||||
|
-- used to rotate older mobs
|
||||||
|
if self.drawtype
|
||||||
|
and self.drawtype == "side" then
|
||||||
|
self.rotate = math.rad(90)
|
||||||
|
end
|
||||||
|
|
||||||
|
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)
|
||||||
|
end,
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
for k,v in pairs(def) do
|
||||||
|
mdef[k] = v
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
minetest.register_entity(name, mdef)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
16
entities.lua
16
entities.lua
|
@ -26,8 +26,8 @@ function make_bunny(name, behavior_fn)
|
||||||
view_range = 15,
|
view_range = 15,
|
||||||
floats = 0,
|
floats = 0,
|
||||||
drops = {
|
drops = {
|
||||||
{name = "mobs:meat_raw",
|
{name = "mobehavior:meat_raw", chance = 1, min = 1, max = 2},
|
||||||
chance = 1, min = 1, max = 1},
|
{name = "fur:small_pelt", chance = 1, min = 1, max = 1},
|
||||||
},
|
},
|
||||||
water_damage = 0,
|
water_damage = 0,
|
||||||
lava_damage = 4,
|
lava_damage = 4,
|
||||||
|
@ -88,8 +88,8 @@ function make_wolf(name, behavior_fn)
|
||||||
view_range = 25,
|
view_range = 25,
|
||||||
floats = 1,
|
floats = 1,
|
||||||
drops = {
|
drops = {
|
||||||
{name = "mobs:meat_raw",
|
{name = "mobehavior:meat_raw", chance = 1, min = 1, max = 1},
|
||||||
chance = 1, min = 1, max = 1},
|
{name = "fur:medium_pelt", chance = 1, min = 1, max = 1},
|
||||||
},
|
},
|
||||||
water_damage = 0,
|
water_damage = 0,
|
||||||
lava_damage = 4,
|
lava_damage = 4,
|
||||||
|
@ -151,7 +151,7 @@ function make_bear(name, behavior_fn)
|
||||||
view_range = 25,
|
view_range = 25,
|
||||||
floats = 1,
|
floats = 1,
|
||||||
drops = {
|
drops = {
|
||||||
{name = "mobs:meat_raw",
|
{name = "mobehavior:meat_raw",
|
||||||
chance = 1, min = 1, max = 1},
|
chance = 1, min = 1, max = 1},
|
||||||
},
|
},
|
||||||
water_damage = 0,
|
water_damage = 0,
|
||||||
|
@ -213,8 +213,7 @@ function make_rat(name, behavior_fn)
|
||||||
view_range = 15,
|
view_range = 15,
|
||||||
floats = 1,
|
floats = 1,
|
||||||
drops = {
|
drops = {
|
||||||
{name = "mobs:meat_raw",
|
{name = "mobehavior:meat_raw", chance = 1, min = 1, max = 1},
|
||||||
chance = 1, min = 1, max = 1},
|
|
||||||
},
|
},
|
||||||
water_damage = 0,
|
water_damage = 0,
|
||||||
lava_damage = 4,
|
lava_damage = 4,
|
||||||
|
@ -239,7 +238,8 @@ end
|
||||||
|
|
||||||
function make_NPC(name, behavior_fn)
|
function make_NPC(name, behavior_fn)
|
||||||
|
|
||||||
mobs:register_simple_mob(mn..":"..name, {
|
-- mobs:register_simple_mob(mn..":"..name, {
|
||||||
|
mobehavior:register_mob_fast(mn..":"..name, {
|
||||||
type = "monster",
|
type = "monster",
|
||||||
passive = false,
|
passive = false,
|
||||||
attack_type = "dogfight",
|
attack_type = "dogfight",
|
||||||
|
|
|
@ -483,7 +483,7 @@ end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
--[[
|
||||||
make_wolf("wolf", function()
|
make_wolf("wolf", function()
|
||||||
return wander_around(6)
|
return wander_around(6)
|
||||||
end)
|
end)
|
||||||
|
@ -498,6 +498,7 @@ end)
|
||||||
make_bear("bear", function()
|
make_bear("bear", function()
|
||||||
return wander_around(6)
|
return wander_around(6)
|
||||||
end)
|
end)
|
||||||
|
]]
|
||||||
|
|
||||||
make_NPC("npc", function()
|
make_NPC("npc", function()
|
||||||
return wander_around(6)
|
return wander_around(6)
|
||||||
|
|
6
init.lua
6
init.lua
|
@ -37,9 +37,13 @@ minetest.register_on_shutdown(saveModData)
|
||||||
|
|
||||||
-- Mob Api
|
-- Mob Api
|
||||||
|
|
||||||
|
-- new api from scratch
|
||||||
|
dofile(path.."/api_fast.lua")
|
||||||
|
|
||||||
|
dofile(path.."/meat.lua")
|
||||||
dofile(path.."/api.lua")
|
dofile(path.."/api.lua")
|
||||||
dofile(path.."/behavior.lua")
|
dofile(path.."/behavior.lua")
|
||||||
dofile(path.."/simple_api.lua")
|
-- dofile(path.."/simple_api.lua")
|
||||||
|
|
||||||
|
|
||||||
dofile(path.."/scripts/init.lua")
|
dofile(path.."/scripts/init.lua")
|
||||||
|
|
|
@ -13,6 +13,7 @@ end
|
||||||
|
|
||||||
-- register mob function
|
-- register mob function
|
||||||
function mobs:register_simple_mob(name, def)
|
function mobs:register_simple_mob(name, def)
|
||||||
|
print("bad bad")
|
||||||
--[[
|
--[[
|
||||||
local btdata = {
|
local btdata = {
|
||||||
waypoints= {},
|
waypoints= {},
|
||||||
|
@ -201,8 +202,8 @@ minetest.register_entity(name, {
|
||||||
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(pos, 5, "tnt_smoke.png")
|
effect(pos, 5, "tnt_smoke.png")
|
||||||
|
print("death by falling")
|
||||||
if check_for_death(self) then
|
if check_for_death(self, pos) then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -328,7 +329,7 @@ minetest.register_entity(name, {
|
||||||
end,
|
end,
|
||||||
|
|
||||||
on_punch = function(self, hitter, tflp, tool_capabilities, dir)
|
on_punch = function(self, hitter, tflp, tool_capabilities, dir)
|
||||||
|
print("got punched !!!!")
|
||||||
-- weapon wear
|
-- weapon wear
|
||||||
local weapon = hitter:get_wielded_item()
|
local weapon = hitter:get_wielded_item()
|
||||||
local punch_interval = 1.4
|
local punch_interval = 1.4
|
||||||
|
@ -359,12 +360,18 @@ minetest.register_entity(name, {
|
||||||
max_hear_distance = 5
|
max_hear_distance = 5
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
local hp = self.object:get_hp()
|
||||||
|
|
||||||
|
local pos = self.object:getpos()
|
||||||
|
print("punched (hp: "..hp..")at "..pos.x..", "..pos.y..", "..pos.z)
|
||||||
|
|
||||||
|
|
||||||
-- exit here if dead
|
-- exit here if dead
|
||||||
if check_for_death(self) then
|
if check_for_death(self, pos) then
|
||||||
|
print("died from punch")
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
print("didn't die from punch")
|
||||||
-- blood_particles
|
-- blood_particles
|
||||||
if self.blood_amount > 0
|
if self.blood_amount > 0
|
||||||
and not disable_blood then
|
and not disable_blood then
|
||||||
|
|
49
spawning.lua
49
spawning.lua
|
@ -18,12 +18,12 @@ minetest.register_abm({
|
||||||
"default:silver_sand",
|
"default:silver_sand",
|
||||||
},
|
},
|
||||||
neighbors = {"air"},
|
neighbors = {"air"},
|
||||||
interval = 20,
|
interval = 30,
|
||||||
chance = 100,
|
chance = 400,
|
||||||
catch_up = false,
|
catch_up = false,
|
||||||
|
|
||||||
action = function(pos, node, active_object_count, active_object_count_wider)
|
action = function(pos, node, active_object_count, active_object_count_wider)
|
||||||
if active_object_count > 15 then
|
if active_object_count > 10 then
|
||||||
--print("too many local objs " .. active_object_count)
|
--print("too many local objs " .. active_object_count)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
@ -52,8 +52,8 @@ minetest.register_abm({
|
||||||
"default:dirt_with_coniferous_litter",
|
"default:dirt_with_coniferous_litter",
|
||||||
},
|
},
|
||||||
neighbors = {"air"},
|
neighbors = {"air"},
|
||||||
interval = 2,
|
interval = 20,
|
||||||
chance = 10,
|
chance = 200,
|
||||||
catch_up = false,
|
catch_up = false,
|
||||||
|
|
||||||
action = function(pos, node, active_object_count, active_object_count_wider)
|
action = function(pos, node, active_object_count, active_object_count_wider)
|
||||||
|
@ -75,3 +75,42 @@ minetest.register_abm({
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-- bunnies
|
||||||
|
minetest.register_abm({
|
||||||
|
nodenames = {
|
||||||
|
"default:dirt_with_grass",
|
||||||
|
"seasons:spring_default_dirt_with_grass",
|
||||||
|
"default:dirt_with_coniferous_litter",
|
||||||
|
"default:desert_sand",
|
||||||
|
"default:silver_sand",
|
||||||
|
},
|
||||||
|
neighbors = {"air"},
|
||||||
|
interval = 30,
|
||||||
|
chance = 600,
|
||||||
|
catch_up = false,
|
||||||
|
|
||||||
|
action = function(pos, node, active_object_count, active_object_count_wider)
|
||||||
|
if active_object_count > 8 then
|
||||||
|
--print("too many local objs " .. active_object_count)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local nearobjs = minetest.get_objects_inside_radius(pos, 40)
|
||||||
|
if #nearobjs > 4 then
|
||||||
|
--print("too many near objs")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
--print("----------spawning rat")
|
||||||
|
local p = minetest.find_node_near(pos, 3, "air")
|
||||||
|
if p then
|
||||||
|
local mob = minetest.add_entity(p, "mobehavior:bunny")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue