mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +02:00
Improve mod status window and add warning dialog before startup
This commit is contained in:
parent
ded71332c9
commit
bbc9a0224a
@ -441,9 +441,9 @@ void CServerHandler::sendGuiAction(ui8 action) const
|
||||
sendLobbyPack(lga);
|
||||
}
|
||||
|
||||
void CServerHandler::sendStartGame(bool allowOnlyAI) const
|
||||
void CServerHandler::sendStartGame(ui8 startOptions) const
|
||||
{
|
||||
verifyStateBeforeStart(allowOnlyAI ? true : settings["session"]["onlyai"].Bool());
|
||||
verifyStateBeforeStart(settings["session"]["onlyai"].Bool() ? startOptions | StartInfo::IGNORE_ONLY_AI : startOptions);
|
||||
LobbyStartGame lsg;
|
||||
sendLobbyPack(lsg);
|
||||
}
|
||||
|
@ -60,7 +60,7 @@ public:
|
||||
virtual void setTurnLength(int npos) const = 0;
|
||||
virtual void sendMessage(const std::string & txt) const = 0;
|
||||
virtual void sendGuiAction(ui8 action) const = 0; // TODO: possibly get rid of it?
|
||||
virtual void sendStartGame(bool allowOnlyAI = false) const = 0;
|
||||
virtual void sendStartGame(ui8 startOptions = StartInfo::NO_OPTIONS) const = 0;
|
||||
};
|
||||
|
||||
/// structure to handle running server and connecting to it
|
||||
@ -129,7 +129,7 @@ public:
|
||||
void setTurnLength(int npos) const override;
|
||||
void sendMessage(const std::string & txt) const override;
|
||||
void sendGuiAction(ui8 action) const override;
|
||||
void sendStartGame(bool allowOnlyAI = false) const override;
|
||||
void sendStartGame(ui8 startOptions = StartInfo::NO_OPTIONS) const override;
|
||||
|
||||
void startGameplay();
|
||||
void endGameplay(bool closeConnection = true);
|
||||
|
@ -71,16 +71,16 @@ CLobbyScreen::CLobbyScreen(ESelectionScreen screenType)
|
||||
|
||||
card->iconDifficulty->addCallback(std::bind(&IServerAPI::setDifficulty, CSH, _1));
|
||||
|
||||
buttonStart = std::make_shared<CButton>(Point(411, 535), "SCNRBEG.DEF", CGI->generaltexth->zelp[103], std::bind(&CLobbyScreen::startScenario, this, false), SDLK_b);
|
||||
buttonStart = std::make_shared<CButton>(Point(411, 535), "SCNRBEG.DEF", CGI->generaltexth->zelp[103], std::bind(&CLobbyScreen::startScenario, this, StartInfo::NO_OPTIONS), SDLK_b);
|
||||
initLobby();
|
||||
break;
|
||||
}
|
||||
case ESelectionScreen::loadGame:
|
||||
{
|
||||
buttonMods = std::make_shared<CButton>(Point(619, 105), "GSPBUT2.DEF", std::make_pair<std::string, std::string>("", ""), [](){ GH.pushInt(new CModsBox()); }, SDLK_h);
|
||||
buttonMods = std::make_shared<CButton>(Point(619, 105), "GSPBUT2.DEF", std::make_pair<std::string, std::string>("", ""), [](){ GH.pushInt(new CModStatusBox()); }, SDLK_h);
|
||||
buttonMods->addTextOverlay(CGI->generaltexth->localizedTexts["lobby"]["buttonMods"]["default"].String(), EFonts::FONT_SMALL, Colors::WHITE);
|
||||
tabOpt = std::make_shared<OptionsTab>();
|
||||
buttonStart = std::make_shared<CButton>(Point(411, 535), "SCNRLOD.DEF", CGI->generaltexth->zelp[103], std::bind(&CLobbyScreen::startScenario, this, false), SDLK_l);
|
||||
buttonStart = std::make_shared<CButton>(Point(411, 535), "SCNRLOD.DEF", CGI->generaltexth->zelp[103], std::bind(&CLobbyScreen::startScenario, this, StartInfo::NO_OPTIONS), SDLK_l);
|
||||
initLobby();
|
||||
break;
|
||||
}
|
||||
@ -124,11 +124,11 @@ void CLobbyScreen::startCampaign()
|
||||
}
|
||||
}
|
||||
|
||||
void CLobbyScreen::startScenario(bool allowOnlyAI)
|
||||
void CLobbyScreen::startScenario(ui8 startOptions)
|
||||
{
|
||||
try
|
||||
{
|
||||
CSH->sendStartGame(allowOnlyAI);
|
||||
CSH->sendStartGame(startOptions);
|
||||
buttonStart->block(true);
|
||||
}
|
||||
catch(ExceptionMapMissing & e)
|
||||
@ -138,7 +138,11 @@ void CLobbyScreen::startScenario(bool allowOnlyAI)
|
||||
catch(ExceptionNoHuman & e)
|
||||
{
|
||||
// You must position yourself prior to starting the game.
|
||||
CInfoWindow::showYesNoDialog(std::ref(CGI->generaltexth->allTexts[530]), CInfoWindow::TCompsInfo(), 0, std::bind(&CLobbyScreen::startScenario, this, true), PlayerColor(1));
|
||||
CInfoWindow::showYesNoDialog(std::ref(CGI->generaltexth->allTexts[530]), CInfoWindow::TCompsInfo(), std::bind(&CLobbyScreen::startScenario, this, startOptions | StartInfo::IGNORE_ONLY_AI), 0, PlayerColor(1));
|
||||
}
|
||||
catch(ExceptionWrongMods & e)
|
||||
{
|
||||
GH.pushInt(new CModStatusBox(true, startOptions));
|
||||
}
|
||||
catch(ExceptionNoTemplate & e)
|
||||
{
|
||||
@ -225,60 +229,49 @@ const CMapInfo * CLobbyScreen::getMapInfo()
|
||||
return CSH->mi.get();
|
||||
}
|
||||
|
||||
CModsBox::CModsBox()
|
||||
CModStatusBox::CModStatusBox(bool showError, ui8 startOptions)
|
||||
: CWindowObject(BORDERED | SHADOW_DISABLED, "DIBOXBCK")
|
||||
{
|
||||
OBJ_CONSTRUCTION_CAPTURING_ALL_NO_DISPOSE;
|
||||
pos.w = 256;
|
||||
pos.w = 360;
|
||||
int lineHeight = graphics->fonts[FONT_SMALL]->getLineHeight();
|
||||
pos.h = 90 + 50 * 3 + lineHeight * CSH->mi->scenarioOptionsOfSave->mods.size();
|
||||
pos.h = 110 + lineHeight * CSH->mi->scenarioOptionsOfSave->mods.size();
|
||||
|
||||
labelTitle = std::make_shared<CLabel>(180, 30, FONT_MEDIUM, CENTER, Colors::YELLOW, CGI->generaltexth->localizedTexts["lobby"]["windowMods"]["title"].String());
|
||||
labelGroupMods = std::make_shared<CLabelGroup>(FONT_SMALL, EAlignment::TOPLEFT, Colors::WHITE);
|
||||
labelGroupStatusWorking = std::make_shared<CLabelGroup>(FONT_SMALL, EAlignment::TOPLEFT, Colors::GREEN);
|
||||
labelGroupStatusMissing = std::make_shared<CLabelGroup>(FONT_SMALL, EAlignment::TOPLEFT, Colors::ORANGE);
|
||||
labelGroupStatusIncompatible = std::make_shared<CLabelGroup>(FONT_SMALL, EAlignment::TOPLEFT, Colors::WHITE);
|
||||
|
||||
labelTitle = std::make_shared<CLabel>(128, 30, FONT_MEDIUM, CENTER, Colors::YELLOW, CGI->generaltexth->localizedTexts["lobby"]["windowMods"]["title"].String());
|
||||
labelGroupStatus = std::make_shared<CLabelGroup>(FONT_SMALL, EAlignment::CENTER, Colors::WHITE);
|
||||
labelGroupMods = std::make_shared<CLabelGroup>(FONT_SMALL, EAlignment::CENTER, Colors::WHITE);
|
||||
auto erroredMods = CGI->modh->checkModsPresent(CSH->mi->scenarioOptionsOfSave->mods);
|
||||
|
||||
for(int i = 0; i < 3; i++)
|
||||
{
|
||||
std::vector<ui8> flags;
|
||||
if(i == 0)
|
||||
labelGroupStatus->add(128, 65 + 50 * i, CGI->generaltexth->localizedTexts["lobby"]["windowMods"]["groups"]["working"].String());
|
||||
if(i == 1)
|
||||
labelGroupStatus->add(128, 65 + 50 * i + lineHeight * labelGroupMods->currentSize(), CGI->generaltexth->localizedTexts["lobby"]["windowMods"]["groups"]["missing"].String());
|
||||
if(i == 2)
|
||||
labelGroupStatus->add(128, 65 + 50 * i + lineHeight * labelGroupMods->currentSize(), CGI->generaltexth->localizedTexts["lobby"]["windowMods"]["groups"]["incompatible"].String());
|
||||
|
||||
for(auto & mod : CSH->mi->scenarioOptionsOfSave->mods)
|
||||
{
|
||||
int positionY = 50 + lineHeight * labelGroupMods->currentSize();
|
||||
labelGroupMods->add(20, positionY, mod.name.substr(0, 30));
|
||||
if(!vstd::contains(erroredMods, mod.identifier))
|
||||
{
|
||||
if(i == 0)
|
||||
labelGroupMods->add(128, 75 + 50 * i + lineHeight * labelGroupMods->currentSize(), mod.name);
|
||||
|
||||
labelGroupStatusWorking->add(258, positionY, CGI->generaltexth->localizedTexts["lobby"]["windowMods"]["groups"]["compatible"].String());
|
||||
}
|
||||
else if(erroredMods[mod.identifier] == CModInfo::INCOMPATIBLE)
|
||||
{
|
||||
labelGroupStatusIncompatible->add(258, positionY, CGI->generaltexth->localizedTexts["lobby"]["windowMods"]["groups"]["incompatible"].String());
|
||||
}
|
||||
else if(erroredMods[mod.identifier] == CModInfo::MISSING)
|
||||
{
|
||||
labelGroupStatusMissing->add(258, positionY, CGI->generaltexth->localizedTexts["lobby"]["windowMods"]["groups"]["missing"].String());
|
||||
}
|
||||
}
|
||||
if(showError)
|
||||
{
|
||||
pos.h += 40;
|
||||
labelErrorMessage = std::make_shared<CMultiLineLabel>(Rect(20, pos.h-90, 320, graphics->fonts[EFonts::FONT_SMALL]->getLineHeight()*2), EFonts::FONT_SMALL, EAlignment::CENTER, Colors::WHITE, CGI->generaltexth->localizedTexts["lobby"]["windowMods"]["errorMessage"].String());
|
||||
buttonOk = std::make_shared<CButton>(Point(110, pos.h-50), "MUBCHCK.DEF", CGI->generaltexth->zelp[561], std::bind(&IServerAPI::sendStartGame, CSH, startOptions | StartInfo::IGNORE_WRONG_MODS), SDLK_RETURN);
|
||||
buttonCancel = std::make_shared<CButton>(Point(196, pos.h-50), "MUBCANC.DEF", CGI->generaltexth->zelp[561], std::bind(&CGuiHandler::popIntTotally, &GH, this), SDLK_ESCAPE);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(i == 1 && erroredMods[mod.identifier] == CModInfo::MISSING)
|
||||
{
|
||||
labelGroupMods->add(128, 75 + 50 * i + lineHeight * labelGroupMods->currentSize(), mod.name);
|
||||
buttonCancel = std::make_shared<CButton>(Point(154, pos.h-50), "MUBCANC.DEF", CGI->generaltexth->zelp[561], std::bind(&CGuiHandler::popIntTotally, &GH, this), SDLK_ESCAPE);
|
||||
}
|
||||
else if(i == 2 && erroredMods[mod.identifier] == CModInfo::INCOMPATIBLE)
|
||||
{
|
||||
labelGroupMods->add(128, 75 + 50 * i + lineHeight * labelGroupMods->currentSize(), mod.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(int j = 0; j < PlayerColor::PLAYER_LIMIT_I; j++)
|
||||
{
|
||||
if((SEL->getPlayerInfo(j).canHumanPlay || SEL->getPlayerInfo(j).canComputerPlay)
|
||||
&& SEL->getPlayerInfo(j).team == TeamID(i))
|
||||
{
|
||||
flags.push_back(j);
|
||||
}
|
||||
}
|
||||
}
|
||||
buttonCancel = std::make_shared<CButton>(Point(100, pos.h-50), "MUBCANC.DEF", CGI->generaltexth->zelp[561], std::bind(&CGuiHandler::popIntTotally, &GH, this), SDLK_ESCAPE);
|
||||
|
||||
background->scaleTo(Point(pos.w, pos.h));
|
||||
center();
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "CSelectionBase.h"
|
||||
|
||||
class CBonusSelection;
|
||||
class CMultiLineLabel;
|
||||
|
||||
class CLobbyScreen : public CSelectionBase
|
||||
{
|
||||
@ -23,7 +24,7 @@ public:
|
||||
~CLobbyScreen();
|
||||
void toggleTab(std::shared_ptr<CIntObject> tab) override;
|
||||
void startCampaign();
|
||||
void startScenario(bool allowOnlyAI = false);
|
||||
void startScenario(ui8 startOptions = 0);
|
||||
void toggleMode(bool host);
|
||||
void toggleChat();
|
||||
|
||||
@ -35,12 +36,16 @@ public:
|
||||
CBonusSelection * bonusSel;
|
||||
};
|
||||
|
||||
class CModsBox : public CWindowObject
|
||||
class CModStatusBox : public CWindowObject
|
||||
{
|
||||
std::shared_ptr<CLabel> labelTitle;
|
||||
std::shared_ptr<CLabelGroup> labelGroupStatus;
|
||||
std::shared_ptr<CLabelGroup> labelGroupMods;
|
||||
std::shared_ptr<CLabelGroup> labelGroupStatusWorking;
|
||||
std::shared_ptr<CLabelGroup> labelGroupStatusMissing;
|
||||
std::shared_ptr<CLabelGroup> labelGroupStatusIncompatible;
|
||||
std::shared_ptr<CMultiLineLabel> labelErrorMessage;
|
||||
std::shared_ptr<CButton> buttonOk;
|
||||
std::shared_ptr<CButton> buttonCancel;
|
||||
public:
|
||||
CModsBox();
|
||||
CModStatusBox(bool showError = false, ui8 startOptions = 0);
|
||||
};
|
||||
|
@ -5,11 +5,12 @@
|
||||
"windowMods" :
|
||||
{
|
||||
"title" : "Mods status",
|
||||
"errorMessage" : "Missing or changed mods might cause crashes. Would you like to continue?"
|
||||
"groups" :
|
||||
{
|
||||
"working" : "Available",
|
||||
"missing" : "Missing",
|
||||
"incompatible" : "Wrong version"
|
||||
"compatible" : "Same version",
|
||||
"incompatible" : "Wrong version",
|
||||
"missing" : "Not installed"
|
||||
}
|
||||
},
|
||||
"buttonMods" :
|
||||
|
@ -61,7 +61,7 @@ std::string StartInfo::getCampaignName() const
|
||||
return VLC->generaltexth->allTexts[508];
|
||||
}
|
||||
|
||||
void LobbyInfo::verifyStateBeforeStart(bool ignoreNoHuman) const
|
||||
void LobbyInfo::verifyStateBeforeStart(ui8 startOptions) const
|
||||
{
|
||||
if(!mi)
|
||||
throw ExceptionMapMissing();
|
||||
@ -72,9 +72,16 @@ void LobbyInfo::verifyStateBeforeStart(bool ignoreNoHuman) const
|
||||
if(i->second.isControlledByHuman())
|
||||
break;
|
||||
|
||||
if(i == si->playerInfos.cend() && !ignoreNoHuman)
|
||||
if(i == si->playerInfos.cend() && !(startOptions & StartInfo::IGNORE_ONLY_AI))
|
||||
throw ExceptionNoHuman();
|
||||
|
||||
if(mi->scenarioOptionsOfSave)
|
||||
{
|
||||
auto erroredMods = VLC->modh->checkModsPresent(mi->scenarioOptionsOfSave->mods);
|
||||
if(erroredMods.size() && !(startOptions & StartInfo::IGNORE_WRONG_MODS))
|
||||
throw ExceptionWrongMods();
|
||||
}
|
||||
|
||||
if(si->mapGenOptions && si->mode == StartInfo::NEW_GAME)
|
||||
{
|
||||
if(!si->mapGenOptions->checkOptions())
|
||||
|
@ -82,6 +82,13 @@ struct DLL_LINKAGE PlayerSettings
|
||||
/// Struct which describes the difficulty, the turn time,.. of a heroes match.
|
||||
struct DLL_LINKAGE StartInfo
|
||||
{
|
||||
enum EStartOptions : ui8
|
||||
{
|
||||
NO_OPTIONS = 0,
|
||||
IGNORE_ONLY_AI = 1,
|
||||
IGNORE_WRONG_MODS = 2
|
||||
};
|
||||
|
||||
enum EMode {NEW_GAME, LOAD_GAME, CAMPAIGN, INVALID = 255};
|
||||
|
||||
EMode mode;
|
||||
@ -179,7 +186,7 @@ struct DLL_LINKAGE LobbyInfo : public LobbyState
|
||||
|
||||
LobbyInfo() {}
|
||||
|
||||
void verifyStateBeforeStart(bool ignoreNoHuman = false) const;
|
||||
void verifyStateBeforeStart(ui8 startOptions = StartInfo::NO_OPTIONS) const;
|
||||
|
||||
bool isClientHost(int clientId) const;
|
||||
std::set<PlayerColor> getAllClientPlayers(int clientId);
|
||||
@ -196,4 +203,5 @@ struct DLL_LINKAGE LobbyInfo : public LobbyState
|
||||
|
||||
class ExceptionMapMissing : public std::exception {};
|
||||
class ExceptionNoHuman : public std::exception {};
|
||||
class ExceptionWrongMods : public std::exception {};
|
||||
class ExceptionNoTemplate : public std::exception {};
|
||||
|
@ -165,7 +165,7 @@ bool LobbyStartGame::applyOnServer(CVCMIServer * srv)
|
||||
{
|
||||
try
|
||||
{
|
||||
srv->verifyStateBeforeStart(true);
|
||||
srv->verifyStateBeforeStart(StartInfo::IGNORE_ONLY_AI | StartInfo::IGNORE_WRONG_MODS);
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user