mirror of
https://github.com/dcs-liberation/dcs_liberation.git
synced 2025-11-10 14:22:26 +00:00
Ground Object and Sam sites locations are chosen from a set of preset location when possible.
This commit is contained in:
parent
7535013848
commit
3ff36c45aa
22
gen/locations/preset_control_point_locations.py
Normal file
22
gen/locations/preset_control_point_locations.py
Normal 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)
|
||||||
59
gen/locations/preset_location_finder.py
Normal file
59
gen/locations/preset_location_finder.py
Normal 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)
|
||||||
15
gen/locations/preset_locations.py
Normal file
15
gen/locations/preset_locations.py
Normal 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
|
||||||
BIN
resources/mizdata/caucasus/Anapa-Vityazevo.miz
Normal file
BIN
resources/mizdata/caucasus/Anapa-Vityazevo.miz
Normal file
Binary file not shown.
BIN
resources/mizdata/caucasus/Batumi.miz
Normal file
BIN
resources/mizdata/caucasus/Batumi.miz
Normal file
Binary file not shown.
BIN
resources/mizdata/caucasus/Beslan.miz
Normal file
BIN
resources/mizdata/caucasus/Beslan.miz
Normal file
Binary file not shown.
BIN
resources/mizdata/caucasus/Gelendzhik.miz
Normal file
BIN
resources/mizdata/caucasus/Gelendzhik.miz
Normal file
Binary file not shown.
BIN
resources/mizdata/caucasus/Gudauta.miz
Normal file
BIN
resources/mizdata/caucasus/Gudauta.miz
Normal file
Binary file not shown.
BIN
resources/mizdata/caucasus/Kobuleti.miz
Normal file
BIN
resources/mizdata/caucasus/Kobuleti.miz
Normal file
Binary file not shown.
BIN
resources/mizdata/caucasus/Krasnodar-Center.miz
Normal file
BIN
resources/mizdata/caucasus/Krasnodar-Center.miz
Normal file
Binary file not shown.
BIN
resources/mizdata/caucasus/Krasnodar-Pashkovsky.miz
Normal file
BIN
resources/mizdata/caucasus/Krasnodar-Pashkovsky.miz
Normal file
Binary file not shown.
BIN
resources/mizdata/caucasus/Krymsk.miz
Normal file
BIN
resources/mizdata/caucasus/Krymsk.miz
Normal file
Binary file not shown.
BIN
resources/mizdata/caucasus/Kutaisi.miz
Normal file
BIN
resources/mizdata/caucasus/Kutaisi.miz
Normal file
Binary file not shown.
BIN
resources/mizdata/caucasus/Maykop-Khanskaya.miz
Normal file
BIN
resources/mizdata/caucasus/Maykop-Khanskaya.miz
Normal file
Binary file not shown.
BIN
resources/mizdata/caucasus/Mineralnye Vody.miz
Normal file
BIN
resources/mizdata/caucasus/Mineralnye Vody.miz
Normal file
Binary file not shown.
BIN
resources/mizdata/caucasus/Mozdok.miz
Normal file
BIN
resources/mizdata/caucasus/Mozdok.miz
Normal file
Binary file not shown.
BIN
resources/mizdata/caucasus/Nalchik.miz
Normal file
BIN
resources/mizdata/caucasus/Nalchik.miz
Normal file
Binary file not shown.
BIN
resources/mizdata/caucasus/Novorossiysk.miz
Normal file
BIN
resources/mizdata/caucasus/Novorossiysk.miz
Normal file
Binary file not shown.
BIN
resources/mizdata/caucasus/Senaki-Kolkhi.miz
Normal file
BIN
resources/mizdata/caucasus/Senaki-Kolkhi.miz
Normal file
Binary file not shown.
BIN
resources/mizdata/caucasus/Sochi-Adler.miz
Normal file
BIN
resources/mizdata/caucasus/Sochi-Adler.miz
Normal file
Binary file not shown.
BIN
resources/mizdata/caucasus/Sukhumi-Babushara.miz
Normal file
BIN
resources/mizdata/caucasus/Sukhumi-Babushara.miz
Normal file
Binary file not shown.
BIN
resources/mizdata/caucasus/Vaziani.miz
Normal file
BIN
resources/mizdata/caucasus/Vaziani.miz
Normal file
Binary file not shown.
BIN
resources/mizdata/syria/Eyn Shemer.miz
Normal file
BIN
resources/mizdata/syria/Eyn Shemer.miz
Normal file
Binary file not shown.
BIN
resources/mizdata/syria/Khalkhalah Defenses.miz
Normal file
BIN
resources/mizdata/syria/Khalkhalah Defenses.miz
Normal file
Binary file not shown.
BIN
resources/mizdata/syria/King Hussein Air College.miz
Normal file
BIN
resources/mizdata/syria/King Hussein Air College.miz
Normal file
Binary file not shown.
@ -21,6 +21,8 @@ from gen.fleet.ship_group_generator import (
|
|||||||
generate_lha_group,
|
generate_lha_group,
|
||||||
generate_ship_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.missiles.missiles_group_generator import generate_missile_group
|
||||||
from gen.sam.sam_group_generator import (
|
from gen.sam.sam_group_generator import (
|
||||||
generate_anti_air_group,
|
generate_anti_air_group,
|
||||||
@ -163,6 +165,7 @@ class ControlPointGroundObjectGenerator:
|
|||||||
def __init__(self, game: Game, control_point: ControlPoint) -> None:
|
def __init__(self, game: Game, control_point: ControlPoint) -> None:
|
||||||
self.game = game
|
self.game = game
|
||||||
self.control_point = control_point
|
self.control_point = control_point
|
||||||
|
self.preset_locations = PresetLocationFinder.compute_possible_locations(game.theater.terrain.name, control_point.full_name)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def faction_name(self) -> str:
|
def faction_name(self) -> str:
|
||||||
@ -217,6 +220,27 @@ class ControlPointGroundObjectGenerator:
|
|||||||
g.groups.append(group)
|
g.groups.append(group)
|
||||||
self.control_point.connected_objectives.append(g)
|
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):
|
class CarrierGroundObjectGenerator(ControlPointGroundObjectGenerator):
|
||||||
def generate(self) -> bool:
|
def generate(self) -> bool:
|
||||||
@ -383,10 +407,20 @@ class AirbaseGroundObjectGenerator(ControlPointGroundObjectGenerator):
|
|||||||
|
|
||||||
obj_name = namegen.random_objective_name()
|
obj_name = namegen.random_objective_name()
|
||||||
template = random.choice(list(self.templates[category].values()))
|
template = random.choice(list(self.templates[category].values()))
|
||||||
point = find_location(category != "oil",
|
|
||||||
self.control_point.position,
|
offshore = category == "oil"
|
||||||
self.game.theater, 10000, 40000,
|
|
||||||
self.control_point.ground_objects)
|
# 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:
|
if point is None:
|
||||||
logging.error(
|
logging.error(
|
||||||
@ -409,9 +443,17 @@ class AirbaseGroundObjectGenerator(ControlPointGroundObjectGenerator):
|
|||||||
|
|
||||||
def generate_aa_site(self) -> None:
|
def generate_aa_site(self) -> None:
|
||||||
obj_name = namegen.random_objective_name()
|
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.game.theater, 10000, 40000,
|
||||||
self.control_point.ground_objects)
|
self.control_point.ground_objects)
|
||||||
|
else:
|
||||||
|
position = location.position
|
||||||
|
|
||||||
if position is None:
|
if position is None:
|
||||||
logging.error(
|
logging.error(
|
||||||
@ -432,9 +474,20 @@ class AirbaseGroundObjectGenerator(ControlPointGroundObjectGenerator):
|
|||||||
self.generate_missile_site()
|
self.generate_missile_site()
|
||||||
|
|
||||||
def generate_missile_site(self) -> None:
|
def generate_missile_site(self) -> None:
|
||||||
point = find_location(True, self.control_point.position,
|
|
||||||
self.game.theater, 2500, 40000, [], False)
|
# Pick from preset locations
|
||||||
if point is None:
|
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(
|
logging.info(
|
||||||
f"Could not find point for {self.control_point} missile site")
|
f"Could not find point for {self.control_point} missile site")
|
||||||
return
|
return
|
||||||
@ -442,7 +495,7 @@ class AirbaseGroundObjectGenerator(ControlPointGroundObjectGenerator):
|
|||||||
group_id = self.game.next_group_id()
|
group_id = self.game.next_group_id()
|
||||||
|
|
||||||
g = MissileSiteGroundObject(namegen.random_objective_name(), 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)
|
group = generate_missile_group(self.game, g, self.faction_name)
|
||||||
g.groups = []
|
g.groups = []
|
||||||
if group is not None:
|
if group is not None:
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user