diff --git a/game/game.py b/game/game.py index 3d503f67..6e88cf96 100644 --- a/game/game.py +++ b/game/game.py @@ -286,6 +286,18 @@ class Game: for tgo in control_point.connected_objectives: self.db.tgos.add(tgo.id, tgo) + # Correct the heading of specifc TGOs, can only be done after init turn 0 + for tgo in self.theater.ground_objects: + # If heading is 0 then we change the orientation to head towards the + # closest conflict. Heading of 0 means that the campaign designer wants + # to determine the heading automatically by liberation. Values other + # than 0 mean it is custom defined. + if tgo.should_head_to_conflict and tgo.heading.degrees == 0: + # Calculate the heading to conflict + heading = self.theater.heading_to_conflict_from(tgo.position) + # Rotate the whole TGO with the new heading + tgo.rotate(heading or tgo.heading) + self.blue.preinit_turn_0() self.red.preinit_turn_0() # We don't need to actually stream events for turn zero because we haven't given diff --git a/game/theater/theatergroundobject.py b/game/theater/theatergroundobject.py index d1545f0f..17d488db 100644 --- a/game/theater/theatergroundobject.py +++ b/game/theater/theatergroundobject.py @@ -262,6 +262,11 @@ class TheaterGroundObject(MissionTarget, SidcDescribable, ABC): unit.position.heading += rotation unit.position.rotate(self.position, rotation) + @property + def should_head_to_conflict(self) -> bool: + """Should this TGO head towards the closest conflict to work properly?""" + return False + class BuildingGroundObject(TheaterGroundObject): def __init__( @@ -421,6 +426,10 @@ class MissileSiteGroundObject(TheaterGroundObject): def purchasable(self) -> bool: return False + @property + def should_head_to_conflict(self) -> bool: + return True + class CoastalSiteGroundObject(TheaterGroundObject): def __init__( @@ -449,6 +458,10 @@ class CoastalSiteGroundObject(TheaterGroundObject): def purchasable(self) -> bool: return False + @property + def should_head_to_conflict(self) -> bool: + return True + class IadsGroundObject(TheaterGroundObject, ABC): def __init__( @@ -473,6 +486,10 @@ class IadsGroundObject(TheaterGroundObject, ABC): yield FlightType.DEAD yield from super().mission_types(for_player) + @property + def should_head_to_conflict(self) -> bool: + return True + # The SamGroundObject represents all type of AA # The TGO can have multiple types of units (AAA,SAM,Support...) @@ -554,6 +571,10 @@ class VehicleGroupGroundObject(TheaterGroundObject): def purchasable(self) -> bool: return True + @property + def should_head_to_conflict(self) -> bool: + return True + class EwrGroundObject(IadsGroundObject): def __init__( diff --git a/game/version.py b/game/version.py index 6b89a606..86052769 100644 --- a/game/version.py +++ b/game/version.py @@ -134,6 +134,10 @@ VERSION = _build_version_string() #: also used later in mission generation to orient the group accordingly. #: This removes the randomization of the orientation from the generation. #: Most campaigns will not need any updates and will work out of the box. +#: If the campaign designer sets the heading to 0 then we will automatically change +#: the orientation of the generated TGO to head towards the conflict if it is +#: required by the TGO to work properly. Values other than 0 will prevent the +#: automatic orientation. #: #: Version 10.1 #: * Campaign designers can now define the recommended economy settings: