#!/usr/bin/env python3 """ CopyLeft 2020-2021 Pascal Engélibert This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, version 3 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see https://www.gnu.org/licenses/. """ import os, subprocess from PIL import Image #### CHANGE THESE SETTINGS ACCORDING TO YOUR SYSTEM # minetestmapper executable path MINETESTMAPPER_PATH = "/home/tuxmain/minetestmapper/minetestmapper" WORLD_PATH = "/var/games/minetest-server/.minetest/worlds/juneland-survival/" # Path to the folder which will contain the tiles OUTPUT_PATH = "/var/www/html/minetest-map/survival/" # Zoom level corresponding to 1:1 ratio (1 node = 1 pixel). # You usually don't need to change this. ZOOM_LEVEL = 7 # Minimum zoom level to generate (1 node < 1 pixel) MIN_ZOOM_LEVEL = 4 # Maximum zoom level to generate (1 node > 1 pixel) MAX_ZOOM_LEVEL = 10 # Tile size in pixels TILE_SIZE = 256 # Number of blocks to generate around the origin (0, 0) # Note: a block is a cube of many nodes RAY = 64 # Additionnal options passed to minetestmapper MINETESTMAPPER_OPTIONS = [ "--drawalpha", "--noemptyimage", "--max-y", "2000", "--colors", "/home/tuxmain/Colors.txt/colors.txt" ] #### END SETTINGS def run_minetestmapper(x, y, z): cmd = [ MINETESTMAPPER_PATH, "-i", WORLD_PATH, "-o", OUTPUT_PATH+"{}/{}/{}.png".format(y, x, z), "--geometry", "{}:{}+{}+{}".format(x*TILE_SIZE, (-1-z)*TILE_SIZE, TILE_SIZE, TILE_SIZE), *MINETESTMAPPER_OPTIONS ] #print(cmd) subprocess.run(cmd) if __name__ == "__main__": y = ZOOM_LEVEL for x in range(-RAY, RAY): os.makedirs(OUTPUT_PATH+"{}/{}".format(y, x), exist_ok=True) for z in range(-RAY, RAY): #print(y, x, z, end="\r") run_minetestmapper(x, y, z) f = 2 for y in range(ZOOM_LEVEL-1, MIN_ZOOM_LEVEL-1, -1): print("zoom level", y) for x in range(-RAY, RAY, f): os.makedirs(OUTPUT_PATH+"{}/{}".format(y, x//f), exist_ok=True) for z in range(-RAY, RAY, f): imgs = [] ok = False for x2 in range(f): line = [] for z2 in range(f): try: img = Image.open("{}{}/{}/{}.png".format(OUTPUT_PATH, ZOOM_LEVEL, x+x2, z+z2)) ok = True except FileNotFoundError: img = None line.append(img) imgs.append(line) if not ok: continue new_img = Image.new("RGB", (TILE_SIZE*f, TILE_SIZE*f)) for x2 in range(f): for z2 in range(f): img = imgs[x2][z2] if img: new_img.paste(img, (x2*TILE_SIZE, z2*TILE_SIZE)) new_img = new_img.resize((TILE_SIZE, TILE_SIZE)) new_img.save("{}{}/{}/{}.png".format(OUTPUT_PATH, y, x//f, z//f)) f *= 2 f = 1 for y in range(ZOOM_LEVEL+1, MAX_ZOOM_LEVEL+1): print("zoom level", y) for x in range(-RAY*f, RAY*f): os.makedirs(OUTPUT_PATH+"{}/{}".format(y, x*2), exist_ok=True) os.makedirs(OUTPUT_PATH+"{}/{}".format(y, x*2+1), exist_ok=True) for z in range(-RAY*f, RAY*f): try: img = Image.open("{}{}/{}/{}.png".format(OUTPUT_PATH, y-1, x, z)) except FileNotFoundError: continue img = img.resize((TILE_SIZE*2, TILE_SIZE*2)) img.crop((0, 0, TILE_SIZE, TILE_SIZE)).save("{}{}/{}/{}.png".format(OUTPUT_PATH, y, x*2, z*2)) img.crop((TILE_SIZE, 0, TILE_SIZE*2, TILE_SIZE)).save("{}{}/{}/{}.png".format(OUTPUT_PATH, y, x*2+1, z*2)) img.crop((0, TILE_SIZE, TILE_SIZE, TILE_SIZE*2)).save("{}{}/{}/{}.png".format(OUTPUT_PATH, y, x*2, z*2+1)) img.crop((TILE_SIZE, TILE_SIZE, TILE_SIZE*2, TILE_SIZE*2)).save("{}{}/{}/{}.png".format(OUTPUT_PATH, y, x*2+1, z*2+1)) f *= 2