Experimental: Add generate script for when a game is launched. It's partially for debugging, and also for players to customize games beyond the scope of the launcher.
This commit is contained in:
parent
6a8f866943
commit
9e73910121
@ -284,6 +284,7 @@ class MenuDialog(QDialog):
|
|||||||
super().__init__(parent)
|
super().__init__(parent)
|
||||||
self.setWindowTitle(title)
|
self.setWindowTitle(title)
|
||||||
self.dialogOptions = options
|
self.dialogOptions = options
|
||||||
|
self.generateScript = False # Flag to indicate script generation
|
||||||
self.init_dialog_ui()
|
self.init_dialog_ui()
|
||||||
|
|
||||||
def init_dialog_ui(self):
|
def init_dialog_ui(self):
|
||||||
@ -316,11 +317,28 @@ class MenuDialog(QDialog):
|
|||||||
setattr(self, f"{key}_widget", dialogWidget)
|
setattr(self, f"{key}_widget", dialogWidget)
|
||||||
dialogLayout.addWidget(dialogWidget)
|
dialogLayout.addWidget(dialogWidget)
|
||||||
|
|
||||||
dialogButtons = QDialogButtonBox(
|
# Custom button box with both Launch and Generate Script options
|
||||||
QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
|
buttonBox = QDialogButtonBox()
|
||||||
dialogButtons.accepted.connect(self.accept)
|
self.launchButton = buttonBox.addButton("Launch Game", QDialogButtonBox.AcceptRole)
|
||||||
dialogButtons.rejected.connect(self.reject)
|
self.scriptButton = buttonBox.addButton("Generate Script", QDialogButtonBox.ActionRole)
|
||||||
dialogLayout.addWidget(dialogButtons)
|
buttonBox.addButton(QDialogButtonBox.Cancel)
|
||||||
|
|
||||||
|
# Connect buttons
|
||||||
|
self.launchButton.clicked.connect(self.acceptLaunch)
|
||||||
|
self.scriptButton.clicked.connect(self.acceptGenerateScript)
|
||||||
|
buttonBox.rejected.connect(self.reject)
|
||||||
|
|
||||||
|
dialogLayout.addWidget(buttonBox)
|
||||||
|
|
||||||
|
def acceptLaunch(self):
|
||||||
|
"""Accept dialog with launch flag"""
|
||||||
|
self.generateScript = False
|
||||||
|
self.accept()
|
||||||
|
|
||||||
|
def acceptGenerateScript(self):
|
||||||
|
"""Accept dialog with script generation flag"""
|
||||||
|
self.generateScript = True
|
||||||
|
self.accept()
|
||||||
|
|
||||||
def get_dialog_values(self) -> dict:
|
def get_dialog_values(self) -> dict:
|
||||||
"""Get the current values from all dialog widgets"""
|
"""Get the current values from all dialog widgets"""
|
||||||
@ -811,6 +829,19 @@ class CustomGameDialog(QDialog):
|
|||||||
class DoomLauncher(QMainWindow):
|
class DoomLauncher(QMainWindow):
|
||||||
"""Main launcher window for Toby Doom"""
|
"""Main launcher window for Toby Doom"""
|
||||||
|
|
||||||
|
deathmatchMaps = [
|
||||||
|
"Com Station (2-4 players)",
|
||||||
|
"Warehouse (2-4 players)",
|
||||||
|
"Sector 3 (2-4 players)",
|
||||||
|
"Dungeon of Doom (2-4 players)",
|
||||||
|
"Ocean Fortress (2-4 players)",
|
||||||
|
"Water Treatment Facility (2-4 players)",
|
||||||
|
"Phobos Base Site 4 (2-4 players)",
|
||||||
|
"Hangar Bay 18 (2-4 players)",
|
||||||
|
"Garden of Demon (2-4 players)",
|
||||||
|
"Outpost 69 (2-4 players)"
|
||||||
|
]
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.setWindowTitle("Toby Doom Launcher")
|
self.setWindowTitle("Toby Doom Launcher")
|
||||||
@ -827,6 +858,563 @@ class DoomLauncher(QMainWindow):
|
|||||||
self.iwadSelector = IWADSelector() # Add IWAD selector
|
self.iwadSelector = IWADSelector() # Add IWAD selector
|
||||||
self.init_launcher_ui()
|
self.init_launcher_ui()
|
||||||
|
|
||||||
|
def generate_single_player_script(self):
|
||||||
|
"""Generate script for single player game"""
|
||||||
|
selectedGame = self.gameCombo.currentText()
|
||||||
|
if selectedGame == "Custom Game":
|
||||||
|
self.generate_custom_game_script()
|
||||||
|
elif selectedGame == "Audio Manual":
|
||||||
|
QMessageBox.information(
|
||||||
|
self,
|
||||||
|
"Not Applicable",
|
||||||
|
"Scripts cannot be generated for Audio Manual"
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
gameFiles = self.get_selected_game_files()
|
||||||
|
if gameFiles:
|
||||||
|
self.generate_launcher_script(gameFiles)
|
||||||
|
|
||||||
|
def generate_deathmatch_script(self):
|
||||||
|
"""Open deathmatch dialog and generate script from settings"""
|
||||||
|
# First show map selection
|
||||||
|
mapOptions = {
|
||||||
|
'map': {
|
||||||
|
'type': 'combobox',
|
||||||
|
'label': 'Select Map',
|
||||||
|
'items': self.deathmatchMaps
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mapDialog = MenuDialog("Select Map", mapOptions, self)
|
||||||
|
if not mapDialog.exec():
|
||||||
|
return
|
||||||
|
|
||||||
|
selectedMap = mapDialog.get_dialog_values()['map']
|
||||||
|
mapIndex = mapOptions['map']['items'].index(selectedMap) + 1 # 1-based index
|
||||||
|
|
||||||
|
# Show game options dialog
|
||||||
|
options = {
|
||||||
|
'mode': {
|
||||||
|
'type': 'combobox',
|
||||||
|
'label': 'Game Mode',
|
||||||
|
'items': [
|
||||||
|
"Host Game",
|
||||||
|
"Join Game",
|
||||||
|
"Bots Only"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
'ip': {
|
||||||
|
'type': 'text',
|
||||||
|
'placeholder': 'Enter IP address to join (required for joining)'
|
||||||
|
},
|
||||||
|
'fraglimit': {
|
||||||
|
'type': 'spinbox',
|
||||||
|
'label': 'Frag Limit',
|
||||||
|
'min': 1,
|
||||||
|
'max': 500,
|
||||||
|
'default': 20
|
||||||
|
},
|
||||||
|
'players': {
|
||||||
|
'type': 'spinbox',
|
||||||
|
'label': 'Number of Players',
|
||||||
|
'min': 2,
|
||||||
|
'max': 4,
|
||||||
|
'default': 2
|
||||||
|
},
|
||||||
|
'skill': {
|
||||||
|
'type': 'spinbox',
|
||||||
|
'label': 'Skill Level',
|
||||||
|
'min': 1,
|
||||||
|
'max': 5,
|
||||||
|
'default': 3
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dialog = MenuDialog("Deathmatch Options", options, self)
|
||||||
|
if dialog.exec():
|
||||||
|
values = dialog.get_dialog_values()
|
||||||
|
gameFiles = self.get_selected_game_files()
|
||||||
|
|
||||||
|
# Add deathmatch map
|
||||||
|
deathMatchMap = str(self.gamePath / "Addons/MAPS/TobyDeathArena_V1-5.wad")
|
||||||
|
if Path(deathMatchMap).exists():
|
||||||
|
gameFiles.append(deathMatchMap)
|
||||||
|
|
||||||
|
gameFlags = self.get_deathmatch_flags(values)
|
||||||
|
|
||||||
|
# Add map selection flag
|
||||||
|
gameFlags.extend(["-warp", str(mapIndex)])
|
||||||
|
|
||||||
|
# Check/set freedm.wad as IWAD
|
||||||
|
freedmPath = self.find_freedm()
|
||||||
|
if not freedmPath:
|
||||||
|
QMessageBox.critical(self, "Error", "Could not find freedm.wad")
|
||||||
|
return
|
||||||
|
|
||||||
|
# Force freedm.wad selection
|
||||||
|
for i in range(self.iwadCombo.count()):
|
||||||
|
if "freedm" in self.iwadCombo.itemText(i).lower():
|
||||||
|
self.iwadCombo.setCurrentIndex(i)
|
||||||
|
break
|
||||||
|
|
||||||
|
self.generate_launcher_script(gameFiles, gameFlags)
|
||||||
|
|
||||||
|
def generate_custom_deathmatch_script(self):
|
||||||
|
"""Generate script for custom deathmatch"""
|
||||||
|
# First find available PK3s for customization
|
||||||
|
pk3List = []
|
||||||
|
for item in self.gamePath.glob('*.pk3'):
|
||||||
|
if item.stat().st_size > 10 * 1024 * 1024: # >10MB
|
||||||
|
pk3List.append(str(item))
|
||||||
|
|
||||||
|
# Add Army of Darkness if available
|
||||||
|
aodWad = self.gamePath / "aoddoom1.wad"
|
||||||
|
if aodWad.exists():
|
||||||
|
pk3List.append(str(aodWad))
|
||||||
|
|
||||||
|
if not pk3List:
|
||||||
|
QMessageBox.warning(self, "Error", "No custom mods found")
|
||||||
|
return
|
||||||
|
|
||||||
|
# Create mod selection dialog
|
||||||
|
modDialog = QDialog(self)
|
||||||
|
modDialog.setWindowTitle("Select Customization")
|
||||||
|
dialogLayout = QVBoxLayout(modDialog)
|
||||||
|
|
||||||
|
modLabel = QLabel("Select Mod:")
|
||||||
|
modCombo = AccessibleComboBox(modDialog)
|
||||||
|
modCombo.setAccessibleName("Mod Selection")
|
||||||
|
for pk3 in pk3List:
|
||||||
|
modCombo.addItem(Path(pk3).stem, userData=pk3)
|
||||||
|
|
||||||
|
dialogLayout.addWidget(modLabel)
|
||||||
|
dialogLayout.addWidget(modCombo)
|
||||||
|
|
||||||
|
buttons = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
|
||||||
|
buttons.accepted.connect(modDialog.accept)
|
||||||
|
buttons.rejected.connect(modDialog.reject)
|
||||||
|
dialogLayout.addWidget(buttons)
|
||||||
|
|
||||||
|
if not modDialog.exec():
|
||||||
|
return
|
||||||
|
|
||||||
|
selectedMod = modCombo.currentData()
|
||||||
|
|
||||||
|
# Show map selection dialog (same as regular deathmatch)
|
||||||
|
mapOptions = {
|
||||||
|
'map': {
|
||||||
|
'type': 'combobox',
|
||||||
|
'label': 'Select Map',
|
||||||
|
'items': self.deathmatchMaps
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mapDialog = MenuDialog("Select Map", mapOptions, self)
|
||||||
|
if not mapDialog.exec():
|
||||||
|
return
|
||||||
|
|
||||||
|
selectedMap = mapDialog.get_dialog_values()['map']
|
||||||
|
mapIndex = mapOptions['map']['items'].index(selectedMap) + 1 # 1-based index
|
||||||
|
|
||||||
|
# Show game options dialog
|
||||||
|
options = {
|
||||||
|
'mode': {
|
||||||
|
'type': 'combobox',
|
||||||
|
'label': 'Game Mode',
|
||||||
|
'items': [
|
||||||
|
"Host Game",
|
||||||
|
"Join Game",
|
||||||
|
"Bots Only"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
'ip': {
|
||||||
|
'type': 'text',
|
||||||
|
'placeholder': 'Enter IP address to join (required for joining)'
|
||||||
|
},
|
||||||
|
'fraglimit': {
|
||||||
|
'type': 'spinbox',
|
||||||
|
'label': 'Frag Limit',
|
||||||
|
'min': 1,
|
||||||
|
'max': 500,
|
||||||
|
'default': 20
|
||||||
|
},
|
||||||
|
'players': {
|
||||||
|
'type': 'spinbox',
|
||||||
|
'label': 'Number of Players',
|
||||||
|
'min': 2,
|
||||||
|
'max': 4,
|
||||||
|
'default': 2
|
||||||
|
},
|
||||||
|
'skill': {
|
||||||
|
'type': 'spinbox',
|
||||||
|
'label': 'Skill Level',
|
||||||
|
'min': 1,
|
||||||
|
'max': 5,
|
||||||
|
'default': 3
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dialog = MenuDialog("Deathmatch Options", options, self)
|
||||||
|
if dialog.exec():
|
||||||
|
values = dialog.get_dialog_values()
|
||||||
|
|
||||||
|
# Set up game files
|
||||||
|
gameFiles = [
|
||||||
|
str(self.gamePath / f"TobyAccMod_V{self.tobyVersion}.pk3")
|
||||||
|
]
|
||||||
|
|
||||||
|
# Add menu addons
|
||||||
|
menuPath = self.gamePath / "Addons/MENU"
|
||||||
|
if menuPath.exists():
|
||||||
|
gameFiles.extend(str(p) for p in menuPath.glob("Toby*.pk3"))
|
||||||
|
|
||||||
|
# Add selected mod
|
||||||
|
gameFiles.append(selectedMod)
|
||||||
|
|
||||||
|
# Add deathmatch map
|
||||||
|
deathMatchMap = str(self.gamePath / "Addons/MAPS/TobyDeathArena_V1-5.wad")
|
||||||
|
if Path(deathMatchMap).exists():
|
||||||
|
gameFiles.append(deathMatchMap)
|
||||||
|
|
||||||
|
# Get deathmatch flags and add map selection
|
||||||
|
gameFlags = self.get_deathmatch_flags(values)
|
||||||
|
gameFlags.extend(["-warp", str(mapIndex)])
|
||||||
|
|
||||||
|
# Check/set freedm.wad as IWAD
|
||||||
|
freedmPath = self.find_freedm()
|
||||||
|
if not freedmPath:
|
||||||
|
QMessageBox.critical(self, "Error", "Could not find freedm.wad")
|
||||||
|
return
|
||||||
|
|
||||||
|
# Force freedm.wad selection
|
||||||
|
for i in range(self.iwadCombo.count()):
|
||||||
|
if "freedm" in self.iwadCombo.itemText(i).lower():
|
||||||
|
self.iwadCombo.setCurrentIndex(i)
|
||||||
|
break
|
||||||
|
|
||||||
|
self.generate_launcher_script(gameFiles, gameFlags)
|
||||||
|
|
||||||
|
def generate_coop_script(self):
|
||||||
|
"""Generate script for co-op mode"""
|
||||||
|
options = {
|
||||||
|
'host': {
|
||||||
|
'type': 'radio',
|
||||||
|
'label': 'Host Game'
|
||||||
|
},
|
||||||
|
'ip': {
|
||||||
|
'type': 'text',
|
||||||
|
'placeholder': 'Enter IP address to join'
|
||||||
|
},
|
||||||
|
'players': {
|
||||||
|
'type': 'spinbox',
|
||||||
|
'label': 'Number of Players',
|
||||||
|
'min': 2,
|
||||||
|
'max': 10,
|
||||||
|
'default': 2
|
||||||
|
},
|
||||||
|
'skill': {
|
||||||
|
'type': 'spinbox',
|
||||||
|
'label': 'Skill Level',
|
||||||
|
'min': 1,
|
||||||
|
'max': 5,
|
||||||
|
'default': 3
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dialog = MenuDialog("Co-op Options", options, self)
|
||||||
|
if dialog.exec():
|
||||||
|
values = dialog.get_dialog_values()
|
||||||
|
gameFiles = self.get_selected_game_files()
|
||||||
|
# Add keyshare for co-op
|
||||||
|
keyshareFile = str(self.gamePath / "keyshare-universal.pk3")
|
||||||
|
if Path(keyshareFile).exists():
|
||||||
|
gameFiles.append(keyshareFile)
|
||||||
|
gameFlags = self.get_coop_flags(values)
|
||||||
|
self.generate_launcher_script(gameFiles, gameFlags)
|
||||||
|
|
||||||
|
def generate_custom_game_script(self):
|
||||||
|
"""Generate script for custom game"""
|
||||||
|
customGames = self.load_custom_games()
|
||||||
|
if not customGames:
|
||||||
|
QMessageBox.warning(
|
||||||
|
self,
|
||||||
|
"No Custom Games",
|
||||||
|
"No custom game configurations found in TobyCustom directory."
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
|
dialog = CustomGameDialog(customGames, self)
|
||||||
|
if not dialog.exec():
|
||||||
|
return
|
||||||
|
|
||||||
|
selectedGame = dialog.get_selected_game()
|
||||||
|
if selectedGame and selectedGame in customGames:
|
||||||
|
config = customGames[selectedGame]
|
||||||
|
|
||||||
|
# Check dependencies before launching
|
||||||
|
if not self.check_dependencies(config.get('dependencies', [])):
|
||||||
|
return
|
||||||
|
|
||||||
|
gameFiles = [] # We'll build this up as we go
|
||||||
|
|
||||||
|
# Always start with TobyAccMod
|
||||||
|
tobyMod = self.gamePath / f"TobyAccMod_V{self.tobyVersion}.pk3"
|
||||||
|
if not tobyMod.exists():
|
||||||
|
QMessageBox.critical(self, "Error", f"Could not find {tobyMod}")
|
||||||
|
return
|
||||||
|
gameFiles.append(str(tobyMod))
|
||||||
|
|
||||||
|
# Handle map selection right after TobyAccMod if specified
|
||||||
|
if config.get('use_map_menu', False) and 'submenu' not in config:
|
||||||
|
mapFiles = ["None"] # Start with None option
|
||||||
|
mapsDir = self.gamePath / "Addons/MAPS"
|
||||||
|
if mapsDir.exists():
|
||||||
|
mapFiles.extend([p.name for p in mapsDir.glob("*.wad")
|
||||||
|
if p.name != "TobyDeathArena_V1-5.wad"])
|
||||||
|
|
||||||
|
# Add Operation MDK as special case
|
||||||
|
opMDK = self.gamePath / "OpMDK.wad"
|
||||||
|
if opMDK.exists():
|
||||||
|
mapFiles.append("OpMDK.wad")
|
||||||
|
|
||||||
|
mapDialog = QDialog(self)
|
||||||
|
mapDialog.setWindowTitle("Select Map")
|
||||||
|
dialogLayout = QVBoxLayout(mapDialog)
|
||||||
|
|
||||||
|
mapLabel = QLabel("Select Map:")
|
||||||
|
mapCombo = AccessibleComboBox(mapDialog)
|
||||||
|
mapCombo.setAccessibleName("Map Selection")
|
||||||
|
mapCombo.addItems(mapFiles)
|
||||||
|
|
||||||
|
dialogLayout.addWidget(mapLabel)
|
||||||
|
dialogLayout.addWidget(mapCombo)
|
||||||
|
|
||||||
|
buttons = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
|
||||||
|
buttons.accepted.connect(mapDialog.accept)
|
||||||
|
buttons.rejected.connect(mapDialog.reject)
|
||||||
|
dialogLayout.addWidget(buttons)
|
||||||
|
|
||||||
|
if not mapDialog.exec():
|
||||||
|
return
|
||||||
|
|
||||||
|
selectedMap = mapCombo.currentText()
|
||||||
|
if selectedMap != "None":
|
||||||
|
if selectedMap == "OpMDK.wad":
|
||||||
|
mapPath = str(self.gamePath / selectedMap)
|
||||||
|
else:
|
||||||
|
mapPath = str(self.gamePath / "Addons/MAPS" / selectedMap)
|
||||||
|
if Path(mapPath).exists():
|
||||||
|
gameFiles.append(mapPath)
|
||||||
|
|
||||||
|
if selectedMap == "TobyDoomLevels.wad":
|
||||||
|
musicRenamer = self.gamePath / "Toby-Doom-Level-Music-Renamer.pk3"
|
||||||
|
if musicRenamer.exists():
|
||||||
|
gameFiles.append(str(musicRenamer))
|
||||||
|
|
||||||
|
# Handle submenu if present
|
||||||
|
if 'submenu' in config:
|
||||||
|
selectedFile = self.show_submenu_dialog(config['submenu'])
|
||||||
|
if not selectedFile:
|
||||||
|
return
|
||||||
|
gameFiles.append(selectedFile)
|
||||||
|
|
||||||
|
# Add remaining files
|
||||||
|
tobyBaseVersion = self.tobyVersion.split('-')[0]
|
||||||
|
for filePath in config.get('files', []):
|
||||||
|
filePath = filePath.format(toby_base_version=tobyBaseVersion)
|
||||||
|
# Handle glob patterns
|
||||||
|
if '*' in filePath:
|
||||||
|
pathObj = self.gamePath / filePath.split('*')[0]
|
||||||
|
pattern = filePath.split('/')[-1]
|
||||||
|
if pathObj.parent.exists():
|
||||||
|
matches = list(pathObj.parent.glob(pattern))
|
||||||
|
gameFiles.extend(str(p) for p in matches)
|
||||||
|
else:
|
||||||
|
fullPath = self.gamePath / filePath
|
||||||
|
if fullPath.exists():
|
||||||
|
gameFiles.append(str(fullPath))
|
||||||
|
|
||||||
|
# Add optional files last
|
||||||
|
for optFile in config.get('optional_files', []):
|
||||||
|
optPath = self.gamePath / optFile
|
||||||
|
if optPath.exists():
|
||||||
|
gameFiles.append(str(optPath))
|
||||||
|
|
||||||
|
# Get any custom flags
|
||||||
|
gameFlags = config.get('flags', [])
|
||||||
|
|
||||||
|
# Generate the script if we have files
|
||||||
|
if gameFiles:
|
||||||
|
iwadIndex = self.iwadCombo.currentIndex()
|
||||||
|
if iwadIndex < 0:
|
||||||
|
QMessageBox.critical(self, "Error", "Please select an IWAD first")
|
||||||
|
return
|
||||||
|
|
||||||
|
self.generate_launcher_script(gameFiles, gameFlags)
|
||||||
|
|
||||||
|
def generate_launcher_script(self, gameFiles, gameFlags=None):
|
||||||
|
"""Generate a batch or bash script for launching the game"""
|
||||||
|
if not gameFiles:
|
||||||
|
return
|
||||||
|
|
||||||
|
gzdoomPath = self.find_gzdoom()
|
||||||
|
if not gzdoomPath:
|
||||||
|
QMessageBox.critical(self, "Error", "GZDoom executable not found")
|
||||||
|
return
|
||||||
|
|
||||||
|
# Get selected IWAD
|
||||||
|
iwadIndex = self.iwadCombo.currentIndex()
|
||||||
|
if iwadIndex < 0:
|
||||||
|
QMessageBox.critical(self, "Error", "Please select an IWAD first")
|
||||||
|
return
|
||||||
|
|
||||||
|
iwadPath = self.iwadCombo.itemData(iwadIndex)
|
||||||
|
iwadName = self.iwadCombo.currentText().lower()
|
||||||
|
|
||||||
|
# Get selected game type
|
||||||
|
selectedGame = self.gameCombo.currentText().replace(" ", "_").lower()
|
||||||
|
|
||||||
|
# Initialize gameFlags if None
|
||||||
|
if gameFlags is None:
|
||||||
|
gameFlags = []
|
||||||
|
|
||||||
|
# Get additional flags from doom_flags.txt
|
||||||
|
additionalFlags = self.get_flags_from_file()
|
||||||
|
if additionalFlags:
|
||||||
|
gameFlags.extend(additionalFlags)
|
||||||
|
|
||||||
|
# Determine file format based on OS
|
||||||
|
extension = ".bat" if platform.system() == "Windows" else ".sh"
|
||||||
|
baseFileName = f"{iwadName}_{selectedGame}{extension}"
|
||||||
|
|
||||||
|
# Handle special case for custom games or different dialogs
|
||||||
|
if selectedGame == "custom_game":
|
||||||
|
baseFileName = f"{iwadName}_custom_game{extension}"
|
||||||
|
elif "-deathmatch" in gameFlags or any("deathmatch" in flag.lower() for flag in gameFlags):
|
||||||
|
baseFileName = f"{iwadName}_deathmatch{extension}"
|
||||||
|
elif "-join" in gameFlags or "-host" in gameFlags:
|
||||||
|
baseFileName = f"{iwadName}_coop{extension}"
|
||||||
|
|
||||||
|
# Clean up the filename (remove any unsafe characters)
|
||||||
|
baseFileName = re.sub(r'[^\w\-\.]', '_', baseFileName)
|
||||||
|
|
||||||
|
if platform.system() == "Windows":
|
||||||
|
# Windows: save in current directory
|
||||||
|
baseDir = Path.cwd()
|
||||||
|
|
||||||
|
# Build Windows batch file content
|
||||||
|
content = ["@echo off"]
|
||||||
|
|
||||||
|
# Use gzdoom.exe with line continuation character
|
||||||
|
content.append("gzdoom.exe ^")
|
||||||
|
content.append(" -stdout ^")
|
||||||
|
|
||||||
|
# Add config file
|
||||||
|
configFile = Path.cwd() / 'TobyConfig.ini'
|
||||||
|
if configFile.exists():
|
||||||
|
content.append(f" -config TobyConfig.ini ^")
|
||||||
|
|
||||||
|
# Add narration type
|
||||||
|
narrationType = self.get_narration_type()
|
||||||
|
content.append(f" +Toby_NarrationOutputType {narrationType} ^")
|
||||||
|
|
||||||
|
# Add IWAD
|
||||||
|
content.append(f" -iwad \"{iwadPath}\" ^")
|
||||||
|
|
||||||
|
# Add game files
|
||||||
|
for file in gameFiles:
|
||||||
|
# Use relative paths with ./ prefix for better readability if possible
|
||||||
|
if str(file).startswith(str(self.gamePath)):
|
||||||
|
relPath = Path(file).relative_to(self.gamePath)
|
||||||
|
content.append(f" -file \"./{relPath}\" ^")
|
||||||
|
else:
|
||||||
|
content.append(f" -file \"{file}\" ^")
|
||||||
|
|
||||||
|
# Add game flags
|
||||||
|
for flag in gameFlags:
|
||||||
|
content.append(f" {flag} ^")
|
||||||
|
|
||||||
|
# Remove the trailing ^ from the last line
|
||||||
|
if content[-1].endswith(" ^"):
|
||||||
|
content[-1] = content[-1][:-2]
|
||||||
|
|
||||||
|
# Add TTS powershell script
|
||||||
|
content.append(" | powershell -ExecutionPolicy Bypass -File DoomTTS.ps1")
|
||||||
|
|
||||||
|
else:
|
||||||
|
# Linux/Mac: save in ~/.local/games/doom
|
||||||
|
baseDir = Path.home() / ".local/games/doom"
|
||||||
|
baseDir.mkdir(parents=True, exist_ok=True) # Create directory if it doesn't exist
|
||||||
|
|
||||||
|
# Build bash script content
|
||||||
|
content = ["#!/usr/bin/env bash"]
|
||||||
|
|
||||||
|
# Use 'exec' with stdbuf, but with line continuations
|
||||||
|
content.append("exec stdbuf -oL /usr/bin/gzdoom \\")
|
||||||
|
|
||||||
|
# Add IWAD
|
||||||
|
content.append(f" -iwad \"{iwadPath}\" \\")
|
||||||
|
|
||||||
|
# Add -file flag before listing the files
|
||||||
|
content.append(" -file \\")
|
||||||
|
|
||||||
|
# Add each game file on its own line
|
||||||
|
for i, file in enumerate(gameFiles):
|
||||||
|
if i < len(gameFiles) - 1:
|
||||||
|
content.append(f" \"{file}\" \\")
|
||||||
|
else:
|
||||||
|
# Last file doesn't need continuation
|
||||||
|
content.append(f" \"{file}\"")
|
||||||
|
|
||||||
|
# Add game flags if present
|
||||||
|
if gameFlags:
|
||||||
|
content.append(" \\") # Add continuation
|
||||||
|
for i, flag in enumerate(gameFlags):
|
||||||
|
if i < len(gameFlags) - 1:
|
||||||
|
content.append(f" {flag} \\")
|
||||||
|
else:
|
||||||
|
# Last flag doesn't need continuation
|
||||||
|
content.append(f" {flag}")
|
||||||
|
|
||||||
|
# This waits for a line of dashes, then starts piping to speech-dispatcher
|
||||||
|
content[-1] = content[-1] + " |"
|
||||||
|
content.append("grep --line-buffered -A 1000000 '^-\\+-*$' |")
|
||||||
|
content.append("grep --line-buffered -v -e '^Unknown' -e '^fluidsynth:'|")
|
||||||
|
content.append("sed -u -e 's/^\\[Toby Accessibility Mod\\] //' -e 's/^M_//' -e 's/\\([a-z]\\)\\([A-Z]\\)/\\1 \\2/g' -e 's/\\([A-Za-z]\\+\\)menu\\>/\\1 menu/g' -e 's/^\\([A-Z][A-Z]*\\)G$/\\L\\1\\E game/g' |")
|
||||||
|
content.append("spd-say --wait -e")
|
||||||
|
|
||||||
|
# Generate a unique filename
|
||||||
|
fileName = baseFileName
|
||||||
|
filePath = baseDir / fileName
|
||||||
|
counter = 1
|
||||||
|
|
||||||
|
# Check if file exists and generate new name if needed
|
||||||
|
while filePath.exists():
|
||||||
|
nameBase, extension = baseFileName.rsplit('.', 1)
|
||||||
|
fileName = f"{nameBase}_{counter}.{extension}"
|
||||||
|
filePath = baseDir / fileName
|
||||||
|
counter += 1
|
||||||
|
|
||||||
|
try:
|
||||||
|
with open(filePath, 'w') as f:
|
||||||
|
f.write('\n'.join(content))
|
||||||
|
|
||||||
|
# Make the file executable on Linux/Mac
|
||||||
|
if platform.system() != "Windows":
|
||||||
|
os.chmod(filePath, 0o755)
|
||||||
|
|
||||||
|
QMessageBox.information(
|
||||||
|
self,
|
||||||
|
"Success",
|
||||||
|
f"Launcher script saved to {filePath}"
|
||||||
|
)
|
||||||
|
except Exception as e:
|
||||||
|
QMessageBox.critical(
|
||||||
|
self,
|
||||||
|
"Error",
|
||||||
|
f"Failed to save launcher script: {e}"
|
||||||
|
)
|
||||||
|
|
||||||
def keyPressEvent(self, event):
|
def keyPressEvent(self, event):
|
||||||
"""Handle key press events"""
|
"""Handle key press events"""
|
||||||
if event.key() == Qt.Key_Escape:
|
if event.key() == Qt.Key_Escape:
|
||||||
@ -881,31 +1469,62 @@ class DoomLauncher(QMainWindow):
|
|||||||
mainLayout.addWidget(QLabel("Narration Style:"))
|
mainLayout.addWidget(QLabel("Narration Style:"))
|
||||||
mainLayout.addWidget(self.narrationCombo)
|
mainLayout.addWidget(self.narrationCombo)
|
||||||
|
|
||||||
# Create buttons
|
# Create button layouts with pairs of launch and generate buttons
|
||||||
|
# Single Player
|
||||||
|
singlePlayerLayout = QHBoxLayout()
|
||||||
self.singlePlayerBtn = QPushButton("&Single Player")
|
self.singlePlayerBtn = QPushButton("&Single Player")
|
||||||
self.deathMatchBtn = QPushButton("&Deathmatch")
|
self.singlePlayerGenBtn = QPushButton("Generate Single Player Script")
|
||||||
self.customDeathMatchBtn = QPushButton("C&ustom Deathmatch") # Alt+U
|
|
||||||
self.coopBtn = QPushButton("&Co-op")
|
|
||||||
self.audioManualBtn = QPushButton("&Audio Manual") # Alt+A
|
|
||||||
|
|
||||||
self.singlePlayerBtn.clicked.connect(self.launch_single_player)
|
self.singlePlayerBtn.clicked.connect(self.launch_single_player)
|
||||||
|
self.singlePlayerGenBtn.clicked.connect(self.generate_single_player_script)
|
||||||
|
singlePlayerLayout.addWidget(self.singlePlayerBtn)
|
||||||
|
singlePlayerLayout.addWidget(self.singlePlayerGenBtn)
|
||||||
|
mainLayout.addLayout(singlePlayerLayout)
|
||||||
|
|
||||||
|
# Deathmatch
|
||||||
|
deathMatchLayout = QHBoxLayout()
|
||||||
|
self.deathMatchBtn = QPushButton("&Deathmatch")
|
||||||
|
self.deathMatchGenBtn = QPushButton("Generate Deathmatch Script")
|
||||||
self.deathMatchBtn.clicked.connect(self.show_deathmatch_dialog)
|
self.deathMatchBtn.clicked.connect(self.show_deathmatch_dialog)
|
||||||
self.customDeathMatchBtn.clicked.connect(self.show_custom_deathmatch_dialog) # New line
|
self.deathMatchGenBtn.clicked.connect(self.generate_deathmatch_script)
|
||||||
|
deathMatchLayout.addWidget(self.deathMatchBtn)
|
||||||
|
deathMatchLayout.addWidget(self.deathMatchGenBtn)
|
||||||
|
mainLayout.addLayout(deathMatchLayout)
|
||||||
|
|
||||||
|
# Custom Deathmatch
|
||||||
|
customDeathMatchLayout = QHBoxLayout()
|
||||||
|
self.customDeathMatchBtn = QPushButton("C&ustom Deathmatch") # Alt+U
|
||||||
|
self.customDeathMatchGenBtn = QPushButton("Generate Custom Deathmatch Script")
|
||||||
|
self.customDeathMatchBtn.clicked.connect(self.show_custom_deathmatch_dialog)
|
||||||
|
self.customDeathMatchGenBtn.clicked.connect(self.generate_custom_deathmatch_script)
|
||||||
|
customDeathMatchLayout.addWidget(self.customDeathMatchBtn)
|
||||||
|
customDeathMatchLayout.addWidget(self.customDeathMatchGenBtn)
|
||||||
|
mainLayout.addLayout(customDeathMatchLayout)
|
||||||
|
|
||||||
|
# Co-op
|
||||||
|
coopLayout = QHBoxLayout()
|
||||||
|
self.coopBtn = QPushButton("&Co-op")
|
||||||
|
self.coopGenBtn = QPushButton("Generate Co-op Script")
|
||||||
self.coopBtn.clicked.connect(self.show_coop_dialog)
|
self.coopBtn.clicked.connect(self.show_coop_dialog)
|
||||||
|
self.coopGenBtn.clicked.connect(self.generate_coop_script)
|
||||||
|
coopLayout.addWidget(self.coopBtn)
|
||||||
|
coopLayout.addWidget(self.coopGenBtn)
|
||||||
|
mainLayout.addLayout(coopLayout)
|
||||||
|
|
||||||
|
# Audio Manual (no script generation for this)
|
||||||
|
self.audioManualBtn = QPushButton("&Audio Manual") # Alt+A
|
||||||
self.audioManualBtn.clicked.connect(self.show_audio_manual)
|
self.audioManualBtn.clicked.connect(self.show_audio_manual)
|
||||||
|
|
||||||
self.singlePlayerBtn.keyPressEvent = lambda e: self.handle_button_keypress(e, self.singlePlayerBtn)
|
|
||||||
self.deathMatchBtn.keyPressEvent = lambda e: self.handle_button_keypress(e, self.deathMatchBtn)
|
|
||||||
self.customDeathMatchBtn.keyPressEvent = lambda e: self.handle_button_keypress(e, self.customDeathMatchBtn) # New line
|
|
||||||
self.coopBtn.keyPressEvent = lambda e: self.handle_button_keypress(e, self.coopBtn)
|
|
||||||
self.audioManualBtn.keyPressEvent = lambda e: self.handle_button_keypress(e, self.audioManualBtn)
|
|
||||||
|
|
||||||
mainLayout.addWidget(self.singlePlayerBtn)
|
|
||||||
mainLayout.addWidget(self.deathMatchBtn)
|
|
||||||
mainLayout.addWidget(self.customDeathMatchBtn)
|
|
||||||
mainLayout.addWidget(self.coopBtn)
|
|
||||||
mainLayout.addWidget(self.audioManualBtn)
|
mainLayout.addWidget(self.audioManualBtn)
|
||||||
|
|
||||||
|
# Set key press event handlers
|
||||||
|
self.singlePlayerBtn.keyPressEvent = lambda e: self.handle_button_keypress(e, self.singlePlayerBtn)
|
||||||
|
self.deathMatchBtn.keyPressEvent = lambda e: self.handle_button_keypress(e, self.deathMatchBtn)
|
||||||
|
self.customDeathMatchBtn.keyPressEvent = lambda e: self.handle_button_keypress(e, self.customDeathMatchBtn)
|
||||||
|
self.coopBtn.keyPressEvent = lambda e: self.handle_button_keypress(e, self.coopBtn)
|
||||||
|
self.audioManualBtn.keyPressEvent = lambda e: self.handle_button_keypress(e, self.audioManualBtn)
|
||||||
|
self.singlePlayerGenBtn.keyPressEvent = lambda e: self.handle_button_keypress(e, self.singlePlayerGenBtn)
|
||||||
|
self.deathMatchGenBtn.keyPressEvent = lambda e: self.handle_button_keypress(e, self.deathMatchGenBtn)
|
||||||
|
self.customDeathMatchGenBtn.keyPressEvent = lambda e: self.handle_button_keypress(e, self.customDeathMatchGenBtn)
|
||||||
|
self.coopGenBtn.keyPressEvent = lambda e: self.handle_button_keypress(e, self.coopGenBtn)
|
||||||
|
|
||||||
def get_narration_type(self) -> int:
|
def get_narration_type(self) -> int:
|
||||||
"""Get the current narration type from config file"""
|
"""Get the current narration type from config file"""
|
||||||
@ -1145,18 +1764,7 @@ class DoomLauncher(QMainWindow):
|
|||||||
'map': {
|
'map': {
|
||||||
'type': 'combobox',
|
'type': 'combobox',
|
||||||
'label': 'Select Map',
|
'label': 'Select Map',
|
||||||
'items': [
|
'items': self.deathmatchMaps
|
||||||
"Com Station (2-4 players)",
|
|
||||||
"Warehouse (2-4 players)",
|
|
||||||
"Sector 3 (2-4 players)",
|
|
||||||
"Dungeon of Doom (2-4 players)",
|
|
||||||
"Ocean Fortress (2-4 players)",
|
|
||||||
"Water Treatment Facility (2-4 players)",
|
|
||||||
"Phobos Base Site 4 (2-4 players)",
|
|
||||||
"Hangar Bay 18 (2-4 players)",
|
|
||||||
"Garden of Demon (2-4 players)",
|
|
||||||
"Outpost 69 (2-4 players)"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1243,8 +1851,11 @@ class DoomLauncher(QMainWindow):
|
|||||||
self.iwadCombo.setCurrentIndex(i)
|
self.iwadCombo.setCurrentIndex(i)
|
||||||
break
|
break
|
||||||
|
|
||||||
# Launch the game
|
# Check if we should generate a script or launch the game
|
||||||
self.launch_game(gameFiles, gameFlags)
|
if dialog.generateScript:
|
||||||
|
self.generate_launcher_script(gameFiles, gameFlags)
|
||||||
|
else:
|
||||||
|
self.launch_game(gameFiles, gameFlags)
|
||||||
|
|
||||||
def load_custom_games(self) -> Dict[str, dict]:
|
def load_custom_games(self) -> Dict[str, dict]:
|
||||||
"""Load all custom game configurations"""
|
"""Load all custom game configurations"""
|
||||||
@ -1336,6 +1947,9 @@ class DoomLauncher(QMainWindow):
|
|||||||
return
|
return
|
||||||
gameFiles.append(str(tobyMod))
|
gameFiles.append(str(tobyMod))
|
||||||
|
|
||||||
|
# Add script generation option to map selection dialog
|
||||||
|
generateScript = False
|
||||||
|
|
||||||
# Handle map selection right after TobyAccMod if specified
|
# Handle map selection right after TobyAccMod if specified
|
||||||
if config.get('use_map_menu', False) and 'submenu' not in config:
|
if config.get('use_map_menu', False) and 'submenu' not in config:
|
||||||
mapFiles = ["None"] # Start with None option
|
mapFiles = ["None"] # Start with None option
|
||||||
@ -1361,14 +1975,28 @@ class DoomLauncher(QMainWindow):
|
|||||||
dialogLayout.addWidget(mapLabel)
|
dialogLayout.addWidget(mapLabel)
|
||||||
dialogLayout.addWidget(mapCombo)
|
dialogLayout.addWidget(mapCombo)
|
||||||
|
|
||||||
buttons = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
|
# Create custom button box with Launch and Generate Script options
|
||||||
buttons.accepted.connect(mapDialog.accept)
|
buttonBox = QDialogButtonBox()
|
||||||
buttons.rejected.connect(mapDialog.reject)
|
launchButton = buttonBox.addButton("Launch Game", QDialogButtonBox.AcceptRole)
|
||||||
dialogLayout.addWidget(buttons)
|
scriptButton = buttonBox.addButton("Generate Script", QDialogButtonBox.ActionRole)
|
||||||
|
buttonBox.addButton(QDialogButtonBox.Cancel)
|
||||||
|
|
||||||
|
# Connect buttons
|
||||||
|
launchButton.clicked.connect(mapDialog.accept)
|
||||||
|
scriptButton.clicked.connect(lambda: setattr(mapDialog, "generateScript", True) or mapDialog.accept())
|
||||||
|
buttonBox.rejected.connect(mapDialog.reject)
|
||||||
|
|
||||||
|
dialogLayout.addWidget(buttonBox)
|
||||||
|
|
||||||
|
# Initialize generateScript flag
|
||||||
|
mapDialog.generateScript = False
|
||||||
|
|
||||||
if not mapDialog.exec():
|
if not mapDialog.exec():
|
||||||
return
|
return
|
||||||
|
|
||||||
|
# Capture the generateScript flag
|
||||||
|
generateScript = getattr(mapDialog, "generateScript", False)
|
||||||
|
|
||||||
selectedMap = mapCombo.currentText()
|
selectedMap = mapCombo.currentText()
|
||||||
if selectedMap != "None":
|
if selectedMap != "None":
|
||||||
if selectedMap == "OpMDK.wad":
|
if selectedMap == "OpMDK.wad":
|
||||||
@ -1385,10 +2013,12 @@ class DoomLauncher(QMainWindow):
|
|||||||
|
|
||||||
# Handle submenu if present
|
# Handle submenu if present
|
||||||
if 'submenu' in config:
|
if 'submenu' in config:
|
||||||
selectedFile = self.show_submenu_dialog(config['submenu'])
|
submenuResult = self.show_submenu_dialog_with_script_option(config['submenu'])
|
||||||
if not selectedFile:
|
if not submenuResult:
|
||||||
return
|
return
|
||||||
|
selectedFile, submenuGenerateScript = submenuResult
|
||||||
gameFiles.append(selectedFile)
|
gameFiles.append(selectedFile)
|
||||||
|
generateScript = submenuGenerateScript
|
||||||
|
|
||||||
# Add remaining files
|
# Add remaining files
|
||||||
tobyBaseVersion = self.tobyVersion.split('-')[0]
|
tobyBaseVersion = self.tobyVersion.split('-')[0]
|
||||||
@ -1422,10 +2052,22 @@ class DoomLauncher(QMainWindow):
|
|||||||
QMessageBox.critical(self, "Error", "Please select an IWAD first")
|
QMessageBox.critical(self, "Error", "Please select an IWAD first")
|
||||||
return
|
return
|
||||||
|
|
||||||
self.launch_game(gameFiles, gameFlags)
|
# Either generate a script or launch the game based on user choice
|
||||||
|
if generateScript:
|
||||||
|
self.generate_launcher_script(gameFiles, gameFlags)
|
||||||
|
else:
|
||||||
|
self.launch_game(gameFiles, gameFlags)
|
||||||
|
|
||||||
def show_submenu_dialog(self, submenu_config) -> Optional[str]:
|
def show_submenu_dialog(self, submenu_config) -> Optional[str]:
|
||||||
"""Show dialog for selecting submenu option"""
|
"""Show dialog for selecting submenu option"""
|
||||||
|
# For backward compatibility - calls new method
|
||||||
|
result = self.show_submenu_dialog_with_script_option(submenu_config)
|
||||||
|
if result:
|
||||||
|
return result[0] # Return just the file path
|
||||||
|
return None
|
||||||
|
|
||||||
|
def show_submenu_dialog_with_script_option(self, submenu_config) -> Optional[Tuple[str, bool]]:
|
||||||
|
"""Show dialog for selecting submenu option with script generation option"""
|
||||||
dialog = QDialog(self)
|
dialog = QDialog(self)
|
||||||
dialog.setWindowTitle(submenu_config['title'])
|
dialog.setWindowTitle(submenu_config['title'])
|
||||||
dialogLayout = QVBoxLayout(dialog)
|
dialogLayout = QVBoxLayout(dialog)
|
||||||
@ -1442,14 +2084,24 @@ class DoomLauncher(QMainWindow):
|
|||||||
dialogLayout.addWidget(label)
|
dialogLayout.addWidget(label)
|
||||||
dialogLayout.addWidget(gameCombo)
|
dialogLayout.addWidget(gameCombo)
|
||||||
|
|
||||||
# Dialog buttons
|
# Create custom button box with Launch and Generate Script options
|
||||||
buttons = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
|
buttonBox = QDialogButtonBox()
|
||||||
buttons.accepted.connect(dialog.accept)
|
launchButton = buttonBox.addButton("Launch Game", QDialogButtonBox.AcceptRole)
|
||||||
buttons.rejected.connect(dialog.reject)
|
scriptButton = buttonBox.addButton("Generate Script", QDialogButtonBox.ActionRole)
|
||||||
dialogLayout.addWidget(buttons)
|
buttonBox.addButton(QDialogButtonBox.Cancel)
|
||||||
|
|
||||||
|
# Connect buttons
|
||||||
|
launchButton.clicked.connect(dialog.accept)
|
||||||
|
scriptButton.clicked.connect(lambda: setattr(dialog, "generateScript", True) or dialog.accept())
|
||||||
|
buttonBox.rejected.connect(dialog.reject)
|
||||||
|
|
||||||
|
dialogLayout.addWidget(buttonBox)
|
||||||
|
|
||||||
|
# Initialize generateScript flag
|
||||||
|
dialog.generateScript = False
|
||||||
|
|
||||||
if dialog.exec():
|
if dialog.exec():
|
||||||
return gameCombo.currentData()
|
return gameCombo.currentData(), getattr(dialog, "generateScript", False)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def launch_single_player(self):
|
def launch_single_player(self):
|
||||||
@ -1490,18 +2142,7 @@ class DoomLauncher(QMainWindow):
|
|||||||
'map': {
|
'map': {
|
||||||
'type': 'combobox',
|
'type': 'combobox',
|
||||||
'label': 'Select Map',
|
'label': 'Select Map',
|
||||||
'items': [
|
'items': self.deathmatchMaps
|
||||||
"Com Station (2-4 players)",
|
|
||||||
"Warehouse (2-4 players)",
|
|
||||||
"Sector 3 (2-4 players)",
|
|
||||||
"Dungeon of Doom (2-4 players)",
|
|
||||||
"Ocean Fortress (2-4 players)",
|
|
||||||
"Water Treatment Facility (2-4 players)",
|
|
||||||
"Phobos Base Site 4 (2-4 players)",
|
|
||||||
"Hangar Bay 18 (2-4 players)",
|
|
||||||
"Garden of Demon (2-4 players)",
|
|
||||||
"Outpost 69 (2-4 players)"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1548,7 +2189,7 @@ class DoomLauncher(QMainWindow):
|
|||||||
'max': 5,
|
'max': 5,
|
||||||
'default': 3
|
'default': 3
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dialog = MenuDialog("Deathmatch Options", options, self)
|
dialog = MenuDialog("Deathmatch Options", options, self)
|
||||||
if dialog.exec():
|
if dialog.exec():
|
||||||
@ -1574,7 +2215,11 @@ class DoomLauncher(QMainWindow):
|
|||||||
self.iwadCombo.setCurrentIndex(i)
|
self.iwadCombo.setCurrentIndex(i)
|
||||||
break
|
break
|
||||||
|
|
||||||
self.launch_game(gameFiles, gameFlags)
|
# Check if we should generate a script or launch the game
|
||||||
|
if dialog.generateScript:
|
||||||
|
self.generate_launcher_script(gameFiles, gameFlags)
|
||||||
|
else:
|
||||||
|
self.launch_game(gameFiles, gameFlags)
|
||||||
|
|
||||||
def show_coop_dialog(self):
|
def show_coop_dialog(self):
|
||||||
"""Show co-op configuration dialog"""
|
"""Show co-op configuration dialog"""
|
||||||
@ -1612,7 +2257,12 @@ class DoomLauncher(QMainWindow):
|
|||||||
if Path(keyshareFile).exists():
|
if Path(keyshareFile).exists():
|
||||||
gameFiles.append(keyshareFile)
|
gameFiles.append(keyshareFile)
|
||||||
gameFlags = self.get_coop_flags(values)
|
gameFlags = self.get_coop_flags(values)
|
||||||
self.launch_game(gameFiles, gameFlags)
|
|
||||||
|
# Check if we should generate a script or launch the game
|
||||||
|
if dialog.generateScript:
|
||||||
|
self.generate_launcher_script(gameFiles, gameFlags)
|
||||||
|
else:
|
||||||
|
self.launch_game(gameFiles, gameFlags)
|
||||||
|
|
||||||
def get_deathmatch_flags(self, values: dict) -> List[str]:
|
def get_deathmatch_flags(self, values: dict) -> List[str]:
|
||||||
"""Get command line flags for deathmatch mode"""
|
"""Get command line flags for deathmatch mode"""
|
||||||
|
Loading…
x
Reference in New Issue
Block a user