def generate(self): rooms = [] num_rooms = 0 ticks = self.max_rooms * 5 for r in range(self.max_rooms): if ticks <= 0: break ticks -= 1 if num_rooms > self.max_rooms: break width = libtcod.random_get_int(0, self.room_min_size, self.room_max_size) height = libtcod.random_get_int(0, self.room_min_size, self.room_max_size) #random position without going out of the boundaries of the map x = libtcod.random_get_int(0, 0, self.length - width - 1) y = libtcod.random_get_int(0, 0, self.width - height - 1) new_room = Rect(x, y, width, height) if not self.check_room_overlap(rooms, new_room): rooms.append(new_room) new_x, new_y = new_room.center() if num_rooms > 0: prev_x, prev_y = rooms[num_rooms - 1].center() if libtcod.random_get_int(0, 0, 1) == 1: self.create_h_tunnel(prev_x, new_x, prev_y) self.create_v_tunnel(prev_y, new_y, new_x) else: self.create_v_tunnel(prev_y, new_y, prev_x) self.create_h_tunnel(prev_x, new_x, new_y) num_rooms += 1 for room in rooms: self.create_room(room)
def find_random_square(self, occupied): startx = libtcod.random_get_int(0, 0, self.current.width) starty = libtcod.random_get_int(0, 0, self.current.height) for y in range(starty, self.current.height): for x in range(startx, self.current.width): if self.map[y][x].passable() and not occupied((x, y)): return x, y #if nothing found - let's try once again return self.find_random_square(occupied)
def find_random_square(self, occupied): startx = libtcod.random_get_int(0, 1, self.map_width) starty = libtcod.random_get_int(0, 1, self.map_height) for y in range(starty, self.map_height): for x in range(startx, self.map_width): if self.map[y][x].passable() and not occupied((x, y)): return x, y #if nothing found - let's try once again return self.find_random_square(occupied)
def place_random_monsters(self): #todo - maybe we should move this to mapgenerator (check for theme, etc) #choose random number of monsters #3d(dlvl) + 3d2 + 7 monsters total - at least 11 monsters on d1 and up-to 40 on d27 num_monsters = util.roll(1, gl.__dlvl__, util.roll(3, 2, 7)) num_monsters -= len(self.critters) free_squares = -2 for x in xrange(self.width): for y in xrange(self.height): tile = self.tile_at(x, y) if tile.passable(): free_squares += 1 num_monsters = util.cap(num_monsters, free_squares) #if it was capped - then map is too small... if num_monsters == free_squares: num_monsters = randrange(1, free_squares / 2) passes = num_monsters * 5 for i in range(num_monsters): if passes <= 0: break passes -= 1 #choose random spot for this monster x, y = self.find_random_square(self.has_critter_at) room = self._find_room(x, y) if room and room.src: if room.src.no_mon_gen: continue #determining critter level. it may vary from XL - 3 to XL + 1. To let is scale better multiply by 100 #cap it to be no lower than 1 crit_hd = max(randrange(gl.__xl__ - 3, gl.__xl__ + 1), 1) self.place_random_critter(gl.__dlvl__, crit_hd, x, y) #check for OOD monster. let's create OOD 10% of the time for now if libtcod.random_get_int(0, 0, 100) >= 89: crit_level = libtcod.random_get_int(0, gl.__dlvl__ + 2, gl.__dlvl__ + 3) crit_hd = max(randrange(gl.__xl__ - 3, gl.__xl__ + 3), 1) x, y = self.find_random_square(self.has_critter_at) room = self._find_room(x, y) if room and room.src: if room.src.no_mon_gen: return self.place_random_critter(crit_level, crit_hd, x, y)
def place_random_monsters(self): #todo - maybe we should move this to mapgenerator (check for theme, etc) #choose random number of monsters #3d(dlvl) + 3d2 + 7 monsters total - at least 11 monsters on d1 and up-to 40 on d27 num_monsters = util.roll(1, gl.__dlvl__, util.roll(3, 2, 7)) num_monsters -= len(self.critters) free_squares = -2 for x in xrange(self.width): for y in xrange(self.height): tile = self.tile_at(x, y) if tile.passable(): free_squares += 1 num_monsters = util.cap(num_monsters, free_squares) #if it was capped - then map is too small... if num_monsters == free_squares: num_monsters = randrange(1 , free_squares / 2) passes = num_monsters * 5 for i in range(num_monsters): if passes <= 0: break passes -= 1 #choose random spot for this monster x, y = self.find_random_square(self.has_critter_at) room = self._find_room(x, y) if room and room.src: if room.src.no_mon_gen: continue #determining critter level. it may vary from XL - 3 to XL + 1. To let is scale better multiply by 100 #cap it to be no lower than 1 crit_hd = max(randrange(gl.__xl__ - 3, gl.__xl__ + 1), 1) self.place_random_critter(gl.__dlvl__, crit_hd, x, y) #check for OOD monster. let's create OOD 10% of the time for now if libtcod.random_get_int(0, 0, 100) >= 89: crit_level = libtcod.random_get_int(0, gl.__dlvl__ + 2, gl.__dlvl__ + 3) crit_hd = max(randrange(gl.__xl__ - 3, gl.__xl__ + 3), 1) x, y = self.find_random_square(self.has_critter_at) room = self._find_room(x, y) if room and room.src: if room.src.no_mon_gen: return self.place_random_critter(crit_level, crit_hd, x, y)
def place_monsters(self): #choose random number of monsters #3d(dlvl) + 3d2 + 7 monsters total - at least 11 monsters on d1 and up-to 40 on d27 num_monsters = util.roll(1, gl.__dlvl__, util.roll(3, 2, 7)) #cap monster generation for now num_monsters = util.cap(num_monsters, 30) for i in range(num_monsters): #choose random spot for this monster x, y = self.find_random_square(self.has_critter_at) #determining critter level. it may vary from XL - 3 to XL + 3. To let is scale better multiply by 100 #cap it to be no lower than 1 crit_hd = util.cap_lower(randrange(gl.__xl__ - 3, gl.__xl__ + 3), 1, 1) self.place_critter(gl.__dlvl__, crit_hd, x, y) #check for OOD monster. let's create OOD 10% of the time for now if libtcod.random_get_int(0, 0, 100) >= 89: crit_level = libtcod.random_get_int(0, gl.__dlvl__ + 2, gl.__dlvl__ + 3) crit_hd = util.cap_lower(randrange(gl.__xl__ - 3, gl.__xl__ + 3), 1, 1) x, y = self.find_random_square(self.has_critter_at) self.place_critter(crit_level, crit_hd, x, y)
def coinflip(): return libtcod.random_get_int(0, 0, 1)
def roll(a, b, c=0, *ignore): return sum(libtcod.random_get_int(0, 1, b) for i in range(a)) + c