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:
walterroach
2020-11-15 21:22:13 -06:00
parent c20e9e19cb
commit c1f88b4a5f
12 changed files with 252 additions and 262 deletions

View File

@@ -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)))

View File

@@ -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

View File

@@ -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:

View File

@@ -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.

View File

@@ -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)

View File

@@ -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