def act(self, game_actions, alert_coord): self.actions = game_actions if self.creature in self.ai_state: chase_coord, chase_vector = self.ai_state[self.creature] else: chase_coord, chase_vector = None, None if self.actions.target_in_sight(alert_coord): # passive actions if chase_coord is not None and chase_coord != alert_coord: chase_vector = get_vector(chase_coord, alert_coord) chase_coord = alert_coord # actions if self.actions.can_reach(alert_coord): feedback = self.actions.attack( get_vector(self.coord, alert_coord)) else: feedback = self._move_towards(alert_coord) else: # chasing and already at the target square and has a chase vector to pursue if chase_coord == self.coord: if chase_vector is not None: # resize the chase vector to the creatures sight so the self.creature can just go there chase_vector = resize_vector_to_len( chase_vector, self.creature.sight) # calculate a new target square overarching_target = add_vector(self.coord, chase_vector) chase_coord = self.level.get_last_pathable_coord( self.coord, overarching_target) # if an obstacle is hit end chase if self.coord == chase_coord: chase_coord, chase_vector = None, None else: chase_coord = None # actions if chase_coord is not None: feedback = self._move_towards(chase_coord) else: feedback = self._move_random() if chase_coord is not None or chase_vector is not None: self.ai_state[self.creature] = chase_coord, chase_vector else: self.remove_creature_state(self.creature) assert feedback.type not in ActionError, \ "AI state bug. Got error from game: {} {}".format(feedback.type, feedback.params)
def act(self, game_actions, alert_coord): self.actions = game_actions if self.creature in self.ai_state: chase_coord, chase_vector = self.ai_state[self.creature] else: chase_coord, chase_vector = None, None if self.actions.target_in_sight(alert_coord): # passive actions if chase_coord is not None and chase_coord != alert_coord: chase_vector = get_vector(chase_coord, alert_coord) chase_coord = alert_coord # actions if self.actions.can_reach(alert_coord): feedback = self.actions.attack(get_vector(self.coord, alert_coord)) else: feedback = self._move_towards(alert_coord) else: # chasing and already at the target square and has a chase vector to pursue if chase_coord == self.coord: if chase_vector is not None: # resize the chase vector to the creatures sight so the self.creature can just go there chase_vector = resize_vector_to_len(chase_vector, self.creature.sight) # calculate a new target square overarching_target = add_vector(self.coord, chase_vector) chase_coord = self.level.get_last_pathable_coord(self.coord, overarching_target) # if an obstacle is hit end chase if self.coord == chase_coord: chase_coord, chase_vector = None, None else: chase_coord = None # actions if chase_coord is not None: feedback = self._move_towards(chase_coord) else: feedback = self._move_random() if chase_coord is not None or chase_vector is not None: self.ai_state[self.creature] = chase_coord, chase_vector else: self.remove_creature_state(self.creature) assert feedback.type not in ActionError, \ "AI state bug. Got error from game: {} {}".format(feedback.type, feedback.params)
def _calculate_next_direction(self, old_direction, walk_type): if walk_type == WALK_IN_PLACE: return old_direction elif walk_type == CORRIDOR: forward_dirs, orthogonal_dirs, ignored_dirs = self._get_corridor_candidate_dirs(old_direction) if len(forward_dirs) == 1: new_direction = forward_dirs.pop() return new_direction elif len(forward_dirs) > 1 and len(orthogonal_dirs) == 1: new_direction = orthogonal_dirs.pop() if all(get_vector(new_direction, other) in Dir.AllPlusStay for other in forward_dirs): return new_direction else: forward = self._passable(old_direction) sides = self._get_side_passables(old_direction) if forward and sides == walk_type: return old_direction return None
def _calculate_next_direction(self, old_direction, walk_type): if walk_type == WALK_IN_PLACE: return old_direction elif walk_type == CORRIDOR: forward_dirs, orthogonal_dirs, ignored_dirs = self._get_corridor_candidate_dirs( old_direction) if len(forward_dirs) == 1: new_direction = forward_dirs.pop() return new_direction elif len(forward_dirs) > 1 and len(orthogonal_dirs) == 1: new_direction = orthogonal_dirs.pop() if all( get_vector(new_direction, other) in Dir.AllPlusStay for other in forward_dirs): return new_direction else: forward = self._passable(old_direction) sides = self._get_side_passables(old_direction) if forward and sides == walk_type: return old_direction return None
def can_reach(self, target_coord): """Free action.""" return (self.coord == target_coord or get_vector(self.coord, target_coord) in Dir.All)