def sa10_site(mission: Mission, position: mapping.Point, heading, prefix="", skill=unit.Skill.Average): russia = mission.country("Russia") vg = mission.vehicle_group(russia, prefix + "SA10 site", Russia.Vehicle.AirDefence.S_300PS_64H6E_sr, position, heading) u = mission.vehicle("Operator 1", Russia.Vehicle.Infantry.Paratrooper_AKS_74) u.position = position.point_from_heading(heading + 180, 10) u.heading = heading vg.add_unit(u) hdg = 90 for i in range(0, 3): # 3 launchers u = mission.vehicle("launcher #" + str(i + 1), Russia.Vehicle.AirDefence.S_300PS_5P85C_ln) u.position = position.point_from_heading(heading + hdg, 50) u.heading = heading vg.add_unit(u) hdg += 90 u = mission.vehicle("radar", Russia.Vehicle.AirDefence.S_300PS_40B6M_tr) u.position = position.point_from_heading(heading, 80) u.heading = heading vg.add_unit(u) u = mission.vehicle("radar", Russia.Vehicle.AirDefence.S_300PS_54K6_cp) u.position = position.point_from_heading(heading + 180, 100) u.heading = heading vg.add_unit(u) for u in vg.units: u.skill = skill return vg
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 extend_ground_position( cls, initial: Point, max_distance: int, heading: Heading, theater: ConflictTheater, ) -> Point: """Finds the first intersection with an exclusion zone in one heading from an initial point up to max_distance""" extended = initial.point_from_heading(heading.degrees, max_distance) if theater.landmap is None: # TODO: Why is this possible? return extended p0 = ShapelyPoint(initial.x, initial.y) p1 = ShapelyPoint(extended.x, extended.y) line = LineString([p0, p1]) intersection = line.intersection( theater.landmap.inclusion_zone_only.boundary) if intersection.is_empty: # Max extent does not intersect with the boundary of the inclusion # zone, so the full front line is usable. This does assume that the # front line was centered on a valid location. return extended # Otherwise extend the front line only up to the intersection. return initial.point_from_heading(heading.degrees, p0.distance(intersection))
def sa10_site(mission: Mission, position: mapping.Point, heading, prefix="", skill=unit.Skill.Average): russia = mission.country("Russia") vg = mission.vehicle_group(russia, prefix + "SA10 site", Russia.Vehicle.AirDefence.SAM_SA_10_S_300PS_CP_54K6, position, heading) u = mission.vehicle("Operator 1", Russia.Vehicle.Infantry.Infantry_Soldier_Rus) u.position = position.point_from_heading(heading + 180, 10) u.heading = heading vg.add_unit(u) hdg = 90 for i in range(0, 3): # 3 launchers u = mission.vehicle("launcher #" + str(i + 1), Russia.Vehicle.AirDefence.SAM_SA_10_S_300PS_LN_5P85C) u.position = position.point_from_heading(heading + hdg, 50) u.heading = heading vg.add_unit(u) hdg += 90 u = mission.vehicle("radar", Russia.Vehicle.AirDefence.SAM_SA_10_S_300PS_TR_30N6) u.position = position.point_from_heading(heading, 80) u.heading = heading vg.add_unit(u) u = mission.vehicle("radar", Russia.Vehicle.AirDefence.SAM_SA_10_S_300PS_SR_64H6E) u.position = position.point_from_heading(heading + 180, 100) u.heading = heading vg.add_unit(u) for u in vg.units: u.skill = skill return vg
def sa10_site(mission: Mission, position: mapping.Point, heading, prefix="", skill=unit.Skill.Average): russia = mission.country("Russia") vg = mission.vehicle_group(russia, prefix + "SA10 site", Russia.Vehicle.AirDefence.SAM_SA_10_S_300_Grumble_Big_Bird_SR, position, heading) u = mission.vehicle("Operator 1", Russia.Vehicle.Infantry.Infantry_AK_74_Rus) u.position = position.point_from_heading(heading + 180, 10) u.heading = heading vg.add_unit(u) hdg = 90 for i in range(0, 3): # 3 launchers u = mission.vehicle("launcher #" + str(i + 1), Russia.Vehicle.AirDefence.SAM_SA_10_S_300_Grumble_TEL_C) u.position = position.point_from_heading(heading + hdg, 50) u.heading = heading vg.add_unit(u) hdg += 90 u = mission.vehicle("radar", Russia.Vehicle.AirDefence.SAM_SA_10_S_300_Grumble_Flap_Lid_TR) u.position = position.point_from_heading(heading, 80) u.heading = heading vg.add_unit(u) u = mission.vehicle("radar", Russia.Vehicle.AirDefence.SAM_SA_10_S_300_Grumble_C2) u.position = position.point_from_heading(heading + 180, 100) u.heading = heading vg.add_unit(u) for u in vg.units: u.skill = skill return vg
def extend_ground_position(cls, initial: Point, max_distance: int, heading: int, theater: ConflictTheater) -> Point: """Finds the first intersection with an exclusion zone in one heading from an initial point up to max_distance""" pos = initial for distance in range(0, int(max_distance), 100): pos = initial.point_from_heading(heading, distance) if not theater.is_on_land(pos): return initial.point_from_heading(heading, distance - 100) return pos
def generate_transportation_destination(self, at: Point): self.generate_transportation_marker(at.point_from_heading(0, 20)) self.mission.static_group(self.mission.country( self.game.player_country), "", _type=Outpost, position=at)
def nearest_land_pos(self, point: Point, extend_dist: int = 50) -> Point: """Returns the nearest point inside a land exclusion zone from point `extend_dist` determines how far inside the zone the point should be placed""" if self.is_on_land(point): return point point = geometry.Point(point.x, point.y) nearest_points = [] if not self.landmap: raise RuntimeError("Landmap not initialized") for inclusion_zone in self.landmap[0]: nearest_pair = ops.nearest_points(point, inclusion_zone) nearest_points.append(nearest_pair[1]) min_distance = point.distance( nearest_points[0]) # type: geometry.Point nearest_point = nearest_points[0] # type: geometry.Point for pt in nearest_points[1:]: distance = point.distance(pt) if distance < min_distance: min_distance = distance nearest_point = pt assert isinstance(nearest_point, geometry.Point) point = Point(point.x, point.y) nearest_point = Point(nearest_point.x, nearest_point.y) new_point = point.point_from_heading( point.heading_between_point(nearest_point), point.distance_to_point(nearest_point) + extend_dist) return new_point
def get_valid_position_for_group(self, conflict_position: Point, combat_width: int, distance_from_frontline: int, heading: int, spawn_heading: int): shifted = conflict_position.point_from_heading( heading, random.randint(0, combat_width)) desired_point = shifted.point_from_heading(spawn_heading, distance_from_frontline) return Conflict.find_ground_position(desired_point, combat_width, heading, self.conflict.theater)
def _extend_ground_position(cls, initial: Point, max_distance: int, heading: int, theater: ConflictTheater) -> Point: pos = initial for offset in range(0, int(max_distance), 500): new_pos = initial.point_from_heading(heading, offset) if theater.is_on_land(new_pos): pos = new_pos else: return pos return pos """
def intercept_conflict(cls, attacker_name: str, defender_name: str, attacker: Country, defender: Country, position: Point, from_cp: ControlPoint, to_cp: ControlPoint, theater: ConflictTheater): heading = from_cp.position.heading_between_point(position) return cls(position=position.point_from_heading( position.heading_between_point(to_cp.position), INTERCEPT_CONFLICT_DISTANCE), theater=theater, from_cp=from_cp, to_cp=to_cp, attackers_side=attacker_name, defenders_side=defender_name, attackers_country=attacker, defenders_country=defender, ground_attackers_location=None, ground_defenders_location=None, air_attackers_location=position.point_from_heading( random.randint(*INTERCEPT_ATTACKERS_HEADING) + heading, INTERCEPT_ATTACKERS_DISTANCE), air_defenders_location=position)
def naval_intercept_conflict(cls, attacker_name: str, defender_name: str, attacker: Country, defender: Country, position: Point, from_cp: ControlPoint, to_cp: ControlPoint, theater: ConflictTheater): attacker_heading = from_cp.position.heading_between_point( to_cp.position) return cls(position=position, theater=theater, from_cp=from_cp, to_cp=to_cp, attackers_side=attacker_name, defenders_side=defender_name, attackers_country=attacker, defenders_country=defender, ground_attackers_location=None, ground_defenders_location=position, air_attackers_location=position.point_from_heading( attacker_heading, AIR_DISTANCE), air_defenders_location=position.point_from_heading( _opposite_heading(attacker_heading), AIR_DISTANCE))
def add_oblong( self, p1: Point, p2: Point, radius: float, color=Rgba(255, 0, 0, 255), fill=Rgba(255, 0, 0, 60), line_thickness=4, line_style=LineStyle.Solid, resolution=20, ) -> FreeFormPolygon: hdg_p1_p2 = p1.heading_between_point(p2) points: List[Point] = [] for i in range(0, resolution + 1): hdg = hdg_p1_p2 - 90 + i * (180 / resolution) points.append(p2.point_from_heading(hdg, radius)) for i in range(0, resolution + 1): hdg = hdg_p1_p2 + 90 + i * (180 / resolution) points.append(p1.point_from_heading(hdg, radius)) # Copy first point and insert last to close the polygon points.append(points[0] * 1) # Transform points to local coordinates startPoint = points[0] * 1 # Copy for point in points: point.x -= startPoint.x point.y -= startPoint.y polygon = self.add_freeform_polygon( startPoint, points, color=color, fill=fill, line_thickness=line_thickness, line_style=line_style, ) return polygon
def get_valid_position_for_group( self, conflict_position: Point, combat_width: int, distance_from_frontline: int, heading: Heading, spawn_heading: Heading, ) -> Optional[Point]: shifted = conflict_position.point_from_heading( heading.degrees, random.randint(0, combat_width)) desired_point = shifted.point_from_heading(spawn_heading.degrees, distance_from_frontline) return FrontLineConflictDescription.find_ground_position( desired_point, combat_width, heading, self.conflict.theater)
def make_sa2_site(mission: Mission, country, center_pos: mapping.Point, orientation=0, size=50, num_launchers=5): fan_song_class = vehicles.AirDefence.SAM_SA_2_TR_SNR_75_Fan_Song ln_class = vehicles.AirDefence.SAM_SA_2_LN_SM_90 name = namegen.next_unit_name(country) vg = mission.vehicle_group(country, name, fan_song_class, center_pos, orientation) for ii in range(num_launchers): ln = mission.vehicle(namegen.next_unit_name(country), ln_class) heading = orientation + 360.0 * ii / num_launchers ln.position = center_pos.point_from_heading(heading, size) ln.heading = heading vg.add_unit(ln) return vg
def _advancing_rendezvous_point(self, attack_transition: Point) -> Point: """Creates a rendezvous point that advances toward the target.""" heading = self._heading_to_package_airfield(attack_transition) return attack_transition.point_from_heading( heading, -self.doctrine.join_distance)
def _split_point(self, egress_point: Point) -> Point: heading = self._heading_to_package_airfield(egress_point) return egress_point.point_from_heading(heading, -self.doctrine.split_distance)
def _retreating_rendezvous_point(self, attack_transition: Point) -> Point: """Creates a rendezvous point that retreats from the origin airfield.""" return attack_transition.point_from_heading( self.package.target.position.heading_between_point( self.package_airfield().position), self.doctrine.join_distance)
def _join_point(self, ingress_point: Point) -> Point: heading = self._heading_to_package_airfield(ingress_point) return ingress_point.point_from_heading(heading, -self.doctrine.join_distance)