mirror of
https://github.com/dcs-retribution/dcs-retribution.git
synced 2025-11-10 15:41:24 +00:00
DCS features a massive range of aircraft and land vehicles, and not all of them make their role(s) clear just from the name alone. What this commit does is add an "information" button (and resultant window) to the recruitment section. This should allow new players to understand what each unit is/does. Current state - every aircraft has a country of origin and an introduction date for that variant. Some also have a small placeholder description, taken from ED's store page for that aircraft. There is also a placeholder picture (taken from a rejected image from my own personal photography) that will, in time, show a banner image of each unit. Todo - add appropriate screenshots for each aircraft's banner, replace the placeholder text for each aircraft (this will take a while...) and add more data points for each unit type, such as a unit role (i.e. "air-superiority fighter", "multirole fighter", etc) or perhaps a list of weapons carried. I also haven't made a start on the huge number of ground units yet.
212 lines
6.8 KiB
Python
212 lines
6.8 KiB
Python
import argparse
|
|
import logging
|
|
import os
|
|
import sys
|
|
from datetime import datetime
|
|
from pathlib import Path
|
|
from typing import Optional
|
|
|
|
import dcs
|
|
from dcs.weapons_data import weapon_ids
|
|
|
|
from PySide2 import QtWidgets
|
|
from PySide2.QtGui import QPixmap
|
|
from PySide2.QtWidgets import QApplication, QSplashScreen
|
|
|
|
from game import Game, db, persistency, VERSION
|
|
from game.data.weapons import (
|
|
WEAPON_FALLBACK_MAP,
|
|
WEAPON_INTRODUCTION_YEARS,
|
|
Weapon,
|
|
)
|
|
from game.settings import Settings
|
|
from game.theater.start_generator import GameGenerator, GeneratorSettings
|
|
from qt_ui import (
|
|
liberation_install,
|
|
liberation_theme,
|
|
logging_config,
|
|
uiconstants,
|
|
)
|
|
from qt_ui.windows.GameUpdateSignal import GameUpdateSignal
|
|
from qt_ui.windows.QLiberationWindow import QLiberationWindow
|
|
from qt_ui.windows.newgame.QCampaignList import Campaign
|
|
from qt_ui.windows.newgame.QNewGameWizard import DEFAULT_BUDGET
|
|
from qt_ui.windows.preferences.QLiberationFirstStartWindow import \
|
|
QLiberationFirstStartWindow
|
|
|
|
|
|
def run_ui(game: Optional[Game] = None) -> None:
|
|
os.environ["QT_AUTO_SCREEN_SCALE_FACTOR"] = "1" # Potential fix for 4K screens
|
|
app = QApplication(sys.argv)
|
|
|
|
# init the theme and load the stylesheet based on the theme index
|
|
liberation_theme.init()
|
|
with open("./resources/stylesheets/"+liberation_theme.get_theme_css_file()) as stylesheet:
|
|
logging.info('Loading stylesheet: %s', liberation_theme.get_theme_css_file())
|
|
app.setStyleSheet(stylesheet.read())
|
|
|
|
# Inject custom payload in pydcs framework
|
|
custom_payloads = os.path.join(os.path.dirname(os.path.realpath(__file__)), "..\\resources\\customized_payloads")
|
|
if os.path.exists(custom_payloads):
|
|
dcs.unittype.FlyingType.payload_dirs.append(custom_payloads)
|
|
else:
|
|
# For release version the path is different.
|
|
custom_payloads = os.path.join(os.path.dirname(os.path.realpath(__file__)),
|
|
"resources\\customized_payloads")
|
|
if os.path.exists(custom_payloads):
|
|
dcs.unittype.FlyingType.payload_dirs.append(custom_payloads)
|
|
|
|
first_start = liberation_install.init()
|
|
if first_start:
|
|
window = QLiberationFirstStartWindow()
|
|
window.exec_()
|
|
|
|
logging.info("Using {} as 'Saved Game Folder'".format(persistency.base_path()))
|
|
logging.info("Using {} as 'DCS installation folder'".format(liberation_install.get_dcs_install_directory()))
|
|
|
|
# Splash screen setup
|
|
pixmap = QPixmap("./resources/ui/splash_screen.png")
|
|
splash = QSplashScreen(pixmap)
|
|
splash.show()
|
|
|
|
# Once splash screen is up : load resources & setup stuff
|
|
uiconstants.load_icons()
|
|
uiconstants.load_event_icons()
|
|
uiconstants.load_aircraft_icons()
|
|
uiconstants.load_vehicle_icons()
|
|
uiconstants.load_aircraft_banners()
|
|
|
|
# Replace DCS Mission scripting file to allow DCS Liberation to work
|
|
try:
|
|
liberation_install.replace_mission_scripting_file()
|
|
except:
|
|
error_dialog = QtWidgets.QErrorMessage()
|
|
error_dialog.setWindowTitle("Wrong DCS installation directory.")
|
|
error_dialog.showMessage("Unable to modify Mission Scripting file. Possible issues with rights. Try running as admin, or please perform the modification of the MissionScripting file manually.")
|
|
error_dialog.exec_()
|
|
|
|
# Apply CSS (need works)
|
|
GameUpdateSignal()
|
|
|
|
# Start window
|
|
window = QLiberationWindow(game)
|
|
window.showMaximized()
|
|
splash.finish(window)
|
|
qt_execution_code = app.exec_()
|
|
|
|
# Restore Mission Scripting file
|
|
logging.info("QT App terminated with status code : " + str(qt_execution_code))
|
|
logging.info("Attempt to restore original mission scripting file")
|
|
liberation_install.restore_original_mission_scripting()
|
|
logging.info("QT process exited with code : " + str(qt_execution_code))
|
|
|
|
|
|
def parse_args() -> argparse.Namespace:
|
|
parser = argparse.ArgumentParser()
|
|
subparsers = parser.add_subparsers(dest="subcommand")
|
|
|
|
def path_arg(arg: str) -> Path:
|
|
path = Path(arg)
|
|
if not path.exists():
|
|
raise argparse.ArgumentTypeError("path does not exist")
|
|
return path
|
|
|
|
parser.add_argument(
|
|
"--warn-missing-weapon-data", action="store_true",
|
|
help="Emits a warning for weapons without date or fallback information."
|
|
)
|
|
|
|
new_game = subparsers.add_parser("new-game")
|
|
|
|
new_game.add_argument(
|
|
"campaign", type=path_arg,
|
|
help="Path to the campaign to start."
|
|
)
|
|
|
|
new_game.add_argument(
|
|
"--blue", default="USA 2005", help="Name of the blue faction."
|
|
)
|
|
|
|
new_game.add_argument(
|
|
"--red", default="Russia 1990", help="Name of the red faction."
|
|
)
|
|
|
|
new_game.add_argument(
|
|
"--supercarrier", action="store_true",
|
|
help="Use the supercarrier module."
|
|
)
|
|
|
|
new_game.add_argument(
|
|
"--auto-procurement", action="store_true",
|
|
help="Automate bluefor procurement."
|
|
)
|
|
|
|
new_game.add_argument(
|
|
"--inverted", action="store_true",
|
|
help="Invert the campaign."
|
|
)
|
|
|
|
return parser.parse_args()
|
|
|
|
|
|
def create_game(campaign_path: Path, blue: str, red: str,
|
|
supercarrier: bool, auto_procurement: bool,
|
|
inverted: bool) -> Game:
|
|
campaign = Campaign.from_json(campaign_path)
|
|
generator = GameGenerator(
|
|
blue, red, campaign.load_theater(),
|
|
Settings(
|
|
supercarrier=supercarrier,
|
|
automate_runway_repair=auto_procurement,
|
|
automate_front_line_reinforcements=auto_procurement,
|
|
automate_aircraft_reinforcements=auto_procurement
|
|
),
|
|
GeneratorSettings(
|
|
start_date=datetime.today(),
|
|
player_budget=DEFAULT_BUDGET,
|
|
enemy_budget=DEFAULT_BUDGET,
|
|
midgame=False,
|
|
inverted=inverted,
|
|
no_carrier=False,
|
|
no_lha=False,
|
|
no_player_navy=False,
|
|
no_enemy_navy=False
|
|
)
|
|
)
|
|
return generator.generate()
|
|
|
|
|
|
def lint_weapon_data() -> None:
|
|
for clsid in weapon_ids:
|
|
weapon = Weapon.from_clsid(clsid)
|
|
if weapon not in WEAPON_INTRODUCTION_YEARS:
|
|
logging.warning(f"{weapon} has no introduction date")
|
|
if weapon not in WEAPON_FALLBACK_MAP:
|
|
logging.warning(f"{weapon} has no fallback")
|
|
|
|
|
|
def main():
|
|
logging_config.init_logging(VERSION)
|
|
|
|
# Load eagerly to catch errors early.
|
|
db.FACTIONS.initialize()
|
|
|
|
game: Optional[Game] = None
|
|
|
|
args = parse_args()
|
|
|
|
# TODO: Flesh out data and then make unconditional.
|
|
if args.warn_missing_weapon_data:
|
|
lint_weapon_data()
|
|
|
|
if args.subcommand == "new-game":
|
|
game = create_game(args.campaign, args.blue, args.red,
|
|
args.supercarrier, args.auto_procurement,
|
|
args.inverted)
|
|
|
|
run_ui(game)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|