mirror of
https://github.com/dcs-retribution/dcs-retribution.git
synced 2025-11-10 15:41:24 +00:00
Decoupling and generalization of templates
Improvement for factions and templates which will allow decoupling of the templates from the actual units - Implement UnitGroup class which matches unit_types and possible templates as the needed abstraction layer for decoupling. - Refactor UnitType, Add ShipUnitType and all ships we currently use - Remove serialized template.json and migrated to multiple yaml templates (one for each template) and multiple .miz - Reorganized a lot of templates and started with generalization of many types (AAA, Flak, SHORAD, Navy) - Fixed a lot of bugs from the previous reworks (group name generation, strike targets...) - Reorganized the faction file completly. removed redundant lists, added presets for complex groups / families of units like sams - Reworked the building template handling. Some templates are unused like "village" - Reworked how groups from templates can be merged again for the dcs group creation (e.g. the skynet plugin requires them to be in the same group) - Allow to define alternative tasks
This commit is contained in:
@@ -15,7 +15,7 @@ class BaiIngressBuilder(PydcsWaypointBuilder):
|
||||
target = self.package.target
|
||||
if isinstance(target, TheaterGroundObject):
|
||||
for group in target.groups:
|
||||
group_names.append(group.name)
|
||||
group_names.append(group.group_name)
|
||||
elif isinstance(target, MultiGroupTransport):
|
||||
group_names.append(target.name)
|
||||
elif isinstance(target, NavalControlPoint):
|
||||
|
||||
@@ -20,9 +20,11 @@ class DeadIngressBuilder(PydcsWaypointBuilder):
|
||||
return
|
||||
|
||||
for group in target.groups:
|
||||
miz_group = self.mission.find_group(group.name)
|
||||
miz_group = self.mission.find_group(group.group_name)
|
||||
if miz_group is None:
|
||||
logging.error(f"Could not find group for DEAD mission {group.name}")
|
||||
logging.error(
|
||||
f"Could not find group for DEAD mission {group.group_name}"
|
||||
)
|
||||
continue
|
||||
|
||||
task = AttackGroup(miz_group.id, weapon_type=WeaponType.Auto)
|
||||
|
||||
@@ -20,9 +20,11 @@ class SeadIngressBuilder(PydcsWaypointBuilder):
|
||||
return
|
||||
|
||||
for group in target.groups:
|
||||
miz_group = self.mission.find_group(group.name)
|
||||
miz_group = self.mission.find_group(group.group_name)
|
||||
if miz_group is None:
|
||||
logging.error(f"Could not find group for SEAD mission {group.name}")
|
||||
logging.error(
|
||||
f"Could not find group for SEAD mission {group.group_name}"
|
||||
)
|
||||
continue
|
||||
|
||||
task = AttackGroup(miz_group.id, weapon_type=WeaponType.Guided)
|
||||
|
||||
@@ -28,7 +28,7 @@ from dcs.triggers import Event, TriggerOnce
|
||||
from dcs.unit import Vehicle, Skill
|
||||
from dcs.unitgroup import VehicleGroup
|
||||
|
||||
from game.data.groundunitclass import GroundUnitClass
|
||||
from game.data.units import UnitClass
|
||||
from game.dcs.aircrafttype import AircraftType
|
||||
from game.dcs.groundunittype import GroundUnitType
|
||||
from game.theater.controlpoint import ControlPoint
|
||||
@@ -221,7 +221,7 @@ class FlotGenerator:
|
||||
if self.game.settings.manpads:
|
||||
# 50% of armored units protected by manpad
|
||||
if random.choice([True, False]):
|
||||
manpads = list(faction.infantry_with_class(GroundUnitClass.Manpads))
|
||||
manpads = list(faction.infantry_with_class(UnitClass.Manpad))
|
||||
if manpads:
|
||||
u = random.choices(
|
||||
manpads, weights=[m.spawn_weight for m in manpads]
|
||||
@@ -237,12 +237,10 @@ class FlotGenerator:
|
||||
)
|
||||
return
|
||||
|
||||
possible_infantry_units = set(
|
||||
faction.infantry_with_class(GroundUnitClass.Infantry)
|
||||
)
|
||||
possible_infantry_units = set(faction.infantry_with_class(UnitClass.Infantry))
|
||||
if self.game.settings.manpads:
|
||||
possible_infantry_units |= set(
|
||||
faction.infantry_with_class(GroundUnitClass.Manpads)
|
||||
faction.infantry_with_class(UnitClass.Manpad)
|
||||
)
|
||||
if not possible_infantry_units:
|
||||
return
|
||||
|
||||
@@ -118,7 +118,7 @@ class LuaGenerator:
|
||||
|
||||
faction = "BlueAA" if cp.captured else "RedAA"
|
||||
|
||||
lua_data[faction][g.name] = {
|
||||
lua_data[faction][g.group_name] = {
|
||||
"name": ground_object.name,
|
||||
"range": threat_range.meters,
|
||||
"position": {
|
||||
|
||||
@@ -22,7 +22,6 @@ from typing import (
|
||||
TypeVar,
|
||||
List,
|
||||
Any,
|
||||
Union,
|
||||
)
|
||||
|
||||
from dcs import Mission, Point, unitgroup
|
||||
@@ -110,108 +109,93 @@ class GroundObjectGenerator:
|
||||
logging.warning(f"Found empty group in {self.ground_object}")
|
||||
continue
|
||||
group_name = group.group_name if unique_name else group.name
|
||||
if group.static_group:
|
||||
# Static Group
|
||||
for i, u in enumerate(group.units):
|
||||
if isinstance(u, SceneryGroundUnit):
|
||||
# Special handling for scenery objects:
|
||||
# Only create a trigger zone and no "real" dcs unit
|
||||
self.add_trigger_zone_for_scenery(u)
|
||||
continue
|
||||
moving_group: Optional[MovingGroup[Any]] = None
|
||||
for i, unit in enumerate(group.units):
|
||||
if isinstance(unit, SceneryGroundUnit):
|
||||
# Special handling for scenery objects:
|
||||
# Only create a trigger zone and no "real" dcs unit
|
||||
self.add_trigger_zone_for_scenery(unit)
|
||||
continue
|
||||
|
||||
# Only skip dead units after trigger zone for scenery created!
|
||||
if not u.alive:
|
||||
continue
|
||||
# Only skip dead units after trigger zone for scenery created!
|
||||
if not unit.alive:
|
||||
continue
|
||||
|
||||
unit_type = unit_type_from_name(u.type)
|
||||
if not unit_type:
|
||||
raise RuntimeError(
|
||||
f"Unit type {u.type} is not a valid dcs unit type"
|
||||
)
|
||||
|
||||
sg = self.m.static_group(
|
||||
country=self.country,
|
||||
name=u.unit_name if unique_name else u.name,
|
||||
_type=unit_type,
|
||||
position=u.position,
|
||||
heading=u.position.heading.degrees,
|
||||
dead=not u.alive,
|
||||
unit_type = unit_type_from_name(unit.type)
|
||||
if not unit_type:
|
||||
raise RuntimeError(
|
||||
f"Unit type {unit.type} is not a valid dcs unit type"
|
||||
)
|
||||
self._register_ground_unit(u, sg.units[0])
|
||||
else:
|
||||
# Moving Group
|
||||
moving_group: Optional[MovingGroup[Any]] = None
|
||||
for i, unit in enumerate(group.units):
|
||||
if not unit.alive:
|
||||
continue
|
||||
if unit.type in vehicle_map:
|
||||
# Vehicle Group
|
||||
unit_type = vehicle_map[unit.type]
|
||||
elif unit.type in ship_map:
|
||||
# Ship Group
|
||||
unit_type = ship_map[group.units[0].type]
|
||||
else:
|
||||
raise RuntimeError(
|
||||
f"Unit type {unit.type} is not a valid dcs unit type"
|
||||
)
|
||||
|
||||
unit_name = unit.unit_name if unique_name else unit.name
|
||||
if moving_group is None:
|
||||
# First unit of the group will create the dcs group
|
||||
if issubclass(unit_type, VehicleType):
|
||||
moving_group = self.m.vehicle_group(
|
||||
self.country,
|
||||
group_name,
|
||||
unit_type,
|
||||
position=unit.position,
|
||||
heading=unit.position.heading.degrees,
|
||||
)
|
||||
moving_group.units[0].player_can_drive = True
|
||||
self.enable_eplrs(moving_group, unit_type)
|
||||
if issubclass(unit_type, ShipType):
|
||||
moving_group = self.m.ship_group(
|
||||
self.country,
|
||||
group_name,
|
||||
unit_type,
|
||||
position=unit.position,
|
||||
heading=unit.position.heading.degrees,
|
||||
)
|
||||
if moving_group:
|
||||
moving_group.units[0].name = unit_name
|
||||
self.set_alarm_state(moving_group)
|
||||
self._register_ground_unit(unit, moving_group.units[0])
|
||||
else:
|
||||
raise RuntimeError("DCS Group creation failed")
|
||||
unit_name = unit.unit_name if unique_name else unit.name
|
||||
if moving_group is None or group.static_group:
|
||||
# First unit of the group will create the dcs group
|
||||
if issubclass(unit_type, VehicleType):
|
||||
moving_group = self.m.vehicle_group(
|
||||
self.country,
|
||||
group_name,
|
||||
unit_type,
|
||||
position=unit.position,
|
||||
heading=unit.position.heading.degrees,
|
||||
)
|
||||
moving_group.units[0].player_can_drive = True
|
||||
self.enable_eplrs(moving_group, unit_type)
|
||||
elif issubclass(unit_type, ShipType):
|
||||
moving_group = self.m.ship_group(
|
||||
self.country,
|
||||
group_name,
|
||||
unit_type,
|
||||
position=unit.position,
|
||||
heading=unit.position.heading.degrees,
|
||||
)
|
||||
elif issubclass(unit_type, StaticType):
|
||||
static_group = self.m.static_group(
|
||||
country=self.country,
|
||||
name=unit_name,
|
||||
_type=unit_type,
|
||||
position=unit.position,
|
||||
heading=unit.position.heading.degrees,
|
||||
dead=not unit.alive,
|
||||
)
|
||||
self._register_ground_unit(unit, static_group.units[0])
|
||||
continue
|
||||
|
||||
if moving_group:
|
||||
moving_group.units[0].name = unit_name
|
||||
self.set_alarm_state(moving_group)
|
||||
self._register_ground_unit(unit, moving_group.units[0])
|
||||
else:
|
||||
# Additional Units in the group
|
||||
dcs_unit: Optional[Unit] = None
|
||||
if issubclass(unit_type, VehicleType):
|
||||
dcs_unit = Vehicle(
|
||||
self.m.next_unit_id(),
|
||||
unit_name,
|
||||
unit.type,
|
||||
)
|
||||
dcs_unit.player_can_drive = True
|
||||
elif issubclass(unit_type, ShipType):
|
||||
dcs_unit = Ship(
|
||||
self.m.next_unit_id(),
|
||||
unit_name,
|
||||
unit_type,
|
||||
)
|
||||
if dcs_unit:
|
||||
dcs_unit.position = unit.position
|
||||
dcs_unit.heading = unit.position.heading.degrees
|
||||
moving_group.add_unit(dcs_unit)
|
||||
self._register_ground_unit(unit, dcs_unit)
|
||||
else:
|
||||
raise RuntimeError("DCS Unit creation failed")
|
||||
raise RuntimeError("DCS Group creation failed")
|
||||
else:
|
||||
# Additional Units in the group
|
||||
dcs_unit: Optional[Unit] = None
|
||||
if issubclass(unit_type, VehicleType):
|
||||
dcs_unit = Vehicle(
|
||||
self.m.next_unit_id(),
|
||||
unit_name,
|
||||
unit.type,
|
||||
)
|
||||
dcs_unit.player_can_drive = True
|
||||
elif issubclass(unit_type, ShipType):
|
||||
dcs_unit = Ship(
|
||||
self.m.next_unit_id(),
|
||||
unit_name,
|
||||
unit_type,
|
||||
)
|
||||
if dcs_unit:
|
||||
dcs_unit.position = unit.position
|
||||
dcs_unit.heading = unit.position.heading.degrees
|
||||
moving_group.add_unit(dcs_unit)
|
||||
self._register_ground_unit(unit, dcs_unit)
|
||||
else:
|
||||
raise RuntimeError("DCS Unit creation failed")
|
||||
|
||||
@staticmethod
|
||||
def enable_eplrs(group: VehicleGroup, unit_type: Type[VehicleType]) -> None:
|
||||
if unit_type.eplrs:
|
||||
group.points[0].tasks.append(EPLRS(group.id))
|
||||
|
||||
def set_alarm_state(self, group: Union[ShipGroup, VehicleGroup]) -> None:
|
||||
def set_alarm_state(self, group: MovingGroup[Any]) -> None:
|
||||
if self.game.settings.perf_red_alert_state:
|
||||
group.points[0].tasks.append(OptAlarmState(2))
|
||||
else:
|
||||
@@ -287,7 +271,7 @@ class MissileSiteGenerator(GroundObjectGenerator):
|
||||
# TODO : Should be pre-planned ?
|
||||
# TODO : Add delay to task to spread fire task over mission duration ?
|
||||
for group in self.ground_object.groups:
|
||||
vg = self.m.find_group(group.name)
|
||||
vg = self.m.find_group(group.group_name)
|
||||
if vg is not None:
|
||||
targets = self.possible_missile_targets()
|
||||
if targets:
|
||||
@@ -327,7 +311,7 @@ class MissileSiteGenerator(GroundObjectGenerator):
|
||||
"""
|
||||
site_range = 0
|
||||
for group in self.ground_object.groups:
|
||||
vg = self.m.find_group(group.name)
|
||||
vg = self.m.find_group(group.group_name)
|
||||
if vg is not None:
|
||||
for u in vg.units:
|
||||
if u.type in vehicle_map:
|
||||
@@ -383,7 +367,7 @@ class GenericCarrierGenerator(GroundObjectGenerator):
|
||||
|
||||
ship_group = self.m.ship_group(
|
||||
self.country,
|
||||
group.name,
|
||||
group.group_name if unique_name else group.name,
|
||||
unit_type,
|
||||
position=group.units[0].position,
|
||||
heading=group.units[0].position.heading.degrees,
|
||||
@@ -523,23 +507,20 @@ class CarrierGenerator(GenericCarrierGenerator):
|
||||
|
||||
def tacan_callsign(self) -> str:
|
||||
# TODO: Assign these properly.
|
||||
if self.control_point.name == "Carrier Strike Group 8":
|
||||
return "TRU"
|
||||
else:
|
||||
return random.choice(
|
||||
[
|
||||
"STE",
|
||||
"CVN",
|
||||
"CVH",
|
||||
"CCV",
|
||||
"ACC",
|
||||
"ARC",
|
||||
"GER",
|
||||
"ABR",
|
||||
"LIN",
|
||||
"TRU",
|
||||
]
|
||||
)
|
||||
return random.choice(
|
||||
[
|
||||
"STE",
|
||||
"CVN",
|
||||
"CVH",
|
||||
"CCV",
|
||||
"ACC",
|
||||
"ARC",
|
||||
"GER",
|
||||
"ABR",
|
||||
"LIN",
|
||||
"TRU",
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
class LhaGenerator(GenericCarrierGenerator):
|
||||
|
||||
Reference in New Issue
Block a user