def smooth_edges(self): print 'Smoothing edges....' t0 = libtcod.sys_elapsed_seconds() hmcopy = libtcod.heightmap_new(game.WORLDMAP_WIDTH, game.WORLDMAP_HEIGHT) mask = libtcod.heightmap_new(game.WORLDMAP_WIDTH, game.WORLDMAP_HEIGHT) for x in range(game.WORLDMAP_WIDTH): for y in range(game.WORLDMAP_HEIGHT): ix = x * 0.04 if x > game.WORLDMAP_WIDTH / 2: ix = (game.WORLDMAP_WIDTH - x - 1) * 0.04 iy = y * 0.04 if y > game.WORLDMAP_HEIGHT / 2: iy = (game.WORLDMAP_HEIGHT - y - 1) * 0.04 if ix > 1.0: ix = 1.0 if iy > 1.0: iy = 1.0 h = min(ix, iy) libtcod.heightmap_set_value(mask, x, y, h) libtcod.heightmap_normalize(mask) libtcod.heightmap_copy(game.heightmap, hmcopy) libtcod.heightmap_multiply_hm(hmcopy, mask, game.heightmap) libtcod.heightmap_normalize(game.heightmap) t1 = libtcod.sys_elapsed_seconds() print ' done! (%.3f seconds)' % (t1 - t0)
def generateRainmap(map): print("Rainfall Generation...") altMap = tcod.heightmap_new(map.width, map.height) latMap = tcod.heightmap_new(map.width, map.height) rainMap = tcod.heightmap_new(map.width, map.height) for y in range(0, map.height): for x in range(0, map.width): # Cosine wave, dipping to -5 at the poles and the tropics latRain = 40 - (50 * (math.cos(math.pi * y / (map.height / 10)))) tcod.heightmap_set_value(rainMap, x, y, latRain) tcod.heightmap_add_voronoi(rainMap, int(map.height * map.width / 256), 3, [0.1, 0.1, 0.1]) tcod.heightmap_normalize(rainMap, 0, 150) tcod.heightmap_clamp(rainMap, 0, 100) for y in range(0, map.height): for x in range(0, map.width): map.setRain(x, y, tcod.heightmap_get_value(rainMap, x, y))
def __init__(self, w, h): global TROPICS_THRESHOLD, TEMPERATE_THRESHOLD, TAIGA_THRESHOLD self.w = w self.h = h self.equator = h/2 TROPICS_THRESHOLD = (self.equator/2)/3 TEMPERATE_THRESHOLD = self.equator/2 TAIGA_THRESHOLD = self.equator - self.equator*0.1 self.tiles = [[ Tile(ix,iy, False, map_tile=True) for iy in range(h) ] for ix in range(w)] x,y = 0,0 self.traffic = [[0 for y in range(h)] for x in range(w)] #this holds the *colour* value of the tiles temps. self.temperature_map = [[0 for y in range(h)] for x in range(w)] self.moisture_map = [[0 for y in range(h)] for x in range(w)] self.hm = libtcod.heightmap_new(self.w, self.h) self.hm2 = libtcod.heightmap_new(self.w, self.h) self.hm3 = libtcod.heightmap_new(self.w, self.h) self.generate_land(self.hm) self.generate_land(self.hm2) self.generate_land(self.hm3) libtcod.noise_set_type(self.noise, libtcod.NOISE_SIMPLEX) self.noise = libtcod.noise_new(2, libtcod.NOISE_DEFAULT_HURST, libtcod.NOISE_DEFAULT_LACUNARITY) #libtcod.heightmap_add_fbm(self.hm3, self.noise, 1, 1, 0, 0, 8, 0.8, 0.5) #self.noise = libtcod.noise_new(2, libtcod.NOISE_DEFAULT_HURST, libtcod.NOISE_DEFAULT_LACUNARITY) #libtcod.heightmap_add_fbm(self.hm3, self.noise, 1, 1, 0, 0, 8, 0.8, 0.5) #self.noise = libtcod.noise_new(2, libtcod.NOISE_DEFAULT_HURST, libtcod.NOISE_DEFAULT_LACUNARITY) #libtcod.heightmap_add_fbm(self.hm3, self.noise, 1, 1, 0, 0, 8, 0.8, 0.5) self.multiply_noise() self.multiply_noise() libtcod.heightmap_normalize(self.hm, 0, 255) #libtcod.heightmap_normalize(self.hm2, 0, 255) #libtcod.heightmap_normalize(self.hm3, 0, 255) #libtcod.heightmap_rain_erosion(self.hm, (self.w + self.h)*4, 0.5, 0.1, None) self.add_noise() self.turn_to_tiles() self.determine_temperatures() self.normalise_temperatures() self.wind_gen = Particle_Map(self,1500) self.generate_mini_map(10) self.cities = [] self.dungeons = [] self.generate_city(libtcod.random_get_int(0, 4, 10)) self.generate_dungeons(10)
def __init__(self, w, h): global TROPICS_THRESHOLD, TEMPERATE_THRESHOLD, TAIGA_THRESHOLD self.w = w self.h = h self.equator = h / 2 TROPICS_THRESHOLD = (self.equator / 2) / 3 TEMPERATE_THRESHOLD = self.equator / 2 TAIGA_THRESHOLD = self.equator - self.equator * 0.1 self.tiles = [[Tile(ix, iy, False, map_tile=True) for iy in range(h)] for ix in range(w)] x, y = 0, 0 self.traffic = [[0 for y in range(h)] for x in range(w)] #this holds the *colour* value of the tiles temps. self.temperature_map = [[0 for y in range(h)] for x in range(w)] self.moisture_map = [[0 for y in range(h)] for x in range(w)] self.hm = libtcod.heightmap_new(self.w, self.h) self.hm2 = libtcod.heightmap_new(self.w, self.h) self.hm3 = libtcod.heightmap_new(self.w, self.h) self.generate_land(self.hm) self.generate_land(self.hm2) self.generate_land(self.hm3) libtcod.noise_set_type(self.noise, libtcod.NOISE_SIMPLEX) self.noise = libtcod.noise_new(2, libtcod.NOISE_DEFAULT_HURST, libtcod.NOISE_DEFAULT_LACUNARITY) #libtcod.heightmap_add_fbm(self.hm3, self.noise, 1, 1, 0, 0, 8, 0.8, 0.5) #self.noise = libtcod.noise_new(2, libtcod.NOISE_DEFAULT_HURST, libtcod.NOISE_DEFAULT_LACUNARITY) #libtcod.heightmap_add_fbm(self.hm3, self.noise, 1, 1, 0, 0, 8, 0.8, 0.5) #self.noise = libtcod.noise_new(2, libtcod.NOISE_DEFAULT_HURST, libtcod.NOISE_DEFAULT_LACUNARITY) #libtcod.heightmap_add_fbm(self.hm3, self.noise, 1, 1, 0, 0, 8, 0.8, 0.5) self.multiply_noise() self.multiply_noise() libtcod.heightmap_normalize(self.hm, 0, 255) #libtcod.heightmap_normalize(self.hm2, 0, 255) #libtcod.heightmap_normalize(self.hm3, 0, 255) #libtcod.heightmap_rain_erosion(self.hm, (self.w + self.h)*4, 0.5, 0.1, None) self.add_noise() self.turn_to_tiles() self.determine_temperatures() self.normalise_temperatures() self.wind_gen = Particle_Map(self, 1500) self.generate_mini_map(10) self.cities = [] self.dungeons = [] self.generate_city(libtcod.random_get_int(0, 4, 10)) self.generate_dungeons(10)
def generate(self): print 'Starting world map generation....' t0 = libtcod.sys_elapsed_seconds() accepted = False world = 1 while not accepted: print 'World #' + str(world) + '....' self.noise = libtcod.noise_new(2, self.rnd) libtcod.noise_set_type(self.noise, libtcod.NOISE_PERLIN) game.heightmap = libtcod.heightmap_new(game.WORLDMAP_WIDTH, game.WORLDMAP_HEIGHT) #game.precipitation = libtcod.heightmap_new(game.WORLDMAP_WIDTH, game.WORLDMAP_HEIGHT) #game.temperature = libtcod.heightmap_new(game.WORLDMAP_WIDTH, game.WORLDMAP_HEIGHT) #game.biome = libtcod.heightmap_new(game.WORLDMAP_WIDTH, game.WORLDMAP_HEIGHT) self.add_landmass() self.smooth_edges() self.set_landmass(self.randomize('float', 0.30, 0.45, 3), self.sandheight) self.add_rivers() self.create_map_images() self.place_dungeons() accepted = self.analyse_world() world += 1 print '-------------' t1 = libtcod.sys_elapsed_seconds() print 'World map generation finished.... (%.3f seconds)' % (t1 - t0)
def generateTempmap(_map): print("Temperature Generation...") _rand = tcod.random_get_instance() _tm = tcod.heightmap_new(_map.width, _map.height) _altMap = tcod.heightmap_new(_map.width, _map.height) _latMap = tcod.heightmap_new(_map.width, _map.height) for y in range(0, _map.height): for x in range(0, _map.width): latitude = -int(180*y/_map.height - 90) latTemp = int(-(latitude*latitude)/51 + 128) tcod.heightmap_set_value(_latMap, x, y, latTemp) alt = _map.heightmap(x, y) if (alt > 0): # expect alt to peak out around 255-320 altTemp = -alt/4 else: altTemp = tcod.random_get_int(_rand,-10, 10) tcod.heightmap_set_value(_altMap, x, y, altTemp) tcod.heightmap_add_hm(_altMap, _latMap, _tm) tcod.heightmap_rain_erosion( _tm, _map.width*_map.height/2, #number of raindrops 0.2, #erosion cooef (f) 0.2) #sediment cooef (f) tcod.heightmap_normalize(_tm, -32, 128) dx = [-1,1,0] dy = [0,0,0] weight = [0.33,0.33,0.33] tcod.heightmap_kernel_transform(_tm,3,dx,dy,weight,-32,128); for y in range(0, _map.height): for x in range(0, _map.width): _map.coords[x][y].setTemp(tcod.heightmap_get_value(_tm, x, y)) return True
def __init__(self,w, h) : self.width = w self.height = h self._hm = libtcod.heightmap_new(w,h) self._cells = [] self.initMap() return
def make_heightmap(size, seed): # Gradient generated by distance to the northeast corner (creates northeast ocean). gradient1 = lt.heightmap_new(size, size) for col in xrange(size): for row in xrange(size): distance = ((row - size) ** 2 + col ** 2) ** 0.5 lt.heightmap_set_value(gradient1, row, col, distance) lt.heightmap_clamp(gradient1, mi=0, ma=WORLD_SIZE) lt.heightmap_scale(gradient1, 2) # Similar gradient, but cube root (creates mountains around edge). gradient2 = lt.heightmap_new(size, size) for col in xrange(size): for row in xrange(size): distance = ((row - size) ** 2 + col ** 2) ** 0.33 lt.heightmap_set_value(gradient2, row, col, distance) lt.heightmap_clamp(gradient2, mi=0, ma=WORLD_SIZE / 6) lt.heightmap_scale(gradient2, 5) # Height map based on Perlin noise. heightmap = lt.heightmap_new(size, size) random = lt.random_new() if seed: random = lt.random_new_from_seed(seed) perlin = lt.noise_new(2, h=2, l=2, random=random) lt.heightmap_add_fbm(heightmap, perlin, mulx=3, muly=3, addx=0, addy=0, octaves=8, delta=50, scale=100) # Add in gradients. lt.heightmap_add_hm(heightmap, gradient1, heightmap) lt.heightmap_add_hm(heightmap, gradient2, heightmap) lt.heightmap_normalize(heightmap, mi=-100, ma=105) lt.heightmap_clamp(heightmap, mi=-50, ma=100) lt.heightmap_normalize(heightmap, mi=-100, ma=100) visualize(heightmap) return heightmap
def generateRainmap(map): print("Rainfall Generation..."); altMap = tcod.heightmap_new(map.width, map.height) latMap = tcod.heightmap_new(map.width, map.height) rainMap = tcod.heightmap_new(map.width, map.height) for y in range(0, map.height): for x in range(0, map.width): # Cosine wave, dipping to -5 at the poles and the tropics latRain = 40-(50*(math.cos(math.pi*y/(map.height/10)))) tcod.heightmap_set_value(rainMap, x, y, latRain) tcod.heightmap_add_voronoi(rainMap, int(map.height * map.width / 256), 3, [0.1,0.1, 0.1] ) tcod.heightmap_normalize(rainMap, 0,150) tcod.heightmap_clamp(rainMap, 0,100) for y in range(0, map.height): for x in range(0, map.width): map.setRain(x, y, tcod.heightmap_get_value(rainMap, x, y))
def initialze(scale=50, weather=False): global noise_field, height_map noise_field = libtcod.noise_new(2, 0.5, 2.0, rnd) # 0.5f and 2.0f libtcod.noise_set_type(noise_field, libtcod.NOISE_SIMPLEX) height_map = libtcod.heightmap_new(Constants.MAP_WIDTH, Constants.MAP_HEIGHT) for y in range(Constants.MAP_HEIGHT): for x in range(Constants.MAP_WIDTH): libtcod.heightmap_set_value(height_map, x, y, get_noise_value(x, y, scale=scale)) libtcod.heightmap_normalize(height_map, 0.0, 1.0) # libtcod.heightmap_add_hill(height_map, 40, 40, 6, 0.8) if weather: libtcod.heightmap_rain_erosion(height_map, 5000, 0.75, .75)
def spherical_noise(self, noise_dx=0.0, noise_dy=0.0, noise_dz=0.0, noise_octaves=4.0, noise_zoom=1.0, noise_hurst=libtcod.NOISE_DEFAULT_HURST, noise_lacunarity=libtcod.NOISE_DEFAULT_LACUNARITY, width=None, height=None, seed=None): self.rnd = libtcod.random_new_from_seed(self.seed) if seed is None else libtcod.random_new_from_seed(seed) noise = libtcod.noise_new(3, noise_hurst, noise_lacunarity, self.rnd) hm = libtcod.heightmap_new(width, height) noise_dx += 0.01 noise_dy += 0.01 noise_dz += 0.01 pi_times_two = 2 * math.pi pi_div_two = math.pi / 2.0 theta = 0.0 phi = pi_div_two * -1.0 x = 0 y = 0 while phi <= pi_div_two: while theta <= pi_times_two: f = [ noise_zoom * math.cos(phi) * math.cos(theta), noise_zoom * math.cos(phi) * math.sin(theta), noise_zoom * math.sin(phi), ] value = libtcod.noise_get_fbm(noise, f, noise_octaves, libtcod.NOISE_PERLIN) # print((x, y, value)) libtcod.heightmap_set_value(hm, x, y, value) theta += (pi_times_two / width) x += 1 phi += (math.pi / (height-1)) y += 1 x = 0 theta = 0.0 return hm
def test_heightmap(): hmap = libtcodpy.heightmap_new(16, 16) repr(hmap) noise = libtcodpy.noise_new(2) # basic operations libtcodpy.heightmap_set_value(hmap, 0, 0, 1) libtcodpy.heightmap_add(hmap, 1) libtcodpy.heightmap_scale(hmap, 1) libtcodpy.heightmap_clear(hmap) libtcodpy.heightmap_clamp(hmap, 0, 0) libtcodpy.heightmap_copy(hmap, hmap) libtcodpy.heightmap_normalize(hmap) libtcodpy.heightmap_lerp_hm(hmap, hmap, hmap, 0) libtcodpy.heightmap_add_hm(hmap, hmap, hmap) libtcodpy.heightmap_multiply_hm(hmap, hmap, hmap) # modifying the heightmap libtcodpy.heightmap_add_hill(hmap, 0, 0, 4, 1) libtcodpy.heightmap_dig_hill(hmap, 0, 0, 4, 1) libtcodpy.heightmap_rain_erosion(hmap, 1, 1, 1) libtcodpy.heightmap_kernel_transform(hmap, 3, [-1, 1, 0], [0, 0, 0], [.33, .33, .33], 0, 1) libtcodpy.heightmap_add_voronoi(hmap, 10, 3, [1, 3, 5]) libtcodpy.heightmap_add_fbm(hmap, noise, 1, 1, 1, 1, 4, 1, 1) libtcodpy.heightmap_scale_fbm(hmap, noise, 1, 1, 1, 1, 4, 1, 1) libtcodpy.heightmap_dig_bezier(hmap, [0, 16, 16, 0], [0, 0, 16, 16], 1, 1, 1, 1) # read data libtcodpy.heightmap_get_value(hmap, 0, 0) libtcodpy.heightmap_get_interpolated_value(hmap, 0, 0) libtcodpy.heightmap_get_slope(hmap, 0, 0) libtcodpy.heightmap_get_normal(hmap, 0, 0, 0) libtcodpy.heightmap_count_cells(hmap, 0, 0) libtcodpy.heightmap_has_land_on_border(hmap, 0) libtcodpy.heightmap_get_minmax(hmap) libtcodpy.noise_delete(noise) libtcodpy.heightmap_delete(hmap)
def getHeightMap(): # test code to print the heightmap hm=libtcod.heightmap_new(HM_WIDTH,HM_HEIGHT) buildMap(hm) result = [[0 for x in range(HM_WIDTH)] for y in range(HM_HEIGHT)] for x in range(HM_WIDTH) : for y in range(HM_HEIGHT) : z = libtcod.heightmap_get_value(hm,x,y) val=int(z*255) & 0xFF tileRanges = [ [0,0], [110,2], [140,3], [190,4], [240,5], [300,6]] tile = takeWhile(lambda e: val >= e[0],tileRanges)[-1][1] result[y][x] = tile return result
def generateSaltmap(_map): print("Salinity Generation..."); _sm = tcod.heightmap_new(_map.width, _map.height) for y in range(0, _map.height): for x in range(0, _map.width): #very crude "distance from ocean" simulation toOcean = _map.distanceToOcean(x,y); if toOcean < 1: salinity = 255 else: salinity = 255/toOcean tcod.heightmap_normalize(_sm, 0, 255) for y in range(0, _map.height): for x in range(0, _map.width): _map.coords[x][y].setSalinity(tcod.heightmap_get_value(_sm, x, y)) return True
def generateSaltmap(_map): print("Salinity Generation...") _sm = tcod.heightmap_new(_map.width, _map.height) for y in range(0, _map.height): for x in range(0, _map.width): #very crude "distance from ocean" simulation toOcean = _map.distanceToOcean(x, y) if toOcean < 1: salinity = 255 else: salinity = 255 / toOcean tcod.heightmap_normalize(_sm, 0, 255) for y in range(0, _map.height): for x in range(0, _map.width): _map.coords[x][y].setSalinity(tcod.heightmap_get_value(_sm, x, y)) return True
def MasterWorldGen(): #------------------------------------------------------- * MASTER GEN * ------------------------------------------------------------- print ' * World Gen START * ' starttime = time.time() #Heightmap hm = libtcod.heightmap_new(WORLD_WIDTH, WORLD_HEIGHT) for i in range(50): libtcod.heightmap_add_hill(hm, randint(WORLD_WIDTH/10,WORLD_WIDTH- WORLD_WIDTH/10), randint(WORLD_HEIGHT/10,WORLD_HEIGHT- WORLD_HEIGHT/10), randint(12,16), randint(6,10)) print '- Main Hills -' for i in range(200): libtcod.heightmap_add_hill(hm, randint(WORLD_WIDTH/10,WORLD_WIDTH- WORLD_WIDTH/10), randint(WORLD_HEIGHT/10,WORLD_HEIGHT- WORLD_HEIGHT/10), randint(2,4), randint(6,10)) print '- Small Hills -' libtcod.heightmap_normalize(hm, 0.0, 1.0) noisehm = libtcod.heightmap_new(WORLD_WIDTH, WORLD_HEIGHT) noise2d = libtcod.noise_new(2,libtcod.NOISE_DEFAULT_HURST, libtcod.NOISE_DEFAULT_LACUNARITY) libtcod.heightmap_add_fbm(noisehm, noise2d,4, 4, 0, 0, 64, 1, 1) libtcod.heightmap_normalize(noisehm, 0.0, 1.0) libtcod.heightmap_multiply_hm(hm, noisehm, hm) print '- Apply Simplex -' PoleGen(hm, 0) print '- South Pole -' PoleGen(hm, 1) print '- North Pole -' TectonicGen(hm,0) TectonicGen(hm,1) print '- Tectonic Gen -' libtcod.heightmap_rain_erosion(hm, WORLD_WIDTH*WORLD_HEIGHT ,0.07,0,0) print '- Erosion -' libtcod.heightmap_clamp(hm, 0.0, 1.0) #Temperature temp = libtcod.heightmap_new(WORLD_WIDTH, WORLD_HEIGHT) Temperature(temp,hm) libtcod.heightmap_normalize(temp, 0.0, 0.8) print '- Temperature Calculation -' #Precipitation preciphm = libtcod.heightmap_new(WORLD_WIDTH, WORLD_HEIGHT) Percipitaion(preciphm) libtcod.heightmap_normalize(preciphm, 0.0, 0.8) print '- Percipitaion Calculation -' # VOLCANISM - RARE AT SEA FOR NEW ISLANDS (?) RARE AT MOUNTAINS > 0.9 (?) RARE AT TECTONIC BORDERS (?) #Initialize Tiles with Map values World = [[0 for y in range(WORLD_HEIGHT)] for x in range(WORLD_WIDTH)] #100x100 array for x in xrange(WORLD_WIDTH): for y in xrange(WORLD_HEIGHT): World[x][y] = Tile(libtcod.heightmap_get_value(hm, x, y), libtcod.heightmap_get_value(temp, x, y), libtcod.heightmap_get_value(preciphm, x, y), 0) print '- Tiles Initialized -' # - Biome info to Tiles - for x in xrange(WORLD_WIDTH): for y in xrange(WORLD_HEIGHT): if World[x][y].height > 0.2: World[x][y].biomeID = 3 if randint(1,10) < 3: World[x][y].biomeID = 5 if World[x][y].height > 0.4: World[x][y].biomeID = 14 if randint(1,10) < 3: World[x][y].biomeID = 5 if World[x][y].height > 0.5: World[x][y].biomeID = 8 if randint(1,10) < 3: World[x][y].biomeID = 14 if World[x][y].temp <= 0.5 and World[x][y].precip >= 0.5: World[x][y].biomeID = 5 if randint(1,10) < 3: World[x][y].biomeID = 14 if World[x][y].temp >= 0.5 and World[x][y].precip >= 0.7: World[x][y].biomeID = 6 if World[x][y].precip >= 0.7 and World[x][y].height > 0.2 and World[x][y].height <= 0.4: World[x][y].biomeID = 2 if World[x][y].temp > 0.75 and World[x][y].precip < 0.35: World[x][y].biomeID = 4 if World[x][y].temp <= 0.22 and World[x][y].height > 0.2: World[x][y].biomeID = randint(11,13) if World[x][y].temp <= 0.3 and World[x][y].temp > 0.2 and World[x][y].height > 0.2 and World[x][y].precip >= 0.6: World[x][y].biomeID = 7 if World[x][y].height > 0.75: World[x][y].biomeID = 9 if World[x][y].height > 0.999: World[x][y].biomeID = 10 if World[x][y].height <= 0.2: World[x][y].biomeID = 0 if World[x][y].height <= 0.1: World[x][y].biomeID = 0 print '- BiomeIDs Atributed -' #River Gen for x in range(2): RiverGen(hm, World) print '- River Gen -' #Free Heightmaps libtcod.heightmap_delete(hm) libtcod.heightmap_delete(temp) libtcod.heightmap_delete(noisehm) elapsed_time = time.time() - starttime print ' * World Gen DONE * in: ',elapsed_time,' seconds' return World
def generateHeightmap(_map): print("Particle Deposition Generation...") _rand = tcod.random_get_instance() _hm = tcod.heightmap_new(_map.width, _map.height) #half-width and -height _hw = _map.width / 2 _hh = _map.height / 2 #quarter-width and -height _qw = _map.width / 4 _qh = _map.height / 4 #define our four "continental centers" _continents = [ (_qw, _qh), #top-left (_map.width - _qw, _qh), #top-right (_qw, _map.height - _qh), #btm-left (_map.width - _qw, _map.height - _qh) ] #btm-right print("Continents:", _continents) _avg = min(_map.width, _map.height) _maxHillHeight = _avg / 4 _maxHillRad = _avg / 8 _iterations = _avg * 32 for i in range(0, _iterations): _quadrant = tcod.random_get_int(_rand, 0, 3) _qx = _continents[_quadrant][0] _qy = _continents[_quadrant][1] _minX = _qx - ((_qw * CONT_SIZE) / 10) _maxX = _qx + ((_qw * CONT_SIZE) / 10) _minY = _qy - _qh _maxY = _qy + _qh x = tcod.random_get_int(_rand, _minX, _maxX) y = tcod.random_get_int(_rand, _minY, _maxY) height = tcod.random_get_int(_rand, -1 * _maxHillHeight, _maxHillHeight) rad = tcod.random_get_int(_rand, 0, _maxHillRad) tcod.heightmap_add_hill(_hm, x, y, rad, height) #"dig out" the space around the edge of the map x = _hw for y in range(0, _map.height, max(1, _maxHillRad / 8)): height = tcod.random_get_int(_rand, _maxHillHeight / -2, -1 * _maxHillHeight) rad = tcod.random_get_int(_rand, 0, _maxHillRad * 2) tcod.heightmap_add_hill(_hm, 0, y, rad, height) tcod.heightmap_add_hill(_hm, _map.width - 1, y, rad, height) for x in range(0, _map.width, max(1, _maxHillRad / 4)): height = tcod.random_get_int(_rand, _maxHillHeight / -2, -1 * _maxHillHeight) rad = tcod.random_get_int(_rand, 0, _maxHillRad * 2) tcod.heightmap_add_hill(_hm, x, 0, rad, height) tcod.heightmap_add_hill(_hm, x, _map.height - 1, rad, height) tcod.heightmap_rain_erosion( _hm, _map.width * _map.height, #number of raindrops 0.2, #erosion cooef (f) 0.2) #sediment cooef (f) _dx = [-2, -1, 0, 1, 2] _dy = [-2, -1, 0, 1, 2] _weight = [0.1, 0.1, 0.2, 0.3, 0.3] tcod.heightmap_kernel_transform(_hm, 5, _dx, _dy, _weight, -64, 255) tcod.heightmap_normalize(_hm, -255, 392) for y in range(0, _map.height): for x in range(0, _map.width): _map.coords[x][y].setAltitude(tcod.heightmap_get_value(_hm, x, y)) return True
def MasterWorldGen( ): #------------------------------------------------------- * MASTER GEN * ------------------------------------------------------------- print ' * World Gen START * ' starttime = time.time() #Heightmap hm = libtcod.heightmap_new(WORLD_WIDTH, WORLD_HEIGHT) for i in range(50): libtcod.heightmap_add_hill( hm, randint(WORLD_WIDTH / 10, WORLD_WIDTH - WORLD_WIDTH / 10), randint(WORLD_HEIGHT / 10, WORLD_HEIGHT - WORLD_HEIGHT / 10), randint(12, 16), randint(6, 10)) print '- Main Hills -' for i in range(200): libtcod.heightmap_add_hill( hm, randint(WORLD_WIDTH / 10, WORLD_WIDTH - WORLD_WIDTH / 10), randint(WORLD_HEIGHT / 10, WORLD_HEIGHT - WORLD_HEIGHT / 10), randint(2, 4), randint(6, 10)) print '- Small Hills -' libtcod.heightmap_normalize(hm, 0.0, 1.0) noisehm = libtcod.heightmap_new(WORLD_WIDTH, WORLD_HEIGHT) noise2d = libtcod.noise_new(2, libtcod.NOISE_DEFAULT_HURST, libtcod.NOISE_DEFAULT_LACUNARITY) libtcod.heightmap_add_fbm(noisehm, noise2d, 4, 4, 0, 0, 32, 1, 1) libtcod.heightmap_normalize(noisehm, 0.0, 1.0) libtcod.heightmap_multiply_hm(hm, noisehm, hm) print '- Apply Simplex -' PoleGen(hm, 0) print '- South Pole -' PoleGen(hm, 1) print '- North Pole -' TectonicGen(hm, 0) TectonicGen(hm, 1) print '- Tectonic Gen -' libtcod.heightmap_rain_erosion(hm, WORLD_WIDTH * WORLD_HEIGHT, 0.07, 0, 0) print '- Erosion -' libtcod.heightmap_clamp(hm, 0.0, 1.0) #Temperature temp = libtcod.heightmap_new(WORLD_WIDTH, WORLD_HEIGHT) Temperature(temp, hm) libtcod.heightmap_normalize(temp, 0.0, 0.8) print '- Temperature Calculation -' #Precipitation preciphm = libtcod.heightmap_new(WORLD_WIDTH, WORLD_HEIGHT) Percipitaion(preciphm, temp) libtcod.heightmap_normalize(preciphm, 0.0, 0.8) print '- Percipitaion Calculation -' #Drainage drainhm = libtcod.heightmap_new(WORLD_WIDTH, WORLD_HEIGHT) drain = libtcod.noise_new(2, libtcod.NOISE_DEFAULT_HURST, libtcod.NOISE_DEFAULT_LACUNARITY) libtcod.heightmap_add_fbm(drainhm, drain, 2, 2, 0, 0, 32, 1, 1) libtcod.heightmap_normalize(drainhm, 0.0, 0.8) print '- Drainage Calculation -' # VOLCANISM - RARE AT SEA FOR NEW ISLANDS (?) RARE AT MOUNTAINS > 0.9 (?) RARE AT TECTONIC BORDERS (?) elapsed_time = time.time() - starttime print ' * World Gen DONE * in: ', elapsed_time, ' seconds' #Initialize Tiles with Map values World = [[0 for y in range(WORLD_HEIGHT)] for x in range(WORLD_WIDTH)] #100x100 array for x in xrange(WORLD_WIDTH): for y in xrange(WORLD_HEIGHT): World[x][y] = Tile(libtcod.heightmap_get_value(hm, x, y), libtcod.heightmap_get_value(temp, x, y), libtcod.heightmap_get_value(preciphm, x, y), libtcod.heightmap_get_value(drainhm, x, y), 0) print '- Tiles Initialized -' #Prosperity Prosperity(World) print '- Prosperity Calculation -' #Biome info to Tile for x in xrange(WORLD_WIDTH): for y in xrange(WORLD_HEIGHT): if World[x][y].height > 0.2: World[x][y].biomeID = 3 if randint(1, 10) < 3: World[x][y].biomeID = 5 if World[x][y].height > 0.4: World[x][y].biomeID = 14 if randint(1, 10) < 3: World[x][y].biomeID = 5 if World[x][y].height > 0.5: World[x][y].biomeID = 8 if randint(1, 10) < 3: World[x][y].biomeID = 14 if World[x][y].temp <= 0.5 and World[x][y].precip >= 0.5: World[x][y].biomeID = 5 if randint(1, 10) < 3: World[x][y].biomeID = 14 if World[x][y].temp >= 0.5 and World[x][y].precip >= 0.7: World[x][y].biomeID = 6 if World[x][y].precip >= 0.7 and World[x][ y].height > 0.2 and World[x][y].height <= 0.4: World[x][y].biomeID = 2 if World[x][y].temp > 0.75 and World[x][y].precip < 0.35: World[x][y].biomeID = 4 if World[x][y].temp <= 0.22 and World[x][y].height > 0.2: World[x][y].biomeID = randint(11, 13) if World[x][y].temp <= 0.3 and World[x][y].temp > 0.2 and World[x][ y].height > 0.2 and World[x][y].precip >= 0.6: World[x][y].biomeID = 7 if World[x][y].height > 0.75: World[x][y].biomeID = 9 if World[x][y].height > 0.999: World[x][y].biomeID = 10 if World[x][y].height <= 0.2: World[x][y].biomeID = 0 if World[x][y].height <= 0.1: World[x][y].biomeID = 0 print '- BiomeIDs Atributed -' #River Gen for x in range(5): RiverGen(World) print '- River Gen -' #Free Heightmaps libtcod.heightmap_delete(hm) libtcod.heightmap_delete(temp) libtcod.heightmap_delete(noisehm) print ' * Biomes/Rivers Sorted *' return World
def generate(self): self.owner.log.message("Generating map...", debug = True) noise = libtcod.noise_new(2, 0.5, 2.0) heightmap = libtcod.heightmap_new(2*self.width, 2*self.height) maxi = 0 mini = 0 self.tiles = [[ Tile() for y in range(self.height) ] for x in range(self.width) ] self.owner.log.message("-- creating heightmap...", debug = True) for x in range(self.width*2): for y in range(self.height*2): f = [3 * float(x) / (2*self.width), 3 * float(y) / (2*self.height)] value = (libtcod.noise_get_fbm(noise, f, 5, libtcod.NOISE_PERLIN))/2 if value > maxi: maxi = value if value < mini: mini = value libtcod.heightmap_set_value(heightmap, x, y, value) # print "-- erode the map" # libtcod.heightmap_rain_erosion(heightmap, self.width*2*self.height*2*2,0.1,0.2) self.owner.log.message("-- normalize heights...", debug = True) self.heightmap = libtcod.heightmap_new(self.width*2, self.height*2) for x in range(self.width*2): for y in range(self.height*2): value = libtcod.heightmap_get_value(heightmap, x, y) if value < 0: value += 1 mini2 = mini + 1 coeff = (value - mini2)/(1-mini2) libtcod.heightmap_set_value(self.heightmap, x, y, -coeff) else: value = value / maxi libtcod.heightmap_set_value(self.heightmap, x, y, value) self.owner.log.message("-- setting up tiles", debug = True) for x in range(self.width): for y in range(self.height): h = libtcod.heightmap_get_value(self.heightmap, x*2, y*2) if h >= 0.05: self.tiles[x][y].terrain = "land" else: self.tiles[x][y].terrain = "water" # self.owner.log.message("-- creating temperature map", debug = True) # noise2 = libtcod.noise_new(2, 0.5, 2.0) # temp_max = 0 # temp_min = 1 # for x in range(self.width): # for y in range(self.height): # f = [3 * float(x) / (self.width), 3 * float(y) / (self.height)] # value = (libtcod.noise_get_fbm(noise2, f, 5, libtcod.NOISE_PERLIN))/2 # value = (value + 1)/2 # if value < temp_min: # temp_min = value # if value > temp_max: # temp_max = value # self.tiles[x][y].temp = value # temp_max = temp_max - temp_min # height_factor = 0.5 # for x in range(self.width): # for y in range(self.height): # temp = (self.tiles[x][y].temp - temp_min)/temp_max # h = libtcod.heightmap_get_value(self.heightmap, x*2, y*2) # if h > 0: # factor = (-h)*height_factor # temp = temp + factor # temp = min(1, temp) # temp = max(0, temp) # self.tiles[x][y].temp = temp self.owner.log.message("-- creating rainfall map", debug = True) noise3 = libtcod.noise_new(2, 0.5, 2.0) self.rainmap = libtcod.heightmap_new(self.width*2, self.height*2) rain_max = 0 rain_min = 1 for x in range(self.width*2): for y in range(self.height*2): f = [5 * float(x) / (self.width*2), 5 * float(y) / (self.height*2)] value = (libtcod.noise_get_fbm(noise3, f, 5, libtcod.NOISE_PERLIN))/2 value = (value + 1)/2 if value < rain_min: rain_min = value if value > rain_max: rain_max = value self.tiles[x/2][y/2].rain = value libtcod.heightmap_set_value(self.rainmap, x, y, value) rain_max = rain_max - rain_min for x in range(self.width*2): for y in range(self.height*2): libtcod.heightmap_set_value(self.rainmap, x, y, (libtcod.heightmap_get_value(self.rainmap, x, y) - rain_min)/rain_max) self.tiles[x/2][y/2].rain = (self.tiles[x/2][y/2].rain - rain_min)/rain_max self.owner.log.message("Terrain complete", debug = True) self.owner.log.message("Painting terrain", debug = True) deep = libtcod.Color(1, 10, 27) mid = libtcod.Color(38, 50, 60) shallow = libtcod.Color(51, 83, 120) water_idx = [0, 70, 210, 255] water_cols = [deep, deep, mid, shallow] water_colormap = libtcod.color_gen_map(water_cols, water_idx) mountaintop = libtcod.Color(145, 196, 88) grass = libtcod.Color(40, 62, 19) foothill = libtcod.Color(57, 81, 34) sand = libtcod.Color(215, 185, 115) watersedge = libtcod.Color(19, 97, 101) land_idx = [0, 15, 20, 128, 255] land_cols = [watersedge, sand, grass, foothill, mountaintop] land_colormap = libtcod.color_gen_map(land_cols, land_idx) # Apply height-based colours for x in range(self.width*2): for y in range(self.height*2): value = libtcod.heightmap_get_value(self.heightmap, x, y) if value < 0: index = int(-value * 255) libtcod.image_put_pixel(self.image, x, y, water_colormap[index]) else: index = int(value * 255) libtcod.image_put_pixel(self.image, x, y, land_colormap[index]) # Adjust colours for desert-plains-forest for x in range(self.width*2): for y in range(self.height*2): if libtcod.heightmap_get_value(self.heightmap, x, y) > 0: rain = libtcod.heightmap_get_value(self.rainmap, x, y) cur_col = libtcod.image_get_pixel(self.image, x, y) cols = [libtcod.light_sepia, cur_col, cur_col, cur_col * 1.1] col_idx = [0, 100, 165, 255] col_map = libtcod.color_gen_map(cols, col_idx) index = int(rain*255) if index > 165 and libtcod.heightmap_get_value(self.heightmap, x, y) > 0.15: self.tiles[x/2][y/2].biome = "forest" self.tiles[x/2][y/2].char = 'T' self.tiles[x/2][y/2].fg_color = grass * 0.7 libtcod.image_put_pixel(self.image, x, y, col_map[index]) self.owner.log.message("-- apply normal shadows", debug = True) for x in range(self.width*2): for y in range(self.height*2): normal = libtcod.heightmap_get_normal(self.heightmap, x, y, 0) nx = normal[0] ny = normal[1] avg = (nx + ny)/2 if avg > 0: avg = 1 else: avg = avg + 1 avg = min(avg/2 + 0.5, 1) col = libtcod.image_get_pixel(self.image, x, y) * avg libtcod.image_put_pixel(self.image, x, y, col) self.owner.log.message("Placing cities", debug=True) self.owner.entities = [] max_cities = 10 num_cities = 0 for i in range(max_cities): x = libtcod.random_get_int(0, 0, self.width - 1) y = libtcod.random_get_int(0, 0, self.height - 1) if self.tiles[x][y].terrain == "land": city = entity.City(self.owner, x, y, '#', libtcod.Color(libtcod.random_get_int(0, 0, 255), libtcod.random_get_int(0, 0, 255), libtcod.random_get_int(0, 0, 255))) self.owner.entities.append(city) num_cities += 1 self.owner.log.message("-- placed " + str(num_cities) + " cities") self.owner.log.message("Map generated", debug = True) self.generated = True
import libtcodpy as libtcod SCREEN_WIDTH = 16 SCREEN_HEIGHT = 16 noise2d = libtcod.noise_new(1) m = libtcod.heightmap_new(SCREEN_WIDTH, SCREEN_HEIGHT) for y in range(SCREEN_HEIGHT): for x in range(SCREEN_WIDTH): n = libtcod.noise_get(noise2d, [2.0 * x / SCREEN_WIDTH - 1.0, 2.0 * y / SCREEN_HEIGHT - 1.0]) n = (n + 1.0) / 2.0 libtcod.heightmap_set_value(m, x, y, n) for y in range(SCREEN_HEIGHT): for x in range(SCREEN_WIDTH): v = libtcod.heightmap_get_value(m, x, y) print(v)