Пример #1
0
    def probableRangedAttack(self):
        """
        Return an action for a ranged attack on a target if such an attack is
        possible.  Otherwise, return None.
        """
        if "two_square_thrower" in self.tags:
            if self.currentLevel.player in self.fov \
                and coordinates.minimumPath(self.coords, self.currentLevel.player.coords) in range(1, 4):
                
                possible_directions = ((2,0),(2,2),(0,2),(-2,2),(-2,0),(-2,-2),(0,-2),(2,-2))
                possible_targets = [coordinates.add(self.coords, i) for i in possible_directions if self.currentLevel.isEmpty(coordinates.add(self.coords, i))]
                visible_targets = [coords for coords in possible_targets if coords in self.fov]
                close_targets = [coords for coords in visible_targets if (coordinates.minimumPath(coords, self.currentLevel.player.coords) <= 1)]
                actual_targets = [coords for coords in close_targets if coords not in self.currentLevel.dudeLayer]
                if len(actual_targets) == 0:
                    return None
                final_target = rng.choice(actual_targets)
                return action.ThrowGrenade(self, final_target)
            else:
                return None
        elif "twelve_square_firer" in self.tags:
            direction = coordinates.get_cardinal_direction(self.coords,
                          self.currentLevel.player.coords)
            dist = coordinates.minimumPath(self.coords,
                   self.currentLevel.player.coords)
            if self.currentLevel.player in self.fov \
                and direction is not None \
                and dist < 12:

                return action.FireArrow(self, direction, 12)
            else:
                return None
        else:
            return None
Пример #2
0
    def are_immediately_accessible(self, coords1, coords2):
        """
        Returns true if a move from coords1 to coords2 is legal given the
        dungeon layout, false otherwise.

        This function does not take into account monsters on either square.
        """

               # the given coordinates are legal
        result = (all(map(self.legalCoordinates, (coords1, coords2))) and
               # the movedDude can move on the dungeon tile of moveCoords
                all(map(self.isEmpty, (coords1, coords2))) and
               # moveCoords is only one square away
                (coordinates.minimumPath(coords1, coords2) == 1))

        # a "corner move," of the following form, is NOT being performed
        # d.      (moving from s to d)
        # #s

        if coordinates.are_diagonally_adjacent(coords1, coords2):
            adjacent_squares = ((coords1[0], coords2[1]), (coords2[0], coords1[1]))
# Return true only if both adjacent squares are empty, i.e. disallow corner moves.
            result = result and all(map(lambda x: self.isEmpty(x), adjacent_squares))
        
        return result
Пример #3
0
    def rangedApproach(self):
        if ("prefer_melee" in self.tags and coordinates.minimumPath(
                self.coords, self.currentLevel.player.coords) == 1):

            # If the monster prefers melee and is in melee range, don't do a ranged attack.

            return self.closeToPlayer()

        ranged_attack = self.probableRangedAttack()
        if ranged_attack is not None:
            return ranged_attack
        else:
            return self.closeToPlayer()