mirror of
https://github.com/dcs-retribution/dcs-retribution.git
synced 2025-11-10 15:41:24 +00:00
frontline refactoring
`FrontLine` is tightly coupled with `ConflictTheater`. Moved into the same module to prevent circular imports. Moved `ConflictTheater.frontline_data` from class var to instance var to allow save games to have different versions of frontlines.
This commit is contained in:
14
gen/armor.py
14
gen/armor.py
@@ -1,7 +1,8 @@
|
||||
from __future__ import annotations
|
||||
import logging
|
||||
import random
|
||||
from dataclasses import dataclass
|
||||
from typing import List
|
||||
from typing import List, TYPE_CHECKING
|
||||
|
||||
from dcs import Mission
|
||||
from dcs.action import AITaskPush
|
||||
@@ -36,6 +37,9 @@ from .conflictgen import Conflict
|
||||
from .ground_forces.combat_stance import CombatStance
|
||||
from game.plugins import LuaPluginManager
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from game import Game
|
||||
|
||||
SPREAD_DISTANCE_FACTOR = 0.1, 0.3
|
||||
SPREAD_DISTANCE_SIZE_FACTOR = 0.1
|
||||
|
||||
@@ -65,7 +69,7 @@ class JtacInfo:
|
||||
|
||||
class GroundConflictGenerator:
|
||||
|
||||
def __init__(self, mission: Mission, conflict: Conflict, game, player_planned_combat_groups, enemy_planned_combat_groups, player_stance):
|
||||
def __init__(self, mission: Mission, conflict: Conflict, game: Game, player_planned_combat_groups, enemy_planned_combat_groups, player_stance):
|
||||
self.mission = mission
|
||||
self.conflict = conflict
|
||||
self.enemy_planned_combat_groups = enemy_planned_combat_groups
|
||||
@@ -93,7 +97,7 @@ class GroundConflictGenerator:
|
||||
if combat_width < 35000:
|
||||
combat_width = 35000
|
||||
|
||||
position = Conflict.frontline_position(self.conflict.from_cp, self.conflict.to_cp)
|
||||
position = Conflict.frontline_position(self.conflict.from_cp, self.conflict.to_cp, self.game.theater)
|
||||
|
||||
# Create player groups at random position
|
||||
for group in self.player_planned_combat_groups:
|
||||
@@ -114,6 +118,8 @@ class GroundConflictGenerator:
|
||||
player_groups.append((g,group))
|
||||
|
||||
self.gen_infantry_group_for_group(g, True, self.mission.country(self.game.player_country), self.conflict.heading + 90)
|
||||
else:
|
||||
logging.warning(f"Unable to get valid position for {group}")
|
||||
|
||||
# Create enemy groups at random position
|
||||
for group in self.enemy_planned_combat_groups:
|
||||
@@ -454,7 +460,7 @@ class GroundConflictGenerator:
|
||||
|
||||
def get_valid_position_for_group(self, conflict_position, isplayer, combat_width, distance_from_frontline):
|
||||
i = 0
|
||||
while i < 25: # 25 attempt for valid position
|
||||
while i < 1000: # 25 attempt for valid position
|
||||
heading_diff = -90 if isplayer else 90
|
||||
shifted = conflict_position[0].point_from_heading(self.conflict.heading,
|
||||
random.randint((int)(-combat_width / 2), (int)(combat_width / 2)))
|
||||
|
||||
@@ -6,7 +6,7 @@ import os
|
||||
import random
|
||||
import logging
|
||||
from dataclasses import dataclass
|
||||
from theater.frontline import FrontLine
|
||||
from theater import FrontLine
|
||||
from typing import List, Dict, TYPE_CHECKING
|
||||
from jinja2 import Environment, FileSystemLoader, select_autoescape
|
||||
|
||||
|
||||
@@ -5,8 +5,7 @@ from typing import Tuple
|
||||
from dcs.country import Country
|
||||
from dcs.mapping import Point
|
||||
|
||||
from theater import ConflictTheater, ControlPoint
|
||||
from theater.frontline import FrontLine
|
||||
from theater import ConflictTheater, ControlPoint, FrontLine
|
||||
|
||||
AIR_DISTANCE = 40000
|
||||
|
||||
@@ -136,8 +135,8 @@ class Conflict:
|
||||
return from_cp.has_frontline and to_cp.has_frontline
|
||||
|
||||
@staticmethod
|
||||
def frontline_position(from_cp: ControlPoint, to_cp: ControlPoint) -> Tuple[Point, int]:
|
||||
frontline = FrontLine(from_cp, to_cp)
|
||||
def frontline_position(from_cp: ControlPoint, to_cp: ControlPoint, theater: ConflictTheater) -> Tuple[Point, int]:
|
||||
frontline = FrontLine(from_cp, to_cp, theater)
|
||||
attack_heading = frontline.attack_heading
|
||||
position = frontline.position
|
||||
return position, _opposite_heading(attack_heading)
|
||||
@@ -160,7 +159,7 @@ class Conflict:
|
||||
|
||||
return Point(*intersection.xy[0]), _heading_sum(heading, 90), intersection.length
|
||||
"""
|
||||
frontline = cls.frontline_position(from_cp, to_cp)
|
||||
frontline = cls.frontline_position(from_cp, to_cp, theater)
|
||||
center_position, heading = frontline
|
||||
left_position, right_position = None, None
|
||||
|
||||
@@ -210,7 +209,7 @@ class Conflict:
|
||||
@classmethod
|
||||
def _find_ground_position(cls, initial: Point, max_distance: int, heading: int, theater: ConflictTheater) -> Point:
|
||||
pos = initial
|
||||
for _ in range(0, int(max_distance), 500):
|
||||
for _ in range(0, int(max_distance), 100):
|
||||
if theater.is_on_land(pos):
|
||||
return pos
|
||||
|
||||
@@ -477,7 +476,7 @@ class Conflict:
|
||||
|
||||
@classmethod
|
||||
def transport_conflict(cls, attacker_name: str, defender_name: str, attacker: Country, defender: Country, from_cp: ControlPoint, to_cp: ControlPoint, theater: ConflictTheater):
|
||||
frontline_position, heading = cls.frontline_position(from_cp, to_cp)
|
||||
frontline_position, heading = cls.frontline_position(from_cp, to_cp, theater)
|
||||
initial_dest = frontline_position.point_from_heading(heading, TRANSPORT_FRONTLINE_DIST)
|
||||
dest = cls._find_ground_position(initial_dest, from_cp.position.distance_to_point(to_cp.position) / 3, heading, theater)
|
||||
if not dest:
|
||||
|
||||
@@ -321,7 +321,7 @@ class ObjectiveFinder:
|
||||
continue
|
||||
|
||||
if Conflict.has_frontline_between(cp, connected):
|
||||
yield FrontLine(cp, connected)
|
||||
yield FrontLine(cp, connected, self.game.theater)
|
||||
|
||||
def vulnerable_control_points(self) -> Iterator[ControlPoint]:
|
||||
"""Iterates over friendly CPs that are vulnerable to enemy CPs.
|
||||
|
||||
@@ -355,7 +355,7 @@ class GroundObjectsGenerator:
|
||||
"""
|
||||
FARP_CAPACITY = 4
|
||||
|
||||
def __init__(self, mission: Mission, conflict: Conflict, game,
|
||||
def __init__(self, mission: Mission, conflict: Conflict, game: Game,
|
||||
radio_registry: RadioRegistry, tacan_registry: TacanRegistry):
|
||||
self.m = mission
|
||||
self.conflict = conflict
|
||||
@@ -370,7 +370,7 @@ class GroundObjectsGenerator:
|
||||
center = self.conflict.center
|
||||
heading = self.conflict.heading - 90
|
||||
else:
|
||||
center, heading = self.conflict.frontline_position(self.conflict.from_cp, self.conflict.to_cp)
|
||||
center, heading = self.conflict.frontline_position(self.conflict.from_cp, self.conflict.to_cp, self.game.theater)
|
||||
heading -= 90
|
||||
|
||||
initial_position = center.point_from_heading(heading, FARP_FRONTLINE_DISTANCE)
|
||||
|
||||
@@ -104,7 +104,7 @@ class VisualGenerator:
|
||||
if from_cp.is_global or to_cp.is_global:
|
||||
continue
|
||||
|
||||
frontline = Conflict.frontline_position(from_cp, to_cp)
|
||||
frontline = Conflict.frontline_position(from_cp, to_cp, self.game.theater)
|
||||
if not frontline:
|
||||
continue
|
||||
|
||||
|
||||
Reference in New Issue
Block a user