mirror of
https://github.com/dcs-retribution/dcs-retribution.git
synced 2025-11-10 15:41:24 +00:00
Restrict transfers to connected bases.
https://github.com/Khopa/dcs_liberation/issues/824
This commit is contained in:
parent
e9ff554f39
commit
65f6a4eddd
@ -8,7 +8,7 @@ from abc import ABC, abstractmethod
|
|||||||
from dataclasses import dataclass, field
|
from dataclasses import dataclass, field
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
from functools import total_ordering
|
from functools import total_ordering
|
||||||
from typing import Any, Dict, Iterator, List, Optional, TYPE_CHECKING, Type
|
from typing import Any, Dict, Iterator, List, Optional, Set, TYPE_CHECKING, Type
|
||||||
|
|
||||||
from dcs.mapping import Point
|
from dcs.mapping import Point
|
||||||
from dcs.ships import (
|
from dcs.ships import (
|
||||||
@ -292,6 +292,23 @@ class ControlPoint(MissionTarget, ABC):
|
|||||||
def is_global(self):
|
def is_global(self):
|
||||||
return not self.connected_points
|
return not self.connected_points
|
||||||
|
|
||||||
|
def transitive_connected_friendly_points(
|
||||||
|
self, seen: Optional[Set[ControlPoint]] = None
|
||||||
|
) -> List[ControlPoint]:
|
||||||
|
if seen is None:
|
||||||
|
seen = {self}
|
||||||
|
|
||||||
|
connected = []
|
||||||
|
for cp in self.connected_points:
|
||||||
|
if cp.captured != self.captured:
|
||||||
|
continue
|
||||||
|
if cp in seen:
|
||||||
|
continue
|
||||||
|
seen.add(cp)
|
||||||
|
connected.append(cp)
|
||||||
|
connected.extend(cp.transitive_connected_friendly_points(seen))
|
||||||
|
return connected
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def is_carrier(self):
|
def is_carrier(self):
|
||||||
"""
|
"""
|
||||||
|
|||||||
23
game/theater/supplyroutes.py
Normal file
23
game/theater/supplyroutes.py
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from typing import Iterator, List, Optional
|
||||||
|
|
||||||
|
from game.theater.controlpoint import ControlPoint
|
||||||
|
|
||||||
|
|
||||||
|
class SupplyRoute:
|
||||||
|
def __init__(self, control_points: List[ControlPoint]) -> None:
|
||||||
|
self.control_points = control_points
|
||||||
|
|
||||||
|
def __contains__(self, item: ControlPoint) -> bool:
|
||||||
|
return item in self.control_points
|
||||||
|
|
||||||
|
def __iter__(self) -> Iterator[ControlPoint]:
|
||||||
|
yield from self.control_points
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def for_control_point(cls, control_point: ControlPoint) -> Optional[SupplyRoute]:
|
||||||
|
connected_friendly_points = control_point.transitive_connected_friendly_points()
|
||||||
|
if not connected_friendly_points:
|
||||||
|
return None
|
||||||
|
return SupplyRoute([control_point] + connected_friendly_points)
|
||||||
@ -24,18 +24,18 @@ from dcs.task import PinpointStrike
|
|||||||
from dcs.unittype import UnitType
|
from dcs.unittype import UnitType
|
||||||
|
|
||||||
from game import db
|
from game import db
|
||||||
from game.theater import ControlPoint
|
from game.theater import ControlPoint, SupplyRoute
|
||||||
from game.transfers import RoadTransferOrder
|
from game.transfers import RoadTransferOrder
|
||||||
from qt_ui.models import GameModel
|
from qt_ui.models import GameModel
|
||||||
from qt_ui.widgets.QLabeledWidget import QLabeledWidget
|
from qt_ui.widgets.QLabeledWidget import QLabeledWidget
|
||||||
|
|
||||||
|
|
||||||
class TransferDestinationComboBox(QComboBox):
|
class TransferDestinationComboBox(QComboBox):
|
||||||
def __init__(self, game_model: GameModel, origin: ControlPoint) -> None:
|
def __init__(self, origin: ControlPoint) -> None:
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
|
||||||
for cp in game_model.game.theater.controlpoints:
|
for cp in SupplyRoute.for_control_point(origin):
|
||||||
if cp != origin and cp.captured and not cp.is_global:
|
if cp != origin and cp.captured:
|
||||||
self.addItem(cp.name, cp)
|
self.addItem(cp.name, cp)
|
||||||
self.model().sort(0)
|
self.model().sort(0)
|
||||||
self.setCurrentIndex(0)
|
self.setCurrentIndex(0)
|
||||||
@ -81,10 +81,10 @@ class UnitTransferList(QFrame):
|
|||||||
|
|
||||||
|
|
||||||
class TransferDestinationPanel(QVBoxLayout):
|
class TransferDestinationPanel(QVBoxLayout):
|
||||||
def __init__(self, label: str, origin: ControlPoint, game_model: GameModel) -> None:
|
def __init__(self, label: str, origin: ControlPoint) -> None:
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
|
||||||
self.source_combo_box = TransferDestinationComboBox(game_model, origin)
|
self.source_combo_box = TransferDestinationComboBox(origin)
|
||||||
self.addLayout(QLabeledWidget(label, self.source_combo_box))
|
self.addLayout(QLabeledWidget(label, self.source_combo_box))
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@ -266,7 +266,7 @@ class NewUnitTransferDialog(QDialog):
|
|||||||
layout = QVBoxLayout()
|
layout = QVBoxLayout()
|
||||||
self.setLayout(layout)
|
self.setLayout(layout)
|
||||||
|
|
||||||
self.dest_panel = TransferDestinationPanel("Destination:", origin, game_model)
|
self.dest_panel = TransferDestinationPanel("Destination:", origin)
|
||||||
self.dest_panel.changed.connect(self.on_destination_changed)
|
self.dest_panel.changed.connect(self.on_destination_changed)
|
||||||
layout.addLayout(self.dest_panel)
|
layout.addLayout(self.dest_panel)
|
||||||
|
|
||||||
|
|||||||
@ -11,7 +11,7 @@ from PySide2.QtWidgets import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
from game import Game, db
|
from game import Game, db
|
||||||
from game.theater import ControlPoint, ControlPointType
|
from game.theater import ControlPoint, ControlPointType, SupplyRoute
|
||||||
from gen.flights.flight import FlightType
|
from gen.flights.flight import FlightType
|
||||||
from qt_ui.dialogs import Dialog
|
from qt_ui.dialogs import Dialog
|
||||||
from qt_ui.models import GameModel
|
from qt_ui.models import GameModel
|
||||||
@ -89,7 +89,7 @@ class QBaseMenu2(QDialog):
|
|||||||
runway_attack_button.setProperty("style", "btn-danger")
|
runway_attack_button.setProperty("style", "btn-danger")
|
||||||
runway_attack_button.clicked.connect(self.new_package)
|
runway_attack_button.clicked.connect(self.new_package)
|
||||||
|
|
||||||
if self.cp.captured and not self.cp.is_global:
|
if self.cp.captured and self.has_transfer_destinations:
|
||||||
transfer_button = QPushButton("Transfer Units")
|
transfer_button = QPushButton("Transfer Units")
|
||||||
bottom_row.addWidget(transfer_button)
|
bottom_row.addWidget(transfer_button)
|
||||||
transfer_button.clicked.connect(self.open_transfer_dialog)
|
transfer_button.clicked.connect(self.open_transfer_dialog)
|
||||||
@ -103,6 +103,10 @@ class QBaseMenu2(QDialog):
|
|||||||
GameUpdateSignal.get_instance().budgetupdated.connect(self.update_budget)
|
GameUpdateSignal.get_instance().budgetupdated.connect(self.update_budget)
|
||||||
self.setLayout(main_layout)
|
self.setLayout(main_layout)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def has_transfer_destinations(self) -> bool:
|
||||||
|
return SupplyRoute.for_control_point(self.cp) is not None
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def can_repair_runway(self) -> bool:
|
def can_repair_runway(self) -> bool:
|
||||||
return self.cp.captured and self.cp.runway_can_be_repaired
|
return self.cp.captured and self.cp.runway_can_be_repaired
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user