def RiverGen(hm, World): X = randint(0,WORLD_WIDTH-1) Y = randint(0,WORLD_HEIGHT-1) while libtcod.heightmap_get_value(hm, X, Y) <= 0.8: X = randint(0,WORLD_WIDTH-1) Y = randint(0,WORLD_HEIGHT-1) XCoor = [0 for x in range(50)] YCoor = [0 for x in range(50)] XCoor[0] = X YCoor[0] = Y for x in range(1,50): XCoor[x],YCoor[x] = LowestNeighbour(X,Y,hm) X = XCoor[x] Y = YCoor[x] if libtcod.heightmap_get_value(hm, X, Y) < 0.2: break for x in range(50): World[XCoor[x]][YCoor[x]].hasRiver = True return
def on_event(self): key = libtcod.Key() mouse = libtcod.Mouse() ev = libtcod.sys_check_for_event(libtcod.EVENT_ANY, key, mouse) if ev == libtcod.EVENT_KEY_PRESS: if key.vk == libtcod.KEY_ESCAPE: self.running = False elif key.vk == libtcod.KEY_CHAR: keychar = chr(key.c) if keychar == "g" or keychar == "G": self.map.generate() elif keychar == "t" or keychar == "T": self.drawing_mode = "tiles" elif keychar == "n" or keychar == "N": self.drawing_mode = "normal" elif keychar == "h" or keychar == "H": self.drawing_mode = "temps" elif keychar == "r" or keychar == "R": self.drawing_mode = "rain" if ev == libtcod.EVENT_MOUSE_PRESS: x = mouse.cx y = mouse.cy print libtcod.heightmap_get_value(self.map.heightmap, x*2, y*2) for entity in self.entities: if entity.x == x and entity.y == y: entity.on_click()
def set_landmass(self, landmass, waterlevel): print 'Reducing landmass....' t0 = libtcod.sys_elapsed_seconds() heightcount = [0] * 256 for x in range(game.WORLDMAP_WIDTH): for y in range(game.WORLDMAP_HEIGHT): h = int(libtcod.heightmap_get_value(game.heightmap, x, y) * 255) heightcount[h] += 1 i, totalcount = 0, 0 while totalcount < game.WORLDMAP_WIDTH * game.WORLDMAP_HEIGHT * (1.0 - landmass): totalcount += heightcount[i] i += 1 newwaterlevel = i / 255.0 landcoef = (1.0 - waterlevel) / (1.0 - newwaterlevel) watercoef = waterlevel / newwaterlevel for x in range(game.WORLDMAP_WIDTH): for y in range(game.WORLDMAP_HEIGHT): h = libtcod.heightmap_get_value(game.heightmap, x, y) if h > newwaterlevel: h = waterlevel + (h - newwaterlevel) * landcoef else: h = h * watercoef libtcod.heightmap_set_value(game.heightmap, x, y, h) t1 = libtcod.sys_elapsed_seconds() print ' done! (%.3f seconds)' % (t1 - t0)
def make_rivers(heightmap, size, seed, river_count=None): rivers = [] sealevel = -15 random = lt.random_new() if seed: random = lt.random_new_from_seed(seed) if river_count is None: river_count = lt.random_get_int(random, 10, 15) mouths = [(0, 0)] for river in xrange(river_count): while True: setting = True col = lt.random_get_int(random, 0, size - 1) row = lt.random_get_int(random, 0, size - 1) if sealevel > lt.heightmap_get_value(heightmap, row, col) >= sealevel - 4: for mouth in mouths: if abs(col - mouth[0]) < 5 and abs(row - mouth[1]) < 5: setting = False if setting: mouths.append((col, row)) rivers.append(River(col, row, heightmap, size, random)) break visualize(rivers, False) # Clean up inappropriate rivers. to_remove = set() i = -1 for river in rivers: i += 1 if len(river.tiles) < 15: to_remove.add(i) if lt.heightmap_get_value(heightmap, river.head_row, river.head_col) < 30: to_remove.add(i) for other in rivers: if river != other: x = True for n in list(to_remove): if other == rivers[n] or river == rivers[n]: x = False if x: for (this_x, this_y) in river.tiles: for (other_x, other_y) in other.tiles: distance = ((this_x - other_x) ** 2 + (this_y - other_y) ** 2) ** 0.5 if distance < 2: to_remove.add(i) break remove = sorted(list(to_remove), reverse=True) for n in remove: rivers.pop(n) if len(rivers) > 0: visualize(heightmap, False) visualize(rivers) else: visualize(heightmap) return rivers
def Temperature(temp, hm): for x in xrange(WORLD_WIDTH): for y in xrange(WORLD_HEIGHT): heighteffect = 0 if y > WORLD_HEIGHT / 2: libtcod.heightmap_set_value(temp, x, y, WORLD_HEIGHT - y - heighteffect) else: libtcod.heightmap_set_value(temp, x, y, y - heighteffect) heighteffect = libtcod.heightmap_get_value(hm, x, y) if heighteffect > 0.8: heighteffect = heighteffect * 5 if y > WORLD_HEIGHT / 2: libtcod.heightmap_set_value( temp, x, y, WORLD_HEIGHT - y - heighteffect) else: libtcod.heightmap_set_value(temp, x, y, y - heighteffect) if heighteffect < 0.25: heighteffect = heighteffect * 10 if y > WORLD_HEIGHT / 2: libtcod.heightmap_set_value( temp, x, y, WORLD_HEIGHT - y - heighteffect) else: libtcod.heightmap_set_value(temp, x, y, y - heighteffect) return
def place_dungeons(self): print 'Placing dungeons....' t0 = libtcod.sys_elapsed_seconds() path = self.set_dijkstra_map() for i in range(game.MAX_THREAT_LEVEL): done = False attempt = 0 while not done and attempt <= 1000: x = libtcod.random_get_int(self.rnd, 0, game.WORLDMAP_WIDTH - 1) y = libtcod.random_get_int(self.rnd, 0, game.WORLDMAP_HEIGHT - 1) cellheight = int(libtcod.heightmap_get_value(game.heightmap, x, y) * 1000) threat = self.set_threat_level(x, y, path) dice = libtcod.random_get_int(self.rnd, 1, 100) if dice <= 65: dtype = 'Dungeon' elif dice <= 95: dtype = 'Cave' else: dtype = 'Maze' if cellheight in range(int(game.terrain['Plains']['elevation'] * 1000), int(game.terrain['High Hills']['maxelev'] * 1000)) and threat == i + 1: self.dungeons.append((len(self.dungeons) + 1, 'Dungeon', 'Dng', x, y, threat + 1, dtype)) done = True attempt += 1 starter_dungeon = libtcod.random_get_int(self.rnd, 1, 4) if starter_dungeon == 1: self.dungeons.append((len(self.dungeons) + 1, 'Starter Dungeon', 'SD', self.player_positionx, self.player_positiony - 1, 1, 'Dungeon')) elif starter_dungeon == 2: self.dungeons.append((len(self.dungeons) + 1, 'Starter Dungeon', 'SD', self.player_positionx + 1, self.player_positiony, 1, 'Dungeon')) elif starter_dungeon == 3: self.dungeons.append((len(self.dungeons) + 1, 'Starter Dungeon', 'SD', self.player_positionx, self.player_positiony + 1, 1, 'Dungeon')) else: self.dungeons.append((len(self.dungeons) + 1, 'Starter Dungeon', 'SD', self.player_positionx - 1, self.player_positiony, 1, 'Dungeon')) t1 = libtcod.sys_elapsed_seconds() print ' done! (%.3f seconds)' % (t1 - t0)
def TectonicGen(hm, hor): TecTiles = [[0 for y in range(WORLD_HEIGHT)] for x in range(WORLD_WIDTH)] #Define Tectonic Borders if hor == 1: pos = randint(WORLD_HEIGHT/10,WORLD_HEIGHT - WORLD_HEIGHT/10) for x in range(WORLD_WIDTH): TecTiles[x][pos] = 1 pos += randint(1,5)-3 if pos < 0: pos = 0 if pos > WORLD_HEIGHT-1: pos = WORLD_HEIGHT-1 if hor == 0: pos = randint(WORLD_WIDTH/10,WORLD_WIDTH - WORLD_WIDTH/10) for y in range(WORLD_HEIGHT): TecTiles[pos][y] = 1 pos += randint(1,5)-3 if pos < 0: pos = 0 if pos > WORLD_WIDTH-1: pos = WORLD_WIDTH-1 #Apply elevation to borders for x in xrange(WORLD_WIDTH/10,WORLD_WIDTH - WORLD_WIDTH/10): for y in xrange(WORLD_HEIGHT/10,WORLD_HEIGHT - WORLD_HEIGHT/10): if TecTiles[x][y] == 1 and libtcod.heightmap_get_value(hm, x, y) > 0.25: libtcod.heightmap_add_hill(hm, x, y, randint(2,4), uniform(0.15,0.18)) return
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 TectonicGen(hm, hor): TecTiles = [[0 for y in range(WORLD_HEIGHT)] for x in range(WORLD_WIDTH)] #Define Tectonic Borders if hor == 1: pos = randint(WORLD_HEIGHT / 10, WORLD_HEIGHT - WORLD_HEIGHT / 10) for x in range(WORLD_WIDTH): TecTiles[x][pos] = 1 pos += randint(1, 5) - 3 if pos < 0: pos = 0 if pos > WORLD_HEIGHT - 1: pos = WORLD_HEIGHT - 1 if hor == 0: pos = randint(WORLD_WIDTH / 10, WORLD_WIDTH - WORLD_WIDTH / 10) for y in range(WORLD_HEIGHT): TecTiles[pos][y] = 1 pos += randint(1, 5) - 3 if pos < 0: pos = 0 if pos > WORLD_WIDTH - 1: pos = WORLD_WIDTH - 1 #Apply elevation to borders for x in xrange(WORLD_WIDTH / 10, WORLD_WIDTH - WORLD_WIDTH / 10): for y in xrange(WORLD_HEIGHT / 10, WORLD_HEIGHT - WORLD_HEIGHT / 10): if TecTiles[x][y] == 1 and libtcod.heightmap_get_value(hm, x, y) > 0.25: libtcod.heightmap_add_hill(hm, x, y, randint(2, 4), uniform(0.15, 0.18)) return
def Percipitaion(preciphm, temphm): libtcod.heightmap_add(preciphm, 2) for x in xrange(WORLD_WIDTH): for y in xrange(WORLD_HEIGHT): temp = libtcod.heightmap_get_value(temphm, x, y) if temp > 0.7: val = libtcod.heightmap_get_value(preciphm, x, y) libtcod.heightmap_set_value(preciphm, x, y, val - temp) precip = libtcod.noise_new(2, libtcod.NOISE_DEFAULT_HURST, libtcod.NOISE_DEFAULT_LACUNARITY) libtcod.heightmap_add_fbm(preciphm, precip, 8, 8, 0, 0, 32, 1, 1) libtcod.heightmap_normalize(preciphm, 0.0, 1.0) return
def turn_to_tiles(self): self.tiles = [] self.tiles = [[ Tile(ix,iy, False, map_tile=True) for iy in range(self.h) ] for ix in range(self.w)] for cell_x in range(self.w): for cell_y in range(self.h): value = int(libtcod.heightmap_get_value(self.hm, cell_x, cell_y)) if value > MOUNTAIN_THRESHOLD: #mountain mountain = 50 + (value - MOUNTAIN_THRESHOLD) shift = libtcod.random_get_int(0,-5,5) tote = mountain + shift if tote > 255: tote = 255 if tote < 0: tote = 0 #self.tiles[cell_x][cell_y] = Tile(cell_x,cell_y, False, map_tile=True, bg=[40 + mountain, value - mountain, 40 + mountain], cost = 20) self.tiles[cell_x][cell_y] = Tile(cell_x,cell_y, False, map_tile=True, bg=[tote, tote, tote], cost = 40) self.tiles[cell_x][cell_y].elevation = value self.tiles[cell_x][cell_y].humidity = libtcod.random_get_int(0,0,5) self.tiles[cell_x][cell_y].humidity_per = self.tiles[cell_x][cell_y].humidity/255*100 self.tiles[cell_x][cell_y].type = "mountain" elif value > WATER_THRESHOLD + COASTLINE_THRESHOLD: #grass ran_1 = 255- value+ libtcod.random_get_int(0,-5,5) if ran_1 > 255: ran_1 = 255 self.tiles[cell_x][cell_y] = Tile(cell_x,cell_y, False, map_tile=True, bg=[10,ran_1,10 + libtcod.random_get_int(0,-5,5)], cost = 15) self.tiles[cell_x][cell_y].elevation = value self.tiles[cell_x][cell_y].humidity = libtcod.random_get_int(0,10,100) self.tiles[cell_x][cell_y].humidity_per = self.tiles[cell_x][cell_y].humidity/255*100 elif value > WATER_THRESHOLD: #coast test = int(math.sqrt(value)) #test = test ** 3 self.tiles[cell_x][cell_y] = Tile(cell_x,cell_y, False, map_tile=True, bg=[value+ libtcod.random_get_int(0,-5,5),value-test+ libtcod.random_get_int(0,-5,5),test]) self.tiles[cell_x][cell_y].elevation = value self.tiles[cell_x][cell_y].humidity = 25.5 self.tiles[cell_x][cell_y].humidity_per = 10.0 else: #water tote = value+ libtcod.random_get_int(0,-5,5) if tote > 255: tote = 255 if tote < 0: tote = 0 self.tiles[cell_x][cell_y] = Tile(cell_x,cell_y, True, map_tile=True, bg=[10,10,tote]) self.tiles[cell_x][cell_y].elevation = value self.tiles[cell_x][cell_y].humidity = 255 self.tiles[cell_x][cell_y].humidity_per = 100.0 self.tiles[cell_x][cell_y].type = "water"
def generate_land(self,hm): print hm.w, hm.h #self.noise = perlin_noise.PerlinNoiseGenerator() #self.noise.generate_noise(self.w, self.h, 1, 16) #print str(self.noise.noise[1][1]) self.noise = libtcod.noise_new(2, libtcod.NOISE_DEFAULT_HURST, libtcod.NOISE_DEFAULT_LACUNARITY) libtcod.heightmap_add_fbm(hm, self.noise, 1, 1, 0, 0, 8, 0.5, 0.8) print "scale", str(libtcod.heightmap_get_value(hm, 1, 1)) self.noise = libtcod.noise_new(2, libtcod.NOISE_DEFAULT_HURST, libtcod.NOISE_DEFAULT_LACUNARITY) libtcod.noise_set_type(self.noise, libtcod.NOISE_PERLIN) libtcod.heightmap_scale_fbm(hm, self.noise, 1, 1, 0, 0, 8, 0.5, 0.8) # self.noise = libtcod.noise_new(2, libtcod.NOISE_DEFAULT_HURST, libtcod.NOISE_DEFAULT_LACUNARITY) # libtcod.heightmap_add_fbm(hm, self.noise, 1, 1, 0, 0, 8, 0.8, 0.5) # libtcod.heightmap_normalize(hm, 0, 255) print "normalized", str(libtcod.heightmap_get_value(hm, 1, 1)) 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 analyse_world(self): print 'Analysing worldmap....' t0 = libtcod.sys_elapsed_seconds() mountain_peak = 0 mountains = 0 high_hills = 0 low_hills = 0 forest = 0 plains = 0 coast = 0 shore = 0 sea = 0 ocean = 0 accepted = True for x in range(game.WORLDMAP_WIDTH): for y in range(game.WORLDMAP_HEIGHT): cellheight = libtcod.heightmap_get_value(game.heightmap, x, y) if cellheight >= game.terrain['Mountain Peak']['elevation']: mountain_peak += 1 elif cellheight >= game.terrain['Mountains']['elevation']: mountains += 1 elif cellheight >= game.terrain['High Hills']['elevation']: high_hills += 1 elif cellheight >= game.terrain['Low Hills']['elevation']: low_hills += 1 elif cellheight >= game.terrain['Forest']['elevation']: forest += 1 elif cellheight >= game.terrain['Plains']['elevation']: plains += 1 elif cellheight >= game.terrain['Coast']['elevation']: coast += 1 elif cellheight >= game.terrain['Shore']['elevation']: shore += 1 elif cellheight >= game.terrain['Sea']['elevation']: sea += 1 else: ocean += 1 if mountain_peak < 15 or mountains < 150 or high_hills < 600 or low_hills < 1500 or coast < 2500: accepted = False if forest > 22000 or plains > 10000 or shore > 8000 or sea > 28000 or ocean > 30000: accepted = False t1 = libtcod.sys_elapsed_seconds() if accepted: print ' accepted! (%.3f seconds)' % (t1 - t0) else: self.player_positionx = 0 self.max_distance = 0 self.dungeons = [] print ' rejected! (%.3f seconds)' % (t1 - t0) return accepted
def generate_land(self, hm): print hm.w, hm.h #self.noise = perlin_noise.PerlinNoiseGenerator() #self.noise.generate_noise(self.w, self.h, 1, 16) #print str(self.noise.noise[1][1]) self.noise = libtcod.noise_new(2, libtcod.NOISE_DEFAULT_HURST, libtcod.NOISE_DEFAULT_LACUNARITY) libtcod.heightmap_add_fbm(hm, self.noise, 1, 1, 0, 0, 8, 0.5, 0.8) print "scale", str(libtcod.heightmap_get_value(hm, 1, 1)) self.noise = libtcod.noise_new(2, libtcod.NOISE_DEFAULT_HURST, libtcod.NOISE_DEFAULT_LACUNARITY) libtcod.noise_set_type(self.noise, libtcod.NOISE_PERLIN) libtcod.heightmap_scale_fbm(hm, self.noise, 1, 1, 0, 0, 8, 0.5, 0.8) # self.noise = libtcod.noise_new(2, libtcod.NOISE_DEFAULT_HURST, libtcod.NOISE_DEFAULT_LACUNARITY) # libtcod.heightmap_add_fbm(hm, self.noise, 1, 1, 0, 0, 8, 0.8, 0.5) # libtcod.heightmap_normalize(hm, 0, 255) print "normalized", str(libtcod.heightmap_get_value(hm, 1, 1)) return hm
def blend_layers(self, x, y, terrain_rotation=0, atmosphere_rotation=0, circle_mask=None, heightmap=None, atmosphere=None, width=None): if width is None: width = self.heightmap_width if heightmap is None: heightmap = self.heightmap if atmosphere is None: atmosphere = self.atmosphere if circle_mask is None: circle_mask = self.circle_mask terrain_color = int(libtcod.heightmap_get_value(heightmap, ((x+terrain_rotation) % width), y)) if terrain_color > 255: terrain_color = 255 r = self.height_colormap[terrain_color][0] g = self.height_colormap[terrain_color][1] b = self.height_colormap[terrain_color][2] if self.atmosphere: cloud_cover = libtcod.heightmap_get_value(atmosphere, ((x+atmosphere_rotation) % width), y) r, g, b = self.blend_colors(r, g, b, 255, 255, 255, cloud_cover) if circle_mask[x][y] < 1.0: r, g, b = self.blend_colors(r, g, b, 0, 0, 0, circle_mask[x][y]) return [r, g, b]
def take_turn(self): self.state.check_for_stateswap() self.currentnoise = libtcod.heightmap_get_value(self.gldir.noisemap, self.owner.x, self.owner.y) if self.owner.fighter.hp != self.hplog[-1]: self.hplog.append(self.owner.fighter.hp) #checks if hp has changed self.gothit = True else self.gothit = False self.timer_since_swap += 1 self.state.execute()
def LowestNeighbour(X,Y,hm): #Diagonals are commented for rivers minval = 5 x = 0 y = 0 if libtcod.heightmap_get_value(hm, X + 1, Y) < minval and X + 1 < WORLD_WIDTH: minval = libtcod.heightmap_get_value(hm, X + 1, Y) x = X + 1 y = Y if libtcod.heightmap_get_value(hm, X, Y + 1) < minval and Y + 1 < WORLD_HEIGHT: minval = libtcod.heightmap_get_value(hm, X, Y + 1) x = X y = Y + 1 #if libtcod.heightmap_get_value(hm, X + 1, Y + 1) < minval and X + 1 < WORLD_WIDTH and Y + 1 < WORLD_HEIGHT and minval > 0.2: #minval = libtcod.heightmap_get_value(hm, X + 1, Y + 1) #x = X + 1 #y = Y + 1 #if libtcod.heightmap_get_value(hm, X - 1, Y - 1) < minval and X - 1 > 0 and Y - 1 > 0 and minval > 0.2: #minval = libtcod.heightmap_get_value(hm, X - 1, Y - 1) #x = X - 1 #y = Y - 1 if libtcod.heightmap_get_value(hm, X - 1, Y) < minval and X - 1 > 0: minval = libtcod.heightmap_get_value(hm, X - 1, Y) x = X - 1 y = Y if libtcod.heightmap_get_value(hm, X, Y - 1) < minval and Y - 1 > 0: minval = libtcod.heightmap_get_value(hm, X, Y - 1) x = X y = Y - 1 #f libtcod.heightmap_get_value(hm, X + 1, Y - 1) < minval and X + 1 < WORLD_WIDTH and Y - 1 > 0 and minval > 0.2: #minval = libtcod.heightmap_get_value(hm, X + 1, Y - 1) #x = X + 1 #y = Y - 1 #if libtcod.heightmap_get_value(hm, X - 1, Y + 1) < minval and X - 1 > 0 and Y + 1 < WORLD_HEIGHT and minval > 0.2 : #minval = libtcod.heightmap_get_value(hm, X - 1, Y + 1) #x = X - 1 #y = Y + 1 return (x,y)
def visualize(area, click=True): if viz: # Heightmap rendering if isinstance(area, lt.HeightMap): lt.console_clear(river_con) lt.console_clear(0) for col in xrange(WORLD_SIZE): for row in xrange(WORLD_SIZE): value = int(lt.heightmap_get_value(area, row, col)) + 15 color = lt.Color((170 - int(value * 1.7)), (160 - value), (80 - value / 2)) if value < 0: color = lt.Color(0, (50 + value / 2), (100 + value)) elif value > 100: n = int(value * 1.3) color = lt.Color(n, n, n) """ color = lt.black if 100 >= value > 85: color = lt.lighter_gray elif 85 >= value > 50: color = lt.darkest_green elif 50 >= value > 10: color = lt.darker_green elif 10 >= value > 0: color = lt.dark_yellow elif 0 >= value > -30: color = lt.darker_azure elif -30 >= value >= -100: color = lt.darkest_azure """ lt.console_set_char_background(con, row, col, color, lt.BKGND_SET) lt.console_blit(con, 0, 0, 0, 0, 0, 0, 0) # River rendering if isinstance(area, list): if isinstance(area[0], River): lt.console_clear(river_con) for river in area: for tile in river.tiles: y, x = tile lt.console_set_char_background(river_con, x, y, lt.azure, lt.BKGND_SET) lt.console_blit(river_con, 0, 0, 0, 0, 0, 0, 0) lt.console_flush() if click: while True: key = lt.console_wait_for_keypress(False) if key.pressed: break
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 create_map_legend(self, con, mode=0): for x in range(game.WORLDMAP_WIDTH): for y in range(game.WORLDMAP_HEIGHT): if mode == 0: cellheight = libtcod.heightmap_get_value(game.heightmap, x, y) else: cellheight = self.hm_list[(y * game.WORLDMAP_WIDTH) + x] if cellheight >= game.terrain['Mountain Peak']['elevation']: # mountain peak bcolor = libtcod.color_lerp(libtcod.silver, libtcod.grey, (1.000 - cellheight) / 0.050) elif cellheight >= game.terrain['Mountains']['elevation']: # mountains bcolor = libtcod.color_lerp(libtcod.grey, libtcod.Color(40, 24, 12), (game.terrain['Mountain Peak']['elevation'] - cellheight) / 0.125) elif cellheight >= game.terrain['High Hills']['elevation']: # hills bcolor = libtcod.color_lerp(libtcod.Color(40, 24, 12), libtcod.Color(53, 33, 16), (game.terrain['Mountains']['elevation'] - cellheight) / 0.125) elif cellheight >= game.terrain['Low Hills']['elevation']: # forest bcolor = libtcod.color_lerp(libtcod.Color(53, 33, 16), libtcod.Color(40, 67, 25), (game.terrain['High Hills']['elevation'] - cellheight) / 0.125) elif cellheight >= game.terrain['Forest']['elevation']: # forest bcolor = libtcod.color_lerp(libtcod.Color(40, 67, 25), libtcod.Color(80, 134, 50), (game.terrain['Low Hills']['elevation'] - cellheight) / 0.345) elif cellheight >= game.terrain['Plains']['elevation']: # plains bcolor = libtcod.color_lerp(libtcod.Color(80, 134, 50), libtcod.Color(112, 150, 80), (game.terrain['Forest']['elevation'] - cellheight) / 0.090) elif cellheight >= game.terrain['Coast']['elevation']: # coast bcolor = libtcod.color_lerp(libtcod.Color(112, 150, 80), libtcod.Color(176, 176, 153), (game.terrain['Plains']['elevation'] - cellheight) / 0.020) elif cellheight >= game.terrain['Shore']['elevation']: # shallow water bcolor = libtcod.color_lerp(libtcod.Color(176, 176, 153), libtcod.Color(47, 67, 103), (game.terrain['Coast']['elevation'] - cellheight) / 0.010) elif cellheight >= game.terrain['Sea']['elevation']: # deep water bcolor = libtcod.color_lerp(libtcod.Color(47, 67, 103), libtcod.Color(8, 32, 72), (game.terrain['Shore']['elevation'] - cellheight) / 0.040) else: # ocean bcolor = libtcod.Color(8, 32, 72) libtcod.console_put_char_ex(con, x, y, ' ', bcolor, bcolor) if mode != 3: libtcod.image_put_pixel(self.map_image_small, x, y, bcolor) if mode == 0: self.hm_list[(y * game.WORLDMAP_WIDTH) + x] = float("{0:.4f}".format(cellheight))
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 Temperature(temp,hm): for x in xrange(WORLD_WIDTH): for y in xrange(WORLD_HEIGHT): heighteffect = 0 if y > WORLD_HEIGHT/2: libtcod.heightmap_set_value(temp, x, y, WORLD_HEIGHT-y-heighteffect) else: libtcod.heightmap_set_value(temp, x, y, y-heighteffect) heighteffect = libtcod.heightmap_get_value(hm, x, y) if heighteffect > 0.8: heighteffect = heighteffect * 5 if y > WORLD_HEIGHT/2: libtcod.heightmap_set_value(temp, x, y, WORLD_HEIGHT-y-heighteffect) else: libtcod.heightmap_set_value(temp, x, y, y-heighteffect) if heighteffect < 0.25: heighteffect = heighteffect * 10 if y > WORLD_HEIGHT/2: libtcod.heightmap_set_value(temp, x, y, WORLD_HEIGHT-y-heighteffect) else: libtcod.heightmap_set_value(temp, x, y, y-heighteffect) return
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 get_height_value(x, y): return libtcod.heightmap_get_value(height_map, x, y)
def worldgentest(nb): t_mountain_peak, h_mountain_peak, l_mountain_peak = 0, 0, 50000 t_mountains, h_mountains, l_mountains = 0, 0, 50000 t_high_hills, h_high_hills, l_high_hills = 0, 0, 50000 t_low_hills, h_low_hills, l_low_hills = 0, 0, 50000 t_forest, h_forest, l_forest = 0, 0, 50000 t_plains, h_plains, l_plains = 0, 0, 50000 t_coast, h_coast, l_coast = 0, 0, 50000 t_shore, h_shore, l_shore = 0, 0, 50000 t_sea, h_sea, l_sea = 0, 0, 50000 t_ocean, h_ocean, l_ocean = 0, 0, 50000 f = open('data/worldstats.txt', 'w') for i in range(nb): mountain_peak = 0 mountains = 0 high_hills = 0 low_hills = 0 forest = 0 plains = 0 coast = 0 shore = 0 sea = 0 ocean = 0 worldgen.World() for x in range(game.WORLDMAP_WIDTH): for y in range(game.WORLDMAP_HEIGHT): cellheight = libtcod.heightmap_get_value(game.heightmap, x, y) if cellheight >= game.terrain['Mountain Peak']['elevation']: mountain_peak += 1 elif cellheight >= game.terrain['Mountains']['elevation']: mountains += 1 elif cellheight >= game.terrain['High Hills']['elevation']: high_hills += 1 elif cellheight >= game.terrain['Low Hills']['elevation']: low_hills += 1 elif cellheight >= game.terrain['Forest']['elevation']: forest += 1 elif cellheight >= game.terrain['Plains']['elevation']: plains += 1 elif cellheight >= game.terrain['Coast']['elevation']: coast += 1 elif cellheight >= game.terrain['Shore']['elevation']: shore += 1 elif cellheight >= game.terrain['Sea']['elevation']: sea += 1 else: ocean += 1 t_mountain_peak += mountain_peak if h_mountain_peak < mountain_peak: h_mountain_peak = mountain_peak if l_mountain_peak > mountain_peak: l_mountain_peak = mountain_peak t_mountains += mountains if h_mountains < mountains: h_mountains = mountains if l_mountains > mountains: l_mountains = mountains t_high_hills += high_hills if h_high_hills < high_hills: h_high_hills = high_hills if l_high_hills > high_hills: l_high_hills = high_hills t_low_hills += low_hills if h_low_hills < low_hills: h_low_hills = low_hills if l_low_hills > low_hills: l_low_hills = low_hills t_forest += forest if h_forest < forest: h_forest = forest if l_forest > forest: l_forest = forest t_plains += plains if h_plains < plains: h_plains = plains if l_plains > plains: l_plains = plains t_coast += coast if h_coast < coast: h_coast = coast if l_coast > coast: l_coast = coast t_shore += shore if h_shore < shore: h_shore = shore if l_shore > shore: l_shore = shore t_sea += sea if h_sea < sea: h_sea = sea if l_sea > sea: l_sea = sea t_ocean += ocean if h_ocean < ocean: h_ocean = ocean if l_ocean > ocean: l_ocean = ocean f.write('World #' + str(i + 1) + '\n') f.write('----------------------\n') f.write('Mountain Peak: ' + str(mountain_peak) + '\n') f.write('Mountains: ' + str(mountains) + '\n') f.write('High Hills: ' + str(high_hills) + '\n') f.write('Low Hills: ' + str(low_hills) + '\n') f.write('Forest: ' + str(forest) + '\n') f.write('Plains: ' + str(plains) + '\n') f.write('Coast: ' + str(coast) + '\n') f.write('Shore: ' + str(shore) + '\n') f.write('Sea: ' + str(sea) + '\n') f.write('Ocean: ' + str(ocean) + '\n') f.write('\n') f.write('Totals\n') f.write('----------------------\n') f.write('Mountain Peak: ' + str(t_mountain_peak) + ' (Avg: ' + str("{0:.2f}".format(float(t_mountain_peak) / nb)) + ', High: ' + str(h_mountain_peak) + ', Low: ' + str(l_mountain_peak) + ')' + '\n') f.write('Mountains: ' + str(t_mountains) + ' (Avg: ' + str("{0:.2f}".format(float(t_mountains) / nb)) + ', High: ' + str(h_mountains) + ', Low: ' + str(l_mountains) + ')' + '\n') f.write('High Hills: ' + str(t_high_hills) + ' (Avg: ' + str("{0:.2f}".format(float(t_high_hills) / nb)) + ', High: ' + str(h_high_hills) + ', Low: ' + str(l_high_hills) + ')' + '\n') f.write('Low Hills: ' + str(t_low_hills) + ' (Avg: ' + str("{0:.2f}".format(float(t_low_hills) / nb)) + ', High: ' + str(h_low_hills) + ', Low: ' + str(l_low_hills) + ')' + '\n') f.write('Forest: ' + str(t_forest) + ' (Avg: ' + str("{0:.2f}".format(float(t_forest) / nb)) + ', High: ' + str(h_forest) + ', Low: ' + str(l_forest) + ')' + '\n') f.write('Plains: ' + str(t_plains) + ' (Avg: ' + str("{0:.2f}".format(float(t_plains) / nb)) + ', High: ' + str(h_plains) + ', Low: ' + str(l_plains) + ')' + '\n') f.write('Coast: ' + str(t_coast) + ' (Avg: ' + str("{0:.2f}".format(float(t_coast) / nb)) + ', High: ' + str(h_coast) + ', Low: ' + str(l_coast) + ')' + '\n') f.write('Shore: ' + str(t_shore) + ' (Avg: ' + str("{0:.2f}".format(float(t_shore) / nb)) + ', High: ' + str(h_shore) + ', Low: ' + str(l_shore) + ')' + '\n') f.write('Sea: ' + str(t_sea) + ' (Avg: ' + str("{0:.2f}".format(float(t_sea) / nb)) + ', High: ' + str(h_sea) + ', Low: ' + str(l_sea) + ')' + '\n') f.write('Ocean: ' + str(t_ocean) + ' (Avg: ' + str("{0:.2f}".format(float(t_ocean) / nb)) + ', High: ' + str(h_ocean) + ', Low: ' + str(l_ocean) + ')' + '\n') f.write('\n') f.close()
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 generate_mini_map(self, zone = 10, hm = None): if hm == None: hm = self.hm if (self.w % zone) > 0: print "doesn't smoothly fit - W" if (self.h % zone) > 0: print "doesn't smoothly fit - H" self.mini_map = [] self.mini_map = [[None for y in range(int(self.h/zone))] for x in range(int(self.w/zone))] for a in range(len(self.tiles)/zone): for b in range(len(self.tiles[a])/zone): cell_x = 0 cell_y = 0 tiles = [[0,[]],[0,[]]] x = a * zone y = b * zone for cell_x in range(zone): if x + cell_x > len(self.tiles)-1: break for cell_y in range(zone): if y + cell_y > len(self.tiles[cell_x])-1: break #TODO: put in catches for the "end" bits where there is less tiles left than the "zone". value = int(libtcod.heightmap_get_value(hm, x + cell_x, y + cell_y)) if value > WATER_THRESHOLD: tiles[0][0] += 1 tiles[0][1].append(value) else: tiles[1][0] += 1 tiles[1][1].append(value) if tiles[0] > tiles[1]: #make land sum_ = sum(num for num in tiles[0][1]) value = sum_ / len(tiles[0][1]) self.mini_map[a][b] = Tile(cell_x,cell_y, False, map_tile=True, bg=[10,value,10]) elif tiles[1] > tiles[0]: #make water sum_ = sum(num for num in tiles[1][1]) value = sum_ / len(tiles[1][1]) self.mini_map[a][b] = Tile(cell_x,cell_y, True, map_tile=True, bg=[10,10,value]) else: #flip for either. flip = libtcod.random_get_int(0, 0, 1) if flip == 1: #water sum_ = sum(num for num in tiles[1][1]) value = sum_ / len(tiles[1][1]) self.mini_map[a][b] = Tile(cell_x,cell_y, True, map_tile=True, bg=[10,10,value]) if flip == 0: #land sum_ = sum(num for num in tiles[0][1]) value = sum_ / len(tiles[0][1]) self.mini_map[a][b] = Tile(cell_x,cell_y, False, map_tile=True, bg=[10,value,10])
def generate_mini_map(self, zone=10, hm=None): if hm == None: hm = self.hm if (self.w % zone) > 0: print "doesn't smoothly fit - W" if (self.h % zone) > 0: print "doesn't smoothly fit - H" self.mini_map = [] self.mini_map = [[None for y in range(int(self.h / zone))] for x in range(int(self.w / zone))] for a in range(len(self.tiles) / zone): for b in range(len(self.tiles[a]) / zone): cell_x = 0 cell_y = 0 tiles = [[0, []], [0, []]] x = a * zone y = b * zone for cell_x in range(zone): if x + cell_x > len(self.tiles) - 1: break for cell_y in range(zone): if y + cell_y > len(self.tiles[cell_x]) - 1: break #TODO: put in catches for the "end" bits where there is less tiles left than the "zone". value = int( libtcod.heightmap_get_value( hm, x + cell_x, y + cell_y)) if value > WATER_THRESHOLD: tiles[0][0] += 1 tiles[0][1].append(value) else: tiles[1][0] += 1 tiles[1][1].append(value) if tiles[0] > tiles[1]: #make land sum_ = sum(num for num in tiles[0][1]) value = sum_ / len(tiles[0][1]) self.mini_map[a][b] = Tile(cell_x, cell_y, False, map_tile=True, bg=[10, value, 10]) elif tiles[1] > tiles[0]: #make water sum_ = sum(num for num in tiles[1][1]) value = sum_ / len(tiles[1][1]) self.mini_map[a][b] = Tile(cell_x, cell_y, True, map_tile=True, bg=[10, 10, value]) else: #flip for either. flip = libtcod.random_get_int(0, 0, 1) if flip == 1: #water sum_ = sum(num for num in tiles[1][1]) value = sum_ / len(tiles[1][1]) self.mini_map[a][b] = Tile(cell_x, cell_y, True, map_tile=True, bg=[10, 10, value]) if flip == 0: #land sum_ = sum(num for num in tiles[0][1]) value = sum_ / len(tiles[0][1]) self.mini_map[a][b] = Tile(cell_x, cell_y, False, map_tile=True, bg=[10, value, 10])
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
def turn_to_tiles(self): self.tiles = [] self.tiles = [[ Tile(ix, iy, False, map_tile=True) for iy in range(self.h) ] for ix in range(self.w)] for cell_x in range(self.w): for cell_y in range(self.h): value = int( libtcod.heightmap_get_value(self.hm, cell_x, cell_y)) if value > MOUNTAIN_THRESHOLD: #mountain mountain = 50 + (value - MOUNTAIN_THRESHOLD) shift = libtcod.random_get_int(0, -5, 5) tote = mountain + shift if tote > 255: tote = 255 if tote < 0: tote = 0 #self.tiles[cell_x][cell_y] = Tile(cell_x,cell_y, False, map_tile=True, bg=[40 + mountain, value - mountain, 40 + mountain], cost = 20) self.tiles[cell_x][cell_y] = Tile(cell_x, cell_y, False, map_tile=True, bg=[tote, tote, tote], cost=40) self.tiles[cell_x][cell_y].elevation = value self.tiles[cell_x][ cell_y].humidity = libtcod.random_get_int(0, 0, 5) self.tiles[cell_x][cell_y].humidity_per = self.tiles[ cell_x][cell_y].humidity / 255 * 100 self.tiles[cell_x][cell_y].type = "mountain" elif value > WATER_THRESHOLD + COASTLINE_THRESHOLD: #grass ran_1 = 255 - value + libtcod.random_get_int(0, -5, 5) if ran_1 > 255: ran_1 = 255 self.tiles[cell_x][cell_y] = Tile( cell_x, cell_y, False, map_tile=True, bg=[10, ran_1, 10 + libtcod.random_get_int(0, -5, 5)], cost=15) self.tiles[cell_x][cell_y].elevation = value self.tiles[cell_x][ cell_y].humidity = libtcod.random_get_int(0, 10, 100) self.tiles[cell_x][cell_y].humidity_per = self.tiles[ cell_x][cell_y].humidity / 255 * 100 elif value > WATER_THRESHOLD: #coast test = int(math.sqrt(value)) #test = test ** 3 self.tiles[cell_x][cell_y] = Tile( cell_x, cell_y, False, map_tile=True, bg=[ value + libtcod.random_get_int(0, -5, 5), value - test + libtcod.random_get_int(0, -5, 5), test ]) self.tiles[cell_x][cell_y].elevation = value self.tiles[cell_x][cell_y].humidity = 25.5 self.tiles[cell_x][cell_y].humidity_per = 10.0 else: #water tote = value + libtcod.random_get_int(0, -5, 5) if tote > 255: tote = 255 if tote < 0: tote = 0 self.tiles[cell_x][cell_y] = Tile(cell_x, cell_y, True, map_tile=True, bg=[10, 10, tote]) self.tiles[cell_x][cell_y].elevation = value self.tiles[cell_x][cell_y].humidity = 255 self.tiles[cell_x][cell_y].humidity_per = 100.0 self.tiles[cell_x][cell_y].type = "water"
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 __init__(self, mouth_col, mouth_row, heightmap, size, random): self.tiles = [] rainlevel = 90 # The level above which rivers have a drastically reduced chance to keep flowing. move = [(-1, -1), (0, -1), (1, -1), (1, 0), (1, 1), (0, 1), (-1, 1), (-1, 0)] # Directions in order clockwise. flowing = True last_turns = 0 current_col = mouth_col current_row = mouth_row # Pick a starting direction: direct = lt.random_get_int(random, 0, 7) # The first direction we'll go. while flowing: if 0 <= current_col < size and 0 <= current_row < size: self.tiles.append((current_col, current_row)) found = tuple() # Build a new list including the two options around the starting directions. new_move = [move[direct - 1], move[direct], move[direct + 1 if direct < 7 else 0]] for direction in new_move: dx, dy = direction value = lt.heightmap_get_value(heightmap, current_row + dx, current_col + dy) here = lt.heightmap_get_value(heightmap, current_row, current_col) if value > here: if found: if found[1] > value: found = (direction, value) else: found = (direction, value) break if found: if found[0] == new_move[0]: if last_turns < -2: found = (new_move[1], 0) else: last_turns -= 2 if found[0] == new_move[2]: if last_turns > 3: found = (new_move[1], 0) else: last_turns += 3 dx, dy = found[0] last_turns += 1 if last_turns < 0 else -1 elif len(found) == 0: dx, dy = new_move[1] if here < -19: flowing = False direct = move.index((dx, dy)) current_col += dy current_row += dx if current_col == size or current_row == size or current_col < 0 or current_col < 0: flowing = False if (current_col, current_row) in self.tiles: flowing = False # Check if we should still be flowing. chance = lt.random_get_float(random, 0, 1) if here > rainlevel and chance < 0.4: flowing = False elif chance < (len(self.tiles) * 0.0005) * (here * 0.00005): flowing = False self.head_col = current_col self.head_row = current_row
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)