mirror of
https://github.com/dcs-retribution/dcs-retribution.git
synced 2025-11-10 15:41:24 +00:00
Replace CP integer ID with a UUID.
This allows unique identification across saves. The front-end needs to be able to differentiate the first carrier in game A and the first carrier in game B, but because carriers (and other non-airfield CPs) are assigned IDs sequentially, collisions were to be expected. The front-end can't tell the difference between a reloaded game and a new turn, so we need to ensure different IDs across games. This is a handy cleanup anyway, since callers constructing CPs no longer need to manually track the CP ID counter. Fixes https://github.com/dcs-liberation/dcs_liberation/issues/2078.
This commit is contained in:
parent
941a7d441c
commit
039ac9ec74
@ -208,25 +208,25 @@ export type ListControlPointsApiArg = void;
|
|||||||
export type GetControlPointByIdApiResponse =
|
export type GetControlPointByIdApiResponse =
|
||||||
/** status 200 Successful Response */ ControlPoint;
|
/** status 200 Successful Response */ ControlPoint;
|
||||||
export type GetControlPointByIdApiArg = {
|
export type GetControlPointByIdApiArg = {
|
||||||
cpId: number;
|
cpId: string;
|
||||||
};
|
};
|
||||||
export type ControlPointDestinationInRangeApiResponse =
|
export type ControlPointDestinationInRangeApiResponse =
|
||||||
/** status 200 Successful Response */ boolean;
|
/** status 200 Successful Response */ boolean;
|
||||||
export type ControlPointDestinationInRangeApiArg = {
|
export type ControlPointDestinationInRangeApiArg = {
|
||||||
cpId: number;
|
cpId: string;
|
||||||
lat: number;
|
lat: number;
|
||||||
lng: number;
|
lng: number;
|
||||||
};
|
};
|
||||||
export type SetControlPointDestinationApiResponse =
|
export type SetControlPointDestinationApiResponse =
|
||||||
/** status 204 Successful Response */ undefined;
|
/** status 204 Successful Response */ undefined;
|
||||||
export type SetControlPointDestinationApiArg = {
|
export type SetControlPointDestinationApiArg = {
|
||||||
cpId: number;
|
cpId: string;
|
||||||
body: LatLng;
|
body: LatLng;
|
||||||
};
|
};
|
||||||
export type ClearControlPointDestinationApiResponse =
|
export type ClearControlPointDestinationApiResponse =
|
||||||
/** status 204 Successful Response */ undefined;
|
/** status 204 Successful Response */ undefined;
|
||||||
export type ClearControlPointDestinationApiArg = {
|
export type ClearControlPointDestinationApiArg = {
|
||||||
cpId: number;
|
cpId: string;
|
||||||
};
|
};
|
||||||
export type GetDebugHoldZonesApiResponse =
|
export type GetDebugHoldZonesApiResponse =
|
||||||
/** status 200 Successful Response */ HoldZones;
|
/** status 200 Successful Response */ HoldZones;
|
||||||
@ -302,12 +302,12 @@ export type OpenTgoInfoDialogApiArg = {
|
|||||||
export type OpenNewControlPointPackageDialogApiResponse =
|
export type OpenNewControlPointPackageDialogApiResponse =
|
||||||
/** status 204 Successful Response */ undefined;
|
/** status 204 Successful Response */ undefined;
|
||||||
export type OpenNewControlPointPackageDialogApiArg = {
|
export type OpenNewControlPointPackageDialogApiArg = {
|
||||||
cpId: number;
|
cpId: string;
|
||||||
};
|
};
|
||||||
export type OpenControlPointInfoDialogApiResponse =
|
export type OpenControlPointInfoDialogApiResponse =
|
||||||
/** status 204 Successful Response */ undefined;
|
/** status 204 Successful Response */ undefined;
|
||||||
export type OpenControlPointInfoDialogApiArg = {
|
export type OpenControlPointInfoDialogApiArg = {
|
||||||
cpId: number;
|
cpId: string;
|
||||||
};
|
};
|
||||||
export type ListSupplyRoutesApiResponse =
|
export type ListSupplyRoutesApiResponse =
|
||||||
/** status 200 Successful Response */ SupplyRoute[];
|
/** status 200 Successful Response */ SupplyRoute[];
|
||||||
@ -335,7 +335,7 @@ export type LatLng = {
|
|||||||
lng: number;
|
lng: number;
|
||||||
};
|
};
|
||||||
export type ControlPoint = {
|
export type ControlPoint = {
|
||||||
id: number;
|
id: string;
|
||||||
name: string;
|
name: string;
|
||||||
blue: boolean;
|
blue: boolean;
|
||||||
position: LatLng;
|
position: LatLng;
|
||||||
|
|||||||
@ -4,7 +4,7 @@ import { ControlPoint } from "./liberationApi";
|
|||||||
import { PayloadAction, createSlice } from "@reduxjs/toolkit";
|
import { PayloadAction, createSlice } from "@reduxjs/toolkit";
|
||||||
|
|
||||||
interface ControlPointsState {
|
interface ControlPointsState {
|
||||||
controlPoints: { [key: number]: ControlPoint };
|
controlPoints: { [key: string]: ControlPoint };
|
||||||
}
|
}
|
||||||
|
|
||||||
const initialState: ControlPointsState = {
|
const initialState: ControlPointsState = {
|
||||||
@ -23,7 +23,7 @@ export const controlPointsSlice = createSlice({
|
|||||||
extraReducers: (builder) => {
|
extraReducers: (builder) => {
|
||||||
builder.addCase(gameLoaded, (state, action) => {
|
builder.addCase(gameLoaded, (state, action) => {
|
||||||
state.controlPoints = action.payload.control_points.reduce(
|
state.controlPoints = action.payload.control_points.reduce(
|
||||||
(acc: { [key: number]: ControlPoint }, curr) => {
|
(acc: { [key: string]: ControlPoint }, curr) => {
|
||||||
acc[curr.id] = curr;
|
acc[curr.id] = curr;
|
||||||
return acc;
|
return acc;
|
||||||
},
|
},
|
||||||
|
|||||||
@ -9,7 +9,7 @@ export default function ControlPointsLayer() {
|
|||||||
<LayerGroup>
|
<LayerGroup>
|
||||||
{Object.values(controlPoints.controlPoints).map((controlPoint) => {
|
{Object.values(controlPoints.controlPoints).map((controlPoint) => {
|
||||||
return (
|
return (
|
||||||
<ControlPoint key={controlPoint.name} controlPoint={controlPoint} />
|
<ControlPoint key={controlPoint.id} controlPoint={controlPoint} />
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
</LayerGroup>
|
</LayerGroup>
|
||||||
|
|||||||
@ -1,9 +1,8 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import logging
|
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
from typing import Any, TYPE_CHECKING, Union, Optional
|
from typing import Any, Optional, TYPE_CHECKING, Union
|
||||||
|
|
||||||
from game.ato.flighttype import FlightType
|
from game.ato.flighttype import FlightType
|
||||||
from game.theater.controlpoint import ControlPoint
|
from game.theater.controlpoint import ControlPoint
|
||||||
@ -67,7 +66,7 @@ class CampaignAirWingConfig:
|
|||||||
by_location: dict[ControlPoint, list[SquadronConfig]] = defaultdict(list)
|
by_location: dict[ControlPoint, list[SquadronConfig]] = defaultdict(list)
|
||||||
for base_id, squadron_configs in data.items():
|
for base_id, squadron_configs in data.items():
|
||||||
if isinstance(base_id, int):
|
if isinstance(base_id, int):
|
||||||
base = theater.find_control_point_by_id(base_id)
|
base = theater.find_control_point_by_airport_id(base_id)
|
||||||
else:
|
else:
|
||||||
base = theater.control_point_named(base_id)
|
base = theater.control_point_named(base_id)
|
||||||
|
|
||||||
|
|||||||
@ -3,23 +3,23 @@ from __future__ import annotations
|
|||||||
import itertools
|
import itertools
|
||||||
from functools import cached_property
|
from functools import cached_property
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Iterator, List, Dict, Tuple, TYPE_CHECKING
|
from typing import Iterator, List, TYPE_CHECKING, Tuple
|
||||||
|
from uuid import UUID
|
||||||
|
|
||||||
from dcs import Mission
|
from dcs import Mission
|
||||||
from dcs.countries import CombinedJointTaskForcesBlue, CombinedJointTaskForcesRed
|
from dcs.countries import CombinedJointTaskForcesBlue, CombinedJointTaskForcesRed
|
||||||
from dcs.country import Country
|
from dcs.country import Country
|
||||||
from dcs.planes import F_15C
|
from dcs.planes import F_15C
|
||||||
from dcs.ships import Stennis, LHA_Tarawa, HandyWind, USS_Arleigh_Burke_IIa
|
from dcs.ships import HandyWind, LHA_Tarawa, Stennis, USS_Arleigh_Burke_IIa
|
||||||
from dcs.statics import Fortification, Warehouse
|
from dcs.statics import Fortification, Warehouse
|
||||||
from dcs.terrain import Airport
|
from dcs.terrain import Airport
|
||||||
from dcs.unitgroup import PlaneGroup, ShipGroup, VehicleGroup, StaticGroup
|
from dcs.unitgroup import PlaneGroup, ShipGroup, StaticGroup, VehicleGroup
|
||||||
from dcs.vehicles import Armor, Unarmed, MissilesSS, AirDefence
|
from dcs.vehicles import AirDefence, Armor, MissilesSS, Unarmed
|
||||||
|
|
||||||
from game.point_with_heading import PointWithHeading
|
from game.point_with_heading import PointWithHeading
|
||||||
from game.positioned import Positioned
|
from game.positioned import Positioned
|
||||||
from game.profiling import logged_duration
|
from game.profiling import logged_duration
|
||||||
from game.scenery_group import SceneryGroup
|
from game.scenery_group import SceneryGroup
|
||||||
from game.utils import Distance, meters, Heading
|
|
||||||
from game.theater.controlpoint import (
|
from game.theater.controlpoint import (
|
||||||
Airfield,
|
Airfield,
|
||||||
Carrier,
|
Carrier,
|
||||||
@ -28,6 +28,7 @@ from game.theater.controlpoint import (
|
|||||||
Lha,
|
Lha,
|
||||||
OffMapSpawn,
|
OffMapSpawn,
|
||||||
)
|
)
|
||||||
|
from game.utils import Distance, Heading, meters
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from game.theater.conflicttheater import ConflictTheater
|
from game.theater.conflicttheater import ConflictTheater
|
||||||
@ -94,7 +95,6 @@ class MizCampaignLoader:
|
|||||||
self.mission = Mission()
|
self.mission = Mission()
|
||||||
with logged_duration("Loading miz"):
|
with logged_duration("Loading miz"):
|
||||||
self.mission.load_file(str(miz))
|
self.mission.load_file(str(miz))
|
||||||
self.control_point_id = itertools.count(1000)
|
|
||||||
|
|
||||||
# If there are no red carriers there usually aren't red units. Make sure
|
# If there are no red carriers there usually aren't red units. Make sure
|
||||||
# both countries are initialized so we don't have to deal with None.
|
# both countries are initialized so we don't have to deal with None.
|
||||||
@ -238,7 +238,7 @@ class MizCampaignLoader:
|
|||||||
return SceneryGroup.from_trigger_zones(self.mission.triggers._zones)
|
return SceneryGroup.from_trigger_zones(self.mission.triggers._zones)
|
||||||
|
|
||||||
@cached_property
|
@cached_property
|
||||||
def control_points(self) -> Dict[int, ControlPoint]:
|
def control_points(self) -> dict[UUID, ControlPoint]:
|
||||||
control_points = {}
|
control_points = {}
|
||||||
for airport in self.mission.terrain.airport_list():
|
for airport in self.mission.terrain.airport_list():
|
||||||
if airport.is_blue() or airport.is_red():
|
if airport.is_blue() or airport.is_red():
|
||||||
@ -248,38 +248,20 @@ class MizCampaignLoader:
|
|||||||
for blue in (False, True):
|
for blue in (False, True):
|
||||||
for group in self.off_map_spawns(blue):
|
for group in self.off_map_spawns(blue):
|
||||||
control_point = OffMapSpawn(
|
control_point = OffMapSpawn(
|
||||||
next(self.control_point_id),
|
str(group.name), group.position, starts_blue=blue
|
||||||
str(group.name),
|
|
||||||
group.position,
|
|
||||||
starts_blue=blue,
|
|
||||||
)
|
)
|
||||||
control_point.captured_invert = group.late_activation
|
control_point.captured_invert = group.late_activation
|
||||||
control_points[control_point.id] = control_point
|
control_points[control_point.id] = control_point
|
||||||
for ship in self.carriers(blue):
|
for ship in self.carriers(blue):
|
||||||
control_point = Carrier(
|
control_point = Carrier(ship.name, ship.position, starts_blue=blue)
|
||||||
ship.name,
|
|
||||||
ship.position,
|
|
||||||
next(self.control_point_id),
|
|
||||||
starts_blue=blue,
|
|
||||||
)
|
|
||||||
control_point.captured_invert = ship.late_activation
|
control_point.captured_invert = ship.late_activation
|
||||||
control_points[control_point.id] = control_point
|
control_points[control_point.id] = control_point
|
||||||
for ship in self.lhas(blue):
|
for ship in self.lhas(blue):
|
||||||
control_point = Lha(
|
control_point = Lha(ship.name, ship.position, starts_blue=blue)
|
||||||
ship.name,
|
|
||||||
ship.position,
|
|
||||||
next(self.control_point_id),
|
|
||||||
starts_blue=blue,
|
|
||||||
)
|
|
||||||
control_point.captured_invert = ship.late_activation
|
control_point.captured_invert = ship.late_activation
|
||||||
control_points[control_point.id] = control_point
|
control_points[control_point.id] = control_point
|
||||||
for fob in self.fobs(blue):
|
for fob in self.fobs(blue):
|
||||||
control_point = Fob(
|
control_point = Fob(str(fob.name), fob.position, starts_blue=blue)
|
||||||
str(fob.name),
|
|
||||||
fob.position,
|
|
||||||
next(self.control_point_id),
|
|
||||||
starts_blue=blue,
|
|
||||||
)
|
|
||||||
control_point.captured_invert = fob.late_activation
|
control_point.captured_invert = fob.late_activation
|
||||||
control_points[control_point.id] = control_point
|
control_points[control_point.id] = control_point
|
||||||
|
|
||||||
|
|||||||
@ -12,6 +12,7 @@ from typing import (
|
|||||||
TYPE_CHECKING,
|
TYPE_CHECKING,
|
||||||
Union,
|
Union,
|
||||||
)
|
)
|
||||||
|
from uuid import UUID
|
||||||
|
|
||||||
from game.dcs.aircrafttype import AircraftType
|
from game.dcs.aircrafttype import AircraftType
|
||||||
from game.dcs.groundunittype import GroundUnitType
|
from game.dcs.groundunittype import GroundUnitType
|
||||||
@ -337,8 +338,10 @@ class Debriefing:
|
|||||||
seen = set()
|
seen = set()
|
||||||
captures = []
|
captures = []
|
||||||
for capture in reversed(self.state_data.base_capture_events):
|
for capture in reversed(self.state_data.base_capture_events):
|
||||||
cp_id_str, new_owner_id_str, _name = capture.split("||")
|
# The ID string in the JSON file will be an airport ID for airport captures
|
||||||
cp_id = int(cp_id_str)
|
# but will be a UUID for all other types, since DCS doesn't know the UUIDs
|
||||||
|
# for the captured FOBs.
|
||||||
|
cp_id, new_owner_id_str, _name = capture.split("||")
|
||||||
|
|
||||||
# Only the most recent capture event matters.
|
# Only the most recent capture event matters.
|
||||||
if cp_id in seen:
|
if cp_id in seen:
|
||||||
@ -346,7 +349,12 @@ class Debriefing:
|
|||||||
seen.add(cp_id)
|
seen.add(cp_id)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
control_point = self.game.theater.find_control_point_by_id(cp_id)
|
control_point = self.game.theater.find_control_point_by_airport_id(
|
||||||
|
int(cp_id)
|
||||||
|
)
|
||||||
|
except ValueError:
|
||||||
|
# The CP ID could not be converted to an int, so it's a UUID.
|
||||||
|
control_point = self.game.theater.find_control_point_by_id(UUID(cp_id))
|
||||||
except KeyError:
|
except KeyError:
|
||||||
# Captured base is not a part of the campaign. This happens when neutral
|
# Captured base is not a part of the campaign. This happens when neutral
|
||||||
# bases are near the conflict. Nothing to do.
|
# bases are near the conflict. Nothing to do.
|
||||||
|
|||||||
@ -7,6 +7,7 @@ from collections.abc import Iterator
|
|||||||
from datetime import date, datetime, timedelta
|
from datetime import date, datetime, timedelta
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
from typing import Any, List, TYPE_CHECKING, Type, Union, cast
|
from typing import Any, List, TYPE_CHECKING, Type, Union, cast
|
||||||
|
from uuid import UUID
|
||||||
|
|
||||||
from dcs.countries import Switzerland, USAFAggressors, UnitedNationsPeacekeepers
|
from dcs.countries import Switzerland, USAFAggressors, UnitedNationsPeacekeepers
|
||||||
from dcs.country import Country
|
from dcs.country import Country
|
||||||
@ -105,7 +106,7 @@ class Game:
|
|||||||
self.date = date(start_date.year, start_date.month, start_date.day)
|
self.date = date(start_date.year, start_date.month, start_date.day)
|
||||||
self.game_stats = GameStats()
|
self.game_stats = GameStats()
|
||||||
self.notes = ""
|
self.notes = ""
|
||||||
self.ground_planners: dict[int, GroundPlanner] = {}
|
self.ground_planners: dict[UUID, GroundPlanner] = {}
|
||||||
self.informations: list[Information] = []
|
self.informations: list[Information] = []
|
||||||
self.message("Game Start", "-" * 40)
|
self.message("Game Start", "-" * 40)
|
||||||
# Culling Zones are for areas around points of interest that contain things we may not wish to cull.
|
# Culling Zones are for areas around points of interest that contain things we may not wish to cull.
|
||||||
|
|||||||
@ -3,7 +3,8 @@ from __future__ import annotations
|
|||||||
import logging
|
import logging
|
||||||
import random
|
import random
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
from typing import Dict, List, TYPE_CHECKING
|
from typing import List, TYPE_CHECKING
|
||||||
|
from uuid import UUID
|
||||||
|
|
||||||
from game.data.units import UnitClass
|
from game.data.units import UnitClass
|
||||||
from game.dcs.groundunittype import GroundUnitType
|
from game.dcs.groundunittype import GroundUnitType
|
||||||
@ -82,7 +83,7 @@ class GroundPlanner:
|
|||||||
self.shorad_groups: List[CombatGroup] = []
|
self.shorad_groups: List[CombatGroup] = []
|
||||||
self.recon_groups: List[CombatGroup] = []
|
self.recon_groups: List[CombatGroup] = []
|
||||||
|
|
||||||
self.units_per_cp: Dict[int, List[CombatGroup]] = {}
|
self.units_per_cp: dict[UUID, List[CombatGroup]] = {}
|
||||||
for cp in self.connected_enemy_cp:
|
for cp in self.connected_enemy_cp:
|
||||||
self.units_per_cp[cp.id] = []
|
self.units_per_cp[cp.id] = []
|
||||||
self.reserve: List[CombatGroup] = []
|
self.reserve: List[CombatGroup] = []
|
||||||
|
|||||||
@ -1,4 +1,3 @@
|
|||||||
import copy
|
|
||||||
import logging
|
import logging
|
||||||
import random
|
import random
|
||||||
from typing import Any, Union
|
from typing import Any, Union
|
||||||
@ -8,7 +7,6 @@ from dcs.country import Country
|
|||||||
from dcs.mapping import Vector2
|
from dcs.mapping import Vector2
|
||||||
from dcs.mission import StartType as DcsStartType
|
from dcs.mission import StartType as DcsStartType
|
||||||
from dcs.planes import F_14A, Su_33
|
from dcs.planes import F_14A, Su_33
|
||||||
from dcs.point import PointAction
|
|
||||||
from dcs.ships import KUZNECOW
|
from dcs.ships import KUZNECOW
|
||||||
from dcs.terrain import Airport, NoParkingSlotError
|
from dcs.terrain import Airport, NoParkingSlotError
|
||||||
from dcs.unitgroup import FlyingGroup, ShipGroup, StaticGroup
|
from dcs.unitgroup import FlyingGroup, ShipGroup, StaticGroup
|
||||||
@ -16,10 +14,10 @@ from dcs.unitgroup import FlyingGroup, ShipGroup, StaticGroup
|
|||||||
from game.ato import Flight
|
from game.ato import Flight
|
||||||
from game.ato.flightstate import InFlight
|
from game.ato.flightstate import InFlight
|
||||||
from game.ato.starttype import StartType
|
from game.ato.starttype import StartType
|
||||||
|
from game.ato.traveltime import GroundSpeed
|
||||||
from game.naming import namegen
|
from game.naming import namegen
|
||||||
from game.theater import Airfield, ControlPoint, Fob, NavalControlPoint, OffMapSpawn
|
from game.theater import Airfield, ControlPoint, Fob, NavalControlPoint, OffMapSpawn
|
||||||
from game.utils import feet, meters
|
from game.utils import feet, meters
|
||||||
from game.ato.traveltime import GroundSpeed
|
|
||||||
|
|
||||||
WARM_START_HELI_ALT = meters(500)
|
WARM_START_HELI_ALT = meters(500)
|
||||||
WARM_START_ALTITUDE = meters(3000)
|
WARM_START_ALTITUDE = meters(3000)
|
||||||
@ -79,12 +77,11 @@ class FlightGroupSpawner:
|
|||||||
return self.generate_mid_mission()
|
return self.generate_mid_mission()
|
||||||
|
|
||||||
def create_idle_aircraft(self) -> FlyingGroup[Any]:
|
def create_idle_aircraft(self) -> FlyingGroup[Any]:
|
||||||
assert isinstance(self.flight.squadron.location, Airfield)
|
airport = self.flight.squadron.location.dcs_airport
|
||||||
|
assert airport is not None
|
||||||
group = self._generate_at_airport(
|
group = self._generate_at_airport(
|
||||||
name=namegen.next_aircraft_name(
|
name=namegen.next_aircraft_name(self.country, self.flight),
|
||||||
self.country, self.flight.departure.id, self.flight
|
airport=airport,
|
||||||
),
|
|
||||||
airport=self.flight.squadron.location.airport,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
group.uncontrolled = True
|
group.uncontrolled = True
|
||||||
@ -95,9 +92,7 @@ class FlightGroupSpawner:
|
|||||||
return self.flight.state.spawn_type
|
return self.flight.state.spawn_type
|
||||||
|
|
||||||
def generate_flight_at_departure(self) -> FlyingGroup[Any]:
|
def generate_flight_at_departure(self) -> FlyingGroup[Any]:
|
||||||
name = namegen.next_aircraft_name(
|
name = namegen.next_aircraft_name(self.country, self.flight)
|
||||||
self.country, self.flight.departure.id, self.flight
|
|
||||||
)
|
|
||||||
cp = self.flight.departure
|
cp = self.flight.departure
|
||||||
try:
|
try:
|
||||||
if self.start_type is StartType.IN_FLIGHT:
|
if self.start_type is StartType.IN_FLIGHT:
|
||||||
@ -135,9 +130,7 @@ class FlightGroupSpawner:
|
|||||||
|
|
||||||
def generate_mid_mission(self) -> FlyingGroup[Any]:
|
def generate_mid_mission(self) -> FlyingGroup[Any]:
|
||||||
assert isinstance(self.flight.state, InFlight)
|
assert isinstance(self.flight.state, InFlight)
|
||||||
name = namegen.next_aircraft_name(
|
name = namegen.next_aircraft_name(self.country, self.flight)
|
||||||
self.country, self.flight.departure.id, self.flight
|
|
||||||
)
|
|
||||||
speed = self.flight.state.estimate_speed()
|
speed = self.flight.state.estimate_speed()
|
||||||
pos = self.flight.state.estimate_position()
|
pos = self.flight.state.estimate_position()
|
||||||
pos += Vector2(random.randint(100, 1000), random.randint(100, 1000))
|
pos += Vector2(random.randint(100, 1000), random.randint(100, 1000))
|
||||||
|
|||||||
@ -18,7 +18,6 @@ from game.ato.flightwaypointtype import FlightWaypointType
|
|||||||
from game.ato.starttype import StartType
|
from game.ato.starttype import StartType
|
||||||
from game.missiongenerator.airsupport import AirSupport
|
from game.missiongenerator.airsupport import AirSupport
|
||||||
from game.settings import Settings
|
from game.settings import Settings
|
||||||
from game.theater import ControlPointType
|
|
||||||
from game.utils import pairwise
|
from game.utils import pairwise
|
||||||
from .baiingress import BaiIngressBuilder
|
from .baiingress import BaiIngressBuilder
|
||||||
from .cargostop import CargoStopBuilder
|
from .cargostop import CargoStopBuilder
|
||||||
@ -27,7 +26,6 @@ from .deadingress import DeadIngressBuilder
|
|||||||
from .default import DefaultWaypointBuilder
|
from .default import DefaultWaypointBuilder
|
||||||
from .holdpoint import HoldPointBuilder
|
from .holdpoint import HoldPointBuilder
|
||||||
from .joinpoint import JoinPointBuilder
|
from .joinpoint import JoinPointBuilder
|
||||||
from .splitpoint import SplitPointBuilder
|
|
||||||
from .landingpoint import LandingPointBuilder
|
from .landingpoint import LandingPointBuilder
|
||||||
from .ocaaircraftingress import OcaAircraftIngressBuilder
|
from .ocaaircraftingress import OcaAircraftIngressBuilder
|
||||||
from .ocarunwayingress import OcaRunwayIngressBuilder
|
from .ocarunwayingress import OcaRunwayIngressBuilder
|
||||||
@ -36,6 +34,7 @@ from .racetrack import RaceTrackBuilder
|
|||||||
from .racetrackend import RaceTrackEndBuilder
|
from .racetrackend import RaceTrackEndBuilder
|
||||||
from .refuel import RefuelPointBuilder
|
from .refuel import RefuelPointBuilder
|
||||||
from .seadingress import SeadIngressBuilder
|
from .seadingress import SeadIngressBuilder
|
||||||
|
from .splitpoint import SplitPointBuilder
|
||||||
from .strikeingress import StrikeIngressBuilder
|
from .strikeingress import StrikeIngressBuilder
|
||||||
from .sweepingress import SweepIngressBuilder
|
from .sweepingress import SweepIngressBuilder
|
||||||
|
|
||||||
@ -213,14 +212,12 @@ class WaypointGenerator:
|
|||||||
def prevent_spawn_at_hostile_airbase(self, trigger: TriggerRule) -> None:
|
def prevent_spawn_at_hostile_airbase(self, trigger: TriggerRule) -> None:
|
||||||
# Prevent delayed flights from spawning at airbases if they were
|
# Prevent delayed flights from spawning at airbases if they were
|
||||||
# captured before they've spawned.
|
# captured before they've spawned.
|
||||||
if self.flight.from_cp.cptype != ControlPointType.AIRBASE:
|
if (airport := self.flight.departure.dcs_airport) is not None:
|
||||||
return
|
trigger.add_condition(
|
||||||
|
CoalitionHasAirdrome(
|
||||||
trigger.add_condition(
|
self.flight.squadron.coalition.coalition_id, airport.id
|
||||||
CoalitionHasAirdrome(
|
)
|
||||||
self.flight.squadron.coalition.coalition_id, self.flight.from_cp.id
|
|
||||||
)
|
)
|
||||||
)
|
|
||||||
|
|
||||||
def set_startup_time(self, delay: timedelta) -> None:
|
def set_startup_time(self, delay: timedelta) -> None:
|
||||||
# Uncontrolled causes the AI unit to spawn, but not begin startup.
|
# Uncontrolled causes the AI unit to spawn, but not begin startup.
|
||||||
|
|||||||
@ -227,7 +227,7 @@ class FlotGenerator:
|
|||||||
)[0]
|
)[0]
|
||||||
self.mission.vehicle_group(
|
self.mission.vehicle_group(
|
||||||
side,
|
side,
|
||||||
namegen.next_infantry_name(side, cp.id, u),
|
namegen.next_infantry_name(side, u),
|
||||||
u.dcs_unit_type,
|
u.dcs_unit_type,
|
||||||
position=infantry_position,
|
position=infantry_position,
|
||||||
group_size=1,
|
group_size=1,
|
||||||
@ -252,7 +252,7 @@ class FlotGenerator:
|
|||||||
)
|
)
|
||||||
self.mission.vehicle_group(
|
self.mission.vehicle_group(
|
||||||
side,
|
side,
|
||||||
namegen.next_infantry_name(side, cp.id, units[0]),
|
namegen.next_infantry_name(side, units[0]),
|
||||||
units[0].dcs_unit_type,
|
units[0].dcs_unit_type,
|
||||||
position=infantry_position,
|
position=infantry_position,
|
||||||
group_size=1,
|
group_size=1,
|
||||||
@ -264,7 +264,7 @@ class FlotGenerator:
|
|||||||
position = infantry_position.random_point_within(55, 5)
|
position = infantry_position.random_point_within(55, 5)
|
||||||
self.mission.vehicle_group(
|
self.mission.vehicle_group(
|
||||||
side,
|
side,
|
||||||
namegen.next_infantry_name(side, cp.id, unit),
|
namegen.next_infantry_name(side, unit),
|
||||||
unit.dcs_unit_type,
|
unit.dcs_unit_type,
|
||||||
position=position,
|
position=position,
|
||||||
group_size=1,
|
group_size=1,
|
||||||
@ -782,7 +782,7 @@ class FlotGenerator:
|
|||||||
|
|
||||||
group = self.mission.vehicle_group(
|
group = self.mission.vehicle_group(
|
||||||
side,
|
side,
|
||||||
namegen.next_unit_name(side, cp.id, unit_type),
|
namegen.next_unit_name(side, unit_type),
|
||||||
unit_type.dcs_unit_type,
|
unit_type.dcs_unit_type,
|
||||||
position=at,
|
position=at,
|
||||||
group_size=count,
|
group_size=count,
|
||||||
|
|||||||
@ -2,22 +2,18 @@ from __future__ import annotations
|
|||||||
|
|
||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
from dcs.action import MarkToAll, SetFlag, DoScript, ClearFlag
|
from dcs.action import ClearFlag, DoScript, MarkToAll, SetFlag
|
||||||
from dcs.condition import (
|
from dcs.condition import (
|
||||||
TimeAfter,
|
|
||||||
AllOfCoalitionOutsideZone,
|
AllOfCoalitionOutsideZone,
|
||||||
PartOfCoalitionInZone,
|
|
||||||
FlagIsFalse,
|
FlagIsFalse,
|
||||||
FlagIsTrue,
|
FlagIsTrue,
|
||||||
|
PartOfCoalitionInZone,
|
||||||
|
TimeAfter,
|
||||||
)
|
)
|
||||||
from dcs.mission import Mission
|
from dcs.mission import Mission
|
||||||
from dcs.task import Option
|
from dcs.task import Option
|
||||||
from dcs.translation import String
|
from dcs.translation import String
|
||||||
from dcs.triggers import (
|
from dcs.triggers import Event, TriggerCondition, TriggerOnce
|
||||||
Event,
|
|
||||||
TriggerOnce,
|
|
||||||
TriggerCondition,
|
|
||||||
)
|
|
||||||
from dcs.unit import Skill
|
from dcs.unit import Skill
|
||||||
|
|
||||||
from game.theater import Airfield
|
from game.theater import Airfield
|
||||||
@ -61,9 +57,12 @@ class TriggerGenerator:
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
# Empty neutrals airports
|
# Empty neutrals airports
|
||||||
cp_ids = [cp.id for cp in self.game.theater.controlpoints]
|
airfields = [
|
||||||
|
cp for cp in self.game.theater.controlpoints if isinstance(cp, Airfield)
|
||||||
|
]
|
||||||
|
airport_ids = {cp.airport.id for cp in airfields}
|
||||||
for airport in self.mission.terrain.airport_list():
|
for airport in self.mission.terrain.airport_list():
|
||||||
if airport.id not in cp_ids:
|
if airport.id not in airport_ids:
|
||||||
airport.unlimited_fuel = False
|
airport.unlimited_fuel = False
|
||||||
airport.unlimited_munitions = False
|
airport.unlimited_munitions = False
|
||||||
airport.unlimited_aircrafts = False
|
airport.unlimited_aircrafts = False
|
||||||
@ -76,21 +75,20 @@ class TriggerGenerator:
|
|||||||
airport.operating_level_fuel = 0
|
airport.operating_level_fuel = 0
|
||||||
|
|
||||||
for airport in self.mission.terrain.airport_list():
|
for airport in self.mission.terrain.airport_list():
|
||||||
if airport.id not in cp_ids:
|
if airport.id not in airport_ids:
|
||||||
airport.unlimited_fuel = True
|
airport.unlimited_fuel = True
|
||||||
airport.unlimited_munitions = True
|
airport.unlimited_munitions = True
|
||||||
airport.unlimited_aircrafts = True
|
airport.unlimited_aircrafts = True
|
||||||
|
|
||||||
for cp in self.game.theater.controlpoints:
|
for airfield in airfields:
|
||||||
if isinstance(cp, Airfield):
|
cp_airport = self.mission.terrain.airport_by_id(airfield.airport.id)
|
||||||
cp_airport = self.mission.terrain.airport_by_id(cp.airport.id)
|
if cp_airport is None:
|
||||||
if cp_airport is None:
|
raise RuntimeError(
|
||||||
raise RuntimeError(
|
f"Could not find {airfield.airport.name} in the mission"
|
||||||
f"Could not find {cp.airport.name} in the mission"
|
|
||||||
)
|
|
||||||
cp_airport.set_coalition(
|
|
||||||
cp.captured and player_coalition or enemy_coalition
|
|
||||||
)
|
)
|
||||||
|
cp_airport.set_coalition(
|
||||||
|
airfield.captured and player_coalition or enemy_coalition
|
||||||
|
)
|
||||||
|
|
||||||
def _set_skill(self, player_coalition: str, enemy_coalition: str) -> None:
|
def _set_skill(self, player_coalition: str, enemy_coalition: str) -> None:
|
||||||
"""
|
"""
|
||||||
|
|||||||
@ -2,7 +2,7 @@ from __future__ import annotations
|
|||||||
|
|
||||||
import random
|
import random
|
||||||
import time
|
import time
|
||||||
from typing import List, Any, TYPE_CHECKING
|
from typing import Any, List, TYPE_CHECKING
|
||||||
|
|
||||||
from dcs.country import Country
|
from dcs.country import Country
|
||||||
|
|
||||||
@ -474,45 +474,27 @@ class NameGenerator:
|
|||||||
cls.cargo_ship_number = 0
|
cls.cargo_ship_number = 0
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def next_aircraft_name(
|
def next_aircraft_name(cls, country: Country, flight: Flight) -> str:
|
||||||
cls, country: Country, parent_base_id: int, flight: Flight
|
|
||||||
) -> str:
|
|
||||||
cls.aircraft_number += 1
|
cls.aircraft_number += 1
|
||||||
try:
|
if flight.custom_name:
|
||||||
if flight.custom_name:
|
name_str = flight.custom_name
|
||||||
name_str = flight.custom_name
|
else:
|
||||||
else:
|
|
||||||
name_str = "{} {}".format(
|
|
||||||
flight.package.target.name, flight.flight_type
|
|
||||||
)
|
|
||||||
except AttributeError: # Here to maintain save compatibility with 2.3
|
|
||||||
name_str = "{} {}".format(flight.package.target.name, flight.flight_type)
|
name_str = "{} {}".format(flight.package.target.name, flight.flight_type)
|
||||||
return "{}|{}|{}|{}|{}|".format(
|
return "{}|{}|{}|{}|".format(
|
||||||
name_str,
|
name_str, country.id, cls.aircraft_number, flight.unit_type.name
|
||||||
country.id,
|
|
||||||
cls.aircraft_number,
|
|
||||||
parent_base_id,
|
|
||||||
flight.unit_type.name,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def next_unit_name(
|
def next_unit_name(cls, country: Country, unit_type: UnitType[Any]) -> str:
|
||||||
cls, country: Country, parent_base_id: int, unit_type: UnitType[Any]
|
|
||||||
) -> str:
|
|
||||||
cls.number += 1
|
cls.number += 1
|
||||||
return "unit|{}|{}|{}|{}|".format(
|
return "unit|{}|{}|{}|".format(country.id, cls.number, unit_type.name)
|
||||||
country.id, cls.number, parent_base_id, unit_type.name
|
|
||||||
)
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def next_infantry_name(
|
def next_infantry_name(cls, country: Country, unit_type: UnitType[Any]) -> str:
|
||||||
cls, country: Country, parent_base_id: int, unit_type: UnitType[Any]
|
|
||||||
) -> str:
|
|
||||||
cls.infantry_number += 1
|
cls.infantry_number += 1
|
||||||
return "infantry|{}|{}|{}|{}|".format(
|
return "infantry|{}|{}|{}|".format(
|
||||||
country.id,
|
country.id,
|
||||||
cls.infantry_number,
|
cls.infantry_number,
|
||||||
parent_base_id,
|
|
||||||
unit_type.name,
|
unit_type.name,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING
|
||||||
|
from uuid import UUID
|
||||||
|
|
||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
|
|
||||||
@ -12,7 +13,7 @@ if TYPE_CHECKING:
|
|||||||
|
|
||||||
|
|
||||||
class ControlPointJs(BaseModel):
|
class ControlPointJs(BaseModel):
|
||||||
id: int
|
id: UUID
|
||||||
name: str
|
name: str
|
||||||
blue: bool
|
blue: bool
|
||||||
position: LeafletPoint
|
position: LeafletPoint
|
||||||
|
|||||||
@ -1,3 +1,5 @@
|
|||||||
|
from uuid import UUID
|
||||||
|
|
||||||
from dcs import Point
|
from dcs import Point
|
||||||
from dcs.mapping import LatLng
|
from dcs.mapping import LatLng
|
||||||
from fastapi import APIRouter, Body, Depends, HTTPException, status
|
from fastapi import APIRouter, Body, Depends, HTTPException, status
|
||||||
@ -25,7 +27,7 @@ def list_control_points(
|
|||||||
"/{cp_id}", operation_id="get_control_point_by_id", response_model=ControlPointJs
|
"/{cp_id}", operation_id="get_control_point_by_id", response_model=ControlPointJs
|
||||||
)
|
)
|
||||||
def get_control_point(
|
def get_control_point(
|
||||||
cp_id: int, game: Game = Depends(GameContext.require)
|
cp_id: UUID, game: Game = Depends(GameContext.require)
|
||||||
) -> ControlPointJs:
|
) -> ControlPointJs:
|
||||||
cp = game.theater.find_control_point_by_id(cp_id)
|
cp = game.theater.find_control_point_by_id(cp_id)
|
||||||
if cp is None:
|
if cp is None:
|
||||||
@ -42,7 +44,7 @@ def get_control_point(
|
|||||||
response_model=bool,
|
response_model=bool,
|
||||||
)
|
)
|
||||||
def destination_in_range(
|
def destination_in_range(
|
||||||
cp_id: int, lat: float, lng: float, game: Game = Depends(GameContext.require)
|
cp_id: UUID, lat: float, lng: float, game: Game = Depends(GameContext.require)
|
||||||
) -> bool:
|
) -> bool:
|
||||||
cp = game.theater.find_control_point_by_id(cp_id)
|
cp = game.theater.find_control_point_by_id(cp_id)
|
||||||
if cp is None:
|
if cp is None:
|
||||||
@ -61,7 +63,7 @@ def destination_in_range(
|
|||||||
status_code=status.HTTP_204_NO_CONTENT,
|
status_code=status.HTTP_204_NO_CONTENT,
|
||||||
)
|
)
|
||||||
def set_destination(
|
def set_destination(
|
||||||
cp_id: int,
|
cp_id: UUID,
|
||||||
destination: LeafletPoint = Body(..., title="destination"),
|
destination: LeafletPoint = Body(..., title="destination"),
|
||||||
game: Game = Depends(GameContext.require),
|
game: Game = Depends(GameContext.require),
|
||||||
) -> None:
|
) -> None:
|
||||||
@ -96,7 +98,7 @@ def set_destination(
|
|||||||
operation_id="clear_control_point_destination",
|
operation_id="clear_control_point_destination",
|
||||||
status_code=status.HTTP_204_NO_CONTENT,
|
status_code=status.HTTP_204_NO_CONTENT,
|
||||||
)
|
)
|
||||||
def cancel_travel(cp_id: int, game: Game = Depends(GameContext.require)) -> None:
|
def cancel_travel(cp_id: UUID, game: Game = Depends(GameContext.require)) -> None:
|
||||||
cp = game.theater.find_control_point_by_id(cp_id)
|
cp = game.theater.find_control_point_by_id(cp_id)
|
||||||
if cp is None:
|
if cp is None:
|
||||||
raise HTTPException(
|
raise HTTPException(
|
||||||
|
|||||||
@ -32,7 +32,7 @@ class GameUpdateEventsJs(BaseModel):
|
|||||||
updated_front_lines: set[UUID]
|
updated_front_lines: set[UUID]
|
||||||
deleted_front_lines: set[UUID]
|
deleted_front_lines: set[UUID]
|
||||||
updated_tgos: set[UUID]
|
updated_tgos: set[UUID]
|
||||||
updated_control_points: set[int]
|
updated_control_points: set[UUID]
|
||||||
reset_on_map_center: LeafletPoint | None
|
reset_on_map_center: LeafletPoint | None
|
||||||
game_unloaded: bool
|
game_unloaded: bool
|
||||||
new_turn: bool
|
new_turn: bool
|
||||||
|
|||||||
@ -53,7 +53,7 @@ def show_tgo_info(
|
|||||||
status_code=status.HTTP_204_NO_CONTENT,
|
status_code=status.HTTP_204_NO_CONTENT,
|
||||||
)
|
)
|
||||||
def new_cp_package(
|
def new_cp_package(
|
||||||
cp_id: int,
|
cp_id: UUID,
|
||||||
game: Game = Depends(GameContext.require),
|
game: Game = Depends(GameContext.require),
|
||||||
qt: QtCallbacks = Depends(QtContext.get),
|
qt: QtCallbacks = Depends(QtContext.get),
|
||||||
) -> None:
|
) -> None:
|
||||||
@ -72,7 +72,7 @@ def new_cp_package(
|
|||||||
status_code=status.HTTP_204_NO_CONTENT,
|
status_code=status.HTTP_204_NO_CONTENT,
|
||||||
)
|
)
|
||||||
def show_control_point_info(
|
def show_control_point_info(
|
||||||
cp_id: int,
|
cp_id: UUID,
|
||||||
game: Game = Depends(GameContext.require),
|
game: Game = Depends(GameContext.require),
|
||||||
qt: QtCallbacks = Depends(QtContext.get),
|
qt: QtCallbacks = Depends(QtContext.get),
|
||||||
) -> None:
|
) -> None:
|
||||||
|
|||||||
@ -33,7 +33,7 @@ class GameUpdateEvents:
|
|||||||
updated_front_lines: set[UUID] = field(default_factory=set)
|
updated_front_lines: set[UUID] = field(default_factory=set)
|
||||||
deleted_front_lines: set[UUID] = field(default_factory=set)
|
deleted_front_lines: set[UUID] = field(default_factory=set)
|
||||||
updated_tgos: set[UUID] = field(default_factory=set)
|
updated_tgos: set[UUID] = field(default_factory=set)
|
||||||
updated_control_points: set[int] = field(default_factory=set)
|
updated_control_points: set[UUID] = field(default_factory=set)
|
||||||
reset_on_map_center: LatLng | None = None
|
reset_on_map_center: LatLng | None = None
|
||||||
game_unloaded: bool = False
|
game_unloaded: bool = False
|
||||||
new_turn: bool = False
|
new_turn: bool = False
|
||||||
|
|||||||
@ -5,6 +5,7 @@ import math
|
|||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Dict, Iterator, List, Optional, TYPE_CHECKING, Tuple
|
from typing import Dict, Iterator, List, Optional, TYPE_CHECKING, Tuple
|
||||||
|
from uuid import UUID
|
||||||
|
|
||||||
from dcs.mapping import Point
|
from dcs.mapping import Point
|
||||||
from dcs.terrain import (
|
from dcs.terrain import (
|
||||||
@ -203,11 +204,17 @@ class ConflictTheater:
|
|||||||
assert closest_red is not None
|
assert closest_red is not None
|
||||||
return closest_blue, closest_red
|
return closest_blue, closest_red
|
||||||
|
|
||||||
def find_control_point_by_id(self, id: int) -> ControlPoint:
|
def find_control_point_by_id(self, cp_id: UUID) -> ControlPoint:
|
||||||
for i in self.controlpoints:
|
for i in self.controlpoints:
|
||||||
if i.id == id:
|
if i.id == cp_id:
|
||||||
return i
|
return i
|
||||||
raise KeyError(f"Cannot find ControlPoint with ID {id}")
|
raise KeyError(f"Cannot find ControlPoint with ID {cp_id}")
|
||||||
|
|
||||||
|
def find_control_point_by_airport_id(self, airport_id: int) -> ControlPoint:
|
||||||
|
for cp in self.controlpoints:
|
||||||
|
if cp.dcs_airport is not None and cp.dcs_airport.id == airport_id:
|
||||||
|
return cp
|
||||||
|
raise KeyError(f"Cannot find ControlPoint with airport ID {airport_id}")
|
||||||
|
|
||||||
def control_point_named(self, name: str) -> ControlPoint:
|
def control_point_named(self, name: str) -> ControlPoint:
|
||||||
for cp in self.controlpoints:
|
for cp in self.controlpoints:
|
||||||
|
|||||||
@ -4,6 +4,7 @@ import heapq
|
|||||||
import itertools
|
import itertools
|
||||||
import logging
|
import logging
|
||||||
import math
|
import math
|
||||||
|
import uuid
|
||||||
from abc import ABC, abstractmethod
|
from abc import ABC, abstractmethod
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
from dataclasses import dataclass, field
|
from dataclasses import dataclass, field
|
||||||
@ -21,6 +22,7 @@ from typing import (
|
|||||||
TYPE_CHECKING,
|
TYPE_CHECKING,
|
||||||
Tuple,
|
Tuple,
|
||||||
)
|
)
|
||||||
|
from uuid import UUID
|
||||||
|
|
||||||
from dcs.mapping import Point
|
from dcs.mapping import Point
|
||||||
from dcs.ships import Forrestal, KUZNECOW, LHA_Tarawa, Stennis, Type_071
|
from dcs.ships import Forrestal, KUZNECOW, LHA_Tarawa, Stennis, Type_071
|
||||||
@ -294,7 +296,6 @@ class ControlPoint(MissionTarget, SidcDescribable, ABC):
|
|||||||
# TODO: cptype is obsolete.
|
# TODO: cptype is obsolete.
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
cp_id: int,
|
|
||||||
name: str,
|
name: str,
|
||||||
position: Point,
|
position: Point,
|
||||||
at: StartingPosition,
|
at: StartingPosition,
|
||||||
@ -302,8 +303,7 @@ class ControlPoint(MissionTarget, SidcDescribable, ABC):
|
|||||||
cptype: ControlPointType = ControlPointType.AIRBASE,
|
cptype: ControlPointType = ControlPointType.AIRBASE,
|
||||||
) -> None:
|
) -> None:
|
||||||
super().__init__(name, position)
|
super().__init__(name, position)
|
||||||
# TODO: Should be Airbase specific.
|
self.id = uuid.uuid4()
|
||||||
self.id = cp_id
|
|
||||||
self.full_name = name
|
self.full_name = name
|
||||||
self.at = at
|
self.at = at
|
||||||
self.starts_blue = starts_blue
|
self.starts_blue = starts_blue
|
||||||
@ -321,7 +321,7 @@ class ControlPoint(MissionTarget, SidcDescribable, ABC):
|
|||||||
self.base: Base = Base()
|
self.base: Base = Base()
|
||||||
self.cptype = cptype
|
self.cptype = cptype
|
||||||
# TODO: Should be Airbase specific.
|
# TODO: Should be Airbase specific.
|
||||||
self.stances: Dict[int, CombatStance] = {}
|
self.stances: dict[UUID, CombatStance] = {}
|
||||||
from ..groundunitorders import GroundUnitOrders
|
from ..groundunitorders import GroundUnitOrders
|
||||||
|
|
||||||
self.ground_unit_orders = GroundUnitOrders(self)
|
self.ground_unit_orders = GroundUnitOrders(self)
|
||||||
@ -334,6 +334,10 @@ class ControlPoint(MissionTarget, SidcDescribable, ABC):
|
|||||||
def __repr__(self) -> str:
|
def __repr__(self) -> str:
|
||||||
return f"<{self.__class__}: {self.name}>"
|
return f"<{self.__class__}: {self.name}>"
|
||||||
|
|
||||||
|
@property
|
||||||
|
def dcs_airport(self) -> Airport | None:
|
||||||
|
return None
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def coalition(self) -> Coalition:
|
def coalition(self) -> Coalition:
|
||||||
if self._coalition is None:
|
if self._coalition is None:
|
||||||
@ -956,7 +960,6 @@ class ControlPoint(MissionTarget, SidcDescribable, ABC):
|
|||||||
class Airfield(ControlPoint):
|
class Airfield(ControlPoint):
|
||||||
def __init__(self, airport: Airport, starts_blue: bool) -> None:
|
def __init__(self, airport: Airport, starts_blue: bool) -> None:
|
||||||
super().__init__(
|
super().__init__(
|
||||||
airport.id,
|
|
||||||
airport.name,
|
airport.name,
|
||||||
airport.position,
|
airport.position,
|
||||||
airport,
|
airport,
|
||||||
@ -966,6 +969,10 @@ class Airfield(ControlPoint):
|
|||||||
self.airport = airport
|
self.airport = airport
|
||||||
self._runway_status = RunwayStatus()
|
self._runway_status = RunwayStatus()
|
||||||
|
|
||||||
|
@property
|
||||||
|
def dcs_airport(self) -> Airport:
|
||||||
|
return self.airport
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def symbol_set_and_entity(self) -> tuple[SymbolSet, Entity]:
|
def symbol_set_and_entity(self) -> tuple[SymbolSet, Entity]:
|
||||||
return SymbolSet.LAND_INSTALLATIONS, LandInstallationEntity.AIPORT_AIR_BASE
|
return SymbolSet.LAND_INSTALLATIONS, LandInstallationEntity.AIPORT_AIR_BASE
|
||||||
@ -1142,14 +1149,9 @@ class NavalControlPoint(ControlPoint, ABC):
|
|||||||
|
|
||||||
|
|
||||||
class Carrier(NavalControlPoint):
|
class Carrier(NavalControlPoint):
|
||||||
def __init__(self, name: str, at: Point, cp_id: int, starts_blue: bool):
|
def __init__(self, name: str, at: Point, starts_blue: bool):
|
||||||
super().__init__(
|
super().__init__(
|
||||||
cp_id,
|
name, at, at, starts_blue, cptype=ControlPointType.AIRCRAFT_CARRIER_GROUP
|
||||||
name,
|
|
||||||
at,
|
|
||||||
at,
|
|
||||||
starts_blue,
|
|
||||||
cptype=ControlPointType.AIRCRAFT_CARRIER_GROUP,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@ -1186,15 +1188,8 @@ class Carrier(NavalControlPoint):
|
|||||||
|
|
||||||
|
|
||||||
class Lha(NavalControlPoint):
|
class Lha(NavalControlPoint):
|
||||||
def __init__(self, name: str, at: Point, cp_id: int, starts_blue: bool):
|
def __init__(self, name: str, at: Point, starts_blue: bool):
|
||||||
super().__init__(
|
super().__init__(name, at, at, starts_blue, cptype=ControlPointType.LHA_GROUP)
|
||||||
cp_id,
|
|
||||||
name,
|
|
||||||
at,
|
|
||||||
at,
|
|
||||||
starts_blue,
|
|
||||||
cptype=ControlPointType.LHA_GROUP,
|
|
||||||
)
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def symbol_set_and_entity(self) -> tuple[SymbolSet, Entity]:
|
def symbol_set_and_entity(self) -> tuple[SymbolSet, Entity]:
|
||||||
@ -1223,14 +1218,9 @@ class OffMapSpawn(ControlPoint):
|
|||||||
def runway_is_operational(self) -> bool:
|
def runway_is_operational(self) -> bool:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def __init__(self, cp_id: int, name: str, position: Point, starts_blue: bool):
|
def __init__(self, name: str, position: Point, starts_blue: bool):
|
||||||
super().__init__(
|
super().__init__(
|
||||||
cp_id,
|
name, position, position, starts_blue, cptype=ControlPointType.OFF_MAP
|
||||||
name,
|
|
||||||
position,
|
|
||||||
position,
|
|
||||||
starts_blue,
|
|
||||||
cptype=ControlPointType.OFF_MAP,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@ -1287,15 +1277,8 @@ class OffMapSpawn(ControlPoint):
|
|||||||
|
|
||||||
|
|
||||||
class Fob(ControlPoint):
|
class Fob(ControlPoint):
|
||||||
def __init__(self, name: str, at: Point, cp_id: int, starts_blue: bool):
|
def __init__(self, name: str, at: Point, starts_blue: bool):
|
||||||
super().__init__(
|
super().__init__(name, at, at, starts_blue, cptype=ControlPointType.FOB)
|
||||||
cp_id,
|
|
||||||
name,
|
|
||||||
at,
|
|
||||||
at,
|
|
||||||
starts_blue,
|
|
||||||
cptype=ControlPointType.FOB,
|
|
||||||
)
|
|
||||||
self.name = name
|
self.name = name
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
|||||||
@ -39,12 +39,6 @@ class QBaseMenu2(QDialog):
|
|||||||
self.game_model = game_model
|
self.game_model = game_model
|
||||||
self.objectName = "menuDialogue"
|
self.objectName = "menuDialogue"
|
||||||
|
|
||||||
try:
|
|
||||||
game = self.game_model.game
|
|
||||||
self.airport = game.theater.terrain.airport_by_id(self.cp.id)
|
|
||||||
except:
|
|
||||||
self.airport = None
|
|
||||||
|
|
||||||
if self.cp.captured:
|
if self.cp.captured:
|
||||||
self.deliveryEvent = None
|
self.deliveryEvent = None
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user