def _generate_groups( self, groups: List[CombatGroup], frontline_vector: Tuple[Point, int, int], is_player: bool, ) -> List[Tuple[VehicleGroup, CombatGroup]]: """Finds valid positions for planned groups and generates a pydcs group for them""" positioned_groups = [] position, heading, combat_width = frontline_vector spawn_heading = ( int(heading_sum(heading, -90)) if is_player else int(heading_sum(heading, 90)) ) country = self.game.player_country if is_player else self.game.enemy_country for group in groups: if group.role == CombatGroupRole.ARTILLERY: distance_from_frontline = ( self.get_artilery_group_distance_from_frontline(group) ) else: distance_from_frontline = random.randint( DISTANCE_FROM_FRONTLINE[group.role][0], DISTANCE_FROM_FRONTLINE[group.role][1], ) final_position = self.get_valid_position_for_group( position, combat_width, distance_from_frontline, heading, spawn_heading ) if final_position is not None: g = self._generate_group( self.mission.country(country), group.units[0], len(group.units), final_position, distance_from_frontline, heading=opposite_heading(spawn_heading), ) if is_player: g.set_skill(self.game.settings.player_skill) else: g.set_skill(self.game.settings.enemy_vehicle_skill) positioned_groups.append((g, group)) if group.role in [CombatGroupRole.APC, CombatGroupRole.IFV]: self.gen_infantry_group_for_group( g, is_player, self.mission.country(country), opposite_heading(spawn_heading), ) else: logging.warning(f"Unable to get valid position for {group}") return positioned_groups
def find_ground_position( cls, initial: Point, max_distance: int, heading: int, theater: ConflictTheater, coerce=True, ) -> Optional[Point]: """ Finds the nearest valid ground position along a provided heading and it's inverse up to max_distance. `coerce=True` will return the closest land position to `initial` regardless of heading or distance `coerce=False` will return None if a point isn't found """ pos = initial if theater.is_on_land(pos): return pos for distance in range(0, int(max_distance), 100): pos = initial.point_from_heading(heading, distance) if theater.is_on_land(pos): return pos pos = initial.point_from_heading(opposite_heading(heading), distance) if coerce: pos = theater.nearest_land_pos(initial) return pos logging.error("Didn't find ground position ({})!".format(initial)) return None
def frontline_position(cls, from_cp: ControlPoint, to_cp: ControlPoint, theater: ConflictTheater) -> Tuple[Point, int]: frontline = FrontLine(from_cp, to_cp, theater) attack_heading = frontline.attack_heading position = cls.find_ground_position(frontline.position, FRONTLINE_LENGTH, heading_sum(attack_heading, 90), theater) return position, opposite_heading(attack_heading)
def frontline_position(cls, frontline: FrontLine, theater: ConflictTheater) -> Tuple[Point, int]: attack_heading = int(frontline.attack_heading) position = cls.find_ground_position( frontline.position, FRONTLINE_LENGTH, heading_sum(attack_heading, 90), theater, ) if position is None: raise RuntimeError("Could not find front line position") return position, opposite_heading(attack_heading)