def main(): parser = ArgumentParser(usage="usage: %(prog)s [options] [" + OPERATIONS + "]") parser.add_argument('OPERATOR', nargs='?') parser.add_argument('FILE', nargs='?') parser.add_argument('-o', '--output-dir', dest='output_dir', help="generate files in DIR [default = '%(default)s']", metavar="DIR", default='.') parser.add_argument('-n', '--worldname', dest='world_name', help="set world name to STR. output is stored in a " + "world file with the name format 'STR.world'. If " + "a name is not provided, then seed_N.world, " + "where N=SEED", metavar="STR") parser.add_argument('--hdf5', dest='hdf5', action="store_true", help="Save world file using HDF5 format. " + "Default = store using protobuf format", default=False) parser.add_argument('-s', '--seed', dest='seed', type=int, help="Use seed=N to initialize the pseudo-random " + "generation. If not provided, one will be " + "selected for you.", metavar="N") parser.add_argument('-t', '--step', dest='step', help="Use step=[" + STEPS + "] to specify how far " + "to proceed in the world generation process. " + "[default='%(default)s']", metavar="STR", default="full") # TODO --step appears to be duplicate of OPERATIONS. Especially if # ancient_map is added to --step parser.add_argument('-x', '--width', dest='width', type=int, help="N = width of the world to be generated " + "[default=%(default)s]", metavar="N", default='512') parser.add_argument('-y', '--height', dest='height', type=int, help="N = height of the world to be generated " + "[default=%(default)s]", metavar="N", default='512') parser.add_argument('-q', '--number-of-plates', dest='number_of_plates', type=int, help="N = number of plates [default = %(default)s]", metavar="N", default='10') parser.add_argument('--recursion_limit', dest='recursion_limit', type=int, help="Set the recursion limit [default = %(default)s]", metavar="N", default='2000') parser.add_argument('-v', '--verbose', dest='verbose', action="store_true", help="Enable verbose messages", default=False) parser.add_argument('--version', dest='version', action="store_true", help="Display version information", default=False) parser.add_argument('--bw', '--black-and-white', dest='black_and_white', action="store_true", help="generate maps in black and white", default=False) # ----------------------------------------------------- g_generate = parser.add_argument_group( "Generate Options", "These options are only useful in plate and " + "world modes") g_generate.add_argument('-r', '--rivers', dest='rivers_map', action="store_true", help="generate rivers map") g_generate.add_argument('--gs', '--grayscale-heightmap', dest='grayscale_heightmap', action="store_true", help='produce a grayscale heightmap') g_generate.add_argument('--ocean_level', dest='ocean_level', type=float, help='elevation cut off for sea level " +' '[default = %(default)s]', metavar="N", default=1.0) g_generate.add_argument( '--temps', dest='temps', help="Provide alternate ranges for temperatures. " + "If not provided, the default values will be used. \n" + "[default = .126/.235/.406/.561/.634/.876]", metavar="#/#/#/#/#/#") g_generate.add_argument( '--humidity', dest='humids', help="Provide alternate ranges for humidities. " + "If not provided, the default values will be used. \n" + "[default = .059/.222/.493/.764/.927/.986/.998]", metavar="#/#/#/#/#/#/#") g_generate.add_argument( '-gv', '--gamma-value', dest='gv', type=float, help="N = Gamma value for temperature/precipitation " + "gamma correction curve. [default = %(default)s]", metavar="N", default='1.25') g_generate.add_argument( '-go', '--gamma-offset', dest='go', type=float, help="N = Adjustment value for temperature/precipitation " + "gamma correction curve. [default = %(default)s]", metavar="N", default='.2') g_generate.add_argument('--not-fade-borders', dest='fade_borders', action="store_false", help="Not fade borders", default=True) g_generate.add_argument('--scatter', dest='scatter_plot', action="store_true", help="generate scatter plot") g_generate.add_argument('--sat', dest='satelite_map', action="store_true", help="generate satellite map") g_generate.add_argument('--ice', dest='icecaps_map', action="store_true", help="generate ice caps map") # ----------------------------------------------------- g_ancient_map = parser.add_argument_group( "Ancient Map Options", "These options are only useful in " + "ancient_map mode") g_ancient_map.add_argument('-w', '--worldfile', dest='world_file', help="FILE to be loaded", metavar="FILE") g_ancient_map.add_argument('-g', '--generatedfile', dest='generated_file', help="name of the FILE", metavar="FILE") g_ancient_map.add_argument('-f', '--resize-factor', dest='resize_factor', type=int, help="resize factor (only integer values). " + "Note this can only be used to increase " + "the size of the map [default=%(default)s]", metavar="N", default='1') g_ancient_map.add_argument('--sea_color', dest='sea_color', help="string for color [" + SEA_COLORS + "]", metavar="S", default="brown") g_ancient_map.add_argument('--not-draw-biome', dest='draw_biome', action="store_false", help="Not draw biome", default=True) g_ancient_map.add_argument('--not-draw-mountains', dest='draw_mountains', action="store_false", help="Not draw mountains", default=True) g_ancient_map.add_argument('--not-draw-rivers', dest='draw_rivers', action="store_false", help="Not draw rivers", default=True) g_ancient_map.add_argument('--draw-outer-border', dest='draw_outer_border', action="store_true", help="Draw outer land border", default=False) # TODO: allow for RGB specification as [r g b], ie [0.5 0.5 0.5] for gray # ----------------------------------------------------- export_options = parser.add_argument_group( "Export Options", "You can specify the formats you wish the generated output to be in. ") export_options.add_argument( "--export-format", dest="export_format", type=str, help="Export to a specific format such as BMP or PNG. " + "See http://www.gdal.org/formats_list.html for possible formats.", default="PNG", metavar="STR") export_options.add_argument( "--export-datatype", dest="export_datatype", type=str, help="Type of stored data, e.g. uint16, int32, float32 etc.", default="uint16", metavar="STR") args = parser.parse_args() if args.version: usage() if os.path.exists(args.output_dir): if not os.path.isdir(args.output_dir): raise Exception("Output dir exists but it is not a dir") else: print('Directory does not exist, we are creating it') os.makedirs(args.output_dir) # it needs to be increased to be able to generate very large maps # the limit is hit when drawing ancient maps sys.setrecursionlimit(args.recursion_limit) if args.number_of_plates < 1 or args.number_of_plates > 100: usage(error="Number of plates should be in [1, 100]") if args.hdf5 and not HDF5_AVAILABLE: usage(error="HDF5 requires the presence of native libraries") operation = "world" if args.OPERATOR is None: pass elif args.OPERATOR is not None and args.OPERATOR.lower() not in OPERATIONS: parser.print_help() usage("Only 1 operation allowed [" + OPERATIONS + "]") else: operation = args.OPERATOR.lower() if args.OPERATOR == 'info' or args.OPERATOR == 'export': if args.FILE is None: parser.print_help() usage("For operation info only the filename should be specified") if not os.path.exists(args.FILE): usage("The specified world file does not exist") maxseed = numpy.iinfo( numpy.uint16 ).max # there is a hard limit somewhere so seeds outside the uint16 range are considered unsafe if args.seed is not None: seed = int(args.seed) assert 0 <= seed <= maxseed, "Seed has to be in the range between 0 and %s, borders included." % maxseed else: seed = numpy.random.randint( 0, maxseed) # first-time RNG initialization is done automatically numpy.random.seed(seed) if args.world_name: world_name = args.world_name else: world_name = "seed_%i" % seed step = check_step(args.step) world_format = 'protobuf' if args.hdf5: world_format = 'hdf5' generation_operation = (operation == 'world') or (operation == 'plates') if args.grayscale_heightmap and not generation_operation: usage(error="Grayscale heightmap can be produced only during world " + "generation") if args.rivers_map and not generation_operation: usage(error="Rivers map can be produced only during world generation") if args.temps and not generation_operation: usage(error="temps can be assigned only during world generation") if args.temps and len(args.temps.split('/')) is not 6: usage(error="temps must have exactly 6 values") if args.go >= 1 or args.go < 0: usage( error= "Gamma offset must be greater than or equal to 0 and less than 1") if args.gv <= 0: usage(error="Gamma value must be greater than 0") temps = [.874, .765, .594, .439, .366, .124] if args.temps: temps = args.temps.split('/') for x in range(0, len(temps)): temps[x] = 1 - float(temps[x]) if args.humids and not generation_operation: usage(error="humidity can be assigned only during world generation") if args.humids and len(args.humids.split('/')) is not 7: usage(error="humidity must have exactly 7 values") humids = [.941, .778, .507, .236, 0.073, .014, .002] if args.humids: humids = args.humids.split('/') for x in range(0, len(humids)): humids[x] = 1 - float(humids[x]) if args.scatter_plot and not generation_operation: usage( error="Scatter plot can be produced only during world generation") print('Worldengine - a world generator (v. %s)' % VERSION) print('-----------------------') if generation_operation: print(' operation : %s generation' % operation) print(' seed : %i' % seed) print(' name : %s' % world_name) print(' width : %i' % args.width) print(' height : %i' % args.height) print(' number of plates : %i' % args.number_of_plates) print(' world format : %s' % world_format) print(' black and white maps : %s' % args.black_and_white) print(' step : %s' % step.name) print(' greyscale heightmap : %s' % args.grayscale_heightmap) print(' icecaps heightmap : %s' % args.icecaps_map) print(' rivers map : %s' % args.rivers_map) print(' scatter plot : %s' % args.scatter_plot) print(' satellite map : %s' % args.satelite_map) print(' fade borders : %s' % args.fade_borders) if args.temps: print(' temperature ranges : %s' % args.temps) if args.humids: print(' humidity ranges : %s' % args.humids) print(' gamma value : %s' % args.gv) print(' gamma offset : %s' % args.go) if operation == 'ancient_map': print(' operation : %s generation' % operation) print(' resize factor : %i' % args.resize_factor) print(' world file : %s' % args.world_file) print(' sea color : %s' % args.sea_color) print(' draw biome : %s' % args.draw_biome) print(' draw rivers : %s' % args.draw_rivers) print(' draw mountains : %s' % args.draw_mountains) print(' draw land outer border : %s' % args.draw_outer_border) #Warning messages warnings = [] if temps != sorted(temps, reverse=True): warnings.append("WARNING: Temperature array not in ascending order") if numpy.amin(temps) < 0: warnings.append( "WARNING: Maximum value in temperature array greater than 1") if numpy.amax(temps) > 1: warnings.append( "WARNING: Minimum value in temperature array less than 0") if humids != sorted(humids, reverse=True): warnings.append("WARNING: Humidity array not in ascending order") if numpy.amin(humids) < 0: warnings.append( "WARNING: Maximum value in humidity array greater than 1") if numpy.amax(humids) > 1: warnings.append( "WARNING: Minimum value in temperature array less than 0") if warnings: print("\n") for x in range(len(warnings)): print(warnings[x]) set_verbose(args.verbose) if operation == 'world': print('') # empty line print('starting (it could take a few minutes) ...') world = generate_world(world_name, args.width, args.height, seed, args.number_of_plates, args.output_dir, step, args.ocean_level, temps, humids, world_format, gamma_curve=args.gv, curve_offset=args.go, fade_borders=args.fade_borders, verbose=args.verbose, black_and_white=args.black_and_white) if args.grayscale_heightmap: generate_grayscale_heightmap( world, '%s/%s_grayscale.png' % (args.output_dir, world_name)) if args.rivers_map: generate_rivers_map( world, '%s/%s_rivers.png' % (args.output_dir, world_name)) if args.scatter_plot: draw_scatter_plot( world, '%s/%s_scatter.png' % (args.output_dir, world_name)) if args.satelite_map: draw_satellite_map( world, '%s/%s_satellite.png' % (args.output_dir, world_name)) if args.icecaps_map: draw_icecaps_map( world, '%s/%s_icecaps.png' % (args.output_dir, world_name)) elif operation == 'plates': print('') # empty line print('starting (it could take a few minutes) ...') generate_plates(seed, world_name, args.output_dir, args.width, args.height, num_plates=args.number_of_plates) elif operation == 'ancient_map': print('') # empty line print('starting (it could take a few minutes) ...') # First, some error checking if args.sea_color == "blue": sea_color = (142, 162, 179, 255) elif args.sea_color == "brown": sea_color = (212, 198, 169, 255) else: usage("Unknown sea color: " + args.sea_color + " Select from [" + SEA_COLORS + "]") if not args.world_file: usage( "For generating an ancient map is necessary to specify the " + "world to be used (-w option)") world = load_world(args.world_file) print_verbose(" * world loaded") if not args.generated_file: args.generated_file = "ancient_map_%s.png" % world.name operation_ancient_map(world, args.generated_file, args.resize_factor, sea_color, args.draw_biome, args.draw_rivers, args.draw_mountains, args.draw_outer_border) elif operation == 'info': world = load_world(args.FILE) print_world_info(world) elif operation == 'export': world = load_world(args.FILE) print_world_info(world) export(world, args.export_format, args.export_datatype, path='%s/%s_elevation' % (args.output_dir, world_name)) else: raise Exception('Unknown operation: valid operations are %s' % OPERATIONS) print('...done')
def main(): parser = ArgumentParser( usage="usage: %(prog)s [options] [" + OPERATIONS + "]") parser.add_argument('OPERATOR', nargs='?') parser.add_argument('FILE', nargs='?') parser.add_argument( '-o', '--output-dir', dest='output_dir', help="generate files in DIR [default = '%(default)s']", metavar="DIR", default='.') parser.add_argument( '-n', '--worldname', dest='world_name', help="set world name to STR. output is stored in a " + "world file with the name format 'STR.world'. If " + "a name is not provided, then seed_N.world, " + "where N=SEED", metavar="STR") # TODO: add description of protocol buffer parser.add_argument('-b', '--protocol-buffer', dest='protobuf', action="store_true", help="Save world file using protocol buffer format. " + "Default = store using pickle format", default=False) parser.add_argument('-s', '--seed', dest='seed', type=int, help="Use seed=N to initialize the pseudo-random " + "generation. If not provided, one will be " + "selected for you.", metavar="N") parser.add_argument('-t', '--step', dest='step', help="Use step=[" + STEPS + "] to specify how far " + "to proceed in the world generation process. " + "[default='%(default)s']", metavar="STR", default="full") # TODO --step appears to be duplicate of OPERATIONS. Especially if # ancient_map is added to --step parser.add_argument('-x', '--width', dest='width', type=int, help="N = width of the world to be generated " + "[default=%(default)s]", metavar="N", default='512') parser.add_argument('-y', '--height', dest='height', type=int, help="N = height of the world to be generated " + "[default=%(default)s]", metavar="N", default='512') parser.add_argument('-q', '--number-of-plates', dest='number_of_plates', type=int, help="N = number of plates [default = %(default)s]", metavar="N", default='10') parser.add_argument('--recursion_limit', dest='recursion_limit', type=int, help="Set the recursion limit [default = %(default)s]", metavar="N", default='2000') parser.add_argument('-v', '--verbose', dest='verbose', action="store_true", help="Enable verbose messages", default=False) parser.add_argument('--version', dest='version', action="store_true", help="Display version information", default=False) parser.add_argument('--bw', '--black-and-white', dest='black_and_white', action="store_true", help="generate maps in black and white", default=False) # ----------------------------------------------------- g_generate = parser.add_argument_group( "Generate Options", "These options are only useful in plate and " + "world modes") g_generate.add_argument('-r', '--rivers', dest='rivers_map', action="store_true", help="generate rivers map") g_generate.add_argument('--gs', '--grayscale-heightmap', dest='grayscale_heightmap', action="store_true", help='produce a grayscale heightmap') g_generate.add_argument('--ocean_level', dest='ocean_level', type=float, help='elevation cut off for sea level " +' '[default = %(default)s]', metavar="N", default=1.0) g_generate.add_argument('--not-fade-borders', dest='fade_borders', action="store_false", help="Not fade borders", default=True) # ----------------------------------------------------- g_ancient_map = parser.add_argument_group( "Ancient Map Options", "These options are only useful in " + "ancient_map mode") g_ancient_map.add_argument('-w', '--worldfile', dest='world_file', help="FILE to be loaded", metavar="FILE") g_ancient_map.add_argument('-g', '--generatedfile', dest='generated_file', help="name of the FILE", metavar="FILE") g_ancient_map.add_argument( '-f', '--resize-factor', dest='resize_factor', type=int, help="resize factor (only integer values). " + "Note this can only be used to increase " + "the size of the map [default=%(default)s]", metavar="N", default='1') g_ancient_map.add_argument('--sea_color', dest='sea_color', help="string for color [" + SEA_COLORS + "]", metavar="S", default="brown") g_ancient_map.add_argument('--not-draw-biome', dest='draw_biome', action="store_false", help="Not draw biome", default=True) g_ancient_map.add_argument('--not-draw-mountains', dest='draw_mountains', action="store_false", help="Not draw mountains", default=True) g_ancient_map.add_argument('--not-draw-rivers', dest='draw_rivers', action="store_false", help="Not draw rivers", default=True) g_ancient_map.add_argument('--draw-outer-border', dest='draw_outer_border', action="store_true", help="Draw outer land border", default=False) # TODO: allow for RGB specification as [r g b], ie [0.5 0.5 0.5] for gray # ----------------------------------------------------- export_options = parser.add_argument_group( "Export Options", "You can specify the formats you wish the generated output to be in. ") export_options.add_argument("--export-type", dest="export_type", help="Export to a specific format such as: BMP or PNG", default="bmp") export_options.add_argument("--export-bpp", dest="export_bpp", type=int, help="Bits per pixel: 8, 16 and 32", default=8) export_options.add_argument("--export-signed", dest="export_signed", action="store_true", help="Used signed bits or not.", default=False) export_options.add_argument("--normalize", dest="export_normalize", action="store_true", help="Normalize data to the min and max of your bpp choice.", default=False) args = parser.parse_args() if args.version: usage() if os.path.exists(args.output_dir): if not os.path.isdir(args.output_dir): raise Exception("Output dir exists but it is not a dir") else: print('Directory does not exist, we are creating it') os.makedirs(args.output_dir) # it needs to be increased to be able to generate very large maps # the limit is hit when drawing ancient maps sys.setrecursionlimit(args.recursion_limit) if args.number_of_plates < 1 or args.number_of_plates > 100: usage(error="Number of plates should be a in [1, 100]") operation = "world" if args.OPERATOR is None: pass elif args.OPERATOR is not None and args.OPERATOR.lower() not in OPERATIONS: parser.print_help() usage("Only 1 operation allowed [" + OPERATIONS + "]") else: operation = args.OPERATOR.lower() if args.OPERATOR == 'info' or args.OPERATOR == 'export': if args.FILE is None: parser.print_help() usage("For operation info only the filename should be specified") if not os.path.exists(args.FILE): usage("The specified world file does not exist") if args.seed is not None: seed = int(args.seed) else: seed = random.randint(0, 65535)#RNG initialization is done automatically random.seed(seed) if args.world_name: world_name = args.world_name else: world_name = "seed_%i" % seed step = check_step(args.step) world_format = 'pickle' if args.protobuf: world_format = 'protobuf' generation_operation = (operation == 'world') or (operation == 'plates') if args.grayscale_heightmap and not generation_operation: usage( error="Grayscale heightmap can be produced only during world " + "generation") if args.rivers_map and not generation_operation: usage(error="Rivers map can be produced only during world generation") print('Worldengine - a world generator (v. %s)' % VERSION) print('-----------------------') print(' operation : %s generation' % operation) if generation_operation: print(' seed : %i' % seed) print(' name : %s' % world_name) print(' width : %i' % args.width) print(' height : %i' % args.height) print(' number of plates : %i' % args.number_of_plates) print(' world format : %s' % world_format) print(' black and white maps : %s' % args.black_and_white) print(' step : %s' % step.name) print(' greyscale heightmap : %s' % args.grayscale_heightmap) print(' rivers map : %s' % args.rivers_map) print(' fade borders : %s' % args.fade_borders) if operation == 'ancient_map': print(' resize factor : %i' % args.resize_factor) print(' world file : %s' % args.world_file) print(' sea color : %s' % args.sea_color) print(' draw biome : %s' % args.draw_biome) print(' draw rivers : %s' % args.draw_rivers) print(' draw mountains : %s' % args.draw_mountains) print(' draw land outer border : %s' % args.draw_outer_border) set_verbose(args.verbose) if operation == 'world': print('') # empty line print('starting (it could take a few minutes) ...') world = generate_world(world_name, args.width, args.height, seed, args.number_of_plates, args.output_dir, step, args.ocean_level, world_format, fade_borders=args.fade_borders, verbose=args.verbose, black_and_white=args.black_and_white) if args.grayscale_heightmap: generate_grayscale_heightmap(world, '%s/%s_grayscale.png' % (args.output_dir, world_name)) if args.rivers_map: generate_rivers_map(world, '%s/%s_rivers.png' % (args.output_dir, world_name)) elif operation == 'plates': print('') # empty line print('starting (it could take a few minutes) ...') generate_plates(seed, world_name, args.output_dir, args.width, args.height, num_plates=args.number_of_plates) elif operation == 'ancient_map': print('') # empty line print('starting (it could take a few minutes) ...') # First, some error checking if args.sea_color == "blue": sea_color = (142, 162, 179, 255) elif args.sea_color == "brown": sea_color = (212, 198, 169, 255) else: usage("Unknown sea color: " + args.sea_color + " Select from [" + SEA_COLORS + "]") if not args.world_file: usage( "For generating an ancient map is necessary to specify the " + "world to be used (-w option)") world = load_world(args.world_file) print_verbose(" * world loaded") if not args.generated_file: args.generated_file = "ancient_map_%s.png" % world.name operation_ancient_map(world, args.generated_file, args.resize_factor, sea_color, args.draw_biome, args.draw_rivers, args.draw_mountains, args.draw_outer_border) elif operation == 'info': world = load_world(args.FILE) print_world_info(world) elif operation == 'export': world = load_world(args.FILE) print_world_info(world) export(world, args.export_type, args.export_bpp, args.export_signed, args.export_normalize) else: raise Exception( 'Unknown operation: valid operations are %s' % OPERATIONS) print('...done')
def main(): parser = ArgumentParser( usage="usage: %(prog)s [options] [" + OPERATIONS + "]") parser.add_argument('OPERATOR', nargs='?') parser.add_argument('FILE', nargs='?') parser.add_argument( '-o', '--output-dir', dest='output_dir', help="generate files in DIR [default = '%(default)s']", metavar="DIR", default='.') parser.add_argument( '-n', '--worldname', dest='world_name', help="set world name to STR. output is stored in a " + "world file with the name format 'STR.world'. If " + "a name is not provided, then seed_N.world, " + "where N=SEED", metavar="STR") parser.add_argument('-s', '--seed', dest='seed', type=int, help="Use seed=N to initialize the pseudo-random " + "generation. If not provided, one will be " + "selected for you.", metavar="N") parser.add_argument('-t', '--step', dest='step', help="Use step=[" + STEPS + "] to specify how far " + "to proceed in the world generation process. " + "[default='%(default)s']", metavar="STR", default="full") # TODO --step appears to be duplicate of OPERATIONS. Especially if # ancient_map is added to --step parser.add_argument('-x', '--width', dest='width', type=int, help="N = width of the world to be generated " + "[default=%(default)s]", metavar="N", default='512') parser.add_argument('-y', '--height', dest='height', type=int, help="N = height of the world to be generated " + "[default=%(default)s]", metavar="N", default='512') parser.add_argument('-q', '--number-of-plates', dest='number_of_plates', type=int, help="N = number of plates [default = %(default)s]", metavar="N", default='10') parser.add_argument('--recursion_limit', dest='recursion_limit', type=int, help="Set the recursion limit [default = %(default)s]", metavar="N", default='2000') parser.add_argument('-v', '--verbose', dest='verbose', action="store_true", help="Enable verbose messages", default=False) parser.add_argument('--version', dest='version', action="store_true", help="Display version information", default=False) parser.add_argument('--bw', '--black-and-white', dest='black_and_white', action="store_true", help="generate maps in black and white", default=False) # ----------------------------------------------------- g_generate = parser.add_argument_group( "Generate Options", "These options are only useful in plate and " + "world modes") g_generate.add_argument('-r', '--rivers', dest='rivers_map', action="store_true", help="generate rivers map") g_generate.add_argument('--gs', '--grayscale-heightmap', dest='grayscale_heightmap', action="store_true", help='produce a grayscale heightmap') g_generate.add_argument('--ocean_level', dest='ocean_level', type=float, help='elevation cut off for sea level " +' '[default = %(default)s]', metavar="N", default=1.0) g_generate.add_argument('--temps', dest='temps', help="Provide alternate ranges for temperatures. " + "If not provided, the default values will be used. \n" + "[default = .126/.235/.406/.561/.634/.876]", metavar="#/#/#/#/#/#") g_generate.add_argument('--humidity', dest='humids', help="Provide alternate ranges for humidities. " + "If not provided, the default values will be used. \n" + "[default = .059/.222/.493/.764/.927/.986/.998]", metavar="#/#/#/#/#/#/#") g_generate.add_argument('-gv', '--gamma-value', dest='gv', type=float, help="N = Gamma value for temperature/precipitation " + "gamma correction curve. [default = %(default)s]", metavar="N", default='1.25') g_generate.add_argument('-go', '--gamma-offset', dest='go', type=float, help="N = Adjustment value for temperature/precipitation " + "gamma correction curve. [default = %(default)s]", metavar="N", default='.2') g_generate.add_argument('--not-fade-borders', dest='fade_borders', action="store_false", help="Not fade borders", default=True) g_generate.add_argument('--scatter', dest='scatter_plot', action="store_true", help="generate scatter plot") g_generate.add_argument('--sat', dest='satelite_map', action="store_true", help="generate satellite map") # ----------------------------------------------------- g_ancient_map = parser.add_argument_group( "Ancient Map Options", "These options are only useful in " + "ancient_map mode") g_ancient_map.add_argument('-w', '--worldfile', dest='world_file', help="FILE to be loaded", metavar="FILE") g_ancient_map.add_argument('-g', '--generatedfile', dest='generated_file', help="name of the FILE", metavar="FILE") g_ancient_map.add_argument( '-f', '--resize-factor', dest='resize_factor', type=int, help="resize factor (only integer values). " + "Note this can only be used to increase " + "the size of the map [default=%(default)s]", metavar="N", default='1') g_ancient_map.add_argument('--sea_color', dest='sea_color', help="string for color [" + SEA_COLORS + "]", metavar="S", default="brown") g_ancient_map.add_argument('--not-draw-biome', dest='draw_biome', action="store_false", help="Not draw biome", default=True) g_ancient_map.add_argument('--not-draw-mountains', dest='draw_mountains', action="store_false", help="Not draw mountains", default=True) g_ancient_map.add_argument('--not-draw-rivers', dest='draw_rivers', action="store_false", help="Not draw rivers", default=True) g_ancient_map.add_argument('--draw-outer-border', dest='draw_outer_border', action="store_true", help="Draw outer land border", default=False) # TODO: allow for RGB specification as [r g b], ie [0.5 0.5 0.5] for gray # ----------------------------------------------------- export_options = parser.add_argument_group( "Export Options", "You can specify the formats you wish the generated output to be in. ") export_options.add_argument("--export-format", dest="export_format", type=str, help="Export to a specific format such as BMP or PNG. " + "See http://www.gdal.org/formats_list.html for possible formats.", default="PNG") export_options.add_argument("--export-datatype", dest="export_datatype", type=str, help="Type of stored data, e.g. uint16, int32, float32 etc.", default="uint16") args = parser.parse_args() if args.version: usage() if os.path.exists(args.output_dir): if not os.path.isdir(args.output_dir): raise Exception("Output dir exists but it is not a dir") else: print('Directory does not exist, we are creating it') os.makedirs(args.output_dir) # it needs to be increased to be able to generate very large maps # the limit is hit when drawing ancient maps sys.setrecursionlimit(args.recursion_limit) if args.number_of_plates < 1 or args.number_of_plates > 100: usage(error="Number of plates should be in [1, 100]") operation = "world" if args.OPERATOR is None: pass elif args.OPERATOR is not None and args.OPERATOR.lower() not in OPERATIONS: parser.print_help() usage("Only 1 operation allowed [" + OPERATIONS + "]") else: operation = args.OPERATOR.lower() if args.OPERATOR == 'info' or args.OPERATOR == 'export': if args.FILE is None: parser.print_help() usage("For operation info only the filename should be specified") if not os.path.exists(args.FILE): usage("The specified world file does not exist") maxseed = numpy.iinfo(numpy.uint16).max # there is a hard limit somewhere so seeds outside the uint16 range are considered unsafe if args.seed is not None: seed = int(args.seed) assert 0 <= seed <= maxseed, "Seed has to be in the range between 0 and %s, borders included." % maxseed else: seed = numpy.random.randint(0, maxseed) # first-time RNG initialization is done automatically numpy.random.seed(seed) if args.world_name: world_name = args.world_name else: world_name = "seed_%i" % seed step = check_step(args.step) world_format = 'protobuf' generation_operation = (operation == 'world') or (operation == 'plates') if args.grayscale_heightmap and not generation_operation: usage( error="Grayscale heightmap can be produced only during world " + "generation") if args.rivers_map and not generation_operation: usage(error="Rivers map can be produced only during world generation") if args.temps and not generation_operation: usage(error="temps can be assigned only during world generation") if args.temps and len(args.temps.split('/')) is not 6: usage(error="temps must have exactly 6 values") if args.go >= 1 or args.go < 0: usage(error="Gamma offset must be greater than or equal to 0 and less than 1") if args.gv <= 0: usage(error="Gamma value must be greater than 0") temps = [.874, .765, .594, .439, .366, .124] if args.temps: temps = args.temps.split('/') for x in range(0,len(temps)): temps[x] = 1 - float(temps[x]) if args.humids and not generation_operation: usage(error="humidity can be assigned only during world generation") if args.humids and len(args.humids.split('/')) is not 7: usage(error="humidity must have exactly 7 values") humids = [.941, .778, .507, .236, 0.073, .014, .002] if args.humids: humids = args.humids.split('/') for x in range(0,len(humids)): humids[x] = 1 - float(humids[x]) if args.scatter_plot and not generation_operation: usage(error="Scatter plot can be produced only during world generation") print('Worldengine - a world generator (v. %s)' % VERSION) print('-----------------------') if generation_operation: print(' operation : %s generation' % operation) print(' seed : %i' % seed) print(' name : %s' % world_name) print(' width : %i' % args.width) print(' height : %i' % args.height) print(' number of plates : %i' % args.number_of_plates) print(' world format : %s' % world_format) print(' black and white maps : %s' % args.black_and_white) print(' step : %s' % step.name) print(' greyscale heightmap : %s' % args.grayscale_heightmap) print(' rivers map : %s' % args.rivers_map) print(' scatter plot : %s' % args.scatter_plot) print(' satellite map : %s' % args.satelite_map) print(' fade borders : %s' % args.fade_borders) if args.temps: print(' temperature ranges : %s' % args.temps) if args.humids: print(' humidity ranges : %s' % args.humids) print(' gamma value : %s' % args.gv) print(' gamma offset : %s' % args.go) if operation == 'ancient_map': print(' operation : %s generation' % operation) print(' resize factor : %i' % args.resize_factor) print(' world file : %s' % args.world_file) print(' sea color : %s' % args.sea_color) print(' draw biome : %s' % args.draw_biome) print(' draw rivers : %s' % args.draw_rivers) print(' draw mountains : %s' % args.draw_mountains) print(' draw land outer border : %s' % args.draw_outer_border) #Warning messages warnings = [] if temps != sorted(temps, reverse=True): warnings.append("WARNING: Temperature array not in ascending order") if numpy.amin(temps) < 0: warnings.append("WARNING: Maximum value in temperature array greater than 1") if numpy.amax(temps) > 1: warnings.append("WARNING: Minimum value in temperature array less than 0") if humids != sorted(humids, reverse=True): warnings.append("WARNING: Humidity array not in ascending order") if numpy.amin(humids) < 0: warnings.append("WARNING: Maximum value in humidity array greater than 1") if numpy.amax(humids) > 1: warnings.append("WARNING: Minimum value in temperature array less than 0") if warnings: print("\n") for x in range(len(warnings)): print(warnings[x]) set_verbose(args.verbose) if operation == 'world': print('') # empty line print('starting (it could take a few minutes) ...') world = generate_world(world_name, args.width, args.height, seed, args.number_of_plates, args.output_dir, step, args.ocean_level, temps, humids, world_format, gamma_curve=args.gv,curve_offset=args.go, fade_borders=args.fade_borders, verbose=args.verbose, black_and_white=args.black_and_white) if args.grayscale_heightmap: generate_grayscale_heightmap(world, '%s/%s_grayscale.png' % (args.output_dir, world_name)) if args.rivers_map: generate_rivers_map(world, '%s/%s_rivers.png' % (args.output_dir, world_name)) if args.scatter_plot: draw_scatter_plot(world, '%s/%s_scatter.png' % (args.output_dir, world_name)) if args.satelite_map: draw_satellite_map(world, '%s/%s_satellite.png' % (args.output_dir, world_name)) elif operation == 'plates': print('') # empty line print('starting (it could take a few minutes) ...') generate_plates(seed, world_name, args.output_dir, args.width, args.height, num_plates=args.number_of_plates) elif operation == 'ancient_map': print('') # empty line print('starting (it could take a few minutes) ...') # First, some error checking if args.sea_color == "blue": sea_color = (142, 162, 179, 255) elif args.sea_color == "brown": sea_color = (212, 198, 169, 255) else: usage("Unknown sea color: " + args.sea_color + " Select from [" + SEA_COLORS + "]") if not args.world_file: usage( "For generating an ancient map is necessary to specify the " + "world to be used (-w option)") world = load_world(args.world_file) print_verbose(" * world loaded") if not args.generated_file: args.generated_file = "ancient_map_%s.png" % world.name operation_ancient_map(world, args.generated_file, args.resize_factor, sea_color, args.draw_biome, args.draw_rivers, args.draw_mountains, args.draw_outer_border) elif operation == 'info': world = load_world(args.FILE) print_world_info(world) elif operation == 'export': world = load_world(args.FILE) print_world_info(world) export(world, args.export_format, args.export_datatype, path = '%s/%s_elevation' % (args.output_dir, world_name)) else: raise Exception( 'Unknown operation: valid operations are %s' % OPERATIONS) print('...done')