1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-08-13 19:54:17 +02:00

Single player spectator

This commit is contained in:
nordsoft
2023-04-13 02:01:13 +04:00
parent f005dbbc14
commit fb4db41891
5 changed files with 25 additions and 18 deletions

View File

@@ -146,7 +146,7 @@ public:
void sendMessage(const std::string & txt) const override; void sendMessage(const std::string & txt) const override;
void sendGuiAction(ui8 action) const override; void sendGuiAction(ui8 action) const override;
void sendRestartGame() const override; void sendRestartGame() const override;
void sendStartGame(bool allowOnlyAI = false) const override; void sendStartGame(bool allowOnlyAI = true) const override;
void startGameplay(VCMI_LIB_WRAP_NAMESPACE(CGameState) * gameState = nullptr); void startGameplay(VCMI_LIB_WRAP_NAMESPACE(CGameState) * gameState = nullptr);
void endGameplay(bool closeConnection = true, bool restart = false); void endGameplay(bool closeConnection = true, bool restart = false);

View File

@@ -401,18 +401,23 @@ void CClient::initPlayerEnvironments()
playerEnvironments.clear(); playerEnvironments.clear();
auto allPlayers = CSH->getAllClientPlayers(CSH->c->connectionID); auto allPlayers = CSH->getAllClientPlayers(CSH->c->connectionID);
if(allPlayers.empty()) bool hasHumanPlayer = false;
{
Settings session = settings.write["session"];
session["spectate"].Bool() = true;
}
for(auto & color : allPlayers) for(auto & color : allPlayers)
{ {
logNetwork->info("Preparing environment for player %s", color.getStr()); logNetwork->info("Preparing environment for player %s", color.getStr());
playerEnvironments[color] = std::make_shared<CPlayerEnvironment>(color, this, std::make_shared<CCallback>(gs, color, this)); playerEnvironments[color] = std::make_shared<CPlayerEnvironment>(color, this, std::make_shared<CCallback>(gs, color, this));
if(!hasHumanPlayer && gs->players[color].isHuman())
hasHumanPlayer = true;
} }
if(!hasHumanPlayer)
{
Settings session = settings.write["session"];
session["spectate"].Bool() = true;
session["spectate-skip-battle-result"].Bool() = true;
}
if(settings["session"]["spectate"].Bool()) if(settings["session"]["spectate"].Bool())
{ {
playerEnvironments[PlayerColor::SPECTATOR] = std::make_shared<CPlayerEnvironment>(PlayerColor::SPECTATOR, this, std::make_shared<CCallback>(gs, boost::none, this)); playerEnvironments[PlayerColor::SPECTATOR] = std::make_shared<CPlayerEnvironment>(PlayerColor::SPECTATOR, this, std::make_shared<CCallback>(gs, boost::none, this));
@@ -581,27 +586,29 @@ void CClient::battleStarted(const BattleInfo * info)
if(vstd::contains(playerint, rightSide.color) && playerint[rightSide.color]->human) if(vstd::contains(playerint, rightSide.color) && playerint[rightSide.color]->human)
def = std::dynamic_pointer_cast<CPlayerInterface>(playerint[rightSide.color]); def = std::dynamic_pointer_cast<CPlayerInterface>(playerint[rightSide.color]);
auto spectratorInterface = std::dynamic_pointer_cast<CPlayerInterface>(playerint[PlayerColor::SPECTATOR]);
//Remove player interfaces for auto battle (quickCombat option) //Remove player interfaces for auto battle (quickCombat option)
if(att && att->isAutoFightOn) if(att && att->isAutoFightOn)
{ {
att.reset(); att.reset();
def.reset(); def.reset();
spectratorInterface.reset();
} }
else if(!settings["session"]["headless"].Bool())
if(!settings["session"]["headless"].Bool())
{ {
if(!!att || !!def) if(!!att || !!def)
{ {
boost::unique_lock<boost::recursive_mutex> un(*CPlayerInterface::pim); boost::unique_lock<boost::recursive_mutex> un(*CPlayerInterface::pim);
CPlayerInterface::battleInt = std::make_shared<BattleInterface>(leftSide.armyObject, rightSide.armyObject, leftSide.hero, rightSide.hero, att, def); CPlayerInterface::battleInt = std::make_shared<BattleInterface>(leftSide.armyObject, rightSide.armyObject, leftSide.hero, rightSide.hero, att, def);
} }
else if(settings["session"]["spectate"].Bool() && !settings["session"]["spectate-skip-battle"].Bool()) else if(false && settings["session"]["spectate"].Bool() && !settings["session"]["spectate-skip-battle"].Bool())
{ {
//spectator for AI-only battles
//TODO: This certainly need improvement //TODO: This certainly need improvement
auto spectratorInt = std::dynamic_pointer_cast<CPlayerInterface>(playerint[PlayerColor::SPECTATOR]); spectratorInterface->cb->setBattle(info);
spectratorInt->cb->setBattle(info);
boost::unique_lock<boost::recursive_mutex> un(*CPlayerInterface::pim); boost::unique_lock<boost::recursive_mutex> un(*CPlayerInterface::pim);
CPlayerInterface::battleInt = std::make_shared<BattleInterface>(leftSide.armyObject, rightSide.armyObject, leftSide.hero, rightSide.hero, att, def, spectratorInt); CPlayerInterface::battleInt = std::make_shared<BattleInterface>(leftSide.armyObject, rightSide.armyObject, leftSide.hero, rightSide.hero, att, def, spectratorInterface);
} }
} }
@@ -637,7 +644,7 @@ void CClient::battleFinished()
if(battleCallbacks.count(side.color)) if(battleCallbacks.count(side.color))
battleCallbacks[side.color]->setBattle(nullptr); battleCallbacks[side.color]->setBattle(nullptr);
if(settings["session"]["spectate"].Bool() && !settings["session"]["spectate-skip-battle"].Bool()) if(battleCallbacks[PlayerColor::SPECTATOR])
battleCallbacks[PlayerColor::SPECTATOR]->setBattle(nullptr); battleCallbacks[PlayerColor::SPECTATOR]->setBattle(nullptr);
setBattle(nullptr); setBattle(nullptr);

View File

@@ -69,14 +69,14 @@ CLobbyScreen::CLobbyScreen(ESelectionScreen screenType)
card->iconDifficulty->addCallback(std::bind(&IServerAPI::setDifficulty, CSH, _1)); 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, true), SDLK_b);
initLobby(); initLobby();
break; break;
} }
case ESelectionScreen::loadGame: case ESelectionScreen::loadGame:
{ {
tabOpt = std::make_shared<OptionsTab>(); 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, true), SDLK_l);
initLobby(); initLobby();
break; break;
} }

View File

@@ -22,7 +22,7 @@ public:
~CLobbyScreen(); ~CLobbyScreen();
void toggleTab(std::shared_ptr<CIntObject> tab) override; void toggleTab(std::shared_ptr<CIntObject> tab) override;
void startCampaign(); void startCampaign();
void startScenario(bool allowOnlyAI = false); void startScenario(bool allowOnlyAI = true);
void toggleMode(bool host); void toggleMode(bool host);
void toggleChat(); void toggleChat();

View File

@@ -514,7 +514,7 @@ OptionsTab::PlayerOptionsEntry::PlayerOptionsEntry(const PlayerSettings & S, con
void OptionsTab::onSetPlayerClicked(const PlayerSettings & ps) const void OptionsTab::onSetPlayerClicked(const PlayerSettings & ps) const
{ {
if(ps.isControlledByAI() || humanPlayers > 1) if(ps.isControlledByAI() || humanPlayers > 0)
CSH->setPlayer(ps.color); CSH->setPlayer(ps.color);
} }