Ground Object and Sam sites locations are chosen from a set of preset location when possible.

This commit is contained in:
Khopa 2020-11-10 23:48:27 +01:00
parent 7535013848
commit 3ff36c45aa
26 changed files with 158 additions and 9 deletions

View File

@ -0,0 +1,22 @@
from dataclasses import dataclass, field
from typing import List
from gen.locations.preset_locations import PresetLocation
@dataclass
class PresetControlPointLocations:
"""A repository of preset locations for a given control point"""
# List of possible ashore locations to generate objects (Represented in miz file by an APC_AAV_7)
ashore_locations: List[PresetLocation] = field(default_factory=list)
# List of possible offshore locations to generate ship groups (Represented in miz file by an Oliver Hazard Perry)
offshore_locations: List[PresetLocation] = field(default_factory=list)
# Possible antiship missiles sites locations (Represented in miz file by Iranian Silkworm missiles)
antiship_locations: List[PresetLocation] = field(default_factory=list)
# List of possible powerplants locations (Represented in miz file by static Workshop A object, USA)
powerplant_locations: List[PresetLocation] = field(default_factory=list)

View File

@ -0,0 +1,59 @@
from pathlib import Path
from typing import List
from dcs import Mission
from dcs.vehicles import MissilesSS
from gen.locations.preset_control_point_locations import PresetControlPointLocations
from gen.locations.preset_locations import PresetLocation
class PresetLocationFinder:
@staticmethod
def compute_possible_locations(terrain_name: str, cp_name: str) -> PresetControlPointLocations:
"""
Extract the list of preset locations from miz data
:param terrain_name: Terrain/Map name
:param cp_name: Control Point / Airbase name
:return:
"""
miz_file = Path("./resources/mizdata/", terrain_name.lower(), cp_name + ".miz")
offshore_locations: List[PresetLocation] = []
ashore_locations: List[PresetLocation] = []
powerplants_locations: List[PresetLocation] = []
antiship_locations: List[PresetLocation] = []
if miz_file.exists():
m = Mission()
m.load_file(miz_file.absolute())
for vehicle_group in m.country("USA").vehicle_group:
if len(vehicle_group.units) > 0:
ashore_locations.append(PresetLocation(vehicle_group.position,
vehicle_group.units[0].heading,
vehicle_group.name))
for ship_group in m.country("USA").ship_group:
if len(ship_group.units) > 0:
offshore_locations.append(PresetLocation(ship_group.position,
ship_group.units[0].heading,
ship_group.name))
for static_group in m.country("USA").static_group:
if len(static_group.units) > 0:
powerplants_locations.append(PresetLocation(static_group.position,
static_group.units[0].heading,
static_group.name))
if m.country("Iran") is not None:
for vehicle_group in m.country("Iran").vehicle_group:
if len(vehicle_group.units) > 0 and vehicle_group.units[0].type == MissilesSS.SS_N_2_Silkworm.id:
antiship_locations.append(PresetLocation(vehicle_group.position,
vehicle_group.units[0].heading,
vehicle_group.name))
return PresetControlPointLocations(ashore_locations, offshore_locations,
antiship_locations, powerplants_locations)

View File

@ -0,0 +1,15 @@
from dataclasses import dataclass
from dcs import Point
@dataclass
class PresetLocation:
"""A preset location"""
position: Point
heading: int
id: str
def __str__(self):
return "-" * 10 + "X: {}\n Y: {}\nHdg: {}°\nId: {}".format(self.position.x, self.position.y, self.heading,
self.id) + "-" * 10

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -21,6 +21,8 @@ from gen.fleet.ship_group_generator import (
generate_lha_group,
generate_ship_group,
)
from gen.locations.preset_location_finder import PresetLocationFinder
from gen.locations.preset_locations import PresetLocation
from gen.missiles.missiles_group_generator import generate_missile_group
from gen.sam.sam_group_generator import (
generate_anti_air_group,
@ -163,6 +165,7 @@ class ControlPointGroundObjectGenerator:
def __init__(self, game: Game, control_point: ControlPoint) -> None:
self.game = game
self.control_point = control_point
self.preset_locations = PresetLocationFinder.compute_possible_locations(game.theater.terrain.name, control_point.full_name)
@property
def faction_name(self) -> str:
@ -217,6 +220,27 @@ class ControlPointGroundObjectGenerator:
g.groups.append(group)
self.control_point.connected_objectives.append(g)
def pick_preset_location(self, offshore=False) -> Optional[PresetLocation]:
"""
Return a preset location if any is setup and still available for this point
@:param offshore Whether this should be an offshore location
@:return The preset location if found; None if it couldn't be found
"""
if offshore:
if len(self.preset_locations.offshore_locations) > 0:
location = random.choice(self.preset_locations.offshore_locations)
self.preset_locations.offshore_locations.remove(location)
logging.info("Picked a preset offshore location")
return location
else:
if len(self.preset_locations.ashore_locations) > 0:
location = random.choice(self.preset_locations.ashore_locations)
self.preset_locations.ashore_locations.remove(location)
logging.info("Picked a preset ashore location")
return location
logging.info("No preset location found")
return None
class CarrierGroundObjectGenerator(ControlPointGroundObjectGenerator):
def generate(self) -> bool:
@ -383,10 +407,20 @@ class AirbaseGroundObjectGenerator(ControlPointGroundObjectGenerator):
obj_name = namegen.random_objective_name()
template = random.choice(list(self.templates[category].values()))
point = find_location(category != "oil",
self.control_point.position,
self.game.theater, 10000, 40000,
self.control_point.ground_objects)
offshore = category == "oil"
# Pick from preset locations
location = self.pick_preset_location(offshore)
# Else try the old algorithm
if location is None:
point = find_location(not offshore,
self.control_point.position,
self.game.theater, 10000, 40000,
self.control_point.ground_objects)
else:
point = location.position
if point is None:
logging.error(
@ -409,9 +443,17 @@ class AirbaseGroundObjectGenerator(ControlPointGroundObjectGenerator):
def generate_aa_site(self) -> None:
obj_name = namegen.random_objective_name()
position = find_location(True, self.control_point.position,
# Pick from preset locations
location = self.pick_preset_location(False)
# If no preset location, then try the old algorithm
if location is None:
position = find_location(True, self.control_point.position,
self.game.theater, 10000, 40000,
self.control_point.ground_objects)
else:
position = location.position
if position is None:
logging.error(
@ -432,9 +474,20 @@ class AirbaseGroundObjectGenerator(ControlPointGroundObjectGenerator):
self.generate_missile_site()
def generate_missile_site(self) -> None:
point = find_location(True, self.control_point.position,
self.game.theater, 2500, 40000, [], False)
if point is None:
# Pick from preset locations
location = self.pick_preset_location(False)
# If no preset location, then try the old algorithm
if location is None:
position = find_location(True, self.control_point.position,
self.game.theater, 2500, 40000,
[], False)
else:
position = location.position
if position is None:
logging.info(
f"Could not find point for {self.control_point} missile site")
return
@ -442,7 +495,7 @@ class AirbaseGroundObjectGenerator(ControlPointGroundObjectGenerator):
group_id = self.game.next_group_id()
g = MissileSiteGroundObject(namegen.random_objective_name(), group_id,
point, self.control_point)
position, self.control_point)
group = generate_missile_group(self.game, g, self.faction_name)
g.groups = []
if group is not None: