mirror of
https://github.com/dcs-retribution/dcs-retribution.git
synced 2025-11-10 15:41:24 +00:00
- factor out own class for the iadsnetwork within the conflicttheater - This class will handle all Skynet related things - no specific group_name handling necessary in future - make iadsbuilding own TGO class because SAM & EWRs are Vehicle Groups. IADS Elements dont have any groups attached. - added command center, connection node and power source as Ground objects which can be added by the campaign designer - adjust lua generator to support new iads units - parse the campaign yaml to get the iads network information - use the range as fallback if no yaml information was found - complete rewrite of the skynet lua script - allow destruction of iads network to be persistent over all rounds - modified the presetlocation handling: the wrapper PresetLocation for PointWithHeading now stores the original name from the campaign miz to have the ability to process campaign yaml configurations based on the ground unit - Implementation of the UI representation for the IADS Network - Give user the option to enable or disable advanced iads - Extended the layout system: Implement Sub task handling to support PD
185 lines
5.2 KiB
Python
185 lines
5.2 KiB
Python
from __future__ import annotations
|
|
|
|
from dataclasses import dataclass
|
|
from typing import Any, Optional, TYPE_CHECKING, Type
|
|
from enum import Enum
|
|
|
|
from dcs.triggers import TriggerZone
|
|
from dcs.unittype import ShipType, StaticType, UnitType as DcsUnitType, VehicleType
|
|
|
|
from game.data.groups import GroupTask
|
|
from game.dcs.groundunittype import GroundUnitType
|
|
from game.dcs.shipunittype import ShipUnitType
|
|
from game.dcs.unittype import UnitType
|
|
from game.point_with_heading import PointWithHeading
|
|
from game.theater.iadsnetwork.iadsrole import IadsRole
|
|
from game.utils import Heading, Distance
|
|
|
|
if TYPE_CHECKING:
|
|
from game.layout.layout import LayoutUnit
|
|
from game.sim import GameUpdateEvents
|
|
from game.theater import TheaterGroundObject
|
|
|
|
|
|
@dataclass
|
|
class TheaterUnit:
|
|
"""Representation of a single Unit in the Game"""
|
|
|
|
# Every Unit has a unique ID generated from the game
|
|
id: int
|
|
# The name of the Unit. Not required to be unique
|
|
name: str
|
|
# DCS UniType of the unit
|
|
type: Type[DcsUnitType]
|
|
# Position and orientation of the Unit
|
|
position: PointWithHeading
|
|
# The parent ground object
|
|
ground_object: TheaterGroundObject
|
|
# State of the unit, dead or alive
|
|
alive: bool = True
|
|
|
|
@staticmethod
|
|
def from_template(
|
|
id: int, dcs_type: Type[DcsUnitType], t: LayoutUnit, go: TheaterGroundObject
|
|
) -> TheaterUnit:
|
|
return TheaterUnit(
|
|
id,
|
|
t.name,
|
|
dcs_type,
|
|
PointWithHeading.from_point(t.position, Heading.from_degrees(t.heading)),
|
|
go,
|
|
)
|
|
|
|
@property
|
|
def unit_type(self) -> Optional[UnitType[Any]]:
|
|
if issubclass(self.type, VehicleType):
|
|
return next(GroundUnitType.for_dcs_type(self.type))
|
|
elif issubclass(self.type, ShipType):
|
|
return next(ShipUnitType.for_dcs_type(self.type))
|
|
# None for not available StaticTypes
|
|
return None
|
|
|
|
def kill(self, events: GameUpdateEvents) -> None:
|
|
self.alive = False
|
|
self.ground_object.invalidate_threat_poly()
|
|
events.update_tgo(self.ground_object)
|
|
|
|
@property
|
|
def unit_name(self) -> str:
|
|
return f"{str(self.id).zfill(4)} | {self.name}"
|
|
|
|
@property
|
|
def display_name(self) -> str:
|
|
dead_label = " [DEAD]" if not self.alive else ""
|
|
unit_label = self.unit_type or self.type.name or self.name
|
|
return f"{str(self.id).zfill(4)} | {unit_label}{dead_label}"
|
|
|
|
@property
|
|
def short_name(self) -> str:
|
|
dead_label = " [DEAD]" if not self.alive else ""
|
|
return f"<b>{self.type.id[0:18]}</b> {dead_label}"
|
|
|
|
@property
|
|
def is_static(self) -> bool:
|
|
return issubclass(self.type, StaticType)
|
|
|
|
@property
|
|
def is_vehicle(self) -> bool:
|
|
return issubclass(self.type, VehicleType)
|
|
|
|
@property
|
|
def is_ship(self) -> bool:
|
|
return issubclass(self.type, ShipType)
|
|
|
|
@property
|
|
def icon(self) -> str:
|
|
return self.type.id
|
|
|
|
@property
|
|
def repairable(self) -> bool:
|
|
# Only let units with UnitType be repairable as we just have prices for them
|
|
return self.unit_type is not None
|
|
|
|
|
|
class SceneryUnit(TheaterUnit):
|
|
"""Special TheaterUnit for handling scenery ground objects"""
|
|
|
|
# Scenery Objects are identified by a special trigger zone
|
|
zone: TriggerZone
|
|
|
|
@property
|
|
def display_name(self) -> str:
|
|
dead_label = " [DEAD]" if not self.alive else ""
|
|
return f"{str(self.id).zfill(4)} | {self.name}{dead_label}"
|
|
|
|
@property
|
|
def short_name(self) -> str:
|
|
dead_label = " [DEAD]" if not self.alive else ""
|
|
return f"<b>{self.name[0:18]}</b> {dead_label}"
|
|
|
|
@property
|
|
def icon(self) -> str:
|
|
return "missing"
|
|
|
|
@property
|
|
def repairable(self) -> bool:
|
|
return False
|
|
|
|
|
|
@dataclass
|
|
class TheaterGroup:
|
|
"""Logical group for multiple TheaterUnits at a specific position"""
|
|
|
|
# Every Theater Group has a unique ID generated from the game
|
|
id: int # Unique ID
|
|
# The name of the Group. Not required to be unique
|
|
name: str
|
|
# Position and orientation of the Group
|
|
position: PointWithHeading
|
|
# All TheaterUnits within the group
|
|
units: list[TheaterUnit]
|
|
# The parent ground object
|
|
ground_object: TheaterGroundObject
|
|
|
|
@staticmethod
|
|
def from_template(
|
|
id: int,
|
|
name: str,
|
|
units: list[TheaterUnit],
|
|
go: TheaterGroundObject,
|
|
) -> TheaterGroup:
|
|
return TheaterGroup(
|
|
id,
|
|
name,
|
|
PointWithHeading.from_point(go.position, go.heading),
|
|
units,
|
|
go,
|
|
)
|
|
|
|
@property
|
|
def group_name(self) -> str:
|
|
return f"{str(self.id).zfill(4)} | {self.name}"
|
|
|
|
@property
|
|
def unit_count(self) -> int:
|
|
return len(self.units)
|
|
|
|
@property
|
|
def alive_units(self) -> int:
|
|
return sum([unit.alive for unit in self.units])
|
|
|
|
|
|
class IadsGroundGroup(TheaterGroup):
|
|
# IADS GroundObject Groups have a specific Role for the system
|
|
iads_role: IadsRole = IadsRole.NO_BEHAVIOR
|
|
|
|
@staticmethod
|
|
def from_group(group: TheaterGroup) -> IadsGroundGroup:
|
|
return IadsGroundGroup(
|
|
group.id,
|
|
group.name,
|
|
group.position,
|
|
group.units,
|
|
group.ground_object,
|
|
)
|