def generate_tgo_for_scenery(self, scenery: SceneryGroup) -> None: # Special Handling for scenery Objects based on trigger zones g = BuildingGroundObject( namegen.random_objective_name(), scenery.category, scenery.position, Heading.from_degrees(0), self.control_point, ) ground_group = TheaterGroup( self.game.next_group_id(), scenery.zone_def.name, PointWithHeading.from_point(scenery.position, Heading.from_degrees(0)), [], g, ) g.groups.append(ground_group) # Each nested trigger zone is a target/building/unit for an objective. for zone in scenery.zones: scenery_unit = SceneryUnit( zone.id, zone.name, dcs.statics.Fortification.White_Flag, PointWithHeading.from_point(zone.position, Heading.from_degrees(0)), g, ) scenery_unit.zone = zone ground_group.units.append(scenery_unit) self.control_point.connected_objectives.append(g)
def _find_random_position( self, min_range: int, max_range: int, on_ground: bool, is_base_defense: bool, avoid_others: bool, ) -> Optional[PointWithHeading]: """ Find a valid ground object location :param on_ground: Whether it should be on ground or on sea (True = on ground) :param min_range: Minimal range from point :param max_range: Max range from point :param is_base_defense: True if the location is for base defense. :return: """ near = self.control_point.position others = self.control_point.ground_objects def is_valid(point: Optional[PointWithHeading]) -> bool: if point is None: return False if on_ground and not self.game.theater.is_on_land(point): return False elif not on_ground and not self.game.theater.is_in_sea(point): return False if avoid_others: for other in others: if other.position.distance_to_point(point) < 10000: return False if is_base_defense: # If it's a base defense we don't care how close it is to other # points. return True # Else verify that it's not too close to another control point. for control_point in self.game.theater.controlpoints: if control_point != self.control_point: if control_point.position.distance_to_point(point) < 30000: return False for ground_obj in control_point.ground_objects: if ground_obj.position.distance_to_point( point) < 10000: return False return True for _ in range(300): # Check if on land or sea p = PointWithHeading.from_point( near.random_point_within(max_range, min_range), random.randint(0, 360)) if is_valid(p): return p return None
def random_from_miz_data(self, offshore: bool) -> Optional[PointWithHeading]: if offshore: locations = self.miz_data.offshore_locations else: locations = self.miz_data.ashore_locations if self.miz_data.offshore_locations: preset = random.choice(locations) locations.remove(preset) return PointWithHeading.from_point(preset.position, preset.heading) return None
def generate(self) -> bool: if not super().generate(): return False lha_names = self.faction.helicopter_carrier_names if not lha_names: logging.info( f"Skipping generation of {self.control_point.name} because " f"{self.faction_name} has no LHAs") return False unit_group = self.armed_forces.random_group_for_task( GroupTask.HELICOPTER_CARRIER) if not unit_group: logging.error( f"{self.faction_name} has no access to HelicopterCarrier") return False self.generate_ground_object_from_group( unit_group, PointWithHeading.from_point(self.control_point.position, self.control_point.heading), ) self.control_point.name = random.choice(lha_names) return True
def generate_fob(self) -> None: self.generate_building_at( GroupTask.FOB, PointWithHeading.from_point(self.control_point.position, self.control_point.heading), )