def __init__(self):
     super(Forest, self).__init__(biome=context.HAB_FOREST,
                                  desctags=(context.MAP_WILDERNESS, ),
                                  wall_filter=converter.ForestConverter(),
                                  mutate=mutator.CellMutator())
     #self.sprites[maps.SPRITE_WALL] = "terrain_wall_woodfort.png"
     self.sprites[maps.SPRITE_GROUND] = "terrain_ground_forest.png"
     #self.sprites[maps.SPRITE_FLOOR] = "terrain_floor_gravel.png"
     self.sprites[maps.SPRITE_CHEST] = "terrain_chest_wood.png"
     self.name = random.choice(self.NAME_PATTERNS).format(
         namegen.random_style_name())
 def __init__(self):
     super(Desert,
           self).__init__(biome=context.HAB_DESERT,
                          desctags=(context.MAP_WILDERNESS, ),
                          wall_filter=converter.DesertConverter(),
                          mutate=mutator.CellMutator(),
                          prepare=prep.HeightfieldPrep(loground=0.05,
                                                       higround=0.15))
     #self.sprites[maps.SPRITE_WALL] = "terrain_wall_woodfort.png"
     self.sprites[maps.SPRITE_GROUND] = "terrain_ground_desert.png"
     #self.sprites[maps.SPRITE_FLOOR] = "terrain_floor_gravel.png"
     self.sprites[maps.SPRITE_CHEST] = "terrain_chest_wood.png"
     self.name = random.choice(self.NAME_PATTERNS).format(
         namegen.random_style_name())
 def __init__(self, fac=None):
     super(CavernDungeon, self).__init__(
         biome=context.HAB_CAVE,
         desctags=[context.MAP_DUNGEON, context.MAP_GODOWN],
         wall_filter=converter.BasicConverter(),
         mutate=mutator.CellMutator())
     self.sprites[maps.SPRITE_WALL] = random.choice(self.WALL_OPTIONS)
     self.sprites[maps.SPRITE_GROUND] = "terrain_ground_under.png"
     self.sprites[maps.SPRITE_FLOOR] = "terrain_floor_gravel.png"
     self.sprites[maps.SPRITE_CHEST] = "terrain_chest_wood.png"
     # Do the custom decorating now.
     if fac:
         if fac.primary in self.CUSTOM_DECOR_TYPES.keys():
             a, b = self.CUSTOM_DECOR_TYPES[fac.primary]
             self.decorate = a(**b)
         elif fac.secondary in self.CUSTOM_DECOR_TYPES.keys():
             a, b = self.CUSTOM_DECOR_TYPES[fac.secondary]
             self.decorate = a(**b)
     self.name = random.choice(self.NAME_PATTERNS).format(
         namegen.random_style_name())
class WildernessPath(RandomScene):
    # Creates a wilderness area, adds a path with sorted contents along line.
    WALL_FILTER = converter.ForestConverter()
    MUTATE = mutator.CellMutator()
    PREPARE = prep.HeightfieldPrep(loground=0.10, higround=0.95)

    def arrange_contents(self, gb):
        self.on_the_path = list()
        for r in self.contents[:]:
            if hasattr(r, "area") and hasattr(r, "priority"):
                self.on_the_path.append(r)
        self.on_the_path.sort(key=self.get_priority)
        x_step = self.area.width // len(self.on_the_path)
        x = self.area.x + x_step // 2
        for r in self.on_the_path:
            r.area = pygame.Rect(0, 0, min(r.width, x_step), r.height)
            r.area.center = (x, self.area.centery + random.randint(-5, 5))
            x += x_step
        # Now that the path has been sorted, sort the rest.
        super(RandomScene, self).arrange_contents(gb)

    def get_priority(self, r):
        return r.priority

    def connect_contents(self, gb):
        # Run the basic connector first.
        super(RandomScene, self).connect_contents(gb)
        # Then, connect all path areas with HIGROUND.
        r_prev = self.on_the_path[0]
        for r in self.on_the_path[1:]:
            self.draw_road_connection(gb, r.area.centerx, r.area.centery,
                                      r_prev.area.centerx, r_prev.area.centery)
            r_prev = r

    def draw_road_connection(self, gb, x1, y1, x2, y2):
        path = animobs.get_line(x1, y1, x2, y2)
        for p in path:
            self.fill(gb, pygame.Rect(p[0] - 2, p[1] - 2, 5, 5), wall=None)
            self.fill(gb,
                      pygame.Rect(p[0] - 1, p[1] - 1, 3, 3),
                      floor=maps.HIGROUND)
class WalledForestScene(RandomScene):
    # Like a cave, but replace certain True walls with trees.
    GAPFILL = gapfiller.MonsterFiller()
    MUTATE = mutator.CellMutator(noise_throttle=100)
    WALL_FILTER = converter.EdgyConverter()
class ForestScene(RandomScene):
    GAPFILL = gapfiller.MonsterFiller()
    WALL_FILTER = converter.ForestConverter(treeline=0.95)
    MUTATE = mutator.CellMutator()
    PREPARE = prep.HeightfieldPrep(loground=0.05, higround=0.85)
class CaveScene(RandomScene):
    GAPFILL = gapfiller.MonsterFiller()
    MUTATE = mutator.CellMutator(noise_throttle=100)
class EdgeOfCivilization(RandomScene):
    """Civilized rooms connected to road; other rooms just connected by loground."""
    WALL_FILTER = converter.ForestConverter()
    MUTATE = mutator.CellMutator()
    PREPARE = prep.HeightfieldPrep(loground=0.15, higround=0.75)

    def arrange_contents(self, gb):
        # Run a road along one edge of the map. Stick everything else in a
        # sub-rect to arrange there. Keep track of the civilized areas.
        self.wilds = rooms.Room(width=self.width - 10,
                                height=self.height,
                                anchor=anchors.west,
                                parent=self)
        self.wilds.area = pygame.Rect(0, 0, self.wilds.width,
                                      self.wilds.height)
        self.wilds.FUZZY_FILL_TERRAIN = maps.LOGROUND
        self.wilds.GAPFILL = gapfiller.MonsterFiller(spacing=16)
        self.wilds.DEFAULT_ROOM = self.DEFAULT_ROOM

        self.civilized_bits = list()
        for r in self.contents[:]:
            if hasattr(r, "area") and r is not self.wilds:
                self.contents.remove(r)
                self.wilds.contents.append(r)
                if context.CIVILIZED in r.tags:
                    self.civilized_bits.append(r)

        # Create the road.
        self.road = pygame.Rect(self.area.x + self.area.width - 10,
                                self.area.y, 7, self.area.height)

        self.roadbits = list()
        for y in range(10):
            x = self.area.x + self.area.width - 10 + random.randint(0, 2)
            roadseg = rooms.Room(width=5,
                                 height=self.height // 10,
                                 parent=self)
            roadseg.area = pygame.Rect(x, y * roadseg.height, roadseg.width,
                                       roadseg.height)
            self.roadbits.append(roadseg)

    def connect_contents(self, gb):
        # Connect all civilized areas with HIGROUND.
        connected = self.roadbits
        r_prev = connected[0]
        for r in connected[1:]:
            self.draw_road_connection(gb, r.area.centerx, r.area.centery,
                                      r_prev.area.centerx, r_prev.area.centery)
            r_prev = r
        self.draw_road_connection(gb, connected[0].area.centerx,
                                  connected[0].area.centery, self.road.centerx,
                                  self.road.top)
        self.draw_road_connection(gb, connected[-1].area.centerx,
                                  connected[-1].area.centery,
                                  self.road.centerx, self.road.bottom)
        for r in self.civilized_bits:
            connected.sort(key=r.find_distance_to)
            self.draw_road_connection(gb, r.area.centerx, r.area.centery,
                                      connected[0].area.centerx,
                                      connected[0].area.centery)
            connected.append(r)

    def draw_road_connection(self, gb, x1, y1, x2, y2):
        path = animobs.get_line(x1, y1, x2, y2)
        for p in path:
            self.fill(gb, pygame.Rect(p[0] - 2, p[1] - 2, 5, 5), wall=None)
            self.fill(gb,
                      pygame.Rect(p[0] - 1, p[1] - 1, 3, 3),
                      floor=maps.HIGROUND)
class DividedIslandScene(RandomScene):
    """The rooms are divided into two groups by a single bridge."""
    # Special elements:
    #  bridge: The room in the middle of the river.
    #  before_bridge: The room before the bridge.
    #  after_bridge: The room after the bridge.
    # Tags of note:
    #  ENTRANCE: Rooms with this tag placed before the bridge
    #  GOAL: Rooms with this tag placed after the bridge
    MUTATE = mutator.CellMutator(noise_throttle=100)
    PREPARE = prep.HeightfieldPrep(loground=0.15, higround=0.7)

    def arrange_contents(self, gb):
        # Divide the map into two segments.
        if random.randint(1, 2) == 1:
            horizontal_river = True
            subzone_height = (self.height - 10) // 2
            # Horizontal river
            z1 = rooms.Room()
            z1.area = pygame.Rect(0, 0, self.width, subzone_height)
            z1.special_c["bridge_anchor"] = anchors.south
            z2 = rooms.Room()
            z2.area = pygame.Rect(0, 0, self.width, subzone_height)
            z2.area.bottomleft = self.area.bottomleft
            z2.special_c["bridge_anchor"] = anchors.north
            river = pygame.Rect(0, 0, self.width, 7)
        else:
            horizontal_river = False
            subzone_width = (self.width - 10) // 2
            # Vertical river
            z1 = rooms.Room()
            z1.area = pygame.Rect(0, 0, subzone_width, self.height)
            z1.special_c["bridge_anchor"] = anchors.east
            z2 = rooms.Room()
            z2.area = pygame.Rect(0, 0, subzone_width, self.height)
            z2.area.topright = self.area.topright
            z2.special_c["bridge_anchor"] = anchors.west
            river = pygame.Rect(0, 0, 7, self.height)
        if random.randint(1, 2) == 1:
            z1, z2 = z2, z1
        z1.GAPFILL = gapfiller.MonsterFiller()
        z1.DEFAULT_ROOM = self.DEFAULT_ROOM
        z2.GAPFILL = gapfiller.MonsterFiller()
        z2.DEFAULT_ROOM = self.DEFAULT_ROOM
        river.center = self.area.center
        self.fill(gb, river, floor=maps.WATER, wall=None)
        self.fill(gb, river.inflate(3, 3), wall=None)

        # Locate the bridge, before_bridge, and after_bridge rooms, creating them
        # if none currently exist.
        bridge = self.special_c.get("bridge") or self.special_c.setdefault(
            "bridge", rooms.FuzzyRoom(parent=self))
        before_bridge = self.special_c.get(
            "before_bridge") or self.special_c.setdefault(
                "before_bridge", self.DEFAULT_ROOM(parent=self))
        after_bridge = self.special_c.get(
            "after_bridge") or self.special_c.setdefault(
                "after_bridge", self.DEFAULT_ROOM(parent=self))
        before_bridge.anchor = z1.special_c["bridge_anchor"]
        after_bridge.anchor = z2.special_c["bridge_anchor"]

        # Go through the remaining rooms, sorting each into either z1 or z2
        z1_turn = True
        for r in self.contents[:]:
            if isinstance(r, Room):
                if r is bridge:
                    r.area = pygame.Rect(0, 0, r.width, r.height)
                    r.area.center = self.area.center
                elif r is before_bridge:
                    self.contents.remove(r)
                    z1.contents.append(r)
                elif r is after_bridge:
                    self.contents.remove(r)
                    z2.contents.append(r)
                elif context.ENTRANCE in r.tags:
                    self.contents.remove(r)
                    z1.contents.append(r)
                elif context.GOAL in r.tags:
                    self.contents.remove(r)
                    z2.contents.append(r)
                elif z1_turn:
                    self.contents.remove(r)
                    z1.contents.append(r)
                    z1_turn = False
                else:
                    self.contents.remove(r)
                    z2.contents.append(r)
                    z1_turn = True

        self.contents += (z1, z2)

    def connect_contents(self, gb):
        # This is pretty easy- just connect before_bridge to bridge to after_bridge.
        bridge = self.special_c["bridge"]
        before_bridge = self.special_c["before_bridge"]
        after_bridge = self.special_c["after_bridge"]
        self.draw_direct_connection(gb, before_bridge.area.centerx,
                                    before_bridge.area.centery,
                                    bridge.area.centerx, bridge.area.centery)
        self.draw_direct_connection(gb, after_bridge.area.centerx,
                                    after_bridge.area.centery,
                                    bridge.area.centerx, bridge.area.centery)