| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417 | 
							- /*
 
-  * StartGameTab.cpp, part of VCMI engine
 
-  *
 
-  * Authors: listed in file AUTHORS in main folder
 
-  *
 
-  * License: GNU General Public License v2.0 or later
 
-  * Full text of license available in license.txt file, in main folder
 
-  *
 
-  */
 
- #include "StdInc.h"
 
- #include "StartGameTab.h"
 
- #include "ui_StartGameTab.h"
 
- #include "../mainwindow_moc.h"
 
- #include "../main.h"
 
- #include "../updatedialog_moc.h"
 
- #include "../modManager/cmodlistview_moc.h"
 
- #include "../../lib/filesystem/Filesystem.h"
 
- #include "../../lib/VCMIDirs.h"
 
- StartGameTab::StartGameTab(QWidget * parent)
 
- 	: QWidget(parent)
 
- 	, ui(new Ui::StartGameTab)
 
- {
 
- 	ui->setupUi(this);
 
- 	ui->buttonGameResume->setIcon(QIcon{":/icons/menu-game.png"}); //TODO: different icon?
 
- 	ui->buttonGameStart->setIcon(QIcon{":/icons/menu-game.png"});
 
- 	ui->buttonGameEditor->setIcon(QIcon{":/icons/menu-editor.png"});
 
- 	refreshState();
 
- 	ui->buttonGameResume->setVisible(false); // TODO: implement
 
- 	ui->buttonPresetExport->setVisible(false); // TODO: implement
 
- 	ui->buttonPresetImport->setVisible(false); // TODO: implement
 
- #ifndef ENABLE_EDITOR
 
- 	ui->buttonGameEditor->hide();
 
- #endif
 
- }
 
- StartGameTab::~StartGameTab()
 
- {
 
- 	delete ui;
 
- }
 
- MainWindow * StartGameTab::getMainWindow()
 
- {
 
- 	foreach(QWidget *w, qApp->allWidgets())
 
- 		if(QMainWindow* mainWin = qobject_cast<QMainWindow*>(w))
 
- 			return dynamic_cast<MainWindow *>(mainWin);
 
- 	return nullptr;
 
- }
 
- void StartGameTab::refreshState()
 
- {
 
- 	refreshGameData();
 
- 	refreshUpdateStatus(EGameUpdateStatus::NOT_CHECKED);//TODO - follow automatic check on startup setting
 
- 	refreshTranslation(getMainWindow()->getTranslationStatus());
 
- 	refreshPresets();
 
- 	refreshMods();
 
- }
 
- void StartGameTab::refreshPresets()
 
- {
 
- 	QSignalBlocker blocker(ui->comboBoxModPresets);
 
- 	QStringList allPresets = getMainWindow()->getModView()->getAllPresets();
 
- 	ui->comboBoxModPresets->clear();
 
- 	ui->comboBoxModPresets->addItems(allPresets);
 
- 	ui->comboBoxModPresets->setCurrentText(getMainWindow()->getModView()->getActivePreset());
 
- 	ui->buttonPresetDelete->setVisible(allPresets.size() > 1);
 
- }
 
- void StartGameTab::refreshGameData()
 
- {
 
- 	// Some players are using pirated version of the game with some of the files missing
 
- 	// leading to broken town hall menu (and possibly other dialogs)
 
- 	// Provide diagnostics to indicate problem with chair-monitor adaptor layer and not with VCMI
 
- 	static constexpr std::array potentiallyMissingFiles = {
 
- 		"Data/TpThBkDg.bmp",
 
- 		"Data/TpThBkFr.bmp",
 
- 		"Data/TpThBkIn.bmp",
 
- 		"Data/TpThBkNc.bmp",
 
- 		"Data/TpThBkSt.bmp",
 
- 		"Data/TpThBRrm.bmp",
 
- 		"Data/TpThBkCs.bmp",
 
- 		"Data/TpThBkRm.bmp",
 
- 		"Data/TpThBkTw.bmp",
 
- 	};
 
- 	// Some players for some reason don't have AB expansion campaign files
 
- 	static constexpr std::array armaggedonBladeCampaigns = {
 
- 		"DATA/AB",
 
- 		"DATA/BLOOD",
 
- 		"DATA/SLAYER",
 
- 		"DATA/FESTIVAL",
 
- 		"DATA/FIRE",
 
- 		"DATA/FOOL",
 
- 	};
 
- 	bool missingSoundtrack = !CResourceHandler::get()->existsResource(AudioPath::builtin("Music/MainMenu"));
 
- 	bool missingVideoFiles = !CResourceHandler::get()->existsResource(VideoPath::builtin("Video/H3Intro")) && !CResourceHandler::get()->existsResource(ResourcePath("Video/H3Intro", EResType::VIDEO_LOW_QUALITY));
 
- 	bool missingGameFiles = false;
 
- 	bool missingCampaings = false;
 
- 	for (const auto & filename : potentiallyMissingFiles)
 
- 		missingGameFiles &= !CResourceHandler::get()->existsResource(ImagePath::builtin(filename));
 
- 	for (const auto & filename : armaggedonBladeCampaigns)
 
- 		missingCampaings &= !CResourceHandler::get()->existsResource(ResourcePath(filename, EResType::CAMPAIGN));
 
- 	ui->labelMissingCampaigns->setVisible(missingCampaings);
 
- 	ui->labelMissingFiles->setVisible(missingGameFiles);
 
- 	ui->labelMissingVideo->setVisible(missingVideoFiles);
 
- 	ui->labelMissingSoundtrack->setVisible(missingSoundtrack);
 
- 	ui->buttonMissingCampaignsHelp->setVisible(missingCampaings);
 
- 	ui->buttonMissingFilesHelp->setVisible(missingGameFiles);
 
- 	ui->buttonMissingVideoHelp->setVisible(missingVideoFiles);
 
- 	ui->buttonMissingSoundtrackHelp->setVisible(missingSoundtrack);
 
- }
 
- void StartGameTab::refreshTranslation(ETranslationStatus status)
 
- {
 
- 	ui->buttonInstallTranslation->setVisible(status == ETranslationStatus::NOT_INSTALLLED);
 
- 	ui->buttonInstallTranslationHelp->setVisible(status == ETranslationStatus::NOT_INSTALLLED);
 
- 	ui->buttonActivateTranslation->setVisible(status == ETranslationStatus::NOT_INSTALLLED);
 
- 	ui->buttonActivateTranslationHelp->setVisible(status == ETranslationStatus::NOT_INSTALLLED);
 
- }
 
- void StartGameTab::refreshMods()
 
- {
 
- 	constexpr int chroniclesCount = 8;
 
- 	QStringList updateableMods = getMainWindow()->getModView()->getUpdateableMods();
 
- 	QStringList chroniclesMods = getMainWindow()->getModView()->getInstalledChronicles();
 
- 	ui->buttonUpdateMods->setText(tr("Update %n mods", "", updateableMods.size()));
 
- 	ui->buttonUpdateMods->setVisible(!updateableMods.empty());
 
- 	ui->buttonUpdateModsHelp->setVisible(!updateableMods.empty());
 
- 	ui->labelChronicles->setText(tr("Heroes Chronicles:\n%n/%1 installed", "", chroniclesMods.size()).arg(chroniclesCount));
 
- 	ui->labelChronicles->setVisible(chroniclesMods.size() != chroniclesCount);
 
- 	ui->buttonChroniclesHelp->setVisible(chroniclesMods.size() != chroniclesCount);
 
- }
 
- void StartGameTab::refreshUpdateStatus(EGameUpdateStatus status)
 
- {
 
- 	QString availableVersion; // TODO
 
- 	ui->labelTitleEngine->setText("VCMI " VCMI_VERSION_STRING);
 
- 	ui->buttonUpdateCheck->setVisible(status == EGameUpdateStatus::NOT_CHECKED);
 
- 	ui->labelUpdateNotFound->setVisible(status == EGameUpdateStatus::NO_UPDATE);
 
- 	ui->labelUpdateAvailable->setVisible(status == EGameUpdateStatus::UPDATE_AVAILABLE);
 
- 	ui->buttonOpenChangelog->setVisible(status == EGameUpdateStatus::UPDATE_AVAILABLE);
 
- 	ui->buttonOpenDownloads->setVisible(status == EGameUpdateStatus::UPDATE_AVAILABLE);
 
- 	if (status == EGameUpdateStatus::UPDATE_AVAILABLE)
 
- 		ui->labelUpdateAvailable->setText(tr("Update to %1 available").arg(availableVersion));
 
- }
 
- void StartGameTab::on_buttonGameStart_clicked()
 
- {
 
- 	getMainWindow()->hide();
 
- 	startGame({});
 
- }
 
- void StartGameTab::on_buttonOpenChangelog_clicked()
 
- {
 
- 	QDesktopServices::openUrl(QUrl("https://vcmi.eu/ChangeLog/"));
 
- }
 
- void StartGameTab::on_buttonOpenDownloads_clicked()
 
- {
 
- 	QDesktopServices::openUrl(QUrl("https://vcmi.eu/download/"));
 
- }
 
- void StartGameTab::on_buttonUpdateCheck_clicked()
 
- {
 
- 	UpdateDialog::showUpdateDialog(true);
 
- }
 
- void StartGameTab::on_buttonGameEditor_clicked()
 
- {
 
- 	getMainWindow()->hide();
 
- 	startEditor({});
 
- }
 
- void StartGameTab::on_buttonImportFiles_clicked()
 
- {
 
- 	const auto & importFunctor = [this]
 
- 	{
 
- #ifndef VCMI_MOBILE
 
- 		QString filter =
 
- 			tr("All supported files") + " (*.h3m *.vmap *.h3c *.vcmp *.zip *.json *.exe);;" +
 
- 			tr("Maps") + " (*.h3m *.vmap);;" +
 
- 			tr("Campaigns") + " (*.h3c *.vcmp);;" +
 
- 			tr("Configs") + " (*.json);;" +
 
- 			tr("Mods") + " (*.zip);;" +
 
- 			tr("Gog files") + " (*.exe)";
 
- #else
 
- 		//Workaround for sometimes incorrect mime for some extensions (e.g. for exe)
 
- 		QString filter = tr("All files (*.*)");
 
- #endif
 
- 		QStringList files = QFileDialog::getOpenFileNames(this, tr("Select files (configs, mods, maps, campaigns, gog files) to install..."), QDir::homePath(), filter);
 
- 		for(const auto & file : files)
 
- 			getMainWindow()->manualInstallFile(file);
 
- 	};
 
- 	// iOS can't display modal dialogs when called directly on button press
 
- 	// https://bugreports.qt.io/browse/QTBUG-98651
 
- 	QTimer::singleShot(0, this, importFunctor);
 
- }
 
- void StartGameTab::on_buttonInstallTranslation_clicked()
 
- {
 
- 	if (getMainWindow()->getTranslationStatus() == ETranslationStatus::NOT_INSTALLLED)
 
- 	{
 
- 		QString preferredlanguage = QString::fromStdString(settings["general"]["language"].String());
 
- 		QString modName = getMainWindow()->getModView()->getTranslationModName(preferredlanguage);
 
- 		getMainWindow()->getModView()->doInstallMod(modName);
 
- 	}
 
- }
 
- void StartGameTab::on_buttonActivateTranslation_clicked()
 
- {
 
- 	QString preferredlanguage = QString::fromStdString(settings["general"]["language"].String());
 
- 	QString modName = getMainWindow()->getModView()->getTranslationModName(preferredlanguage);
 
- 	getMainWindow()->getModView()->enableModByName(modName);
 
- }
 
- void StartGameTab::on_buttonUpdateMods_clicked()
 
- {
 
- 	QStringList updateableMods = getMainWindow()->getModView()->getUpdateableMods();
 
- 	getMainWindow()->switchToModsTab();
 
- 	for (const auto & modName : updateableMods)
 
- 		getMainWindow()->getModView()->doUpdateMod(modName);
 
- }
 
- void StartGameTab::on_buttonHelpImportFiles_clicked()
 
- {
 
- 	QString message = tr(
 
- 		"This option allows you to import additional data files into your VCMI installation. "
 
- 		"At the moment, following options are supported:\n\n"
 
- 		" - Heroes III Maps (.h3m or .vmap).\n"
 
- 		" - Heroes III Campaigns (.h3c or .vcmp).\n"
 
- 		" - Heroes III Chronicles using offline backup installer from GOG.com (.exe).\n"
 
- 		" - VCMI mods in zip format (.zip)\n"
 
- 		" - VCMI configuration files (.json)\n"
 
- 	);
 
- 	QMessageBox::information(this, ui->buttonImportFiles->text(), message);
 
- }
 
- void StartGameTab::on_buttonInstallTranslationHelp_clicked()
 
- {
 
- 	QString message = tr(
 
- 		"Your Heroes III version uses different language. "
 
- 		"VCMI provides translations of the game into various languages that you can use. "
 
- 		"Use this option to automatically install such translation to your language."
 
- 	);
 
- 	QMessageBox::information(this, ui->buttonInstallTranslation->text(), message);
 
- }
 
- void StartGameTab::on_buttonActivateTranslationHelp_clicked()
 
- {
 
- 	QString message = tr(
 
- 		"Translation of Heroes III into your language is installed, but has been turned off. "
 
- 		"Use this option to enable it."
 
- 	);
 
- 	QMessageBox::information(this, ui->buttonActivateTranslation->text(), message);
 
- }
 
- void StartGameTab::on_buttonUpdateModsHelp_clicked()
 
- {
 
- 	QString message = tr(
 
- 		"A new version of some of the mods that you have installed is now available in mod repository. "
 
- 		"Use this option to automatically update all your mods to latest version.\n\n"
 
- 		"WARNING: In some cases, updated versions of mods may not be compatible with your existing saves. "
 
- 		"You many want to postpone mod update until you finish any of your ongoing games."
 
- 		);
 
- 	QMessageBox::information(this, ui->buttonUpdateMods->text(), message);
 
- }
 
- void StartGameTab::on_buttonChroniclesHelp_clicked()
 
- {
 
- 	QString message = tr(
 
- 		"If you own Heroes Chronicles on gog.com, you can use offline backup installers provided by gog "
 
- 		"to import Heroes Chronicles data into VCMI as custom campaigns.\n"
 
- 		"To import Heroes Chronicles, download offline backup installer of each chronicle that you wish to install, "
 
- 		"select 'Import files' option and select downloaded file. "
 
- 		"This will generate and install mod for VCMI that contains imported chronicles"
 
- 	);
 
- 	QMessageBox::information(this, ui->labelChronicles->text(), message);
 
- }
 
- void StartGameTab::on_buttonMissingSoundtrackHelp_clicked()
 
- {
 
- 	QString message = tr(
 
- 		"VCMI has detected that Heroes III music files are missing from your installation. "
 
- 		"VCMI will run, but in-game music will not be available.\n\n"
 
- 		"To resolve this problem, please copy missing mp3 files from Heroes III to VCMI data files directory manually "
 
- 		"or reinstall VCMI and re-import Heroes III data files"
 
- 	);
 
- 	QMessageBox::information(this, ui->labelMissingSoundtrack->text(), message);
 
- }
 
- void StartGameTab::on_buttonMissingVideoHelp_clicked()
 
- {
 
- 	QString message = tr(
 
- 		"VCMI has detected that Heroes III video files are missing from your installation. "
 
- 		"VCMI will run, but in-game cutscenes will not be available.\n\n"
 
- 		"To resolve this problem, please copy VIDEO.VID file from Heroes III to VCMI data files directory manually "
 
- 		"or reinstall VCMI and re-import Heroes III data files"
 
- 		);
 
- 	QMessageBox::information(this, ui->labelMissingVideo->text(), message);
 
- }
 
- void StartGameTab::on_buttonMissingFilesHelp_clicked()
 
- {
 
- 	QString message = tr(
 
- 		"VCMI has detected that some of Heroes III data files are missing from your installation. "
 
- 		"You may attempt to run VCMI, but game may not work as expected or crash.\n\n"
 
- 		"To resolve this problem, please reinstall game and reimport data files using supported version of Heroes III. "
 
- 		"VCMI requires Heroes III: Shadow of Death or Complete Edition to run, which you can get (for example) from gog.com"
 
- 	);
 
- 	QMessageBox::information(this, ui->labelMissingFiles->text(), message);
 
- }
 
- void StartGameTab::on_buttonMissingCampaignsHelp_clicked()
 
- {
 
- 	QString message = tr(
 
- 		"VCMI has detected that some of Heroes III: Armageddon's Blade data files are missing from your installation. "
 
- 		"VCMI will work, but Armageddon's Blade campaigns will not be available.\n\n"
 
- 		"To resolve this problem, please copy missing data files from Heroes III to VCMI data files directory manually "
 
- 		"or reinstall VCMI and re-import Heroes III data files"
 
- 	);
 
- 	QMessageBox::information(this, ui->labelMissingCampaigns->text(), message);
 
- }
 
- void StartGameTab::on_buttonPresetExport_clicked()
 
- {
 
- 	// TODO
 
- }
 
- void StartGameTab::on_buttonPresetImport_clicked()
 
- {
 
- 	// TODO
 
- }
 
- void StartGameTab::on_buttonPresetNew_clicked()
 
- {
 
- 	bool ok;
 
- 	QString presetName = QInputDialog::getText(
 
- 		this,
 
- 		ui->buttonPresetNew->text(),
 
- 		tr("Enter preset name:"),
 
- 		QLineEdit::Normal,
 
- 		QString(),
 
- 		&ok);
 
- 	if (ok && !presetName.isEmpty())
 
- 	{
 
- 		getMainWindow()->getModView()->createNewPreset(presetName);
 
- 		getMainWindow()->getModView()->activatePreset(presetName);
 
- 		refreshPresets();
 
- 	}
 
- }
 
- void StartGameTab::on_buttonPresetDelete_clicked()
 
- {
 
- 	QString activePresetBefore = getMainWindow()->getModView()->getActivePreset();
 
- 	QStringList allPresets = getMainWindow()->getModView()->getAllPresets();
 
- 	allPresets.removeAll(activePresetBefore);
 
- 	if (!allPresets.empty())
 
- 	{
 
- 		getMainWindow()->getModView()->activatePreset(allPresets.front());
 
- 		getMainWindow()->getModView()->deletePreset(activePresetBefore);
 
- 		refreshPresets();
 
- 	}
 
- }
 
- void StartGameTab::on_comboBoxModPresets_currentTextChanged(const QString &presetName)
 
- {
 
- 	getMainWindow()->getModView()->activatePreset(presetName);
 
- }
 
- void StartGameTab::on_buttonPresetRename_clicked()
 
- {
 
- 	QString currentName = getMainWindow()->getModView()->getActivePreset();
 
- 	bool ok;
 
- 	QString newName = QInputDialog::getText(
 
- 		this,
 
- 		ui->buttonPresetNew->text(),
 
- 		tr("Rename preset '%1' to:").arg(currentName),
 
- 		QLineEdit::Normal,
 
- 		currentName,
 
- 		&ok);
 
- 	if (ok && !newName.isEmpty())
 
- 	{
 
- 		getMainWindow()->getModView()->renamePreset(currentName, newName);
 
- 		refreshPresets();
 
- 	}
 
- }
 
 
  |