From 1fbc8b83a9a248095b25a22629a5d80ce48aff26 Mon Sep 17 00:00:00 2001 From: Wuzzy Date: Fri, 6 Sep 2019 18:10:08 +0200 Subject: [PATCH] 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. --- mods/village/generate.lua | 10 +++++++--- mods/village/mapgen.lua | 33 +++++++++++++++++++++++++++------ 2 files changed, 34 insertions(+), 9 deletions(-) diff --git a/mods/village/generate.lua b/mods/village/generate.lua index 738f205..1e1376a 100644 --- a/mods/village/generate.lua +++ b/mods/village/generate.lua @@ -429,7 +429,6 @@ function village.spawn_chunk(pos, orient, replace, pr, chunktype, nofill, dont_c "village:entity_spawner", function(pos) table.insert(ent_spawns, pos) - minetest.remove_node(pos) end, true) if #ent_spawns > 0 then @@ -440,14 +439,19 @@ function village.spawn_chunk(pos, orient, replace, pr, chunktype, nofill, dont_c end local spawn, index = util.choice_element(ent_spawns, pr) if spawn ~= nil then - spawn.y = spawn.y + 1.6 - minetest.add_entity(spawn, ent) + local meta = minetest.get_meta(spawn) + meta:set_string("entity", ent) + minetest.get_node_timer(spawn):start(1) -- Prevent spawning on same tile table.remove(ent_spawns, index) end end end end + -- Remove unused entity spawners + for e=1, #ent_spawns do + minetest.remove_node(ent_spawns[e]) + end end end diff --git a/mods/village/mapgen.lua b/mods/village/mapgen.lua index 63b3ade..65ab15d 100644 --- a/mods/village/mapgen.lua +++ b/mods/village/mapgen.lua @@ -25,18 +25,39 @@ minetest.register_node( "village:entity_spawner", { description = S("Village Entity Spawner"), - tiles = { - "village_entity.png", "village_entity.png", "village_entity.png", - "village_entity.png", "village_entity.png^[transformFX", "village_entity.png^[transformFX" - }, - is_ground_content = false, + drawtype = "airlike", + pointable = false, + inventory_image = "village_entity.png", + wield_image = "village_entity.png", + is_ground_content = true, sunlight_propagates = true, paramtype = "light", post_effect_color = { a = 0x40, r = 0x8D, g = 0x75, b = 0x97 }, walkable = false, + floodable = true, + buildable_to = true, drop = "", 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(