Not a clue.

master
James Stevenson 2019-01-17 16:20:34 -05:00
parent 187c9c40a2
commit eea4a4a535
2 changed files with 105 additions and 73 deletions

View File

@ -4,6 +4,7 @@
local random = math.random
local redo = mobs.redo
local check_for_player = mobs.check_for_player
local limiter = mobs.limiter
minetest.register_node("mobs:spawner", {
@ -24,78 +25,84 @@ minetest.register_node("mobs:spawner", {
on_blast = function()
end,
on_timer = function(pos, elapsed)
if elapsed >= 30 then
local node = minetest.get_node_or_nil({
x = pos.x,
y = pos.y - 1,
z = pos.z,
})
if node and node.name then
local node_below = minetest.registered_nodes[node.name]
if node_below and not node_below.walkable then
return redo(pos)
end
end
local light = minetest.get_node_light(pos)
limiter(pos)
local mobs = {
"mobs:rat",
"mobs:npc",
}
local biome = minetest.get_biome_name(minetest.get_biome_data(pos).biome)
local tod = (minetest.get_timeofday() or 0) * 24000
local night = tod > 19000 or tod < 06000
local protection = minetest.find_node_near(pos, 13,
{"protector:protect", "protector:protect2"}, true)
if not protection and (biome == "underground" or night) and
light < 3 then
local mobs_to_insert = {
"mobs:dungeon_master",
"mobs:oerkki",
"mobs:zombie" .. random(4),
}
for i = 1, #mobs_to_insert do
mobs[#mobs + 1] = mobs_to_insert[i]
end
end
if biome ~= "underground" then
local mobs_to_insert = {
"mobs:sheep_white",
"mobs:kitten",
"mobs:bunny",
}
for i = 1, #mobs_to_insert do
mobs[#mobs + 1] = mobs_to_insert[i]
end
end
local mob = mobs[random(#mobs)]
local colbox = minetest.registered_entities[mob].collisionbox
local spawn_pos = {
x = pos.x,
y = pos.y + 1.6,
z = pos.z,
}
local p1 = {
x = spawn_pos.x + colbox[1],
y = spawn_pos.y + colbox[2],
z = spawn_pos.z + colbox[3],
}
local p2 = {
x = spawn_pos.x + colbox[4],
y = spawn_pos.y + colbox[5],
z = spawn_pos.z + colbox[6],
}
-- Check mob's collisionbox for adequate space to spawn.
local d = vector.distance(p1, p2)
local r, s = minetest.find_nodes_in_area(p1, p2, "air", true)
if s["air"] < d then
if check_for_player(pos) then
minetest.get_node_timer(pos):set(10, 0)
end
limiter(pos)
local node = minetest.get_node_or_nil({
x = pos.x,
y = pos.y - 1,
z = pos.z,
})
if node and node.name then
local node_below = minetest.registered_nodes[node.name]
if node_below and not node_below.walkable then
return redo(pos)
end
minetest.add_entity(spawn_pos, mob)
redo(pos)
else
minetest.get_node_timer(pos):set(elapsed + 1, elapsed)
end
local light = minetest.get_node_light(pos)
local mobs = {
"mobs:rat",
"mobs:npc",
}
local biome = minetest.get_biome_name(minetest.get_biome_data(pos).biome)
local tod = (minetest.get_timeofday() or 0) * 24000
local night = tod > 19000 or tod < 06000
local protection = minetest.find_node_near(pos, 13,
{"protector:protect", "protector:protect2"}, true)
if not protection and (biome == "underground" or night) and
light < 3 then
local mobs_to_insert = {
"mobs:dungeon_master",
"mobs:oerkki",
"mobs:zombie" .. random(4),
}
for i = 1, #mobs_to_insert do
mobs[#mobs + 1] = mobs_to_insert[i]
end
end
if biome ~= "underground" then
local mobs_to_insert = {
"mobs:sheep_white",
"mobs:kitten",
"mobs:bunny",
}
for i = 1, #mobs_to_insert do
mobs[#mobs + 1] = mobs_to_insert[i]
end
end
local mob = mobs[random(#mobs)]
local colbox = minetest.registered_entities[mob].collisionbox
local spawn_pos = {
x = pos.x,
y = pos.y + 1.6,
z = pos.z,
}
local p1 = {
x = spawn_pos.x + colbox[1],
y = spawn_pos.y + colbox[2],
z = spawn_pos.z + colbox[3],
}
local p2 = {
x = spawn_pos.x + colbox[4],
y = spawn_pos.y + colbox[5],
z = spawn_pos.z + colbox[6],
}
-- Check mob's collisionbox for adequate space to spawn.
local d = vector.distance(p1, p2)
local r, s = minetest.find_nodes_in_area(p1, p2, "air", true)
if s["air"] < d then
return redo(pos)
end
print("Spawning " .. mob)
minetest.add_entity(spawn_pos, mob)
redo(pos)
end,
})

View File

@ -1,5 +1,17 @@
local random = math.random
mobs.check_for_player = function(pos)
local objects_in_radius = minetest.get_objects_inside_radius(pos, 16)
for i = 1, #objects_in_radius do
local object = objects_in_radius[i]
local player = object:is_player()
if player then
return true
end
end
return
end
mobs.undercrowd = function(pos, radius)
radius = radius or 3
local r = minetest.get_objects_inside_radius(pos, radius)
@ -34,18 +46,24 @@ minetest.register_on_mods_loaded(function()
end
end
end)
mobs.redo = function(pos, radius)
print("Redoing.")
radius = radius or 1
local p1 = {
x = pos.x - radius,
y = pos.y - radius,
z = pos.z - radius,
}
local p2 = {
x = pos.x + radius,
y = pos.y + radius,
z = pos.z + radius,
}
local n = minetest.find_node_near(pos, radius, "mobs:spawner")
if n then
local t = minetest.get_node_timer(n)
@ -54,6 +72,7 @@ mobs.redo = function(pos, radius)
t:start(1)
end
end
local a = minetest.find_nodes_in_area_under_air(p1, p2, "group:reliable")
if a and a[1] then
print("Setting spawner.")
@ -63,6 +82,7 @@ mobs.redo = function(pos, radius)
y = an.y + 1,
z = an.z,
}
print("Setting spawner.")
minetest.set_node(np, {name = "mobs:spawner"})
end
end
@ -73,12 +93,14 @@ mobs.limiter = function(pos, radius, limit, immediate_surrounding, surrounding)
limit = limit or radius * 3
immediate_surrounding = immediate_surrounding or
minetest.get_objects_inside_radius(pos, radius)
if #immediate_surrounding > 6 then
print("Limiting.")
return redo(pos)
return
end
local surrounding = surrounding or
minetest.get_objects_inside_radius(pos, radius * 3)
if #surrounding > 18 then
local h = 0
for i = 1, #surrounding do
@ -92,8 +114,7 @@ mobs.limiter = function(pos, radius, limit, immediate_surrounding, surrounding)
end
end
if h > limit then
print("Limiting.")
return redo(pos)
return
end
end
end
@ -115,7 +136,9 @@ minetest.register_globalstep(function(dtime)
if not pos then
break
end
undercrowd(pos, 8)
if minetest.find_node_near(pos, 8, "mobs:spawner") then
break
end
@ -128,10 +151,12 @@ minetest.register_globalstep(function(dtime)
if minetest.get_node_or_nil(pos).name ~= "air" then
break
end
local added = minetest.add_node(pos, {name = "mobs:spawner"})
if not added then
break
end
minetest.get_node_timer(pos):start(0)
end
end)