mirror of
https://github.com/vcmi/vcmi.git
synced 2026-06-19 22:57:37 +02:00
Merge pull request #2805 from IvanSavenko/bugfixing_beta
Bugfixing for 1.3.2
This commit is contained in:
@@ -173,6 +173,8 @@
|
||||
|
||||
"vcmi.heroWindow.openCommander.hover" : "Відкрити вікно командира",
|
||||
"vcmi.heroWindow.openCommander.help" : "Показує інформацію про командира героя",
|
||||
"vcmi.heroWindow.openBackpack.hover" : "Відкрити вікно рюкзака з артефактами",
|
||||
"vcmi.heroWindow.openBackpack.help" : "Відкриває вікно, що дозволяє легше керувати рюкзаком артефактів",
|
||||
|
||||
"vcmi.commanderWindow.artifactMessage" : "Бажаєте передати цей артефакт герою?",
|
||||
|
||||
|
||||
@@ -573,17 +573,35 @@ void CServerHandler::sendRestartGame() const
|
||||
sendLobbyPack(endGame);
|
||||
}
|
||||
|
||||
void CServerHandler::sendStartGame(bool allowOnlyAI) const
|
||||
bool CServerHandler::validateGameStart(bool allowOnlyAI) const
|
||||
{
|
||||
try
|
||||
{
|
||||
verifyStateBeforeStart(allowOnlyAI ? true : settings["session"]["onlyai"].Bool());
|
||||
}
|
||||
catch (const std::exception & e)
|
||||
catch(CModHandler::Incompatibility & e)
|
||||
{
|
||||
showServerError( std::string("Unable to start map! Reason: ") + e.what());
|
||||
return;
|
||||
logGlobal->warn("Incompatibility exception during start scenario: %s", e.what());
|
||||
|
||||
auto errorMsg = CGI->generaltexth->translate("vcmi.server.errors.modsIncompatibility") + '\n';
|
||||
errorMsg += e.what();
|
||||
|
||||
showServerError(errorMsg);
|
||||
return false;
|
||||
}
|
||||
catch(std::exception & e)
|
||||
{
|
||||
logGlobal->error("Exception during startScenario: %s", e.what());
|
||||
showServerError( std::string("Unable to start map! Reason: ") + e.what());
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CServerHandler::sendStartGame(bool allowOnlyAI) const
|
||||
{
|
||||
verifyStateBeforeStart(allowOnlyAI ? true : settings["session"]["onlyai"].Bool());
|
||||
|
||||
LobbyStartGame lsg;
|
||||
if(client)
|
||||
@@ -708,7 +726,7 @@ void CServerHandler::startCampaignScenario(std::shared_ptr<CampaignState> cs)
|
||||
});
|
||||
}
|
||||
|
||||
void CServerHandler::showServerError(std::string txt) const
|
||||
void CServerHandler::showServerError(const std::string & txt) const
|
||||
{
|
||||
CInfoWindow::showInfoDialog(txt, {});
|
||||
}
|
||||
|
||||
@@ -148,16 +148,18 @@ public:
|
||||
void sendRestartGame() const override;
|
||||
void sendStartGame(bool allowOnlyAI = false) const override;
|
||||
|
||||
bool validateGameStart(bool allowOnlyAI = false) const;
|
||||
void debugStartTest(std::string filename, bool save = false);
|
||||
|
||||
void startGameplay(VCMI_LIB_WRAP_NAMESPACE(CGameState) * gameState = nullptr);
|
||||
void endGameplay(bool closeConnection = true, bool restart = false);
|
||||
void startCampaignScenario(std::shared_ptr<CampaignState> cs = {});
|
||||
void showServerError(std::string txt) const;
|
||||
void showServerError(const std::string & txt) const;
|
||||
|
||||
// TODO: LobbyState must be updated within game so we should always know how many player interfaces our client handle
|
||||
int howManyPlayerInterfaces();
|
||||
ui8 getLoadMode();
|
||||
|
||||
void debugStartTest(std::string filename, bool save = false);
|
||||
void restoreLastSession();
|
||||
|
||||
void visitForLobby(CPackForLobby & lobbyPack);
|
||||
|
||||
@@ -102,7 +102,10 @@ void ApplyOnLobbyHandlerNetPackVisitor::visitLobbyEndGame(LobbyEndGame & pack)
|
||||
}
|
||||
|
||||
if(pack.restart)
|
||||
handler.sendStartGame();
|
||||
{
|
||||
if (handler.validateGameStart())
|
||||
handler.sendStartGame();
|
||||
}
|
||||
}
|
||||
|
||||
void ApplyOnLobbyHandlerNetPackVisitor::visitLobbyStartGame(LobbyStartGame & pack)
|
||||
|
||||
@@ -402,7 +402,7 @@ bool AdventureMapShortcuts::optionCanViewQuests()
|
||||
|
||||
bool AdventureMapShortcuts::optionCanToggleLevel()
|
||||
{
|
||||
return optionInMapView() && LOCPLINT->cb->getMapSize().z > 1;
|
||||
return optionSidePanelActive() && LOCPLINT->cb->getMapSize().z > 1;
|
||||
}
|
||||
|
||||
bool AdventureMapShortcuts::optionMapLevelSurface()
|
||||
|
||||
@@ -128,6 +128,7 @@ void InputHandler::preprocessEvent(const SDL_Event & ev)
|
||||
#endif
|
||||
else if(ev.type == SDL_KEYDOWN && ev.key.keysym.sym==SDLK_F4)
|
||||
{
|
||||
boost::unique_lock<boost::recursive_mutex> lock(*CPlayerInterface::pim);
|
||||
Settings full = settings.write["video"]["fullscreen"];
|
||||
full->Bool() = !full->Bool();
|
||||
|
||||
|
||||
@@ -343,7 +343,7 @@ void CBonusSelection::updateAfterStateChange()
|
||||
{
|
||||
buttonStart->block(getCampaign()->scenario(CSH->campaignMap).travelOptions.bonusesToChoose.size());
|
||||
}
|
||||
else if(buttonStart->isBlocked())
|
||||
else
|
||||
{
|
||||
buttonStart->block(false);
|
||||
}
|
||||
@@ -390,6 +390,9 @@ void CBonusSelection::goBack()
|
||||
|
||||
void CBonusSelection::startMap()
|
||||
{
|
||||
if (!CSH->validateGameStart())
|
||||
return;
|
||||
|
||||
auto showPrologVideo = [=]()
|
||||
{
|
||||
auto exitCb = [=]()
|
||||
|
||||
@@ -88,6 +88,8 @@ CLobbyScreen::CLobbyScreen(ESelectionScreen screenType)
|
||||
break;
|
||||
}
|
||||
|
||||
buttonStart->block(true); // to be unblocked after map list is ready
|
||||
|
||||
buttonBack = std::make_shared<CButton>(Point(581, 535), "SCNRBACK.DEF", CGI->generaltexth->zelp[105], [&]()
|
||||
{
|
||||
CSH->sendClientDisconnecting();
|
||||
@@ -126,34 +128,11 @@ void CLobbyScreen::startCampaign()
|
||||
|
||||
void CLobbyScreen::startScenario(bool allowOnlyAI)
|
||||
{
|
||||
try
|
||||
if (CSH->validateGameStart(allowOnlyAI))
|
||||
{
|
||||
CSH->sendStartGame(allowOnlyAI);
|
||||
buttonStart->block(true);
|
||||
}
|
||||
catch(CModHandler::Incompatibility & e)
|
||||
{
|
||||
logGlobal->warn("Incompatibility exception during start scenario: %s", e.what());
|
||||
|
||||
auto errorMsg = CGI->generaltexth->translate("vcmi.server.errors.modsIncompatibility") + '\n';
|
||||
errorMsg += e.what();
|
||||
|
||||
CInfoWindow::showInfoDialog(errorMsg, CInfoWindow::TCompsInfo(), PlayerColor(1));
|
||||
}
|
||||
catch(std::exception & e)
|
||||
{
|
||||
logGlobal->error("Exception during startScenario: %s", e.what());
|
||||
|
||||
if(std::string(e.what()) == "ExceptionNoHuman")
|
||||
CInfoWindow::showInfoDialog(CGI->generaltexth->allTexts[530], CInfoWindow::TCompsInfo(), PlayerColor(1));
|
||||
|
||||
if(std::string(e.what()) == "ExceptionNoTemplate")
|
||||
CInfoWindow::showInfoDialog(CGI->generaltexth->allTexts[751], CInfoWindow::TCompsInfo(), PlayerColor(1));
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
logGlobal->error("Unknown exception");
|
||||
}
|
||||
}
|
||||
|
||||
void CLobbyScreen::toggleMode(bool host)
|
||||
@@ -192,6 +171,8 @@ void CLobbyScreen::updateAfterStateChange()
|
||||
if(CSH->mi && tabOpt)
|
||||
tabOpt->recreate();
|
||||
|
||||
buttonStart->block(CSH->mi == nullptr || CSH->isGuest());
|
||||
|
||||
card->changeSelection();
|
||||
if (card->iconDifficulty)
|
||||
{
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include "../render/CAnimation.h"
|
||||
#include "../render/Canvas.h"
|
||||
#include "../render/IImage.h"
|
||||
#include "../render/Colors.h"
|
||||
|
||||
#include "../../CCallback.h"
|
||||
|
||||
@@ -246,7 +247,6 @@ uint8_t MapRendererRoad::checksum(IMapRendererContext & context, const int3 & co
|
||||
|
||||
MapRendererBorder::MapRendererBorder()
|
||||
{
|
||||
emptyFill = std::make_unique<Canvas>(Point(32,32));
|
||||
animation = std::make_unique<CAnimation>("EDG");
|
||||
animation->preload();
|
||||
}
|
||||
@@ -298,7 +298,7 @@ void MapRendererBorder::renderTile(IMapRendererContext & context, Canvas & targe
|
||||
}
|
||||
else
|
||||
{
|
||||
target.draw(*emptyFill, Point(0,0));
|
||||
target.drawColor(Rect(0,0,32,32), Colors::BLACK);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -90,7 +90,6 @@ public:
|
||||
class MapRendererBorder
|
||||
{
|
||||
std::unique_ptr<CAnimation> animation;
|
||||
std::unique_ptr<Canvas> emptyFill;
|
||||
|
||||
size_t getIndexForTile(IMapRendererContext & context, const int3 & coordinates);
|
||||
|
||||
|
||||
@@ -87,7 +87,7 @@ CHeroWindow::CHeroWindow(const CGHeroInstance * hero)
|
||||
if(settings["general"]["enableUiEnhancements"].Bool())
|
||||
{
|
||||
questlogButton = std::make_shared<CButton>(Point(314, 429), "hsbtns4.def", CButton::tooltip(heroscrn[0]), [=](){ LOCPLINT->showQuestLog(); }, EShortcut::ADVENTURE_QUEST_LOG);
|
||||
backpackButton = std::make_shared<CButton>(Point(424, 429), "buttons/backpack", CButton::tooltipLocalized("vcmi.heroWindow.Backpack"), [=](){ createBackpackWindow(); }, EShortcut::HERO_BACKPACK);
|
||||
backpackButton = std::make_shared<CButton>(Point(424, 429), "buttons/backpack", CButton::tooltipLocalized("vcmi.heroWindow.openBackpack"), [=](){ createBackpackWindow(); }, EShortcut::HERO_BACKPACK);
|
||||
backpackButton->addOverlay(std::make_shared<CPicture>("buttons/backpackButtonIcon"));
|
||||
dismissButton = std::make_shared<CButton>(Point(534, 429), "hsbtns2.def", CButton::tooltip(heroscrn[28]), [=](){ dismissCurrent(); }, EShortcut::HERO_DISMISS);
|
||||
}
|
||||
|
||||
@@ -126,7 +126,7 @@
|
||||
"playerColored" : true,
|
||||
"area": { "top" : 0, "left": 0, "width" : 32, "height" : 32 }
|
||||
}
|
||||
],
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "adventureMapContainer",
|
||||
@@ -142,7 +142,7 @@
|
||||
"playerColored" : true,
|
||||
"area": { "top" : 0, "left": 0, "width" : 32, "height" : 32 }
|
||||
}
|
||||
],
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "adventureMapButton",
|
||||
@@ -507,12 +507,19 @@
|
||||
"area": { "top" : 23, "left": 128, "width" : 60, "height" : 32 }
|
||||
},
|
||||
{
|
||||
"type": "adventureMapButton",
|
||||
"name": "worldViewSurface",
|
||||
"image" : "IAM003.DEF",
|
||||
"hotkey": "adventureToggleMapLevel",
|
||||
"playerColored" : true,
|
||||
"area": { "top" : 79, "left": 343, "width" : 32, "height" : 32 }
|
||||
"type": "adventureMapContainer",
|
||||
"hideWhen" : "mapLayerSurface",
|
||||
"area": { "top" : 343, "left": 79, "width" : 32, "height" : 32 }
|
||||
"items" : [
|
||||
{
|
||||
"type": "adventureMapButton",
|
||||
"name": "worldViewSurface",
|
||||
"image" : "IAM003.DEF",
|
||||
"hotkey": "adventureToggleMapLevel",
|
||||
"playerColored" : true,
|
||||
"area": { "top" : 0, "left": 0, "width" : 32, "height" : 32 }
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "adventureMapButton",
|
||||
@@ -523,12 +530,19 @@
|
||||
"area": { "top" : 343, "left": 5, "width" : 66, "height" : 32 }
|
||||
},
|
||||
{
|
||||
"type": "adventureMapButton",
|
||||
"name": "worldViewUnderground",
|
||||
"image" : "IAM010.DEF",
|
||||
"playerColored" : true,
|
||||
"hotkey": "adventureToggleMapLevel",
|
||||
"type": "adventureMapContainer",
|
||||
"hideWhen" : "mapLayerUnderground",
|
||||
"area": { "top" : 343, "left": 79, "width" : 32, "height" : 32 }
|
||||
"items" : [
|
||||
{
|
||||
"type": "adventureMapButton",
|
||||
"name": "worldViewUnderground",
|
||||
"image" : "IAM010.DEF",
|
||||
"playerColored" : true,
|
||||
"hotkey": "adventureToggleMapLevel",
|
||||
"area": { "top" : 0, "left": 0, "width" : 32, "height" : 32 }
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "adventureMapButton",
|
||||
|
||||
@@ -764,10 +764,10 @@ void CModListView::installMods(QStringList archives)
|
||||
enableMod(mod);
|
||||
}
|
||||
|
||||
checkManagerErrors();
|
||||
|
||||
for(QString archive : archives)
|
||||
QFile::remove(archive);
|
||||
|
||||
checkManagerErrors();
|
||||
}
|
||||
|
||||
void CModListView::on_refreshButton_clicked()
|
||||
|
||||
@@ -39,6 +39,11 @@ QString detectModArchive(QString path, QString modName)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
logGlobal->error("Failed to detect mod path in archive!");
|
||||
logGlobal->debug("List of file in archive:");
|
||||
for(auto file : files)
|
||||
logGlobal->debug("%s", file.c_str());
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
+3
-3
@@ -71,7 +71,7 @@ std::string StartInfo::getCampaignName() const
|
||||
void LobbyInfo::verifyStateBeforeStart(bool ignoreNoHuman) const
|
||||
{
|
||||
if(!mi || !mi->mapHeader)
|
||||
throw std::domain_error("There is no map to start!");
|
||||
throw std::domain_error(VLC->generaltexth->translate("core.genrltxt.529"));
|
||||
|
||||
auto missingMods = CMapService::verifyMapHeaderMods(*mi->mapHeader);
|
||||
CModHandler::Incompatibility::ModList modList;
|
||||
@@ -88,12 +88,12 @@ void LobbyInfo::verifyStateBeforeStart(bool ignoreNoHuman) const
|
||||
break;
|
||||
|
||||
if(i == si->playerInfos.cend() && !ignoreNoHuman)
|
||||
throw std::domain_error("There is no human player on map");
|
||||
throw std::domain_error(VLC->generaltexth->translate("core.genrltxt.530"));
|
||||
|
||||
if(si->mapGenOptions && si->mode == StartInfo::NEW_GAME)
|
||||
{
|
||||
if(!si->mapGenOptions->checkOptions())
|
||||
throw std::domain_error("No random map template found!");
|
||||
throw std::domain_error(VLC->generaltexth->translate("core.genrltxt.751"));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -157,7 +157,15 @@ std::vector<std::string> ZipArchive::listFiles(const boost::filesystem::path & f
|
||||
|
||||
unzFile file = unzOpen2_64(filename.c_str(), FileStream::GetMinizipFilefunc());
|
||||
|
||||
if (unzGoToFirstFile(file) == UNZ_OK)
|
||||
if (file == nullptr)
|
||||
{
|
||||
logGlobal->error("Failed to open file '%s'! Unable to list files!", filename.string());
|
||||
return {};
|
||||
}
|
||||
|
||||
int result = unzGoToFirstFile(file);
|
||||
|
||||
if (result == UNZ_OK)
|
||||
{
|
||||
do
|
||||
{
|
||||
@@ -171,9 +179,21 @@ std::vector<std::string> ZipArchive::listFiles(const boost::filesystem::path & f
|
||||
unzGetCurrentFileInfo64(file, &info, zipFilename.data(), static_cast<uLong>(zipFilename.size()), nullptr, 0, nullptr, 0);
|
||||
|
||||
ret.emplace_back(zipFilename.data(), zipFilename.size());
|
||||
|
||||
result = unzGoToNextFile(file);
|
||||
}
|
||||
while (result == UNZ_OK);
|
||||
|
||||
if (result != UNZ_OK && result != UNZ_END_OF_LIST_OF_FILE)
|
||||
{
|
||||
logGlobal->error("Failed to list file from '%s'! Error code %d", filename.string(), result);
|
||||
}
|
||||
while (unzGoToNextFile(file) == UNZ_OK);
|
||||
}
|
||||
else
|
||||
{
|
||||
logGlobal->error("Failed to list files from '%s'! Error code %d", filename.string(), result);
|
||||
}
|
||||
|
||||
unzClose(file);
|
||||
|
||||
return ret;
|
||||
|
||||
@@ -589,6 +589,11 @@ void CGameHandler::endBattle(int3 tile, const CGHeroInstance * heroAttacker, con
|
||||
battleResult.data->exp[0] += 500;
|
||||
}
|
||||
|
||||
// Give 500 exp to winner if a town was conquered during the battle
|
||||
const auto * defendedTown = battleGetDefendedTown();
|
||||
if (defendedTown && battleResult.data->winner == BattleSide::ATTACKER)
|
||||
battleResult.data->exp[BattleSide::ATTACKER] += 500;
|
||||
|
||||
if(heroAttacker)
|
||||
battleResult.data->exp[0] = heroAttacker->calculateXp(battleResult.data->exp[0]);//scholar skill
|
||||
if(heroDefender)
|
||||
|
||||
Reference in New Issue
Block a user