コード例 #1
0
ファイル: dude.py プロジェクト: nrook/Spirit
    def closeToPlayer(self):
        """
        Pathfind to the player, and attack him if possible.
        """

        player_location = self.currentLevel.player.coords

        # If adjacent to the player, attack him.
        if coordinates.adjacent(player_location, self.coords):
            if rng.percentChance(self.specfreq):
                return action.SpecialMelee(self, self.currentLevel.player,
                                           self.spec)
            else:
                return action.Attack(
                    self, self.currentLevel.player,
                    "%(SOURCE_NAME)s attacks %(TARGET_NAME)s! (%(DAMAGE)d)")

# Otherwise, pathfind toward him.
        else:
            path = pf.find_shortest_path(self.currentLevel, self.coords,
                                         player_location, False)
            if path != []:
                move_coords = coordinates.subtract(path[1], path[0])
                return action.Move(self, move_coords)
            else:
                return action.Wait(self)
コード例 #2
0
ファイル: dude.py プロジェクト: codelurker/Spirit
    def traveling(self):
        """
        Calculate the action of a monster moving to a specific location.

        Note that a "path" variable must exist for this to make sense.
        """

# self.path[0] should be the monster's current square.
# self.path[1] should be the square the monster wants to move to.
# self.path[-1] should be the monster's ultimate destination.

        assert self.path != None, "Despite the monster being in state TRAVELING, the path variable is null."

        if self.currentLevel.player in self.fov:
            self.state = ais.FIGHTING
            return self.fighting()
        else:
            path_is_invalid = False

            if len(self.path) == 0:
                assert False # This shouldn't happen!
                path_is_invalid = True
            elif self.coords != self.path[0]:
# Something has moved the monster since its last turn.
                path_is_invalid = True
            elif len(self.path) == 1:
# Since self.coords == self.path[0], the monster has reached its destination!
                self.state = ais.WANDERING
                return self.wandering()
            elif not self.canMove(self.path[1]):
                path_is_invalid = True

            if path_is_invalid:
                if len(self.path) == 0:
# If the path is completely empty, something has gone wrong.
                    assert False
# Just give up and return to being stationary.
                    self.state = ais.RESTING
                    return self.resting()
                else:
                    destination = self.path[-1]
                    self.path = pf.find_shortest_path(self.currentLevel, self.coords, destination, True)
                    if len(self.path) == 0:
# There simply is no path to the destination!
# Set self.path to only contain the destination, so that next turn, this code
# attempts to find another path.
                        self.path = [destination]
                        return action.Wait(self)
                    elif len(self.path) == 1:
# This should not happen!
                        assert False
                        return action.Wait(self)

            if self.canMove(self.path[1]):
                move_direction = coordinates.subtract(self.path[1], self.coords)
                self.path.pop(0)
                return action.Move(self, move_direction)
            else:
                assert False, "The supposedly legal path contains an illegal move!"
                return action.Wait(self)
コード例 #3
0
ファイル: dude.py プロジェクト: nrook/Spirit
    def fighting(self):
        """
        Calculate the action of a monster who sees the player.
        """

        if self.currentLevel.player not in self.fov:
            if self.player_last_location is not None:
                # The player has escaped!  Find a likely square where he could have gone.
                adjacent_coords = coordinates.adjacent_coords(
                    self.player_last_location)
                legal_coords = [
                    i for i in adjacent_coords
                    if coordinates.legal(i, self.currentLevel.dimensions)
                ]
                passable_coords = [
                    i for i in legal_coords if self.currentLevel.isEmpty(i)
                ]
                out_of_vision_coords = \
                    [i for i in passable_coords if i not in self.fov]

                if len(out_of_vision_coords) > 0:
                    # There is a possible escape route!  Pursue!
                    self.direction = coordinates.subtract(
                        rng.choice(out_of_vision_coords),
                        self.player_last_location)
                    self.path = pf.find_shortest_path(
                        self.currentLevel, self.coords,
                        self.player_last_location, False)
                    if self.path == []:
                        # There is no route to the player's escape route.  Wait, but stay in
                        # state FIGHTING so as to take advantage of any route that opens up.
                        return action.Wait(self)
                    self.state = ais.TRAVELING
                    return self.traveling()
                else:
                    # There is no possible escape route; give up and rest.
                    self.state = ais.RESTING
                    return self.resting()

            else:
                assert False

        else:
            self.player_last_location = self.currentLevel.player.coords

            if self.AICode == "CLOSE":
                return self.closeToPlayer()

            elif self.AICode == "RANGEDAPPROACH":
                return self.rangedApproach()

            else:
                raise exc.InvalidDataWarning(
                    "The monster %s has an unknown AICode, %s" % (self.name,
                                                                  self.AICode))
                return action.Wait(self)

        assert False