-- highlandpools 0.1.1 by paramat -- For latest stable Minetest back to 0.4.8 -- Depends default -- Licenses: code WTFPL -- Parameters local YMAX = 195 -- Maximum altitude for pools local FLOW = 256 -- Stuff highlandpools = {} -- Functions function highlandpools_remtree(x, y, z, area, data) local c_tree = minetest.get_content_id("default:tree") local c_apple = minetest.get_content_id("default:apple") local c_leaves = minetest.get_content_id("default:leaves") local c_air = minetest.get_content_id("air") -- for j = 1, 7 do -- for i = -2, 2 do -- for k = -2, 2 do -- local vi = area:index(x+i, y+j, z+k) -- if data[vi] == c_tree -- or data[vi] == c_apple -- or data[vi] == c_leaves then -- data[vi] = c_air -- end -- end -- end -- end -- for j = 1, 7 do -- for i = -2, 2 do -- for k = -2, 2 do -- local vi = area:index(x+i, y-j, z+k) -- if data[vi] == c_tree -- or data[vi] == c_apple -- or data[vi] == c_leaves then -- data[vi] = c_air -- end -- end -- end -- end end -- On generated function minetest.register_on_generated(function(minp, maxp, seed) local y0 = minp.y if y0 < -32 or y0 > YMAX then return end local t1 = os.clock() local x0 = minp.x local z0 = minp.z --print ("[highlandpools] chunk ("..x0.." "..y0.." "..z0..")") local x1 = maxp.x local y1 = maxp.y local z1 = maxp.z local sidelen = x1 - x0 -- actually sidelen - 1 local vm, emin, emax = minetest.get_mapgen_object("voxelmanip") local area = VoxelArea:new{MinEdge=emin, MaxEdge=emax} local data = vm:get_data() local c_air = minetest.get_content_id("air") local c_ignore = minetest.get_content_id("ignore") local c_watsour = minetest.get_content_id("default:river_water_source") local c_grass = minetest.get_content_id("default:dirt_with_grass") local c_grass2 = minetest.get_content_id("aotearoa:restiad_peat") local c_grass3 = minetest.get_content_id("default:dirt_with_coniferous_litter") local c_grass4 = minetest.get_content_id("aotearoa:forest_peat") local c_grass5 = minetest.get_content_id("aotearoa:dirt_with_dark_litter") local c_tree = minetest.get_content_id("default:tree") local c_apple = minetest.get_content_id("default:apple") local c_leaves = minetest.get_content_id("default:leaves") local c_dirt = minetest.get_content_id("default:dirt") for xcen = x0 + 8, x1 - 7, 8 do for zcen = z0 + 8, z1 - 7, 8 do local yasurf = false -- y of above surface node for y = y1, 2, -1 do local vi = area:index(xcen, y, zcen) local c_node = data[vi] if y == y1 and c_node ~= c_air then -- if top node solid break elseif c_node == c_watsour then break elseif c_node == c_grass then yasurf = y + 1 break elseif c_node == c_grass2 then yasurf = y + 1 break elseif c_node == c_grass3 then yasurf = y + 1 break elseif c_node == c_grass4 then yasurf = y + 1 break elseif c_node == c_grass5 then yasurf = y + 1 break end end if yasurf then local abort = false for ser = 1, 80 do local vi = area:index(xcen + ser, yasurf, zcen) local c_node = data[vi] if xcen + ser == x1 then abort = true elseif c_node ~= c_air and c_node ~= c_tree and c_node ~= c_leaves and c_node ~= c_apple then break end end for ser = 1, 80 do local vi = area:index(xcen - ser, yasurf, zcen) local c_node = data[vi] if xcen - ser == x0 then abort = true elseif c_node ~= c_air and c_node ~= c_tree and c_node ~= c_leaves and c_node ~= c_apple then break end end for ser = 1, 80 do local vi = area:index(xcen, yasurf, zcen + ser) local c_node = data[vi] if zcen + ser == z1 then abort = true elseif c_node ~= c_air and c_node ~= c_tree and c_node ~= c_leaves and c_node ~= c_apple then break end end for ser = 1, 80 do local vi = area:index(xcen, yasurf, zcen - ser) local c_node = data[vi] if zcen - ser == z0 then abort = true elseif c_node ~= c_air and c_node ~= c_tree and c_node ~= c_leaves and c_node ~= c_apple then break end end if abort then break end local vi = area:index(xcen, yasurf, zcen) data[vi] = c_watsour local flab = false -- flow abort for flow = 1, FLOW do for z = z0, z1 do for x = x0, x1 do local vif = area:index(x, yasurf, z) if data[vif] == c_watsour then if x == x0 or x == x1 or z == z0 or z == z1 then flab = true -- if water at chunk edge abort flow break else -- flow water local vie = area:index(x + 1, yasurf, z) local viw = area:index(x - 1, yasurf, z) local vin = area:index(x, yasurf, z + 1) local vis = area:index(x, yasurf, z - 1) if data[vie] == c_tree then --highlandpools_remtree(x + 1, yasurf, z, area, data) data[vie] = c_watsour elseif data[vie] == c_air or data[vie] == c_apple or data[vie] == c_leaves then data[vie] = c_watsour end if data[viw] == c_tree then --highlandpools_remtree(x - 1, yasurf, z, area, data) data[viw] = c_watsour elseif data[viw] == c_air or data[viw] == c_apple or data[viw] == c_leaves then data[viw] = c_watsour end if data[vin] == c_tree then --highlandpools_remtree(x, yasurf, z + 1, area, data) data[vin] = c_watsour elseif data[vin] == c_air or data[vin] == c_apple or data[vin] == c_leaves then data[vin] = c_watsour end if data[vis] == c_tree then --highlandpools_remtree(x, yasurf, z - 1, area, data) data[vis] = c_watsour elseif data[vis] == c_air or data[vis] == c_apple or data[vis] == c_leaves then data[vis] = c_watsour end end end end if flab then break end end if flab then break end end if flab then -- erase water from this y level for z = z0, z1 do for x = x0, x1 do local vi = area:index(x, yasurf, z) if data[vi] == c_watsour then data[vi] = c_air end end end else -- flow downwards add dirt for z = z0, z1 do for x = x0, x1 do local vi = area:index(x, yasurf, z) if data[vi] == c_watsour then for y = yasurf - 1, y0, -1 do local viu = area:index(x, y, z) if data[viu] == c_air then data[viu] = c_watsour elseif data[viu] == c_grass then data[viu] = c_dirt break else break end end end end end end end end end vm:set_data(data) vm:set_lighting({day=0, night=0}) vm:calc_lighting() vm:write_to_map(data) --local chugent = math.ceil((os.clock() - t1) * 1000) --print ("[highlandpools] time "..chugent.." ms") end) local function dissolve(pos_dissolve, pos_liquid) local node = minetest.get_node(pos_liquid) local name = node.name local nodedef = minetest.registered_nodes[name] if nodedef and nodedef.liquidtype ~= "none" then minetest.set_node(pos_dissolve, {name="air"}) return true end end minetest.register_abm({ nodenames = {"group:grass", "group:horsetail", "group:plant", "group:flower", "group:flora", "group:dry_grass", "group:leaves", "group:dissolve", "group:bush", "group:bushes", "group:sapling", "group:vines"}, neighbors = {"group:liquid"}, interval = 5, chance = 1, action = function(pos, node) if dissolve(pos, {x=pos.x, y=pos.y+1, z=pos.z}) then return end if dissolve(pos, {x=pos.x+1, y=pos.y, z=pos.z}) then return end if dissolve(pos, {x=pos.x-1, y=pos.y, z=pos.z}) then return end if dissolve(pos, {x=pos.x, y=pos.y, z=pos.z+1}) then return end if dissolve(pos, {x=pos.x, y=pos.y, z=pos.z-1}) then return end end, })