Change villager spawning algorithm

Now the entity spawners regularily check if another object is nearby, only then they spawn.
This should make entity spawns more reliable.
This commit is contained in:
Wuzzy 2019-09-06 18:10:08 +02:00
parent 1b833cc850
commit 1fbc8b83a9
2 changed files with 34 additions and 9 deletions

View File

@ -429,7 +429,6 @@ function village.spawn_chunk(pos, orient, replace, pr, chunktype, nofill, dont_c
"village:entity_spawner", "village:entity_spawner",
function(pos) function(pos)
table.insert(ent_spawns, pos) table.insert(ent_spawns, pos)
minetest.remove_node(pos)
end, true) end, true)
if #ent_spawns > 0 then if #ent_spawns > 0 then
@ -440,14 +439,19 @@ function village.spawn_chunk(pos, orient, replace, pr, chunktype, nofill, dont_c
end end
local spawn, index = util.choice_element(ent_spawns, pr) local spawn, index = util.choice_element(ent_spawns, pr)
if spawn ~= nil then if spawn ~= nil then
spawn.y = spawn.y + 1.6 local meta = minetest.get_meta(spawn)
minetest.add_entity(spawn, ent) meta:set_string("entity", ent)
minetest.get_node_timer(spawn):start(1)
-- Prevent spawning on same tile -- Prevent spawning on same tile
table.remove(ent_spawns, index) table.remove(ent_spawns, index)
end end
end end
end end
end end
-- Remove unused entity spawners
for e=1, #ent_spawns do
minetest.remove_node(ent_spawns[e])
end
end end
end end

View File

@ -25,18 +25,39 @@ minetest.register_node(
"village:entity_spawner", "village:entity_spawner",
{ {
description = S("Village Entity Spawner"), description = S("Village Entity Spawner"),
tiles = { drawtype = "airlike",
"village_entity.png", "village_entity.png", "village_entity.png", pointable = false,
"village_entity.png", "village_entity.png^[transformFX", "village_entity.png^[transformFX" inventory_image = "village_entity.png",
}, wield_image = "village_entity.png",
is_ground_content = false, is_ground_content = true,
sunlight_propagates = true, sunlight_propagates = true,
paramtype = "light", paramtype = "light",
post_effect_color = { a = 0x40, r = 0x8D, g = 0x75, b = 0x97 }, post_effect_color = { a = 0x40, r = 0x8D, g = 0x75, b = 0x97 },
walkable = false, walkable = false,
floodable = true,
buildable_to = true,
drop = "", drop = "",
groups = {dig_immediate = 3, not_in_creative_inventory = 1}, groups = {dig_immediate = 3, not_in_creative_inventory = 1},
sounds = default.node_sound_defaults() sounds = default.node_sound_defaults(),
on_timer = function(pos, elapsed)
-- Wait until some objects are nearby ...
local objs_around = minetest.get_objects_inside_radius(pos, 12)
-- ... but not TOO nearby (occupying the pos)
local objs_near = minetest.get_objects_inside_radius(pos, 1.2)
if #objs_around > 0 and #objs_near == 0 then
local ent = minetest.get_meta(pos):get_string("entity")
if ent ~= "" then
minetest.add_entity({x=pos.x, y=pos.y+0.6, z=pos.z}, ent)
else
minetest.log("error", "[village] Entity spawner without 'entity' in meta set @ "..minetest.pos_to_string(pos))
end
minetest.remove_node(pos)
return
else
-- Don't spawn and try again later
minetest.get_node_timer(pos):start(5)
end
end,
}) })
minetest.register_node( minetest.register_node(