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
def recalculate(self, level_, initial_location): """ Set this fov to the squares seen from initial_location on level_. level_ - The level on which the field of view is being calculated. initial_location - the viewpoint from which the field of view is being calculated. """ dimensions = level_.dimensions border = set() fov_set = set() dude_set = set() border.add(initial_location) while len(border) != 0: next_border = set() for i in border: for adjacent in coordinates.adjacent_coords(i): if adjacent in fov_set or adjacent in border or adjacent in next_border: pass elif not coordinates.legal(adjacent, dimensions): pass else: if level_.dungeonGlyph(adjacent) in OPEN_GLYPHS: next_border.add(adjacent) else: fov_set.add(adjacent) if adjacent in level_.dudeLayer: dude_set.add(level_.dudeLayer[adjacent]) fov_set.add(i) border = next_border self.__the_field = fov_set self.dudes = frozenset(dude_set)