コード例 #1
0
ファイル: level.py プロジェクト: nate1001/vecter_hack
    def __init__(self, player, tiletypes, label):

        self.label = label
        self._player = player
        self._size = (len(tiletypes[0]), len(tiletypes))
        self._grid = Grid(self._size)
        self._open_tiles = Flags.from_tiles_attr(tiletypes, 'is_open')
        self._torch_map = Flags(self._size)

        for y, row in enumerate(tiletypes):
            for x, tiletype in enumerate(row):
                tile = Tile(tiletype, x, y)
                self[x,y] = tile
コード例 #2
0
ファイル: level.py プロジェクト: nate1001/vecter_hack
class Level(dict):

    neighbors = {
      ( 0,-1):  'n',  
      ( 0, 1):  's',  
      (-1, 0):  'w',  
      ( 1, 0):  'e',  
      (-1,-1):  'nw', 
      ( 1,-1):  'ne',  
      (-1, 1):  'sw', 
      ( 1, 1):  'se', 
    }

    class View(dict):

        def __init__(self, level):

            self.label = level.label
            self.size = level._size

            for tile in level.values():
                self[(tile.x, tile.y)] = tile.view(level._player)

        def values(self):
            return self.tiles()

        def tiles(self):
            
            t = []
            for y in range(self.size[1]):
                for x in range(self.size[0]):
                    tile = self[x,y]
                    tile.neighbors = {}
                    for off, direc in Level.neighbors.items():
                        tile.neighbors[direc] = self.get((x + off[0], y + off[1]))
                    t.append(tile)
            return t

    def __init__(self, player, tiletypes, label):

        self.label = label
        self._player = player
        self._size = (len(tiletypes[0]), len(tiletypes))
        self._grid = Grid(self._size)
        self._open_tiles = Flags.from_tiles_attr(tiletypes, 'is_open')
        self._torch_map = Flags(self._size)

        for y, row in enumerate(tiletypes):
            for x, tiletype in enumerate(row):
                tile = Tile(tiletype, x, y)
                self[x,y] = tile

    def __repr__(self):
        return "<Level {}>".format(self.label)

    @property
    def staircases_up(self):
        return [t for t in self.itervalues() if t.tiletype.name == 'staircase up']

    @property
    def staircases_down(self):
        return [t for t in self.itervalues() if t.tiletype.name == 'staircase down']
    
    @property
    def beings(self):
        return [t.being for t in self.itervalues() if t.being]

    @property
    def lights(self):
        return [t for t in self.itervalues() if t.light]

    def kill_being(self, being):
        tiles = [t for t in self.values() if t.being is being]
        if len(tiles) != 1:
            raise ValueError(being)
        tiles[0].being = None

    def view(self):
        return self.__class__.View(self)

    def _set_torch_map(self):

        flags = Flags(self._size)
        for tile, light in [(tile, tile.light) for tile in self.lights]:
            f = self._grid.fov(self._open_tiles, tile.idx, light.radius)
            flags = flags | f

        self._torch_map = flags

    def set_fov(self, being):
        radius = being.see_radius
        tile = self.tile_for(being)
        see = self._grid.fov(self._open_tiles & self._torch_map, tile.idx, radius)
        being.vision.set_see(see)

    def get_ray(self, tile, direction, length, all_types=False):
        idxs = Ray.ray_by_offset(tile.idx, direction.offset, length)
        tiles = []
        for idx in idxs:
            tile = self.get(idx)
            # if its open take it
            if tile and tile.tiletype.is_open:
                tiles.append(tile)
            # else if we want closed tiles also
            elif all_types and tile:
                tiles.append(tile)
            # take the wall and break
            elif tile:
                tiles.append(tile)
                break
        return tiles

    def add_being(self, tile, being):
        tile.being = being
        being.direction = 'sw'
        being.new_level(self._size)

    def move_being(self, subject, target):
        if target.being:
            raise ValueError(target.being)
        target.being = subject.being
        subject.being = None
        # we may be moving more than one tile
        try:
            direc = subject.direction(target)
            target.being.direction = direc.abr
        except ValueError:
            #just keep the old direction 
            pass

    def being_distance(self, being, other):
        x1, y1 = self.tile_for(being).idx
        x2, y2 = self.tile_for(other).idx
        return ((x2 - x1)**2 + (y2 - y1)**2)**.5

    def chase_player(self, monster):

        blocked = Flags(self._size)
        for other in [
            b for b in self.beings 
            if b is not self._player and b is not monster]:
            t = self.tile_for(other)
            blocked[t.idx] = True
        
        p = self.tile_for(self._player)
        m = self.tile_for(monster)
        path = self._grid.get_path(self._open_tiles & ~blocked, p.idx, m.idx)
        if not path:
            return None
        return self[path[0]]

    def adjacent_tile(self, tile, direction):
        '''Return the adjacent tile by the direction or None.'''

        offset = direction.offset
        x, y = tile.x + offset[0], tile.y + offset[1]
        return self.get((x,y))

    def adjacent_tiles(self, tile):
        '''Return all adjacent tiles to this tile.'''
        adj = [ d.offset for d in direction_by_abr.values()]
        return [t for t in [self.get((tile.x + idx[0],tile.y + idx[1])) for idx in adj] if t]

    def tile_for(self, thing):

        if type(thing) is Being:
            tiles = [t for t in self.values() if t.being is thing]
        #else its equipment
        else:
            tiles = [i for i in [t.inventory for t in self.values()] if thing is i]

        if len(tiles) != 1:
            logger.error('tiles %s length != 1', tiles)
            raise KeyError(tiles)
        return tiles[0]

    def open_door(self, tile):
        if not tile.openable:
            raise TypeError('tile cannot be opened.'.format(tile))
        tiletype = TileType.get_door_type(tile.tiletype.direction, False, True, False)
        tiletype = TileType(tile.tiletype.name.replace('closed', 'open'))
        tile.tiletype = tiletype
        return True

    def close_door(self, tile):
        if not tile.closable:
            raise TypeError('tile cannot be closed.'.format(tile))
        tiletype = TileType.get_door_type(tile.tiletype.direction, False, False, False)
        tile.tiletype = tiletype
        return True

    def lock_door(self, tile):
        if not tile.lockable:
            raise TypeError('tile cannot be locked.'.format(tile))
        tiletype = TileType.get_door_type(tile.tiletype.direction, False, False, True)
        tile.tiletype = tiletype
        return True

    def unlock_door(self, tile):
        if not tile.unlockable:
            raise TypeError('tile cannot be unlocked.'.format(tile))
        tiletype = TileType.get_door_type(tile.tiletype.direction, False, False, False)
        tile.tiletype = tiletype
        return True

    def break_door(self, tile):
        if not tile.breakable:
            raise TypeError('tile cannot be broken.'.format(tile))
        tiletype = TileType.get_door_type(tile.tiletype.direction, True, True, False)
        tile.tiletype = tiletype
        return True

    def fix_door(self, tile):
        if not tile.fixable:
            raise TypeError('tile cannot be fixed.'.format(tile))
        tiletype = TileType.get_door_type(tile.tiletype.direction, False, True, False)
        tile.tiletype = tiletype
        return True