mirror of
https://github.com/dcs-retribution/dcs-retribution.git
synced 2025-11-10 15:41:24 +00:00
Rename frontline vector to bounds, add a class.
This isn't actually the data that callers usually want. Most of the callers just want the bounds. The heading and length are trivially computed from that. Add a class to contain the result so it's easier to refactor.
This commit is contained in:
parent
46ddd884a2
commit
a9f6e3a0c3
@ -77,11 +77,16 @@ class Builder(IBuilder[CasFlightPlan, CasLayout]):
|
||||
FrontLineConflictDescription,
|
||||
)
|
||||
|
||||
ingress, heading, distance = FrontLineConflictDescription.frontline_vector(
|
||||
bounds = FrontLineConflictDescription.frontline_bounds(
|
||||
location, self.theater, self.coalition.game.settings
|
||||
)
|
||||
center = ingress.point_from_heading(heading.degrees, distance / 2)
|
||||
egress = ingress.point_from_heading(heading.degrees, distance)
|
||||
ingress = bounds.left_position
|
||||
center = ingress.point_from_heading(
|
||||
bounds.heading_from_left_to_right.degrees, bounds.length / 2
|
||||
)
|
||||
egress = ingress.point_from_heading(
|
||||
bounds.heading_from_left_to_right.degrees, bounds.length
|
||||
)
|
||||
|
||||
ingress_distance = ingress.distance_to_point(self.flight.departure.position)
|
||||
egress_distance = egress.distance_to_point(self.flight.departure.position)
|
||||
|
||||
@ -15,14 +15,14 @@ from dcs.task import (
|
||||
)
|
||||
from dcs.unittype import UnitType
|
||||
|
||||
from game.ato.ai_flight_planner_db import AEWC_CAPABLE
|
||||
from game.callsigns import callsign_for_support_unit
|
||||
from game.naming import namegen
|
||||
from game.radio.radios import RadioRegistry
|
||||
from game.radio.tacan import TacanBand, TacanRegistry, TacanUsage
|
||||
from game.utils import Heading
|
||||
from game.ato.ai_flight_planner_db import AEWC_CAPABLE
|
||||
from .missiondata import MissionData, AwacsInfo, TankerInfo
|
||||
from .frontlineconflictdescription import FrontLineConflictDescription
|
||||
from .missiondata import AwacsInfo, MissionData, TankerInfo
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from game import Game
|
||||
|
||||
@ -85,18 +85,16 @@ class DrawingsGenerator:
|
||||
Generate a frontline "line" for each active frontline
|
||||
"""
|
||||
for front_line in self.game.theater.conflicts():
|
||||
(
|
||||
plane_start,
|
||||
heading,
|
||||
distance,
|
||||
) = FrontLineConflictDescription.frontline_vector(
|
||||
bounds = FrontLineConflictDescription.frontline_bounds(
|
||||
front_line, self.game.theater, self.game.settings
|
||||
)
|
||||
|
||||
end_point = plane_start.point_from_heading(heading.degrees, distance)
|
||||
end_point = bounds.left_position.point_from_heading(
|
||||
bounds.heading_from_left_to_right.degrees, bounds.length
|
||||
)
|
||||
shape = self.player_layer.add_line_segment(
|
||||
plane_start,
|
||||
end_point - plane_start,
|
||||
bounds.left_position,
|
||||
end_point - bounds.left_position,
|
||||
line_thickness=16,
|
||||
color=FRONTLINE_COLORS,
|
||||
line_style=LineStyle.Triangle,
|
||||
|
||||
@ -43,9 +43,9 @@ from game.radio.radios import RadioRegistry
|
||||
from game.theater.controlpoint import ControlPoint
|
||||
from game.unitmap import UnitMap
|
||||
from game.utils import Heading
|
||||
from .missiondata import MissionData, JtacInfo
|
||||
from .frontlineconflictdescription import FrontLineConflictDescription
|
||||
from .lasercoderegistry import LaserCodeRegistry
|
||||
from .missiondata import JtacInfo, MissionData
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from game import Game
|
||||
@ -100,18 +100,14 @@ class FlotGenerator:
|
||||
self.conflict.front_line, self.game.theater, self.game.settings
|
||||
)
|
||||
|
||||
frontline_vector = FrontLineConflictDescription.frontline_vector(
|
||||
self.conflict.front_line, self.game.theater, self.game.settings
|
||||
)
|
||||
|
||||
# Create player groups at random position
|
||||
player_groups = self._generate_groups(
|
||||
self.player_planned_combat_groups, frontline_vector, True
|
||||
self.player_planned_combat_groups, is_player=True
|
||||
)
|
||||
|
||||
# Create enemy groups at random position
|
||||
enemy_groups = self._generate_groups(
|
||||
self.enemy_planned_combat_groups, frontline_vector, False
|
||||
self.enemy_planned_combat_groups, is_player=False
|
||||
)
|
||||
|
||||
# TODO: Differentiate AirConflict and GroundConflict classes.
|
||||
@ -698,33 +694,33 @@ class FlotGenerator:
|
||||
return rg
|
||||
|
||||
def get_valid_position_for_group(
|
||||
self,
|
||||
conflict_position: Point,
|
||||
combat_width: int,
|
||||
distance_from_frontline: int,
|
||||
heading: Heading,
|
||||
spawn_heading: Heading,
|
||||
) -> Optional[Point]:
|
||||
shifted = conflict_position.point_from_heading(
|
||||
heading.degrees, random.randint(0, combat_width)
|
||||
self, distance_from_frontline: int, spawn_heading: Heading
|
||||
) -> Point | None:
|
||||
assert self.conflict.heading is not None
|
||||
assert self.conflict.size is not None
|
||||
shifted = self.conflict.position.point_from_heading(
|
||||
self.conflict.heading.degrees,
|
||||
random.randint(0, self.conflict.size),
|
||||
)
|
||||
desired_point = shifted.point_from_heading(
|
||||
spawn_heading.degrees, distance_from_frontline
|
||||
)
|
||||
return FrontLineConflictDescription.find_ground_position(
|
||||
desired_point, combat_width, heading, self.conflict.theater
|
||||
desired_point,
|
||||
self.conflict.size,
|
||||
self.conflict.heading,
|
||||
self.conflict.theater,
|
||||
)
|
||||
|
||||
def _generate_groups(
|
||||
self,
|
||||
groups: list[CombatGroup],
|
||||
frontline_vector: Tuple[Point, Heading, int],
|
||||
is_player: bool,
|
||||
self, groups: list[CombatGroup], is_player: bool
|
||||
) -> List[Tuple[VehicleGroup, CombatGroup]]:
|
||||
"""Finds valid positions for planned groups and generates a pydcs group for them"""
|
||||
positioned_groups = []
|
||||
position, heading, combat_width = frontline_vector
|
||||
spawn_heading = heading.left if is_player else heading.right
|
||||
assert self.conflict.heading is not None
|
||||
spawn_heading = (
|
||||
self.conflict.heading.left if is_player else self.conflict.heading.right
|
||||
)
|
||||
country = self.game.coalition_for(is_player).country_name
|
||||
for group in groups:
|
||||
if group.role == CombatGroupRole.ARTILLERY:
|
||||
@ -738,7 +734,7 @@ class FlotGenerator:
|
||||
)
|
||||
|
||||
final_position = self.get_valid_position_for_group(
|
||||
position, combat_width, distance_from_frontline, heading, spawn_heading
|
||||
distance_from_frontline, spawn_heading
|
||||
)
|
||||
|
||||
if final_position is not None:
|
||||
|
||||
@ -1,7 +1,8 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
from typing import Tuple, Optional
|
||||
from dataclasses import dataclass
|
||||
from typing import Optional, Tuple
|
||||
|
||||
from dcs.country import Country
|
||||
from dcs.mapping import Point
|
||||
@ -12,6 +13,15 @@ from game.theater.conflicttheater import ConflictTheater, FrontLine
|
||||
from game.theater.controlpoint import ControlPoint
|
||||
from game.utils import Heading
|
||||
|
||||
FRONTLINE_LENGTH = 80000
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class FrontLineBounds:
|
||||
left_position: Point
|
||||
heading_from_left_to_right: Heading
|
||||
length: int
|
||||
|
||||
|
||||
class FrontLineConflictDescription:
|
||||
def __init__(
|
||||
@ -26,7 +36,6 @@ class FrontLineConflictDescription:
|
||||
heading: Optional[Heading] = None,
|
||||
size: Optional[int] = None,
|
||||
):
|
||||
|
||||
self.attackers_side = attackers_side
|
||||
self.defenders_side = defenders_side
|
||||
self.attackers_country = attackers_country
|
||||
@ -66,9 +75,9 @@ class FrontLineConflictDescription:
|
||||
return position, attack_heading.opposite
|
||||
|
||||
@classmethod
|
||||
def frontline_vector(
|
||||
def frontline_bounds(
|
||||
cls, front_line: FrontLine, theater: ConflictTheater, settings: Settings
|
||||
) -> Tuple[Point, Heading, int]:
|
||||
) -> FrontLineBounds:
|
||||
"""
|
||||
Returns a vector for a valid frontline location avoiding exclusion zones.
|
||||
"""
|
||||
@ -88,7 +97,7 @@ class FrontLineConflictDescription:
|
||||
theater,
|
||||
)
|
||||
distance = int(left_position.distance_to_point(right_position))
|
||||
return left_position, right_heading, distance
|
||||
return FrontLineBounds(left_position, right_heading, distance)
|
||||
|
||||
@classmethod
|
||||
def frontline_cas_conflict(
|
||||
@ -102,19 +111,20 @@ class FrontLineConflictDescription:
|
||||
settings: Settings,
|
||||
) -> FrontLineConflictDescription:
|
||||
assert cls.has_frontline_between(front_line.blue_cp, front_line.red_cp)
|
||||
position, heading, distance = cls.frontline_vector(
|
||||
front_line, theater, settings
|
||||
)
|
||||
# TODO: Break apart the front-line and air conflict descriptions.
|
||||
# We're wastefully not caching the front-line bounds here because air conflicts
|
||||
# can't compute bounds, only a position.
|
||||
bounds = cls.frontline_bounds(front_line, theater, settings)
|
||||
conflict = cls(
|
||||
position=position,
|
||||
heading=heading,
|
||||
position=bounds.left_position,
|
||||
heading=bounds.heading_from_left_to_right,
|
||||
theater=theater,
|
||||
front_line=front_line,
|
||||
attackers_side=attacker_name,
|
||||
defenders_side=defender_name,
|
||||
attackers_country=attacker,
|
||||
defenders_country=defender,
|
||||
size=distance,
|
||||
size=bounds.length,
|
||||
)
|
||||
return conflict
|
||||
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import random
|
||||
from typing import TYPE_CHECKING, Any
|
||||
from typing import Any, TYPE_CHECKING
|
||||
|
||||
from dcs.mission import Mission
|
||||
from dcs.unit import Static
|
||||
@ -79,18 +79,16 @@ class VisualsGenerator:
|
||||
if from_cp.is_global or to_cp.is_global:
|
||||
continue
|
||||
|
||||
(
|
||||
plane_start,
|
||||
heading,
|
||||
distance,
|
||||
) = FrontLineConflictDescription.frontline_vector(
|
||||
bounds = FrontLineConflictDescription.frontline_bounds(
|
||||
front_line, self.game.theater, self.game.settings
|
||||
)
|
||||
if not plane_start:
|
||||
continue
|
||||
|
||||
for offset in range(0, distance, self.game.settings.perf_smoke_spacing):
|
||||
position = plane_start.point_from_heading(heading.degrees, offset)
|
||||
for offset in range(
|
||||
0, bounds.length, self.game.settings.perf_smoke_spacing
|
||||
):
|
||||
position = bounds.left_position.point_from_heading(
|
||||
bounds.heading_from_left_to_right.degrees, offset
|
||||
)
|
||||
|
||||
for k, v in FRONT_SMOKE_TYPE_CHANCES.items():
|
||||
if random.randint(0, 100) <= k:
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user