diff --git a/__init__.py b/__init__.py index d0f0f4d5..ae9ff0be 100755 --- a/__init__.py +++ b/__init__.py @@ -20,11 +20,6 @@ m = dcs.Mission() theater = theater.caucasus.CaucasusTheater() start_generator.generate_initial(theater, "Russia") -theater.kutaisi.base.aircraft = { - F_15C: 4, - A_10C: 2, -} - g = Game(theater=theater) w = ui.window.Window() diff --git a/game/event.py b/game/event.py index e90ae8af..62b3caf2 100644 --- a/game/event.py +++ b/game/event.py @@ -83,7 +83,7 @@ class GroundInterceptEvent(Event): defender=self.defender, attacker_clients=clients, defender_clients={}, - attacker_airport=self.from_cp.at, + from_cp=self.from_cp, position=position, target=targets, strikegroup=strikegroup) @@ -121,9 +121,8 @@ class InterceptEvent(Event): defender=self.defender, attacker_clients=clients, defender_clients={}, - attacker_airport=self.from_cp.at, - destination=self.to_cp, - destination_port=self.to_cp.at, + from_cp=self.from_cp, + to_cp=self.to_cp, escort=escort, transport={transport_unit: 1}, airdefense={airdefense_unit: self.AIRDEFENSE_COUNT}, @@ -139,9 +138,8 @@ class InterceptEvent(Event): defender=self.defender, attacker_clients={}, defender_clients=clients, - attacker_airport=None, - destination=self.to_cp, - destination_port=self.to_cp.at, + from_cp=self.from_cp, + to_cp=self.to_cp, escort=escort, transport={transport_unit: 1}, interceptors=interceptors, @@ -180,7 +178,6 @@ class CaptureEvent(Event): defender=self.defender, attacker_clients={}, defender_clients=clients, - attacker_airport=None, from_cp=self.from_cp, to_cp=self.to_cp, cas=cas, @@ -198,7 +195,6 @@ class CaptureEvent(Event): defender=self.defender, attacker_clients=clients, defender_clients={}, - attacker_airport=self.from_cp.at, from_cp=self.from_cp, to_cp=self.to_cp, cas=cas, diff --git a/game/game.py b/game/game.py index 1cfcebe9..2a45b906 100644 --- a/game/game.py +++ b/game/game.py @@ -23,8 +23,8 @@ COMMISION_AMOUNTS_FACTORS = { } -ENEMY_INTERCEPT_PROBABILITY_BASE = 15 -ENEMY_CAPTURE_PROBABILITY_BASE = 5 +ENEMY_INTERCEPT_PROBABILITY_BASE = 10 +ENEMY_CAPTURE_PROBABILITY_BASE = 3 PLAYER_INTERCEPT_PROBABILITY_BASE = 30 PLAYER_GROUNDINTERCEPT_PROBABILITY_BASE = 30 @@ -128,7 +128,8 @@ class Game: return event def units_delivery_remove(self, event: Event): - self.events.remove(event) + if event in self.events: + self.events.remove(event) def initiate_event(self, event: Event): event.operation.generate() diff --git a/game/operation.py b/game/operation.py index b2593ada..c811345c 100644 --- a/game/operation.py +++ b/game/operation.py @@ -43,7 +43,6 @@ class CaptureOperation(Operation): defender: Country, attacker_clients: db.PlaneDict, defender_clients: db.PlaneDict, - attacker_airport: typing.Optional[Airport], from_cp: ControlPoint, to_cp: ControlPoint, cas: db.PlaneDict, @@ -59,7 +58,6 @@ class CaptureOperation(Operation): self.to_cp = to_cp self.attacker_clients = attacker_clients self.defender_clients = defender_clients - self.attacker_airport = attacker_airport self.cas = cas self.escort = escort self.intercept = intercept @@ -74,8 +72,8 @@ class CaptureOperation(Operation): self.aagen.generate(self.aa) self.airgen.generate_defense(self.intercept, clients=self.defender_clients) - self.airgen.generate_cas(self.cas, clients=self.attacker_clients, at=self.attacker_airport) - self.airgen.generate_cas_escort(self.escort, clients=self.attacker_clients, at=self.attacker_airport) + self.airgen.generate_cas(self.cas, clients=self.attacker_clients, at=self.from_cp.at) + self.airgen.generate_cas_escort(self.escort, clients=self.attacker_clients, at=self.from_cp.at) class InterceptOperation(Operation): @@ -85,9 +83,8 @@ class InterceptOperation(Operation): defender: Country, attacker_clients: db.PlaneDict, defender_clients: db.PlaneDict, - attacker_airport: typing.Optional[Airport], - destination: ControlPoint, - destination_port: Airport, + from_cp: ControlPoint, + to_cp: ControlPoint, escort: db.PlaneDict, transport: db.PlaneDict, airdefense: db.AirDefenseDict, @@ -95,14 +92,14 @@ class InterceptOperation(Operation): conflict = Conflict.intercept_conflict( attacker=attacker, defender=defender, - position=destination.position, + position=to_cp.position, heading=randint(0, 360), radials=ALL_RADIALS ) super(InterceptOperation, self).__init__(mission, conflict) - self.destination_port = destination_port - self.attacker_airport = attacker_airport + self.to_cp = to_cp + self.from_cp = from_cp self.attacker_clients = attacker_clients self.defender_clients = defender_clients self.escort = escort @@ -111,11 +108,14 @@ class InterceptOperation(Operation): self.interceptors = interceptors def generate(self): - self.airgen.generate_transport(self.transport, self.destination_port) + self.airgen.generate_transport(self.transport, self.to_cp.at) self.airgen.generate_transport_escort(self.escort, clients=self.defender_clients) self.aagen.generate(self.airdefense) - self.airgen.generate_interception(self.interceptors, clients=self.attacker_clients, airport=self.attacker_airport) + if self.from_cp.is_global: + self.airgen.generate_interception(self.interceptors, clients=self.attacker_clients, at=self.shipgen.generate(self.from_cp.at)) + else: + self.airgen.generate_interception(self.interceptors, clients=self.attacker_clients, at=self.from_cp.at) class GroundInterceptOperation(Operation): @@ -123,9 +123,9 @@ class GroundInterceptOperation(Operation): mission: Mission, attacker: Country, defender: Country, + from_cp: ControlPoint, attacker_clients: db.PlaneDict, defender_clients: db.PlaneDict, - attacker_airport: typing.Optional[Airport], position: Point, target: db.ArmorDict, strikegroup: db.PlaneDict): @@ -140,10 +140,10 @@ class GroundInterceptOperation(Operation): super(GroundInterceptOperation, self).__init__(mission, conflict) self.attacker_clients = attacker_clients self.defender_clients = defender_clients - self.attacker_airport = attacker_airport + self.from_cp = from_cp self.strikegroup = strikegroup self.target = target def generate(self): - self.airgen.generate_cas(self.strikegroup, clients=self.attacker_clients, at=self.attacker_airport) + self.airgen.generate_cas(self.strikegroup, clients=self.attacker_clients, at=self.from_cp.at) self.armorgen.generate({}, self.target) diff --git a/gen/aircraft.py b/gen/aircraft.py index 8c645b5e..e96c3171 100644 --- a/gen/aircraft.py +++ b/gen/aircraft.py @@ -53,7 +53,7 @@ class AircraftConflictGenerator: country=side, name=name, aircraft_type=unit_type, - airport=airport, + airport=self.m.terrain.airport_by_id(airport.id), maintask=None, start_type=StartType.Cold, group_size=count, @@ -104,11 +104,11 @@ class AircraftConflictGenerator: return group def _generate_group(self, name: str, side: Country, unit_type: FlyingType, count: int, client_count: int, at: db.StartingPosition): - if type(at) == Point: + if isinstance(at, Point): return self._generate_inflight(name, side, unit_type, count, client_count, at) - elif type(at) == Airport: + elif issubclass(at, Airport): return self._generate_at_airport(name, side, unit_type, count, client_count, at) - elif type(at) == ShipGroup: + elif isinstance(at, ShipGroup): return self._generate_at_carrier(name, side, unit_type, count, client_count, at) else: assert False diff --git a/gen/shipgen.py b/gen/shipgen.py index 5268df0e..7c04cd7f 100644 --- a/gen/shipgen.py +++ b/gen/shipgen.py @@ -19,14 +19,13 @@ from dcs.task import * class ShipGenerator: - def __init__(self, mission: Mission, conflict: Conflict, position: Point): + def __init__(self, mission: Mission, conflict: Conflict): self.m = mission self.conflict = conflict - self.position = position - def generate(self): - self.m.ship_group( + def generate(self, at: Point) -> ShipGroup: + return self.m.ship_group( country=self.conflict.attackers_side, name=namegen.next_transport_group_name(), _type=dcs.ships.CVN_74_John_C__Stennis, - position=self.position) + position=at) diff --git a/theater/base.py b/theater/base.py index 5964ed72..c727b383 100644 --- a/theater/base.py +++ b/theater/base.py @@ -29,6 +29,7 @@ class Base: self.armor = {} self.aa = {} self.commision_points = {} + self.strength = 1 @property def total_planes(self) -> int: diff --git a/theater/caucasus.py b/theater/caucasus.py index 36c4e32b..055287f3 100644 --- a/theater/caucasus.py +++ b/theater/caucasus.py @@ -3,7 +3,11 @@ from dcs.terrain import caucasus from .conflicttheater import * from .base import * + class CaucasusTheater(ConflictTheater): + reference_points = {(-317948.32727306, 635639.37385346): (282.5, 319), + (-355692.3067714, 617269.96285781): (269, 352), } + soganlug = ControlPoint.from_airport(caucasus.Soganlug, ALL_RADIALS, SIZE_SMALL, IMPORTANCE_LOW) kutaisi = ControlPoint.from_airport(caucasus.Kutaisi, ALL_RADIALS, SIZE_SMALL, IMPORTANCE_LOW) senaki = ControlPoint.from_airport(caucasus.Senaki_Kolkhi, ALL_RADIALS, SIZE_REGULAR, IMPORTANCE_LOW) @@ -13,21 +17,24 @@ class CaucasusTheater(ConflictTheater): gudauta = ControlPoint.from_airport(caucasus.Gudauta, COAST_VERTICAL, SIZE_REGULAR, IMPORTANCE_MEDIUM) sochi = ControlPoint.from_airport(caucasus.Sochi_Adler, COAST_VERTICAL, SIZE_BIG, IMPORTANCE_HIGH) + gelendzhik = ControlPoint.from_airport(caucasus.Gelendzhik, COAST_VERTICAL, SIZE_BIG, IMPORTANCE_MEDIUM) maykop = ControlPoint.from_airport(caucasus.Maykop_Khanskaya, ALL_RADIALS, SIZE_LARGE, IMPORTANCE_HIGH) krasnodar = ControlPoint.from_airport(caucasus.Krasnodar_Center, ALL_RADIALS, SIZE_LARGE, IMPORTANCE_HIGH) - novorossiysk = ControlPoint.from_airport(caucasus.Novorossiysk, COAST_VERTICAL, SIZE_BIG, IMPORTANCE_HIGH) - gelendzhik = ControlPoint.from_airport(caucasus.Gelendzhik, COAST_VERTICAL, SIZE_BIG, IMPORTANCE_HIGH) + novorossiysk = ControlPoint.from_airport(caucasus.Novorossiysk, COAST_VERTICAL, SIZE_BIG, IMPORTANCE_MEDIUM) krymsk = ControlPoint.from_airport(caucasus.Krymsk, ALL_RADIALS, SIZE_LARGE, IMPORTANCE_HIGH) anapa = ControlPoint.from_airport(caucasus.Anapa_Vityazevo, ALL_RADIALS, SIZE_LARGE, IMPORTANCE_HIGH) - beslan = ControlPoint.from_airport(caucasus.Beslan, ALL_RADIALS, SIZE_REGULAR, IMPORTANCE_MEDIUM) - nalchik = ControlPoint.from_airport(caucasus.Nalchik, ALL_RADIALS, SIZE_REGULAR, IMPORTANCE_MEDIUM) - mineralnye = ControlPoint.from_airport(caucasus.Mineralnye_Vody, ALL_RADIALS, SIZE_BIG, IMPORTANCE_HIGH) - mozdok = ControlPoint.from_airport(caucasus.Mozdok, ALL_RADIALS, SIZE_BIG, IMPORTANCE_HIGH) + beslan = ControlPoint.from_airport(caucasus.Beslan, ALL_RADIALS, SIZE_REGULAR, IMPORTANCE_LOW) + nalchik = ControlPoint.from_airport(caucasus.Nalchik, ALL_RADIALS, SIZE_REGULAR, IMPORTANCE_LOW) + mineralnye = ControlPoint.from_airport(caucasus.Mineralnye_Vody, ALL_RADIALS, SIZE_BIG, IMPORTANCE_MEDIUM) + mozdok = ControlPoint.from_airport(caucasus.Mozdok, ALL_RADIALS, SIZE_BIG, IMPORTANCE_MEDIUM) - #carrier_1 = ControlPoint() + carrier_1 = ControlPoint.carrier("Carrier", mapping.Point(-355810.6875, 516399.1875)) def __init__(self): + super(CaucasusTheater, self).__init__() + + self.carrier_1.captured = True self.soganlug.captured = True self.add_controlpoint(self.soganlug, connected_to=[self.kutaisi, self.beslan]) @@ -50,3 +57,5 @@ class CaucasusTheater(ConflictTheater): self.add_controlpoint(self.krymsk, connected_to=[self.novorossiysk, self.anapa, self.krasnodar]) self.add_controlpoint(self.anapa, connected_to=[self.novorossiysk, self.krymsk]) self.add_controlpoint(self.krasnodar, connected_to=[self.krymsk, self.maykop]) + + self.add_controlpoint(self.carrier_1) diff --git a/theater/conflicttheater.py b/theater/conflicttheater.py index b82abda4..9aba464d 100644 --- a/theater/conflicttheater.py +++ b/theater/conflicttheater.py @@ -20,7 +20,8 @@ COAST_HORIZONTAL = [315, 0, 45, ] class ConflictTheater: - controlpoints = [] # type: typing.List[ControlPoint] + controlpoints = None # type: typing.Collection[ControlPoint] + reference_points = None # type: typing.Dict def __init__(self): self.controlpoints = [] diff --git a/theater/controlpoint.py b/theater/controlpoint.py index 34fa2248..762dd50c 100644 --- a/theater/controlpoint.py +++ b/theater/controlpoint.py @@ -33,9 +33,18 @@ class ControlPoint: def from_airport(cls, airport: Airport, radials: typing.Collection[int], size: int, importance: int): return cls(airport.name, airport.position, airport, radials, size, importance) + @classmethod + def carrier(cls, name: str, at: Point): + import theater.conflicttheater + return cls(name, at, at, theater.conflicttheater.ALL_RADIALS, theater.conflicttheater.SIZE_SMALL, 1) + def __str__(self): return self.name + @property + def is_global(self): + return not self.connected_points + def connect(self, to): self.connected_points.append(to) diff --git a/theater/start_generator.py b/theater/start_generator.py index c46577d4..97c1059a 100644 --- a/theater/start_generator.py +++ b/theater/start_generator.py @@ -19,11 +19,12 @@ def generate_initial(theater: ConflictTheater, enemy: str): for task in [CAP, FighterSweep, CAS, AirDefence]: suitable_unittypes = db.find_unittype(task, enemy) - suitable_unittypes.sort(key=lambda x: db.PRICES[x]) + suitable_unittypes.sort(key=lambda x: db.PRICES[x], reverse=True) - importance = cp.importance * 10 - 10 - units_idx_start = int(importance * UNIT_VARIETY) + importance = IMPORTANCE_HIGH * 10 - cp.importance * 10 + units_idx_start = int(importance) units_idx_end = units_idx_start + UNIT_VARIETY + print("{} - {}-{}".format(cp.name, units_idx_start, units_idx_end)) range_start = min(len(suitable_unittypes)-1, units_idx_start) range_end = min(len(suitable_unittypes), units_idx_end) @@ -31,5 +32,4 @@ def generate_initial(theater: ConflictTheater, enemy: str): typecount = max(math.floor(importance * UNIT_AMOUNT_FACTOR), 1) units = {unittype: typecount for unittype in unittypes} - print("{} - {}".format(cp.name, units)) cp.base.commision_units(units) diff --git a/ui/overviewcanvas.py b/ui/overviewcanvas.py index b124f046..9e1032f4 100644 --- a/ui/overviewcanvas.py +++ b/ui/overviewcanvas.py @@ -4,6 +4,7 @@ from tkinter.ttk import * from ui.window import * from game.game import * +from theater.conflicttheater import * class OverviewCanvas: @@ -18,11 +19,11 @@ class OverviewCanvas: self.game = game def cp_coordinates(self, cp: ControlPoint) -> (int, int): - point_a = (-317948.32727306, 635639.37385346) - point_a_img = 282.5, 319 + point_a = list(self.game.theater.reference_points.keys())[0] + point_a_img = self.game.theater.reference_points[point_a] - point_b = (-355692.3067714, 617269.96285781) - point_b_img = 269, 352 + point_b = list(self.game.theater.reference_points.keys())[1] + point_b_img = self.game.theater.reference_points[point_b] x_dist = point_a_img[0] - point_b_img[0] lon_dist = point_a[1] - point_b[1]