mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-22 22:13:35 +02:00
Merge pull request #5061 from IvanSavenko/bugfixing_beta
Fixes for issues found in current beta
This commit is contained in:
commit
5560467cc4
@ -430,9 +430,10 @@ void ApplyClientNetPackVisitor::visitPlayerEndsGame(PlayerEndsGame & pack)
|
|||||||
{
|
{
|
||||||
callAllInterfaces(cl, &IGameEventsReceiver::gameOver, pack.player, pack.victoryLossCheckResult);
|
callAllInterfaces(cl, &IGameEventsReceiver::gameOver, pack.player, pack.victoryLossCheckResult);
|
||||||
|
|
||||||
|
bool localHumanWinsGame = vstd::contains(cl.playerint, pack.player) && cl.getPlayerState(pack.player)->human && pack.victoryLossCheckResult.victory();
|
||||||
bool lastHumanEndsGame = CSH->howManyPlayerInterfaces() == 1 && vstd::contains(cl.playerint, pack.player) && cl.getPlayerState(pack.player)->human && !settings["session"]["spectate"].Bool();
|
bool lastHumanEndsGame = CSH->howManyPlayerInterfaces() == 1 && vstd::contains(cl.playerint, pack.player) && cl.getPlayerState(pack.player)->human && !settings["session"]["spectate"].Bool();
|
||||||
|
|
||||||
if(lastHumanEndsGame)
|
if(lastHumanEndsGame || localHumanWinsGame)
|
||||||
{
|
{
|
||||||
assert(adventureInt);
|
assert(adventureInt);
|
||||||
if(adventureInt)
|
if(adventureInt)
|
||||||
|
@ -115,7 +115,7 @@ public:
|
|||||||
|
|
||||||
virtual std::shared_ptr<const ISharedImage> horizontalFlip() const = 0;
|
virtual std::shared_ptr<const ISharedImage> horizontalFlip() const = 0;
|
||||||
virtual std::shared_ptr<const ISharedImage> verticalFlip() const = 0;
|
virtual std::shared_ptr<const ISharedImage> verticalFlip() const = 0;
|
||||||
virtual std::shared_ptr<const ISharedImage> scaleInteger(int factor, SDL_Palette * palette) const = 0;
|
virtual std::shared_ptr<const ISharedImage> scaleInteger(int factor, SDL_Palette * palette, EImageBlitMode blitMode) const = 0;
|
||||||
virtual std::shared_ptr<const ISharedImage> scaleTo(const Point & size, SDL_Palette * palette) const = 0;
|
virtual std::shared_ptr<const ISharedImage> scaleTo(const Point & size, SDL_Palette * palette) const = 0;
|
||||||
|
|
||||||
|
|
||||||
|
@ -201,7 +201,7 @@ CBitmapFont::CBitmapFont(const std::string & filename):
|
|||||||
static const std::map<std::string, EScalingAlgorithm> filterNameToEnum = {
|
static const std::map<std::string, EScalingAlgorithm> filterNameToEnum = {
|
||||||
{ "nearest", EScalingAlgorithm::NEAREST},
|
{ "nearest", EScalingAlgorithm::NEAREST},
|
||||||
{ "bilinear", EScalingAlgorithm::BILINEAR},
|
{ "bilinear", EScalingAlgorithm::BILINEAR},
|
||||||
{ "xbrz", EScalingAlgorithm::XBRZ}
|
{ "xbrz", EScalingAlgorithm::XBRZ_ALPHA}
|
||||||
};
|
};
|
||||||
|
|
||||||
auto filterName = settings["video"]["fontUpscalingFilter"].String();
|
auto filterName = settings["video"]["fontUpscalingFilter"].String();
|
||||||
|
@ -278,7 +278,7 @@ void SDLImageShared::optimizeSurface()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<const ISharedImage> SDLImageShared::scaleInteger(int factor, SDL_Palette * palette) const
|
std::shared_ptr<const ISharedImage> SDLImageShared::scaleInteger(int factor, SDL_Palette * palette, EImageBlitMode mode) const
|
||||||
{
|
{
|
||||||
if (factor <= 0)
|
if (factor <= 0)
|
||||||
throw std::runtime_error("Unable to scale by integer value of " + std::to_string(factor));
|
throw std::runtime_error("Unable to scale by integer value of " + std::to_string(factor));
|
||||||
@ -293,7 +293,13 @@ std::shared_ptr<const ISharedImage> SDLImageShared::scaleInteger(int factor, SDL
|
|||||||
if(preScaleFactor == factor)
|
if(preScaleFactor == factor)
|
||||||
return shared_from_this();
|
return shared_from_this();
|
||||||
else if(preScaleFactor == 1)
|
else if(preScaleFactor == 1)
|
||||||
scaled = CSDL_Ext::scaleSurfaceIntegerFactor(surf, factor, EScalingAlgorithm::XBRZ);
|
{
|
||||||
|
// dump heuristics to differentiate tileable UI elements from map object / combat assets
|
||||||
|
if (mode == EImageBlitMode::OPAQUE || mode == EImageBlitMode::COLORKEY || mode == EImageBlitMode::SIMPLE)
|
||||||
|
scaled = CSDL_Ext::scaleSurfaceIntegerFactor(surf, factor, EScalingAlgorithm::XBRZ_OPAQUE);
|
||||||
|
else
|
||||||
|
scaled = CSDL_Ext::scaleSurfaceIntegerFactor(surf, factor, EScalingAlgorithm::XBRZ_ALPHA);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
scaled = CSDL_Ext::scaleSurface(surf, (surf->w / preScaleFactor) * factor, (surf->h / preScaleFactor) * factor);
|
scaled = CSDL_Ext::scaleSurface(surf, (surf->w / preScaleFactor) * factor, (surf->h / preScaleFactor) * factor);
|
||||||
|
|
||||||
@ -589,12 +595,12 @@ void SDLImageRGB::scaleTo(const Point & size)
|
|||||||
|
|
||||||
void SDLImageIndexed::scaleInteger(int factor)
|
void SDLImageIndexed::scaleInteger(int factor)
|
||||||
{
|
{
|
||||||
image = image->scaleInteger(factor, currentPalette);
|
image = image->scaleInteger(factor, currentPalette, blitMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SDLImageRGB::scaleInteger(int factor)
|
void SDLImageRGB::scaleInteger(int factor)
|
||||||
{
|
{
|
||||||
image = image->scaleInteger(factor, nullptr);
|
image = image->scaleInteger(factor, nullptr, blitMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SDLImageRGB::exportBitmap(const boost::filesystem::path & path) const
|
void SDLImageRGB::exportBitmap(const boost::filesystem::path & path) const
|
||||||
|
@ -60,7 +60,7 @@ public:
|
|||||||
std::shared_ptr<IImage> createImageReference(EImageBlitMode mode) const override;
|
std::shared_ptr<IImage> createImageReference(EImageBlitMode mode) const override;
|
||||||
std::shared_ptr<const ISharedImage> horizontalFlip() const override;
|
std::shared_ptr<const ISharedImage> horizontalFlip() const override;
|
||||||
std::shared_ptr<const ISharedImage> verticalFlip() const override;
|
std::shared_ptr<const ISharedImage> verticalFlip() const override;
|
||||||
std::shared_ptr<const ISharedImage> scaleInteger(int factor, SDL_Palette * palette) const override;
|
std::shared_ptr<const ISharedImage> scaleInteger(int factor, SDL_Palette * palette, EImageBlitMode blitMode) const override;
|
||||||
std::shared_ptr<const ISharedImage> scaleTo(const Point & size, SDL_Palette * palette) const override;
|
std::shared_ptr<const ISharedImage> scaleTo(const Point & size, SDL_Palette * palette) const override;
|
||||||
|
|
||||||
friend class SDLImageLoader;
|
friend class SDLImageLoader;
|
||||||
|
@ -683,12 +683,17 @@ SDL_Surface * CSDL_Ext::scaleSurfaceIntegerFactor(SDL_Surface * surf, int factor
|
|||||||
case EScalingAlgorithm::BILINEAR:
|
case EScalingAlgorithm::BILINEAR:
|
||||||
xbrz::bilinearScale(srcPixels, intermediate->w, intermediate->h, dstPixels, ret->w, ret->h);
|
xbrz::bilinearScale(srcPixels, intermediate->w, intermediate->h, dstPixels, ret->w, ret->h);
|
||||||
break;
|
break;
|
||||||
case EScalingAlgorithm::XBRZ:
|
case EScalingAlgorithm::XBRZ_ALPHA:
|
||||||
tbb::parallel_for(tbb::blocked_range<size_t>(0, intermediate->h, granulation), [factor, srcPixels, dstPixels, intermediate](const tbb::blocked_range<size_t> & r)
|
case EScalingAlgorithm::XBRZ_OPAQUE:
|
||||||
|
{
|
||||||
|
auto format = algorithm == EScalingAlgorithm::XBRZ_OPAQUE ? xbrz::ColorFormat::ARGB_CLAMPED : xbrz::ColorFormat::ARGB;
|
||||||
|
tbb::parallel_for(tbb::blocked_range<size_t>(0, intermediate->h, granulation), [factor, srcPixels, dstPixels, intermediate, format](const tbb::blocked_range<size_t> & r)
|
||||||
{
|
{
|
||||||
xbrz::scale(factor, srcPixels, dstPixels, intermediate->w, intermediate->h, xbrz::ColorFormat::ARGB, {}, r.begin(), r.end());
|
|
||||||
|
xbrz::scale(factor, srcPixels, dstPixels, intermediate->w, intermediate->h, format, {}, r.begin(), r.end());
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
throw std::runtime_error("invalid scaling algorithm!");
|
throw std::runtime_error("invalid scaling algorithm!");
|
||||||
}
|
}
|
||||||
|
@ -31,7 +31,8 @@ enum class EScalingAlgorithm : int8_t
|
|||||||
{
|
{
|
||||||
NEAREST,
|
NEAREST,
|
||||||
BILINEAR,
|
BILINEAR,
|
||||||
XBRZ
|
XBRZ_OPAQUE, // xbrz, image edges are considered to have same color as pixel inside image
|
||||||
|
XBRZ_ALPHA // xbrz, image edges are considered to be transparent
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace CSDL_Ext
|
namespace CSDL_Ext
|
||||||
|
@ -198,8 +198,3 @@ void SettingsMainWindow::onScreenResize()
|
|||||||
if (tab)
|
if (tab)
|
||||||
tab->updateResolutionSelector();
|
tab->updateResolutionSelector();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SettingsMainWindow::inputModeChanged(InputMode mode)
|
|
||||||
{
|
|
||||||
tabContentArea->reset();
|
|
||||||
}
|
|
||||||
|
@ -42,6 +42,5 @@ public:
|
|||||||
|
|
||||||
void showAll(Canvas & to) override;
|
void showAll(Canvas & to) override;
|
||||||
void onScreenResize() override;
|
void onScreenResize() override;
|
||||||
void inputModeChanged(InputMode mode) override;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1195,6 +1195,22 @@ void xbrz::scale(size_t factor, const uint32_t* src, uint32_t* trg, int srcWidth
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case ColorFormat::ARGB_CLAMPED:
|
||||||
|
switch (factor)
|
||||||
|
{
|
||||||
|
case 2:
|
||||||
|
return scaleImage<Scaler2x<ColorGradientARGB>, ColorDistanceARGB, OobReaderDuplicate>(src, trg, srcWidth, srcHeight, cfg, yFirst, yLast);
|
||||||
|
case 3:
|
||||||
|
return scaleImage<Scaler3x<ColorGradientARGB>, ColorDistanceARGB, OobReaderDuplicate>(src, trg, srcWidth, srcHeight, cfg, yFirst, yLast);
|
||||||
|
case 4:
|
||||||
|
return scaleImage<Scaler4x<ColorGradientARGB>, ColorDistanceARGB, OobReaderDuplicate>(src, trg, srcWidth, srcHeight, cfg, yFirst, yLast);
|
||||||
|
case 5:
|
||||||
|
return scaleImage<Scaler5x<ColorGradientARGB>, ColorDistanceARGB, OobReaderDuplicate>(src, trg, srcWidth, srcHeight, cfg, yFirst, yLast);
|
||||||
|
case 6:
|
||||||
|
return scaleImage<Scaler6x<ColorGradientARGB>, ColorDistanceARGB, OobReaderDuplicate>(src, trg, srcWidth, srcHeight, cfg, yFirst, yLast);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case ColorFormat::ARGB:
|
case ColorFormat::ARGB:
|
||||||
switch (factor)
|
switch (factor)
|
||||||
{
|
{
|
||||||
@ -1238,6 +1254,7 @@ bool xbrz::equalColorTest(uint32_t col1, uint32_t col2, ColorFormat colFmt, doub
|
|||||||
case ColorFormat::RGB:
|
case ColorFormat::RGB:
|
||||||
return ColorDistanceRGB::dist(col1, col2, luminanceWeight) < equalColorTolerance;
|
return ColorDistanceRGB::dist(col1, col2, luminanceWeight) < equalColorTolerance;
|
||||||
case ColorFormat::ARGB:
|
case ColorFormat::ARGB:
|
||||||
|
case ColorFormat::ARGB_CLAMPED:
|
||||||
return ColorDistanceARGB::dist(col1, col2, luminanceWeight) < equalColorTolerance;
|
return ColorDistanceARGB::dist(col1, col2, luminanceWeight) < equalColorTolerance;
|
||||||
case ColorFormat::ARGB_UNBUFFERED:
|
case ColorFormat::ARGB_UNBUFFERED:
|
||||||
return ColorDistanceUnbufferedARGB::dist(col1, col2, luminanceWeight) < equalColorTolerance;
|
return ColorDistanceUnbufferedARGB::dist(col1, col2, luminanceWeight) < equalColorTolerance;
|
||||||
|
@ -44,6 +44,7 @@ enum class ColorFormat //from high bits -> low bits, 8 bit per channel
|
|||||||
{
|
{
|
||||||
RGB, //8 bit for each red, green, blue, upper 8 bits unused
|
RGB, //8 bit for each red, green, blue, upper 8 bits unused
|
||||||
ARGB, //including alpha channel, BGRA byte order on little-endian machines
|
ARGB, //including alpha channel, BGRA byte order on little-endian machines
|
||||||
|
ARGB_CLAMPED, // like ARGB, but edges are treated as opaque, with same color as edge
|
||||||
ARGB_UNBUFFERED, //like ARGB, but without the one-time buffer creation overhead (ca. 100 - 300 ms) at the expense of a slightly slower scaling time
|
ARGB_UNBUFFERED, //like ARGB, but without the one-time buffer creation overhead (ca. 100 - 300 ms) at the expense of a slightly slower scaling time
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -441,9 +441,10 @@ void CModListView::selectMod(const QModelIndex & index)
|
|||||||
Helper::enableScrollBySwiping(ui->modInfoBrowser);
|
Helper::enableScrollBySwiping(ui->modInfoBrowser);
|
||||||
Helper::enableScrollBySwiping(ui->changelogBrowser);
|
Helper::enableScrollBySwiping(ui->changelogBrowser);
|
||||||
|
|
||||||
QStringList notInstalledDependencies = this->getModsToInstall(modName);
|
QStringList notInstalledDependencies = getModsToInstall(modName);
|
||||||
QStringList unavailableDependencies = this->findUnavailableMods(notInstalledDependencies);
|
QStringList unavailableDependencies = findUnavailableMods(notInstalledDependencies);
|
||||||
bool translationMismatch = mod.isTranslation() && CGeneralTextHandler::getPreferredLanguage() != mod.getBaseLanguage().toStdString();
|
bool translationMismatch = mod.isTranslation() && CGeneralTextHandler::getPreferredLanguage() != mod.getBaseLanguage().toStdString();
|
||||||
|
bool modIsBeingDownloaded = enqueuedModDownloads.contains(mod.getID());
|
||||||
|
|
||||||
ui->disableButton->setVisible(modStateModel->isModInstalled(mod.getID()) && modStateModel->isModEnabled(mod.getID()));
|
ui->disableButton->setVisible(modStateModel->isModInstalled(mod.getID()) && modStateModel->isModEnabled(mod.getID()));
|
||||||
ui->enableButton->setVisible(modStateModel->isModInstalled(mod.getID()) && !modStateModel->isModEnabled(mod.getID()));
|
ui->enableButton->setVisible(modStateModel->isModInstalled(mod.getID()) && !modStateModel->isModEnabled(mod.getID()));
|
||||||
@ -454,9 +455,9 @@ void CModListView::selectMod(const QModelIndex & index)
|
|||||||
// Block buttons if action is not allowed at this time
|
// Block buttons if action is not allowed at this time
|
||||||
ui->disableButton->setEnabled(true);
|
ui->disableButton->setEnabled(true);
|
||||||
ui->enableButton->setEnabled(notInstalledDependencies.empty() && !translationMismatch);
|
ui->enableButton->setEnabled(notInstalledDependencies.empty() && !translationMismatch);
|
||||||
ui->installButton->setEnabled(unavailableDependencies.empty());
|
ui->installButton->setEnabled(unavailableDependencies.empty() && !modIsBeingDownloaded);
|
||||||
ui->uninstallButton->setEnabled(true);
|
ui->uninstallButton->setEnabled(true);
|
||||||
ui->updateButton->setEnabled(unavailableDependencies.empty());
|
ui->updateButton->setEnabled(unavailableDependencies.empty() && !modIsBeingDownloaded);
|
||||||
|
|
||||||
loadScreenshots();
|
loadScreenshots();
|
||||||
}
|
}
|
||||||
@ -544,9 +545,6 @@ QStringList CModListView::getModsToInstall(QString mod)
|
|||||||
candidates.pop_back();
|
candidates.pop_back();
|
||||||
processed.push_back(potentialToInstall);
|
processed.push_back(potentialToInstall);
|
||||||
|
|
||||||
if (modStateModel->isModExists(potentialToInstall) && modStateModel->isModInstalled(potentialToInstall))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (modStateModel->isSubmod(potentialToInstall))
|
if (modStateModel->isSubmod(potentialToInstall))
|
||||||
{
|
{
|
||||||
QString topParent = modStateModel->getTopParent(potentialToInstall);
|
QString topParent = modStateModel->getTopParent(potentialToInstall);
|
||||||
@ -560,7 +558,8 @@ QStringList CModListView::getModsToInstall(QString mod)
|
|||||||
potentialToInstall = modStateModel->getTopParent(potentialToInstall);
|
potentialToInstall = modStateModel->getTopParent(potentialToInstall);
|
||||||
}
|
}
|
||||||
|
|
||||||
result.push_back(potentialToInstall);
|
if (modStateModel->isModExists(potentialToInstall) && !modStateModel->isModInstalled(potentialToInstall))
|
||||||
|
result.push_back(potentialToInstall);
|
||||||
|
|
||||||
if (modStateModel->isModExists(potentialToInstall))
|
if (modStateModel->isModExists(potentialToInstall))
|
||||||
{
|
{
|
||||||
@ -580,6 +579,8 @@ void CModListView::on_updateButton_clicked()
|
|||||||
{
|
{
|
||||||
QString modName = ui->allModsView->currentIndex().data(ModRoles::ModNameRole).toString();
|
QString modName = ui->allModsView->currentIndex().data(ModRoles::ModNameRole).toString();
|
||||||
doUpdateMod(modName);
|
doUpdateMod(modName);
|
||||||
|
|
||||||
|
ui->updateButton->setEnabled(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CModListView::doUpdateMod(const QString & modName)
|
void CModListView::doUpdateMod(const QString & modName)
|
||||||
@ -587,14 +588,14 @@ void CModListView::doUpdateMod(const QString & modName)
|
|||||||
auto targetMod = modStateModel->getMod(modName);
|
auto targetMod = modStateModel->getMod(modName);
|
||||||
|
|
||||||
if(targetMod.isUpdateAvailable())
|
if(targetMod.isUpdateAvailable())
|
||||||
downloadFile(modName + ".zip", targetMod.getDownloadUrl(), modName, targetMod.getDownloadSizeBytes());
|
downloadMod(targetMod);
|
||||||
|
|
||||||
for(const auto & name : getModsToInstall(modName))
|
for(const auto & name : getModsToInstall(modName))
|
||||||
{
|
{
|
||||||
auto mod = modStateModel->getMod(name);
|
auto mod = modStateModel->getMod(name);
|
||||||
// update required mod, install missing (can be new dependency)
|
// update required mod, install missing (can be new dependency)
|
||||||
if(mod.isUpdateAvailable() || !mod.isInstalled())
|
if(mod.isUpdateAvailable() || !mod.isInstalled())
|
||||||
downloadFile(name + ".zip", mod.getDownloadUrl(), name, mod.getDownloadSizeBytes());
|
downloadMod(mod);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -617,14 +618,18 @@ void CModListView::on_installButton_clicked()
|
|||||||
{
|
{
|
||||||
QString modName = ui->allModsView->currentIndex().data(ModRoles::ModNameRole).toString();
|
QString modName = ui->allModsView->currentIndex().data(ModRoles::ModNameRole).toString();
|
||||||
|
|
||||||
for(const auto & name : getModsToInstall(modName))
|
doInstallMod(modName);
|
||||||
{
|
|
||||||
auto mod = modStateModel->getMod(name);
|
ui->installButton->setEnabled(false);
|
||||||
if(mod.isAvailable())
|
}
|
||||||
downloadFile(name + ".zip", mod.getDownloadUrl(), name, mod.getDownloadSizeBytes());
|
|
||||||
else if(!modStateModel->isModEnabled(name))
|
void CModListView::downloadMod(const ModState & mod)
|
||||||
enableModByName(name);
|
{
|
||||||
}
|
if (enqueuedModDownloads.contains(mod.getID()))
|
||||||
|
return;
|
||||||
|
|
||||||
|
enqueuedModDownloads.push_back(mod.getID());
|
||||||
|
downloadFile(mod.getID() + ".zip", mod.getDownloadUrl(), mod.getName(), mod.getDownloadSizeBytes());
|
||||||
}
|
}
|
||||||
|
|
||||||
void CModListView::downloadFile(QString file, QUrl url, QString description, qint64 sizeBytes)
|
void CModListView::downloadFile(QString file, QUrl url, QString description, qint64 sizeBytes)
|
||||||
@ -697,6 +702,7 @@ void CModListView::downloadFinished(QStringList savedFiles, QStringList failedFi
|
|||||||
doInstallFiles = true;
|
doInstallFiles = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enqueuedModDownloads.clear();
|
||||||
dlManager->deleteLater();
|
dlManager->deleteLater();
|
||||||
dlManager = nullptr;
|
dlManager = nullptr;
|
||||||
|
|
||||||
@ -796,6 +802,7 @@ void CModListView::installFiles(QStringList files)
|
|||||||
{
|
{
|
||||||
ChroniclesExtractor ce(this, [&prog](float progress) { prog = progress; });
|
ChroniclesExtractor ce(this, [&prog](float progress) { prog = progress; });
|
||||||
ce.installChronicles(exe);
|
ce.installChronicles(exe);
|
||||||
|
enableModByName("chronicles");
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -959,11 +966,13 @@ void CModListView::on_screenshotsList_clicked(const QModelIndex & index)
|
|||||||
|
|
||||||
void CModListView::doInstallMod(const QString & modName)
|
void CModListView::doInstallMod(const QString & modName)
|
||||||
{
|
{
|
||||||
for(const auto & name : modStateModel->getMod(modName).getDependencies())
|
for(const auto & name : getModsToInstall(modName))
|
||||||
{
|
{
|
||||||
auto mod = modStateModel->getMod(name);
|
auto mod = modStateModel->getMod(name);
|
||||||
if(!mod.isInstalled())
|
if(mod.isAvailable())
|
||||||
downloadFile(name + ".zip", mod.getDownloadUrl(), name, mod.getDownloadSizeBytes());
|
downloadMod(mod);
|
||||||
|
else if(!modStateModel->isModEnabled(name))
|
||||||
|
enableModByName(name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,6 +37,8 @@ class CModListView : public QWidget
|
|||||||
CModFilterModel * filterModel;
|
CModFilterModel * filterModel;
|
||||||
CDownloadManager * dlManager;
|
CDownloadManager * dlManager;
|
||||||
|
|
||||||
|
QStringList enqueuedModDownloads;
|
||||||
|
|
||||||
void setupModModel();
|
void setupModModel();
|
||||||
void setupFilterModel();
|
void setupFilterModel();
|
||||||
void setupModsView();
|
void setupModsView();
|
||||||
@ -111,6 +113,7 @@ public:
|
|||||||
/// returns true if mod is currently installed
|
/// returns true if mod is currently installed
|
||||||
bool isModInstalled(const QString & modName);
|
bool isModInstalled(const QString & modName);
|
||||||
|
|
||||||
|
void downloadMod(const ModState & mod);
|
||||||
void downloadFile(QString file, QUrl url, QString description, qint64 sizeBytes = 0);
|
void downloadFile(QString file, QUrl url, QString description, qint64 sizeBytes = 0);
|
||||||
void installFiles(QStringList mods);
|
void installFiles(QStringList mods);
|
||||||
|
|
||||||
|
@ -102,7 +102,7 @@ void StartGameTab::refreshGameData()
|
|||||||
};
|
};
|
||||||
|
|
||||||
bool missingSoundtrack = !CResourceHandler::get()->existsResource(AudioPath::builtin("Music/MainMenu"));
|
bool missingSoundtrack = !CResourceHandler::get()->existsResource(AudioPath::builtin("Music/MainMenu"));
|
||||||
bool missingVideoFiles = !CResourceHandler::get()->existsResource(VideoPath::builtin("Video/H3Intro"));
|
bool missingVideoFiles = !CResourceHandler::get()->existsResource(VideoPath::builtin("Video/H3Intro")) && !CResourceHandler::get()->existsResource(ResourcePath("Video/H3Intro", EResType::VIDEO_LOW_QUALITY));
|
||||||
bool missingGameFiles = false;
|
bool missingGameFiles = false;
|
||||||
bool missingCampaings = false;
|
bool missingCampaings = false;
|
||||||
|
|
||||||
|
@ -1400,8 +1400,10 @@ bool CGameState::checkForVictory(const PlayerColor & player, const EventConditio
|
|||||||
case EventCondition::TRANSPORT:
|
case EventCondition::TRANSPORT:
|
||||||
{
|
{
|
||||||
const auto * t = getTown(condition.objectID);
|
const auto * t = getTown(condition.objectID);
|
||||||
return (t->visitingHero && t->visitingHero->getOwner() == player && t->visitingHero->hasArt(condition.objectType.as<ArtifactID>())) ||
|
bool garrisonedWon = t->garrisonHero && t->garrisonHero->getOwner() == player && t->garrisonHero->hasArt(condition.objectType.as<ArtifactID>());
|
||||||
(t->garrisonHero && t->garrisonHero->getOwner() == player && t->garrisonHero->hasArt(condition.objectType.as<ArtifactID>()));
|
bool visitingWon = t->visitingHero && t->visitingHero->getOwner() == player && t->visitingHero->hasArt(condition.objectType.as<ArtifactID>());
|
||||||
|
|
||||||
|
return garrisonedWon || visitingWon;
|
||||||
}
|
}
|
||||||
case EventCondition::DAYS_PASSED:
|
case EventCondition::DAYS_PASSED:
|
||||||
{
|
{
|
||||||
@ -1436,6 +1438,9 @@ PlayerColor CGameState::checkForStandardWin() const
|
|||||||
TeamID winnerTeam = TeamID::NO_TEAM;
|
TeamID winnerTeam = TeamID::NO_TEAM;
|
||||||
for(const auto & elem : players)
|
for(const auto & elem : players)
|
||||||
{
|
{
|
||||||
|
if(elem.second.status == EPlayerStatus::WINNER)
|
||||||
|
return elem.second.color;
|
||||||
|
|
||||||
if(elem.second.status == EPlayerStatus::INGAME && elem.first.isValidPlayer())
|
if(elem.second.status == EPlayerStatus::INGAME && elem.first.isValidPlayer())
|
||||||
{
|
{
|
||||||
if(supposedWinner == PlayerColor::NEUTRAL)
|
if(supposedWinner == PlayerColor::NEUTRAL)
|
||||||
|
@ -120,8 +120,7 @@ const JsonNode & ModDescription::getLocalizedValue(const std::string & keyName)
|
|||||||
|
|
||||||
const JsonNode & ModDescription::getValue(const std::string & keyName) const
|
const JsonNode & ModDescription::getValue(const std::string & keyName) const
|
||||||
{
|
{
|
||||||
const JsonNode & localValue = getLocalValue(keyName);
|
if (!isInstalled() || isUpdateAvailable())
|
||||||
if (localValue.isNull())
|
|
||||||
return getRepositoryValue(keyName);
|
return getRepositoryValue(keyName);
|
||||||
else
|
else
|
||||||
return getLocalValue(keyName);
|
return getLocalValue(keyName);
|
||||||
|
Loading…
Reference in New Issue
Block a user