Exemplo n.º 1
0
 def _near_enough_to_aim(self, target):
     # Melee units (range <= 2) shouldn't attack units
     # on the other side of a wall.
     if not self._can_go(target.x, target.y) \
         and self.range <= 2 * PRECISION \
         and not target.blocked_exit:
             return False
     if self.minimal_range and square_of_distance(self.x, self.y, target.x, target.y) < self.minimal_range * self.minimal_range:
         return False
     d = target.aim_range(self)
     return square_of_distance(self.x, self.y, target.x, target.y) < d * d
Exemplo n.º 2
0
 def update(self):
     x, y = self.target
     u = self.unit
     subsquare = u.world.get_subsquare_id_from_xy
     d2 = square_of_distance(x, y, u.x, u.y)
     if subsquare(x, y) != subsquare(u.x, u.y):
         if u.go_to_xy(x, y):
             self.complete()
     else:
         # try as long as the distance is decreasing
         previous_d2 = square_of_distance(x, y, u.x, u.y)
         if u.go_to_xy(
                 x, y) or square_of_distance(x, y, u.x, u.y) > previous_d2:
             self.complete()
Exemplo n.º 3
0
 def object_from_mousepos(self, pos):
     self._update_coefs()
     x, y = pos
     for o in self.interface.dobjets.values():
         xo, yo = self._object_coords(o)
         if square_of_distance(x, y, xo, yo) <= R2 + 1:  # XXX + 1 ?
             return o
Exemplo n.º 4
0
 def object_from_mousepos(self, pos):
     self._update_coefs()
     x, y = pos
     for o in self.interface.dobjets.values():
         xo, yo = self._object_coords(o)
         if square_of_distance(x, y, xo, yo) <= R2 + 1: # is + 1 necessary?
             return o
Exemplo n.º 5
0
 def _near_enough_to_aim(self, target):
     # Melee units shouldn't attack units on the other side of a wall.
     if self.is_melee and not self._can_go(
             target.place) and not target.blocked_exit:
         return False
     if self.minimal_range and square_of_distance(
             self.x, self.y, target.x,
             target.y) < self.minimal_range * self.minimal_range:
         return False
     range = self.range
     if self.is_ballistic and self.height > target.height:
         # each height difference has a bonus of 1
         bonus = (self.height - target.height) * PRECISION * 1
         range += bonus
     d = max(self.radius + DISTANCE_MARGIN, range) + target.radius
     return square_of_distance(self.x, self.y, target.x, target.y) < d * d
Exemplo n.º 6
0
 def _already_walked(self, x, y):
     n = 0
     radius_2 = self.radius * self.radius
     for lw, xw, yw, weight in self.walked:
         if self.place is lw and square_of_distance(x, y, xw, yw) < radius_2:
             n += weight
     return n
Exemplo n.º 7
0
 def _choose_enemy(self, place):
     known = self.player.known_enemies(place)
     reachable_enemies = [x for x in known if self.can_attack(x)]
     if reachable_enemies:
         reachable_enemies.sort(key=lambda x: (
             -x.menace, square_of_distance(self.x, self.y, x.x, x.y), x.id))
         self.action = AttackAction(self, reachable_enemies[0])
         return True
Exemplo n.º 8
0
 def _choose_enemy(self, place):
     known = self.player.known_enemies(place)
     reachable_enemies = [x for x in known if self.can_attack(x)]
     if reachable_enemies:
         reachable_enemies.sort(key=lambda x: (- x.value, square_of_distance(self.x, self.y, x.x, x.y), x.id))
         self.action_target = reachable_enemies[0] # attack nearest
         self.notify("attack") # XXX move this into set_action_target()?
         return True
Exemplo n.º 9
0
 def splash_aim(self, target):
     damage_radius_2 = self.damage_radius * self.damage_radius
     for o in target.place.objects[:]:
         if not self.is_an_enemy(o) and o is not target:
             pass  # no friendly fire (unless o is the target)
         elif isinstance(o, Creature) \
            and square_of_distance(o.x, o.y, target.x, target.y) <= damage_radius_2 \
            and self.can_attack_if_in_range(o):
             self._hit_or_miss(o)
Exemplo n.º 10
0
 def splash_aim(self, target):
     damage_radius_2 = self.damage_radius * self.damage_radius
     for o in target.place.objects[:]:
         if not self.is_an_enemy(o):
             pass  # no friendly fire
         elif isinstance(o, Creature) \
            and square_of_distance(o.x, o.y, target.x, target.y) <= damage_radius_2 \
            and self.can_attack_if_in_range(o):
             self.hit(o)
Exemplo n.º 11
0
 def _is_seeing(self, u):
     if (u.is_invisible or u.is_cloaked) and u not in self.detected_units:
         return
     x = u.x
     y = u.y
     for avp in self.allied_vision:
         for avu in self._potential_neighbors(x, y):
             radius2 = avu.sight_range * avu.sight_range
             if (square_of_distance(avu.x, avu.y, x, y) < radius2
                 and (avu.sight_range >= self.world.square_width
                      or u.place in avu.get_observed_squares())):
                 return True
Exemplo n.º 12
0
 def _is_seeing(self, u):
     if (u.is_invisible or u.is_cloaked) and u not in self.detected_units:
         return
     x = u.x
     y = u.y
     for avp in self.allied_vision:
         for avu in self._potential_neighbors(x, y):
             radius2 = avu.sight_range * avu.sight_range
             if (square_of_distance(avu.x, avu.y, x, y) < radius2
                     and (avu.sight_range >= self.world.square_width
                          or u.place in avu.get_observed_squares())):
                 return True
Exemplo n.º 13
0
 def _near_enough(self, target):
     # note: always returns False if the target is a square
     if target.place is self.place:
         d = self.radius + target.radius + DISTANCE_MARGIN
         return square_of_distance(self.x, self.y, target.x,
                                   target.y) < d * d
Exemplo n.º 14
0
 def nearest_water(self):
     places = [sq for sq in self.place.strict_neighbors if sq.is_water]
     if places:
         return min(
             places,
             key=lambda sq: square_of_distance(sq.x, sq.y, self.x, self.y))
Exemplo n.º 15
0
 def _near_enough_to_use(self, target):
     if self.is_an_enemy(target):
         return self._near_enough_to_aim(target)
     elif target.place is self.place:
         d = target.use_range(self)
         return square_of_distance(self.x, self.y, target.x, target.y) < d * d