diff --git a/init.lua b/init.lua index 36574b2..98bfcf9 100644 --- a/init.lua +++ b/init.lua @@ -116,24 +116,31 @@ minetest.register_on_generated(function(minp, maxp, seed) local pos = vector.add(use, def.offset) minetest.place_schematic(pos, def.schematic, "random") - -- Very Hacky Solution due to minetest.place_schematic carrying the replacements parameter between calls. - -- This parses the schematic file manually, then replaces appropriate nodes between all possible positions. local schematic_size = {} + + -- Open the schematic and read the three size integers into schematic_size. local sf = io.open(def.schematic, "rb") sf:read(6) schematic_size.x = string.byte(sf:read(1)) * 256 + string.byte(sf:read(1)) schematic_size.y = string.byte(sf:read(1)) * 256 + string.byte(sf:read(1)) schematic_size.z = string.byte(sf:read(1)) * 256 + string.byte(sf:read(1)) sf:close() + + local mid = vector.add(pos, vector.divide(schematic_size, 2)) + + -- Replace appropriate nodes in the possible schematic area. for k,v in pairs(r) do - local positions = minetest.find_nodes_in_area(vector.subtract(pos, schematic_size), vector.add(maxp, schematic_size), {k}) + local positions = minetest.find_nodes_in_area(vector.subtract(mid, schematic_size), vector.add(mid, schematic_size), {k}) if positions then for _,p in ipairs(positions) do minetest.set_node(p, {name=v}) end end end - -- End Very Hacky Solution + + if def.special then + def.special(pos, mid, schematic_size) + end end end end diff --git a/schematics/meteor_1.mts b/schematics/meteor_1.mts new file mode 100644 index 0000000..7f77267 Binary files /dev/null and b/schematics/meteor_1.mts differ diff --git a/structures.lua b/structures.lua index 75ba856..c50d304 100644 --- a/structures.lua +++ b/structures.lua @@ -187,7 +187,7 @@ end ancient_world.register("ancient_world:mine_1", { schematic = minetest.get_modpath("ancient_world") .. "/schematics/mine_1.mts", type = "decoration", - on = {"default:dirt_with_grass"}, + on = {"default:dirt_with_grass", "default:dirt_with_dry_grass"}, offset = { x = 0, y = -48, @@ -207,3 +207,57 @@ ancient_world.register("ancient_world:mine_1", { {"default:stone_with_gold", "default:stone_with_copper", "default:stone_with_iron"}), }, }) + +ancient_world.register("ancient_world:meteor_1", { + schematic = minetest.get_modpath("ancient_world") .. "/schematics/meteor_1.mts", + type = "decoration", + on = {"default:dirt_with_grass", "default:dirt_with_dry_grass"}, + offset = { + x = 0, + y = -2, + z = 0, + }, + limit_y = { + max = 31000, + min = -32, + }, + replacements = { + ["ancient_world:placeholder_1"] = "fire:basic_flame", + }, + special = function(pos, mid, schematic_size) + local want = { + ["default:dirt_with_dry_grass"] = true, + ["default:dirt_with_grass"] = true, + ["default:stone"] = true, + } + local t = vector.add(mid, schematic_size) + t.y = t.y - 4 + local positions = minetest.find_nodes_in_area(vector.subtract(mid, schematic_size), t, {"air"}) + if positions then + for _,p in ipairs(positions) do + if math.random(1, 100) <= 10 then + local hit = p + local tries = 1 + while true do + hit = vector.add(hit, {x=0, y=-1, z=0}) + if want[minetest.get_node(vector.add(hit, {x=0, y=-1, z=0})).name] then + break + end + if want[minetest.get_node(vector.add(hit, {x=0, y=-1, z=0})).name] == "ignore" then + hit = nil + break + end + if tries > 16 then + hit = nil + break + end + tries = tries + 1 + end + if hit then + minetest.set_node(hit, {name="default:dirt"}) + end + end + end + end + end, +})