diff --git a/game/point_with_heading.py b/game/point_with_heading.py index 7eed4da2..9769ba02 100644 --- a/game/point_with_heading.py +++ b/game/point_with_heading.py @@ -1,5 +1,7 @@ from __future__ import annotations +import math + from dcs import Point from game.utils import Heading @@ -16,3 +18,12 @@ class PointWithHeading(Point): p.y = point.y p.heading = heading return p + + def rotate(self, origin: Point, heading: Heading) -> None: + """Rotates the Point by a given angle clockwise around the origin""" + ox, oy = origin.x, origin.y + px, py = self.x, self.y + radians = heading.radians + + self.x = ox + math.cos(radians) * (px - ox) - math.sin(radians) * (py - oy) + self.y = oy + math.sin(radians) * (px - ox) + math.cos(radians) * (py - oy) diff --git a/game/theater/theatergroundobject.py b/game/theater/theatergroundobject.py index 51c3666d..81d5794b 100644 --- a/game/theater/theatergroundobject.py +++ b/game/theater/theatergroundobject.py @@ -472,12 +472,14 @@ class LhaGroundObject(GenericCarrierGroundObject): class MissileSiteGroundObject(TheaterGroundObject): - def __init__(self, name: str, position: Point, control_point: ControlPoint) -> None: + def __init__( + self, name: str, position: Point, heading: Heading, control_point: ControlPoint + ) -> None: super().__init__( name=name, category="missile", position=position, - heading=Heading.from_degrees(0), + heading=heading, control_point=control_point, sea_object=False, ) @@ -534,13 +536,14 @@ class SamGroundObject(IadsGroundObject): self, name: str, position: Point, + heading: Heading, control_point: ControlPoint, ) -> None: super().__init__( name=name, category="aa", position=position, - heading=Heading.from_degrees(0), + heading=heading, control_point=control_point, sea_object=False, ) @@ -599,13 +602,14 @@ class VehicleGroupGroundObject(TheaterGroundObject): self, name: str, position: Point, + heading: Heading, control_point: ControlPoint, ) -> None: super().__init__( name=name, category="armor", position=position, - heading=Heading.from_degrees(0), + heading=heading, control_point=control_point, sea_object=False, ) @@ -624,13 +628,14 @@ class EwrGroundObject(IadsGroundObject): self, name: str, position: Point, + heading: Heading, control_point: ControlPoint, ) -> None: super().__init__( name=name, category="ewr", position=position, - heading=Heading.from_degrees(0), + heading=heading, control_point=control_point, sea_object=False, ) diff --git a/gen/templates.py b/gen/templates.py index b989bf59..522c40f6 100644 --- a/gen/templates.py +++ b/gen/templates.py @@ -7,13 +7,14 @@ import random from abc import ABC, abstractmethod from dataclasses import dataclass, field from enum import Enum -from typing import Iterator, Any, TYPE_CHECKING, Optional, Tuple, Union +from typing import Iterator, Any, TYPE_CHECKING, Optional, Union from dcs import Point from dcs.ships import ship_map from dcs.unit import Unit from dcs.unittype import UnitType from dcs.vehicles import vehicle_map +from game.data.radar_db import UNITS_WITH_RADAR from game.dcs.groundunittype import GroundUnitType from game.theater.theatergroundobject import ( @@ -329,19 +330,26 @@ class GroundObjectTemplate(ABC): for u_id, unit in enumerate(tgo_group.units): unit.id = game.next_unit_id() unit.name = f"{self.name} {g_id}-{u_id}" - if isinstance(self, AirDefenceTemplate): - # Head SAM and EWR towards the center of the conflict - unit.position.heading = ( - game.theater.heading_to_conflict_from(unit.position) - or unit.position.heading - ) unit.position = PointWithHeading.from_point( Point( ground_object.position.x + unit.position.x, ground_object.position.y + unit.position.y, ), - unit.position.heading, + # Align heading to GroundObject defined by the campaign designer + unit.position.heading + ground_object.heading, ) + if ( + isinstance(self, AirDefenceTemplate) + and unit.unit_type + and unit.unit_type.dcs_unit_type in UNITS_WITH_RADAR + ): + # Head Radars towards the center of the conflict + unit.position.heading = ( + game.theater.heading_to_conflict_from(unit.position) + or unit.position.heading + ) + # Rotate unit around the center to align the orientation of the group + unit.position.rotate(ground_object.position, ground_object.heading) ground_object.groups.append(tgo_group) return ground_object @@ -422,9 +430,9 @@ class AirDefenceTemplate(GroundObjectTemplate): control_point: ControlPoint, ) -> IadsGroundObject: if self.template_type == "EWR": - return EwrGroundObject(name, position, control_point) + return EwrGroundObject(name, position, position.heading, control_point) elif self.template_type in ["Long", "Medium", "Short", "AAA"]: - return SamGroundObject(name, position, control_point) + return SamGroundObject(name, position, position.heading, control_point) raise RuntimeError( f" No Template Definition for AirDefence with subcategory {self.template_type}" ) @@ -480,7 +488,7 @@ class ArmorTemplate(GroundObjectTemplate): position: PointWithHeading, control_point: ControlPoint, ) -> TheaterGroundObject: - return VehicleGroupGroundObject(name, position, control_point) + return VehicleGroupGroundObject(name, position, position.heading, control_point) class MissileTemplate(GroundObjectTemplate): @@ -490,7 +498,7 @@ class MissileTemplate(GroundObjectTemplate): position: PointWithHeading, control_point: ControlPoint, ) -> TheaterGroundObject: - return MissileSiteGroundObject(name, position, control_point) + return MissileSiteGroundObject(name, position, position.heading, control_point) TEMPLATE_TYPES = { diff --git a/resources/tools/template_helper.py b/resources/tools/template_helper.py index 5bc5b697..e7311fab 100644 --- a/resources/tools/template_helper.py +++ b/resources/tools/template_helper.py @@ -521,6 +521,7 @@ def update_factions(generator_names) -> None: # ground_object = SamGroundObject( # namegen.random_objective_name(), # initial_position, + # Heading.from_degrees(0), # control_point, # ) #