From 23f4df766c501c1ba3d8148a975fecab2ce1ff27 Mon Sep 17 00:00:00 2001 From: Khopa Date: Sun, 9 Aug 2020 17:31:53 +0200 Subject: [PATCH] Now possible to open and save game under different names. --- changelog.md | 2 ++ game/game.py | 4 +++ qt_ui/uiconstants.py | 2 -- qt_ui/widgets/map/QLiberationScene.py | 2 +- qt_ui/windows/QLiberationWindow.py | 37 +++++++++++++++++--------- resources/tools/generate_landmap.py | 2 +- userdata/persistency.py | 38 +++++++++++++++++++++------ 7 files changed, 62 insertions(+), 25 deletions(-) diff --git a/changelog.md b/changelog.md index e1583ec0..a1d9239f 100644 --- a/changelog.md +++ b/changelog.md @@ -1,6 +1,7 @@ # 2.0.10 ## Features/Improvements : +* **[Misc]** Now possible to save game in a different file, and to open DCS Liberation savegame files. (You are not restricted to a single save file anymore) * **[UI/UX]** New dark UI Theme and default theme improvement by Deus * **[UI/UX]** New "satellite" map backgrounds * **[UX]** Base menu is opened with a single mouse click @@ -27,6 +28,7 @@ * **[Mission Generator]** Fixed FW-190A8 spawning with bomb rack for CAP missions * **[Mission Generator]** Fixed A-20G spawning with no payload * **[Mission Generator]** Fixed Su-33 spawning too heavy to take off from carrier +* **[Mission Generator]** Fixed Harrier AV-8B spawning too heavy to take off from tarawa * **[Mission Generator]** Base defense units were not controllable with Combined Arms * **[Mission Generator]** Tanker speed was too low * **[Mission Generator]** Tanker TACAN settings were wrong diff --git a/game/game.py b/game/game.py index d0e846d2..c437d2b1 100644 --- a/game/game.py +++ b/game/game.py @@ -75,6 +75,7 @@ class Game: self.__culling_points = self.compute_conflicts_position() self.__frontlineData = [] self.__destroyed_units = [] + self.savepath = "" self.sanitize_sides() @@ -242,6 +243,9 @@ class Game: gplanner.plan_groundwar() self.ground_planners[cp.id] = gplanner + # Autosave progress + persistency.autosave(self) + def _enemy_reinforcement(self): """ Compute and commision reinforcement for enemy bases diff --git a/qt_ui/uiconstants.py b/qt_ui/uiconstants.py index 56696477..c0f13eac 100644 --- a/qt_ui/uiconstants.py +++ b/qt_ui/uiconstants.py @@ -10,8 +10,6 @@ from userdata.liberation_theme import get_theme_icons URLS : Dict[str, str] = { "Manual": "https://github.com/khopa/dcs_liberation/wiki", - "Troubleshooting": "https://github.com/shdwp/dcs_liberation/wiki/Troubleshooting", - "Modding": "https://github.com/shdwp/dcs_liberation/wiki/Modding-tutorial", "Repository": "https://github.com/khopa/dcs_liberation", "ForumThread": "https://forums.eagle.ru/showthread.php?t=214834", "Issues": "https://github.com/khopa/dcs_liberation/issues" diff --git a/qt_ui/widgets/map/QLiberationScene.py b/qt_ui/widgets/map/QLiberationScene.py index c6989298..30f0b56a 100644 --- a/qt_ui/widgets/map/QLiberationScene.py +++ b/qt_ui/widgets/map/QLiberationScene.py @@ -8,6 +8,6 @@ class QLiberationScene(QGraphicsScene): def __init__(self, parent): super().__init__(parent) - item = self.addText("No save file found. Go to \"File/New Game\" to setup a new campaign.", + item = self.addText("Go to \"File/New Game\" to setup a new campaign or go to \"File/Open\" to load an existing save game.", CONST.FONT_PRIMARY) item.setDefaultTextColor(CONST.COLORS["white"]) diff --git a/qt_ui/windows/QLiberationWindow.py b/qt_ui/windows/QLiberationWindow.py index 50bf8d55..74bd08a3 100644 --- a/qt_ui/windows/QLiberationWindow.py +++ b/qt_ui/windows/QLiberationWindow.py @@ -104,25 +104,23 @@ class QLiberationWindow(QMainWindow): file_menu = self.menu.addMenu("File") file_menu.addAction(self.newGameAction) - file_menu.addAction(QIcon(CONST.ICONS["Open"]), "Open") # TODO : implement + file_menu.addAction(self.openAction) file_menu.addAction(self.saveGameAction) + file_menu.addAction(self.saveAsAction) file_menu.addSeparator() file_menu.addAction(self.showLiberationPrefDialogAction) file_menu.addSeparator() - #file_menu.addAction("Save As") # TODO : implement #file_menu.addAction("Close Current Game", lambda: self.closeGame()) # Not working file_menu.addAction("Exit" , lambda: self.exit()) - help_menu = self.menu.addMenu("Help") + help_menu.addAction("Discord Server", lambda: webbrowser.open_new_tab("https://" + "discord.gg" + "/" + "bKrt" + "rkJ")) + help_menu.addAction("Github Repository", lambda: webbrowser.open_new_tab("https://github.com/khopa/dcs_liberation")) + help_menu.addAction("Releases", lambda: webbrowser.open_new_tab("https://github.com/Khopa/dcs_liberation/releases")) help_menu.addAction("Online Manual", lambda: webbrowser.open_new_tab(URLS["Manual"])) - help_menu.addAction("Discord", lambda: webbrowser.open_new_tab("https://" + "discord.gg" + "/" + "bKrt" + "rkJ")) - #help_menu.addAction("Troubleshooting Guide", lambda: webbrowser.open_new_tab(URLS["Troubleshooting"])) - #help_menu.addAction("Modding Guide", lambda: webbrowser.open_new_tab(URLS["Modding"])) - #help_menu.addSeparator() ----> Note from Khopa : I disable these links since it's not up to date for this branch - #help_menu.addAction("Contribute", lambda: webbrowser.open_new_tab(URLS["Repository"])) - help_menu.addAction("Forum Thread", lambda: webbrowser.open_new_tab(URLS["ForumThread"])) + help_menu.addAction("ED Forum Thread", lambda: webbrowser.open_new_tab(URLS["ForumThread"])) help_menu.addAction("Report an issue", lambda: webbrowser.open_new_tab(URLS["Issues"])) + help_menu.addSeparator() help_menu.addAction(self.showAboutDialogAction) @@ -172,15 +170,28 @@ class QLiberationWindow(QMainWindow): wizard.accepted.connect(lambda: self.onGameGenerated(wizard.generatedGame)) def openFile(self): - file = str(QFileDialog.getOpenFileName(self, "Select game file to open")) + file = QFileDialog.getOpenFileName(self, "Select game file to open", + dir=persistency._dcs_saved_game_folder, + filter="*.liberation") + if file is not None: + game = persistency.load_game(file[0]) + self.setGame(game) + GameUpdateSignal.get_instance().updateGame(self.game) def saveGame(self): logging.info("Saving game") - persistency.save_game(self.game) - GameUpdateSignal.get_instance().updateGame(self.game) + + if self.game.savepath: + persistency.save_game(self.game) + GameUpdateSignal.get_instance().updateGame(self.game) + else: + self.saveGameAs() def saveGameAs(self): - file = str(QFileDialog.getSaveFileName(self, "Save As", dir=persistency._dcs_saved_game_folder)) + file = QFileDialog.getSaveFileName(self, "Save As", dir=persistency._dcs_saved_game_folder, filter="*.liberation") + if file is not None: + self.game.savepath = file[0] + persistency.save_game(self.game) def onGameGenerated(self, game: Game): logging.info("On Game generated") diff --git a/resources/tools/generate_landmap.py b/resources/tools/generate_landmap.py index f4124ba5..6d8d98ce 100644 --- a/resources/tools/generate_landmap.py +++ b/resources/tools/generate_landmap.py @@ -3,7 +3,7 @@ import pickle from dcs.mission import Mission from dcs.planes import A_10C -for terrain in ["cau", "gulf", "nev", "channel"]: +for terrain in ["gulf", "nev", "channel", "normandy"]: print("Terrain " + terrain) m = Mission() m.load_file("./{}_terrain.miz".format(terrain)) diff --git a/userdata/persistency.py b/userdata/persistency.py index 61c0ee9f..9e55dda0 100644 --- a/userdata/persistency.py +++ b/userdata/persistency.py @@ -9,27 +9,25 @@ _file_abs_path = None def setup(user_folder: str): global _dcs_saved_game_folder _dcs_saved_game_folder = user_folder - _file_abs_path = os.path.join(base_path(), "liberation_save") - + _file_abs_path = os.path.join(base_path(), "default.liberation") def base_path() -> str: global _dcs_saved_game_folder assert _dcs_saved_game_folder return _dcs_saved_game_folder - def _save_file() -> str: - return os.path.join(base_path(), "liberation_save") - + return os.path.join(base_path(), "default.liberation") def _temporary_save_file() -> str: - return os.path.join(base_path(), "liberation_save_tmp") + return os.path.join(base_path(), "tmpsave.liberation") +def _autosave_path() -> str: + return os.path.join(base_path(), "autosave.liberation") def _save_file_exists() -> bool: return os.path.exists(_save_file()) - def mission_path_for(name: str) -> str: return os.path.join(base_path(), "Missions", "{}".format(name)) @@ -46,13 +44,37 @@ def restore_game(): logging.error("Invalid Save game") return None +def load_game(path): + with open(path, "rb") as f: + try: + save = pickle.load(f) + save.savepath = path + return save + except: + logging.error("Invalid Save game") + return None def save_game(game) -> bool: try: with open(_temporary_save_file(), "wb") as f: pickle.dump(game, f) - shutil.copy(_temporary_save_file(), _save_file()) + shutil.copy(_temporary_save_file(), game.savepath) return True except Exception as e: logging.error(e) return False + +def autosave(game) -> bool: + """ + Autosave to the autosave location + :param game: Game to save + :return: True if saved succesfully + """ + try: + with open(_autosave_path(), "wb") as f: + pickle.dump(game, f) + return True + except Exception as e: + logging.error(e) + return False +