new frontline position finding method; AA for strikes; other minor fixes and adjustments

This commit is contained in:
Vasyl Horbachenko 2018-10-12 00:12:25 +03:00
parent 35a7da2816
commit 0015667829
13 changed files with 87 additions and 23 deletions

View File

@ -35,6 +35,17 @@ class StrikeOperation(Operation):
conflict=conflict)
def generate(self):
for global_cp in self.game.theater.controlpoints:
if not global_cp.is_global:
continue
ship = self.shipgen.generate_carrier(type=db.find_unittype(Carriage, self.game.player)[0],
country=self.game.player,
at=global_cp.at)
if global_cp == self.from_cp and not self.is_quick:
self.attackers_starting_position = ship
targets = [] # type: typing.List[typing.Tuple[str, Point]]
category_counters = {} # type: typing.Dict[str, int]
processed_groups = []

View File

@ -155,7 +155,7 @@ class Conflict:
return from_cp.has_frontline and to_cp.has_frontline
@classmethod
def frontline_position(cls, from_cp: ControlPoint, to_cp: ControlPoint) -> typing.Tuple[Point, int]:
def frontline_position0(cls, from_cp: ControlPoint, to_cp: ControlPoint) -> typing.Tuple[Point, int]:
cp_distance = from_cp.position.distance_to_point(to_cp.position)
cp_distance -= cp_distance * to_cp.frontline_offset + cp_distance * from_cp.frontline_offset
@ -164,8 +164,45 @@ class Conflict:
return to_cp.position.point_from_heading(heading, distance), heading
@classmethod
def frontline_vector(cls, from_cp: ControlPoint, to_cp: ControlPoint, theater: ConflictTheater) -> typing.Tuple[Point, int, int]:
center_position, heading = cls.frontline_position(from_cp, to_cp)
def frontline_position2(cls, theater: ConflictTheater, from_cp: ControlPoint, to_cp: ControlPoint) -> typing.Optional[typing.Tuple[Point, int]]:
attack_heading = from_cp.position.heading_between_point(to_cp.position)
attack_starting_position = cls._find_ground_position(from_cp.position, 200000, attack_heading, theater)
if not attack_starting_position:
return None
attack_ending_position = cls._find_ground_position(to_cp.position, 200000, _opposite_heading(attack_heading), theater)
if not attack_ending_position:
return None
attack_distance = attack_ending_position.distance_to_point(attack_starting_position)
strength_delta = (from_cp.base.strength - to_cp.base.strength) / 1.0
middle_position = attack_starting_position.point_from_heading(attack_heading, attack_distance / 2)
return middle_position.point_from_heading(attack_heading, strength_delta * attack_distance), _opposite_heading(attack_heading)
@classmethod
def frontline_position(cls, theater: ConflictTheater, from_cp: ControlPoint, to_cp: ControlPoint) -> typing.Optional[typing.Tuple[Point, int]]:
attack_heading = from_cp.position.heading_between_point(to_cp.position)
attack_distance = from_cp.position.distance_to_point(to_cp.position)
middle_point = from_cp.position.point_from_heading(attack_heading, attack_distance / 2)
strength_delta = (from_cp.base.strength - to_cp.base.strength) / 1.0
position = middle_point.point_from_heading(attack_heading, strength_delta * attack_distance / 2 - FRONTLINE_MIN_CP_DISTANCE)
ground_position = cls._find_ground_position(position, attack_distance / 2 - FRONTLINE_MIN_CP_DISTANCE, attack_heading, theater)
if ground_position:
return ground_position, attack_heading
else:
print(from_cp, to_cp)
return None
@classmethod
def frontline_vector(cls, from_cp: ControlPoint, to_cp: ControlPoint, theater: ConflictTheater) -> typing.Optional[typing.Tuple[Point, int, int]]:
frontline = cls.frontline_position(theater, from_cp, to_cp)
if not frontline:
return None
center_position, heading = frontline
left_position, right_position = None, None
if not theater.is_on_land(center_position):
@ -401,7 +438,7 @@ class Conflict:
@classmethod
def transport_conflict(cls, 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(theater, from_cp, to_cp)
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

@ -98,7 +98,11 @@ class VisualGenerator:
def _generate_frontline_smokes(self):
for from_cp, to_cp in self.game.theater.conflicts():
point, heading = Conflict.frontline_position(from_cp, to_cp)
frontline = Conflict.frontline_position(self.game.theater, from_cp, to_cp)
if not frontline:
continue
point, heading = frontline
plane_start = point.point_from_heading(turn_heading(heading, 90), FRONTLINE_LENGTH / 2)
for offset in range(0, FRONTLINE_LENGTH, FRONT_SMOKE_SPACING):

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -11,7 +11,7 @@ def load_templates():
temp_mis = Mission()
temp_mis.load_file("resources/tools/groundobject_templates.miz")
groups = {} # type: typing.Dict[str, typing.Dict[int, typing.Collection[Static]]]
groups = {} # type: typing.Dict[str, typing.Dict[int, typing.List[Static]]]
for static_group in temp_mis.country("USA").static_group:
for static in static_group.units:
@ -42,6 +42,7 @@ def load_templates():
"heading": static.heading,
})
tpls["aa"] = {0: [{"type": "AA", "offset": Point(0, 0), "heading": 0}]}
return tpls

View File

@ -3,18 +3,20 @@ import typing
import math
import itertools
from game import db
from theater.controlpoint import ControlPoint
from dcs.planes import *
from dcs.vehicles import *
from dcs.task import *
from game import db
STRENGTH_AA_ASSEMBLE_MIN = 0.2
PLANES_SCRAMBLE_MIN_BASE = 4
PLANES_SCRAMBLE_MAX_BASE = 8
PLANES_SCRAMBLE_FACTOR = 0.6
BASE_MAX_STRENGTH = 1
BASE_MIN_STRENGTH = 0
class Base:
aircraft = {} # type: typing.Dict[PlaneType, int]
@ -136,10 +138,10 @@ class Base:
def affect_strength(self, amount):
self.strength += amount
if self.strength > 1:
self.strength = 1
elif self.strength < 0:
self.strength = 0.001
if self.strength > BASE_MAX_STRENGTH:
self.strength = BASE_MAX_STRENGTH
elif self.strength <= 0:
self.strength = BASE_MIN_STRENGTH
def scramble_count(self, multiplier: float, task: Task = None) -> int:
if task:

View File

@ -25,12 +25,12 @@ class CaucasusTheater(ConflictTheater):
kutaisi = ControlPoint.from_airport(caucasus.Kutaisi, LAND, SIZE_SMALL, IMPORTANCE_LOW)
senaki = ControlPoint.from_airport(caucasus.Senaki_Kolkhi, LAND, SIZE_REGULAR, IMPORTANCE_LOW)
kobuleti = ControlPoint.from_airport(caucasus.Kobuleti, COAST_A_E, SIZE_SMALL, 1.1)
batumi = ControlPoint.from_airport(caucasus.Batumi, COAST_DL_E, SIZE_SMALL, 1.3)
batumi = ControlPoint.from_airport(caucasus.Batumi, COAST_DL_E, SIZE_SMALL, 1.3, has_frontline=False)
sukhumi = ControlPoint.from_airport(caucasus.Sukhumi_Babushara, COAST_DR_E, SIZE_REGULAR, 1.2)
gudauta = ControlPoint.from_airport(caucasus.Gudauta, COAST_DR_E, SIZE_REGULAR, 1.2)
sochi = ControlPoint.from_airport(caucasus.Sochi_Adler, COAST_DR_E, SIZE_BIG, IMPORTANCE_HIGH)
gudauta = ControlPoint.from_airport(caucasus.Gudauta, COAST_DR_E, SIZE_REGULAR, 1.2, has_frontline=False)
sochi = ControlPoint.from_airport(caucasus.Sochi_Adler, COAST_DR_E, SIZE_BIG, IMPORTANCE_HIGH, has_frontline=False)
gelendzhik = ControlPoint.from_airport(caucasus.Gelendzhik, COAST_DR_E, SIZE_BIG, 1.1)
gelendzhik = ControlPoint.from_airport(caucasus.Gelendzhik, COAST_DR_E, SIZE_BIG, 1.1, has_frontline=False)
maykop = ControlPoint.from_airport(caucasus.Maykop_Khanskaya, LAND, SIZE_LARGE, IMPORTANCE_HIGH)
krasnodar = ControlPoint.from_airport(caucasus.Krasnodar_Center, LAND, SIZE_LARGE, IMPORTANCE_HIGH)
novorossiysk = ControlPoint.from_airport(caucasus.Novorossiysk, COAST_DR_E, SIZE_BIG, 1.2)
@ -75,6 +75,7 @@ class CaucasusTheater(ConflictTheater):
self.carrier_1.captured = True
self.soganlug.captured = True
self.gudauta.captured = True
def add_controlpoint(self, point: ControlPoint, connected_to: typing.Collection[ControlPoint] = []):
point.name = " ".join(re.split(r"[ -]", point.name)[:1])

View File

@ -49,7 +49,7 @@ class ControlPoint:
@classmethod
def carrier(cls, name: str, at: Point):
import theater.conflicttheater
return cls(0, name, at, at, theater.conflicttheater.LAND, theater.conflicttheater.SIZE_SMALL, 1)
return cls(0, name, at, at, theater.conflicttheater.LAND, theater.conflicttheater.SIZE_SMALL, 1, has_frontline=False)
def __str__(self):
return self.name

View File

@ -13,7 +13,7 @@ class NevadaTheater(ConflictTheater):
daytime_map = {
"dawn": (4, 6),
"day": (6, 17),
"dusk": (17, 19),
"dusk": (17, 18),
"night": (0, 5),
}

View File

@ -59,7 +59,7 @@ def generate_groundobjects(theater: ConflictTheater):
group_id = 0
for cp in theater.enemy_points():
for _ in range(0, random.randrange(3, 6)):
available_categories = list(tpls)
available_categories = list(tpls) + ["aa", "aa", "aa"]
tpl_category = random.choice(available_categories)
tpl = random.choice(list(tpls[tpl_category].values()))
@ -87,7 +87,7 @@ def generate_groundobjects(theater: ConflictTheater):
g.cp_id = cp.id
g.dcs_identifier = object["type"]
g.heading = object["heading"],
g.heading = object["heading"]
g.position = Point(point.x + object["offset"].x, point.y + object["offset"].y)
cp.ground_objects.append(g)

View File

@ -80,8 +80,16 @@ class OverviewCanvas:
self.canvas.create_line((coords[0], coords[1], connected_coords[0], connected_coords[1]), width=2, fill=color)
if cp.captured and not connected_cp.captured and Conflict.has_frontline_between(cp, connected_cp):
frontline_pos, heading, distance = Conflict.frontline_vector(cp, connected_cp, self.game.theater)
distance = max(distance, 1000)
frontline = Conflict.frontline_vector(cp, connected_cp, self.game.theater)
if not frontline:
print(cp, connected_cp)
continue
frontline_pos, heading, distance = frontline
if distance < 10000:
frontline_pos = frontline_pos.point_from_heading(heading + 180, 5000)
distance = 10000
start_coords = self.transform_point(frontline_pos, treshold=10)
end_coords = self.transform_point(frontline_pos.point_from_heading(heading, distance), treshold=60)