mirror of
https://github.com/dcs-retribution/dcs-retribution.git
synced 2025-11-10 15:41:24 +00:00
Waiting and Debriefing Window, QT UI is now functionnal.
This commit is contained in:
parent
c4dc432be1
commit
adb9e38ff4
@ -1,17 +1,31 @@
|
||||
import logging
|
||||
import os
|
||||
import sys
|
||||
from time import sleep
|
||||
|
||||
import dcs
|
||||
from PySide2.QtGui import QPixmap
|
||||
from PySide2.QtWidgets import QApplication, QLabel, QSplashScreen
|
||||
|
||||
from qt_ui import uiconstants
|
||||
from qt_ui.windows.GameUpdateSignal import GameUpdateSignal
|
||||
from qt_ui.windows.QLiberationWindow import QLiberationWindow
|
||||
from userdata import persistency
|
||||
from userdata import persistency, logging as logging_module
|
||||
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
assert len(sys.argv) >= 3, "__init__.py should be started with two mandatory arguments: %UserProfile% location and application version"
|
||||
|
||||
persistency.setup(sys.argv[1])
|
||||
dcs.planes.FlyingType.payload_dirs = [
|
||||
os.path.join(os.path.dirname(os.path.realpath(__file__)), "resources\\payloads")]
|
||||
|
||||
VERSION_STRING = sys.argv[2]
|
||||
logging_module.setup_version_string(VERSION_STRING)
|
||||
logging.info("Using {} as userdata folder".format(persistency.base_path()))
|
||||
|
||||
app = QApplication(sys.argv)
|
||||
|
||||
# Splash screen setup
|
||||
@ -38,4 +52,5 @@ if __name__ == "__main__":
|
||||
window.show()
|
||||
|
||||
splash.finish(window)
|
||||
sys.exit(app.exec_())
|
||||
sys.exit(app.exec_())
|
||||
|
||||
|
||||
@ -52,7 +52,12 @@ class QMapControlPoint(QGraphicsRectItem):
|
||||
self.update()
|
||||
|
||||
def contextMenuEvent(self, event: QGraphicsSceneContextMenuEvent):
|
||||
openBaseMenu = QAction("Open base menu")
|
||||
|
||||
if self.model.captured:
|
||||
openBaseMenu = QAction("Open base menu")
|
||||
else:
|
||||
openBaseMenu = QAction("Open intel menu")
|
||||
|
||||
openBaseMenu.triggered.connect(self.openBaseMenu)
|
||||
|
||||
menu = QMenu("Menu", self.parent)
|
||||
|
||||
@ -15,7 +15,6 @@ class QMapEvent(QGraphicsRectItem):
|
||||
self.parent = parent
|
||||
self.setAcceptHoverEvents(True)
|
||||
self.setZValue(2)
|
||||
print(x,y,w,h)
|
||||
self.setToolTip(str(self.gameEvent))
|
||||
|
||||
def paint(self, painter, option, widget=None):
|
||||
@ -31,7 +30,6 @@ class QMapEvent(QGraphicsRectItem):
|
||||
painter.setBrush(CONST.COLORS["red"])
|
||||
|
||||
painter.drawRect(option.rect)
|
||||
print(option.rect)
|
||||
painter.drawPixmap(option.rect, CONST.EVENT_ICONS[self.gameEvent.__class__])
|
||||
painter.restore()
|
||||
|
||||
@ -39,5 +37,5 @@ class QMapEvent(QGraphicsRectItem):
|
||||
self.openBriefing()
|
||||
|
||||
def openBriefing(self):
|
||||
self.briefing = QBriefingWindow(self.window(), self.gameEvent)
|
||||
self.briefing = QBriefingWindow(self.gameEvent)
|
||||
self.briefing.show()
|
||||
@ -1,11 +1,22 @@
|
||||
from PySide2.QtCore import QObject, Signal
|
||||
|
||||
from game import Game
|
||||
from game.event import Event, Debriefing
|
||||
|
||||
|
||||
class DebriefingSignal:
|
||||
|
||||
def __init__(self, game, gameEvent, debriefing):
|
||||
self.game = game
|
||||
self.gameEvent = gameEvent
|
||||
self.debriefing = debriefing
|
||||
|
||||
|
||||
class GameUpdateSignal(QObject):
|
||||
|
||||
instance = None
|
||||
gameupdated = Signal(Game)
|
||||
debriefingReceived = Signal(DebriefingSignal)
|
||||
|
||||
def __init__(self):
|
||||
super(GameUpdateSignal, self).__init__()
|
||||
@ -14,6 +25,11 @@ class GameUpdateSignal(QObject):
|
||||
def updateGame(self, game: Game):
|
||||
self.gameupdated.emit(game)
|
||||
|
||||
def sendDebriefing(self, game: Game, gameEvent: Event, debriefing: Debriefing):
|
||||
sig = DebriefingSignal(game, gameEvent, debriefing)
|
||||
self.gameupdated.emit(game)
|
||||
self.debriefingReceived.emit(sig)
|
||||
|
||||
@staticmethod
|
||||
def get_instance():
|
||||
return GameUpdateSignal.instance
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
from PySide2.QtCore import Qt
|
||||
from PySide2.QtGui import QWindow, QCloseEvent
|
||||
from PySide2.QtWidgets import QHBoxLayout, QLabel, QWidget, QFrame, QDialog, QVBoxLayout, QGridLayout, QPushButton
|
||||
from PySide2.QtWidgets import QHBoxLayout, QLabel, QWidget, QFrame, QDialog, QVBoxLayout, QGridLayout, QPushButton, \
|
||||
QGroupBox
|
||||
from dcs.unittype import UnitType
|
||||
|
||||
from game.event import UnitsDeliveryEvent
|
||||
@ -30,7 +31,7 @@ class QBaseMenu(QDialog):
|
||||
self.deliveryEvent = self.game.units_delivery_event(self.cp)
|
||||
|
||||
self.setWindowFlags(Qt.WindowStaysOnTopHint)
|
||||
self.setMinimumSize(200, 200)
|
||||
self.setMinimumSize(300, 200)
|
||||
self.setModal(True)
|
||||
self.initUi()
|
||||
|
||||
@ -52,13 +53,22 @@ class QBaseMenu(QDialog):
|
||||
self.topLayoutWidget.setProperty("style", "baseMenuHeader")
|
||||
self.topLayoutWidget.setLayout(self.topLayout)
|
||||
|
||||
units = {
|
||||
CAP: db.find_unittype(CAP, self.game.player_name),
|
||||
Embarking: db.find_unittype(Embarking, self.game.player_name),
|
||||
AirDefence: db.find_unittype(AirDefence, self.game.player_name),
|
||||
CAS: db.find_unittype(CAS, self.game.player_name),
|
||||
PinpointStrike: db.find_unittype(PinpointStrike, self.game.player_name),
|
||||
}
|
||||
if self.cp.captured:
|
||||
units = {
|
||||
CAP: db.find_unittype(CAP, self.game.player_name),
|
||||
Embarking: db.find_unittype(Embarking, self.game.player_name),
|
||||
CAS: db.find_unittype(CAS, self.game.player_name),
|
||||
PinpointStrike: db.find_unittype(PinpointStrike, self.game.player_name),
|
||||
AirDefence: db.find_unittype(AirDefence, self.game.player_name),
|
||||
}
|
||||
else:
|
||||
units = {
|
||||
CAP: db.find_unittype(CAP, self.game.enemy_name),
|
||||
Embarking: db.find_unittype(Embarking, self.game.enemy_name),
|
||||
AirDefence: db.find_unittype(AirDefence, self.game.enemy_name),
|
||||
CAS: db.find_unittype(CAS, self.game.enemy_name),
|
||||
PinpointStrike: db.find_unittype(PinpointStrike, self.game.enemy_name),
|
||||
}
|
||||
|
||||
self.mainLayout = QVBoxLayout()
|
||||
self.mainLayout.addWidget(self.topLayoutWidget)
|
||||
@ -111,8 +121,33 @@ class QBaseMenu(QDialog):
|
||||
|
||||
for unit_type in units_column:
|
||||
add_purchase_row(unit_type)
|
||||
self.mainLayout.addLayout(self.unitLayout)
|
||||
else:
|
||||
intel = QGroupBox("Intel")
|
||||
intelLayout = QVBoxLayout()
|
||||
|
||||
row = 0
|
||||
for task_type in units.keys():
|
||||
units_column = list(set(units[task_type]))
|
||||
|
||||
if sum([self.cp.base.total_units_of_type(u) for u in units_column]) > 0:
|
||||
|
||||
group = QGroupBox(db.task_name(task_type))
|
||||
groupLayout = QGridLayout()
|
||||
group.setLayout(groupLayout)
|
||||
|
||||
row = 0
|
||||
for unit_type in units_column:
|
||||
existing_units = self.cp.base.total_units_of_type(unit_type)
|
||||
if existing_units == 0:
|
||||
continue
|
||||
groupLayout.addWidget(QLabel("<b>" + db.unit_type_name(unit_type) + "</b>"), row, 0)
|
||||
groupLayout.addWidget(QLabel(str(existing_units)), row, 1)
|
||||
row += 1
|
||||
|
||||
intelLayout.addWidget(group)
|
||||
self.mainLayout.addLayout(intelLayout)
|
||||
|
||||
self.mainLayout.addLayout(self.unitLayout)
|
||||
self.setLayout(self.mainLayout)
|
||||
|
||||
|
||||
|
||||
@ -7,14 +7,15 @@ from pip._internal.utils import typing
|
||||
|
||||
from game.game import AWACS_BUDGET_COST, PinpointStrike, db, Event, FrontlineAttackEvent, FrontlinePatrolEvent, Task, \
|
||||
UnitType
|
||||
from qt_ui.windows.QWaitingForMissionResultWindow import QWaitingForMissionResultWindow
|
||||
from userdata.persistency import base_path
|
||||
import qt_ui.uiconstants as CONST
|
||||
|
||||
|
||||
class QBriefingWindow(QDialog):
|
||||
|
||||
def __init__(self, parent, gameEvent: Event):
|
||||
super(QBriefingWindow, self).__init__(parent)
|
||||
def __init__(self, gameEvent: Event):
|
||||
super(QBriefingWindow, self).__init__()
|
||||
self.gameEvent = gameEvent
|
||||
self.setWindowTitle("Briefing : " + str(gameEvent))
|
||||
self.setMinimumSize(200,200)
|
||||
@ -40,7 +41,7 @@ class QBriefingWindow(QDialog):
|
||||
self.depart_from = QComboBox()
|
||||
|
||||
for cp in [b for b in self.game.theater.controlpoints if b.captured]:
|
||||
self.depart_from.addItem(str(cp.name))
|
||||
self.depart_from.addItem(str(cp.name), cp)
|
||||
|
||||
self.depart_layout.addWidget(self.depart_from_label)
|
||||
self.depart_layout.addWidget(self.depart_from)
|
||||
@ -91,24 +92,11 @@ class QBriefingWindow(QDialog):
|
||||
scramble_row(flight_task, t, c, True, row)
|
||||
row += 1
|
||||
|
||||
# Options
|
||||
|
||||
|
||||
"""
|
||||
header("Ready?")
|
||||
self.error_label = label("", columnspan=4)
|
||||
self.error_label["fg"] = RED
|
||||
Button(self.frame, text="Commit", command=self.start, **STYLES["btn-primary"]).grid(column=0, row=row,
|
||||
sticky=E, padx=5,
|
||||
pady=(10, 10))
|
||||
Button(self.frame, text="Back", command=self.dismiss, **STYLES["btn-warning"]).grid(column=3, row=row,
|
||||
sticky=E, padx=5,
|
||||
pady=(10, 10))"""
|
||||
|
||||
self.action_layout = QHBoxLayout()
|
||||
self.commit_button = QPushButton("Commit")
|
||||
self.back_button = QPushButton("Commit")
|
||||
self.back_button = QPushButton("Cancel")
|
||||
self.commit_button.clicked.connect(self.start)
|
||||
self.back_button.clicked.connect(self.close)
|
||||
self.action_layout.addWidget(self.commit_button)
|
||||
self.action_layout.addWidget(self.back_button)
|
||||
|
||||
@ -169,7 +157,6 @@ class QBriefingWindow(QDialog):
|
||||
def debriefing_directory_location(self) -> str:
|
||||
return os.path.join(base_path(), "liberation_debriefings")
|
||||
|
||||
|
||||
def start(self):
|
||||
|
||||
if self.awacs_checkbox.isChecked() == 1:
|
||||
@ -185,6 +172,11 @@ class QBriefingWindow(QDialog):
|
||||
ca_slots = 0
|
||||
self.gameEvent.ca_slots = ca_slots
|
||||
|
||||
|
||||
# Resolve Departure CP
|
||||
self.gameEvent.departure_cp = self.depart_from.itemData(self.depart_from.currentIndex())
|
||||
|
||||
|
||||
flights = {k: {} for k in self.gameEvent.tasks} # type: db.TaskForceDict
|
||||
units_scramble_counts = {} # type: typing.Dict[typing.Type[UnitType], int]
|
||||
tasks_scramble_counts = {} # type: typing.Dict[typing.Type[Task], int]
|
||||
@ -243,11 +235,12 @@ class QBriefingWindow(QDialog):
|
||||
|
||||
self.gameEvent.player_defending(flights)
|
||||
|
||||
self.gameEvent.departure_cp = self.gameEvent.from_cp
|
||||
self.game.initiate_event(self.gameEvent)
|
||||
|
||||
# EventResultsMenu(self.window, self.parent, self.game, self.gameEvent).display()
|
||||
waiting = QWaitingForMissionResultWindow(self.gameEvent, self.game)
|
||||
waiting.show()
|
||||
|
||||
self.close()
|
||||
|
||||
def showErrorMessage(self, text):
|
||||
about = QMessageBox()
|
||||
|
||||
@ -1,17 +1,82 @@
|
||||
from PySide2.QtGui import QWindow
|
||||
from PySide2.QtWidgets import QHBoxLayout, QLabel, QWidget
|
||||
import os
|
||||
|
||||
from PySide2 import QtCore
|
||||
from PySide2.QtGui import QMovie
|
||||
from PySide2.QtWidgets import QLabel, QDialog, QVBoxLayout, QGroupBox, QGridLayout, QPushButton
|
||||
|
||||
from game.game import Event, db, Game
|
||||
from userdata.debriefing import wait_for_debriefing, Debriefing
|
||||
from userdata.persistency import base_path
|
||||
|
||||
|
||||
class QDebriefingWindow(QWindow):
|
||||
class QDebriefingWindow(QDialog):
|
||||
|
||||
def __init__(self, parent):
|
||||
super(QDebriefingWindow, self).__init__(parent)
|
||||
self.initUi()
|
||||
def __init__(self, debriefing: Debriefing, gameEvent: Event, game: Game):
|
||||
super(QDebriefingWindow, self).__init__()
|
||||
|
||||
def initUi(self):
|
||||
layout = QHBoxLayout()
|
||||
layout.addWidget(QLabel("TODO : This will be the debriefing menu"))
|
||||
self.setModal(True)
|
||||
self.setWindowTitle("Debriefing")
|
||||
self.setMinimumSize(300, 200)
|
||||
|
||||
central_widget = QWidget()
|
||||
central_widget.setLayout(layout)
|
||||
self.setCentralWidget(central_widget)
|
||||
self.game = game
|
||||
self.gameEvent = gameEvent
|
||||
self.debriefing = debriefing
|
||||
|
||||
self.player_losses = debriefing.destroyed_units.get(self.game.player_country, {})
|
||||
self.enemy_losses = debriefing.destroyed_units.get(self.game.enemy_country, {})
|
||||
|
||||
self.initUI()
|
||||
|
||||
def initUI(self):
|
||||
|
||||
self.layout = QVBoxLayout()
|
||||
|
||||
# Result
|
||||
|
||||
if self.gameEvent.is_successfull(self.debriefing):
|
||||
title = QLabel("<b>Operation Succesfull !</b>")
|
||||
title.setProperty("style", "title-success")
|
||||
else:
|
||||
title = QLabel("<b>Operation failed !</b>")
|
||||
title.setProperty("style", "title-danger")
|
||||
self.layout.addWidget(title)
|
||||
|
||||
# Player lost units
|
||||
lostUnits = QGroupBox(self.game.player_country + "'s lost units :")
|
||||
lostUnitsLayout = QGridLayout()
|
||||
lostUnits.setLayout(lostUnitsLayout)
|
||||
|
||||
row = 0
|
||||
for unit_type, count in self.player_losses.items():
|
||||
lostUnitsLayout.addWidget(QLabel(db.unit_type_name(unit_type)), row, 0)
|
||||
lostUnitsLayout.addWidget(QLabel("{}".format(count)), row, 1)
|
||||
row += 1
|
||||
|
||||
self.layout.addWidget(lostUnits)
|
||||
|
||||
# Enemy lost units
|
||||
enemylostUnits = QGroupBox(self.game.enemy_country + "'s lost units :")
|
||||
enemylostUnitsLayout = QGridLayout()
|
||||
enemylostUnits.setLayout(enemylostUnitsLayout)
|
||||
|
||||
row = 0
|
||||
if self.debriefing.destroyed_objects:
|
||||
enemylostUnitsLayout.addWidget(QLabel("Ground assets"), row, 0)
|
||||
enemylostUnitsLayout.addWidget(QLabel("{}".format(len(self.debriefing.destroyed_objects))), row, 1)
|
||||
row += 1
|
||||
|
||||
for unit_type, count in self.enemy_losses.items():
|
||||
if count == 0:
|
||||
continue
|
||||
enemylostUnitsLayout.addWidget(QLabel(db.unit_type_name(unit_type)), row, 0)
|
||||
enemylostUnitsLayout.addWidget(QLabel("{}".format(count)), row, 1)
|
||||
row += 1
|
||||
|
||||
self.layout.addWidget(enemylostUnits)
|
||||
|
||||
# confirm button
|
||||
okay = QPushButton("Okay")
|
||||
okay.clicked.connect(self.close)
|
||||
self.layout.addWidget(okay)
|
||||
|
||||
self.setLayout(self.layout)
|
||||
|
||||
@ -8,7 +8,8 @@ from game import Game
|
||||
from qt_ui.uiconstants import URLS
|
||||
from qt_ui.widgets.QTopPanel import QTopPanel
|
||||
from qt_ui.widgets.map.QLiberationMap import QLiberationMap
|
||||
from qt_ui.windows.GameUpdateSignal import GameUpdateSignal
|
||||
from qt_ui.windows.GameUpdateSignal import GameUpdateSignal, DebriefingSignal
|
||||
from qt_ui.windows.QDebriefingWindow import QDebriefingWindow
|
||||
from qt_ui.windows.QNewGameWizard import NewGameWizard
|
||||
from userdata import persistency
|
||||
|
||||
@ -52,6 +53,7 @@ class QLiberationWindow(QMainWindow):
|
||||
|
||||
def connectSignals(self):
|
||||
GameUpdateSignal.get_instance().gameupdated.connect(self.setGame)
|
||||
GameUpdateSignal.get_instance().debriefingReceived.connect(self.onDebriefing)
|
||||
|
||||
def initActions(self):
|
||||
self.newGameAction = QAction("New Game", self)
|
||||
@ -154,3 +156,8 @@ class QLiberationWindow(QMainWindow):
|
||||
about.setText(text)
|
||||
print(about.textFormat())
|
||||
about.exec_()
|
||||
|
||||
def onDebriefing(self, debrief: DebriefingSignal):
|
||||
print("On Debriefing")
|
||||
self.debriefing = QDebriefingWindow(debrief.debriefing, debrief.gameEvent, debrief.game)
|
||||
self.debriefing.show()
|
||||
|
||||
61
qt_ui/windows/QWaitingForMissionResultWindow.py
Normal file
61
qt_ui/windows/QWaitingForMissionResultWindow.py
Normal file
@ -0,0 +1,61 @@
|
||||
import os
|
||||
|
||||
from PySide2 import QtCore
|
||||
from PySide2.QtGui import QMovie
|
||||
from PySide2.QtWidgets import QLabel, QDialog, QVBoxLayout
|
||||
|
||||
from game.game import Event, Game
|
||||
from qt_ui.windows.GameUpdateSignal import GameUpdateSignal
|
||||
from userdata.debriefing import wait_for_debriefing, Debriefing
|
||||
from userdata.persistency import base_path
|
||||
|
||||
|
||||
class QWaitingForMissionResultWindow(QDialog):
|
||||
|
||||
def __init__(self, gameEvent: Event, game: Game):
|
||||
super(QWaitingForMissionResultWindow, self).__init__()
|
||||
self.setModal(True)
|
||||
self.gameEvent = gameEvent
|
||||
self.game = game
|
||||
self.setWindowTitle("Waiting for mission completion.")
|
||||
self.setWindowFlag(QtCore.Qt.WindowCloseButtonHint, False)
|
||||
|
||||
self.initUi()
|
||||
wait_for_debriefing(lambda debriefing: self.process_debriefing(debriefing))
|
||||
|
||||
def initUi(self):
|
||||
self.layout = QVBoxLayout()
|
||||
self.layout.addWidget(QLabel("<b>You are clear for takeoff !</b>"))
|
||||
self.layout.addWidget(QLabel("In DCS open and play the mission : "))
|
||||
self.layout.addWidget(QLabel("<i>liberation_nextturn</i>"))
|
||||
self.layout.addWidget(QLabel("or"))
|
||||
self.layout.addWidget(QLabel("<i>liberation_nextturn_quick</i>"))
|
||||
self.layout.addWidget(QLabel("<b>Then save the debriefing to the folder :</b>"))
|
||||
self.layout.addWidget(QLabel(self.debriefing_directory_location()))
|
||||
|
||||
progress = QLabel("")
|
||||
progress.setAlignment(QtCore.Qt.AlignCenter)
|
||||
progressBar = QMovie("./resources/ui/loader.gif")
|
||||
progress.setMovie(progressBar)
|
||||
self.layout.addWidget(progress)
|
||||
progressBar.start()
|
||||
|
||||
self.setLayout(self.layout)
|
||||
|
||||
def process_debriefing(self, debriefing: Debriefing):
|
||||
|
||||
print("DEBRIEFING !!")
|
||||
|
||||
debriefing.calculate_units(regular_mission=self.gameEvent.operation.regular_mission,
|
||||
quick_mission=self.gameEvent.operation.quick_mission,
|
||||
player_country=self.game.player_country,
|
||||
enemy_country=self.game.enemy_country)
|
||||
|
||||
self.game.finish_event(event=self.gameEvent, debriefing=debriefing)
|
||||
self.game.pass_turn(ignored_cps=[self.gameEvent.to_cp, ])
|
||||
|
||||
GameUpdateSignal.get_instance().sendDebriefing(self.game, self.gameEvent, debriefing)
|
||||
self.close()
|
||||
|
||||
def debriefing_directory_location(self) -> str:
|
||||
return os.path.join(base_path(), "liberation_debriefings")
|
||||
BIN
resources/ui/loader.gif
Normal file
BIN
resources/ui/loader.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 11 KiB |
@ -139,7 +139,7 @@ class Debriefing:
|
||||
for unit in group.units:
|
||||
if unit.id in self._dead_units:
|
||||
unit_type = db.unit_type_of(unit)
|
||||
logging.info("debriefing: found dead unit {} ({}, {})".format(str(unit.name), unit.id, unit_type))
|
||||
logging.info("debriefing: found dead unit {} ({}, {}) for country {}".format(str(unit.name), unit.id, unit_type, country_name))
|
||||
|
||||
assert country_name
|
||||
assert unit_type
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user