Rotate ground-units as in the campaign miz

This implements a logic to rotate groups which are generated from templates like the origin (ground unit) which was placed by the campaign designer
This commit is contained in:
RndName 2022-01-17 20:31:49 +01:00
parent 5febcdd4e4
commit daf4704fe7
4 changed files with 42 additions and 17 deletions

View File

@ -1,5 +1,7 @@
from __future__ import annotations from __future__ import annotations
import math
from dcs import Point from dcs import Point
from game.utils import Heading from game.utils import Heading
@ -16,3 +18,12 @@ class PointWithHeading(Point):
p.y = point.y p.y = point.y
p.heading = heading p.heading = heading
return p 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)

View File

@ -472,12 +472,14 @@ class LhaGroundObject(GenericCarrierGroundObject):
class MissileSiteGroundObject(TheaterGroundObject): 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__( super().__init__(
name=name, name=name,
category="missile", category="missile",
position=position, position=position,
heading=Heading.from_degrees(0), heading=heading,
control_point=control_point, control_point=control_point,
sea_object=False, sea_object=False,
) )
@ -534,13 +536,14 @@ class SamGroundObject(IadsGroundObject):
self, self,
name: str, name: str,
position: Point, position: Point,
heading: Heading,
control_point: ControlPoint, control_point: ControlPoint,
) -> None: ) -> None:
super().__init__( super().__init__(
name=name, name=name,
category="aa", category="aa",
position=position, position=position,
heading=Heading.from_degrees(0), heading=heading,
control_point=control_point, control_point=control_point,
sea_object=False, sea_object=False,
) )
@ -599,13 +602,14 @@ class VehicleGroupGroundObject(TheaterGroundObject):
self, self,
name: str, name: str,
position: Point, position: Point,
heading: Heading,
control_point: ControlPoint, control_point: ControlPoint,
) -> None: ) -> None:
super().__init__( super().__init__(
name=name, name=name,
category="armor", category="armor",
position=position, position=position,
heading=Heading.from_degrees(0), heading=heading,
control_point=control_point, control_point=control_point,
sea_object=False, sea_object=False,
) )
@ -624,13 +628,14 @@ class EwrGroundObject(IadsGroundObject):
self, self,
name: str, name: str,
position: Point, position: Point,
heading: Heading,
control_point: ControlPoint, control_point: ControlPoint,
) -> None: ) -> None:
super().__init__( super().__init__(
name=name, name=name,
category="ewr", category="ewr",
position=position, position=position,
heading=Heading.from_degrees(0), heading=heading,
control_point=control_point, control_point=control_point,
sea_object=False, sea_object=False,
) )

View File

@ -7,13 +7,14 @@ import random
from abc import ABC, abstractmethod from abc import ABC, abstractmethod
from dataclasses import dataclass, field from dataclasses import dataclass, field
from enum import Enum 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 import Point
from dcs.ships import ship_map from dcs.ships import ship_map
from dcs.unit import Unit from dcs.unit import Unit
from dcs.unittype import UnitType from dcs.unittype import UnitType
from dcs.vehicles import vehicle_map from dcs.vehicles import vehicle_map
from game.data.radar_db import UNITS_WITH_RADAR
from game.dcs.groundunittype import GroundUnitType from game.dcs.groundunittype import GroundUnitType
from game.theater.theatergroundobject import ( from game.theater.theatergroundobject import (
@ -329,19 +330,26 @@ class GroundObjectTemplate(ABC):
for u_id, unit in enumerate(tgo_group.units): for u_id, unit in enumerate(tgo_group.units):
unit.id = game.next_unit_id() unit.id = game.next_unit_id()
unit.name = f"{self.name} {g_id}-{u_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( unit.position = PointWithHeading.from_point(
Point( Point(
ground_object.position.x + unit.position.x, ground_object.position.x + unit.position.x,
ground_object.position.y + unit.position.y, 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) ground_object.groups.append(tgo_group)
return ground_object return ground_object
@ -422,9 +430,9 @@ class AirDefenceTemplate(GroundObjectTemplate):
control_point: ControlPoint, control_point: ControlPoint,
) -> IadsGroundObject: ) -> IadsGroundObject:
if self.template_type == "EWR": 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"]: 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( raise RuntimeError(
f" No Template Definition for AirDefence with subcategory {self.template_type}" f" No Template Definition for AirDefence with subcategory {self.template_type}"
) )
@ -480,7 +488,7 @@ class ArmorTemplate(GroundObjectTemplate):
position: PointWithHeading, position: PointWithHeading,
control_point: ControlPoint, control_point: ControlPoint,
) -> TheaterGroundObject: ) -> TheaterGroundObject:
return VehicleGroupGroundObject(name, position, control_point) return VehicleGroupGroundObject(name, position, position.heading, control_point)
class MissileTemplate(GroundObjectTemplate): class MissileTemplate(GroundObjectTemplate):
@ -490,7 +498,7 @@ class MissileTemplate(GroundObjectTemplate):
position: PointWithHeading, position: PointWithHeading,
control_point: ControlPoint, control_point: ControlPoint,
) -> TheaterGroundObject: ) -> TheaterGroundObject:
return MissileSiteGroundObject(name, position, control_point) return MissileSiteGroundObject(name, position, position.heading, control_point)
TEMPLATE_TYPES = { TEMPLATE_TYPES = {

View File

@ -521,6 +521,7 @@ def update_factions(generator_names) -> None:
# ground_object = SamGroundObject( # ground_object = SamGroundObject(
# namegen.random_objective_name(), # namegen.random_objective_name(),
# initial_position, # initial_position,
# Heading.from_degrees(0),
# control_point, # control_point,
# ) # )
# #