|
@@ -487,6 +487,10 @@ void CClient::newGame( CConnection *con, StartInfo *si )
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
+ if(settings["session"]["spectate"].Bool())
|
|
|
+ {
|
|
|
+ installNewPlayerInterface(std::make_shared<CPlayerInterface>(PlayerColor::SPECTATOR), PlayerColor::SPECTATOR, true);
|
|
|
+ }
|
|
|
loadNeutralBattleAI();
|
|
|
}
|
|
|
|
|
@@ -638,9 +642,6 @@ void CClient::serialize(BinaryDeserializer & h, const int version, const std::se
|
|
|
nInt->human = isHuman;
|
|
|
nInt->playerID = pid;
|
|
|
|
|
|
- if(playerIDs.count(pid))
|
|
|
- installNewPlayerInterface(nInt, pid);
|
|
|
-
|
|
|
nInt->loadGame(h, version);
|
|
|
if(settings["session"]["onlyai"].Bool() && isHuman)
|
|
|
{
|
|
@@ -654,6 +655,20 @@ void CClient::serialize(BinaryDeserializer & h, const int version, const std::se
|
|
|
installNewPlayerInterface(nInt, pid);
|
|
|
GH.totalRedraw();
|
|
|
}
|
|
|
+ else
|
|
|
+ {
|
|
|
+ if(playerIDs.count(pid))
|
|
|
+ installNewPlayerInterface(nInt, pid);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if(settings["session"]["spectate"].Bool())
|
|
|
+ {
|
|
|
+ removeGUI();
|
|
|
+ auto p = std::make_shared<CPlayerInterface>(PlayerColor::SPECTATOR);
|
|
|
+ installNewPlayerInterface(p, PlayerColor::SPECTATOR, true);
|
|
|
+ GH.curInt = p.get();
|
|
|
+ LOCPLINT->activateForSpectator();
|
|
|
+ GH.totalRedraw();
|
|
|
}
|
|
|
|
|
|
if(playerIDs.count(PlayerColor::NEUTRAL))
|
|
@@ -759,15 +774,29 @@ void CClient::battleStarted(const BattleInfo * info)
|
|
|
def = std::dynamic_pointer_cast<CPlayerInterface>( playerint[rightSide.color] );
|
|
|
}
|
|
|
|
|
|
- if(!settings["session"]["headless"].Bool()
|
|
|
- && (!!att || !!def || gs->scenarioOps->mode == StartInfo::DUEL))
|
|
|
+ if(!settings["session"]["headless"].Bool())
|
|
|
{
|
|
|
- boost::unique_lock<boost::recursive_mutex> un(*CPlayerInterface::pim);
|
|
|
- auto bi = new CBattleInterface(leftSide.armyObject, rightSide.armyObject, leftSide.hero, rightSide.hero,
|
|
|
- Rect((screen->w - 800)/2,
|
|
|
- (screen->h - 600)/2, 800, 600), att, def);
|
|
|
+ if(!!att || !!def || gs->scenarioOps->mode == StartInfo::DUEL)
|
|
|
+ {
|
|
|
+ boost::unique_lock<boost::recursive_mutex> un(*CPlayerInterface::pim);
|
|
|
+ auto bi = new CBattleInterface(leftSide.armyObject, rightSide.armyObject, leftSide.hero, rightSide.hero,
|
|
|
+ Rect((screen->w - 800)/2,
|
|
|
+ (screen->h - 600)/2, 800, 600), att, def);
|
|
|
|
|
|
- GH.pushInt(bi);
|
|
|
+ GH.pushInt(bi);
|
|
|
+ }
|
|
|
+ else if(settings["session"]["spectate"].Bool() && !settings["session"]["spectate-skip-battle"].Bool())
|
|
|
+ {
|
|
|
+ //TODO: This certainly need improvement
|
|
|
+ auto spectratorInt = std::dynamic_pointer_cast<CPlayerInterface>(playerint[PlayerColor::SPECTATOR]);
|
|
|
+ spectratorInt->cb->setBattle(info);
|
|
|
+ boost::unique_lock<boost::recursive_mutex> un(*CPlayerInterface::pim);
|
|
|
+ auto bi = new CBattleInterface(leftSide.armyObject, rightSide.armyObject, leftSide.hero, rightSide.hero,
|
|
|
+ Rect((screen->w - 800)/2,
|
|
|
+ (screen->h - 600)/2, 800, 600), att, def, spectratorInt);
|
|
|
+
|
|
|
+ GH.pushInt(bi);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
auto callBattleStart = [&](PlayerColor color, ui8 side){
|
|
@@ -778,6 +807,8 @@ void CClient::battleStarted(const BattleInfo * info)
|
|
|
callBattleStart(leftSide.color, 0);
|
|
|
callBattleStart(rightSide.color, 1);
|
|
|
callBattleStart(PlayerColor::UNFLAGGABLE, 1);
|
|
|
+ if(settings["session"]["spectate"].Bool() && !settings["session"]["spectate-skip-battle"].Bool())
|
|
|
+ callBattleStart(PlayerColor::SPECTATOR, 1);
|
|
|
|
|
|
if(info->tacticDistance && vstd::contains(battleints,info->sides[info->tacticsSide].color))
|
|
|
{
|
|
@@ -790,6 +821,9 @@ void CClient::battleFinished()
|
|
|
for(auto & side : gs->curB->sides)
|
|
|
if(battleCallbacks.count(side.color))
|
|
|
battleCallbacks[side.color]->setBattle(nullptr);
|
|
|
+
|
|
|
+ if(settings["session"]["spectate"].Bool() && !settings["session"]["spectate-skip-battle"].Bool())
|
|
|
+ battleCallbacks[PlayerColor::SPECTATOR]->setBattle(nullptr);
|
|
|
}
|
|
|
|
|
|
void CClient::loadNeutralBattleAI()
|
|
@@ -887,7 +921,7 @@ void CClient::campaignMapFinished( std::shared_ptr<CCampaignState> camp )
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-void CClient::installNewPlayerInterface(std::shared_ptr<CGameInterface> gameInterface, boost::optional<PlayerColor> color)
|
|
|
+void CClient::installNewPlayerInterface(std::shared_ptr<CGameInterface> gameInterface, boost::optional<PlayerColor> color, bool battlecb)
|
|
|
{
|
|
|
boost::unique_lock<boost::recursive_mutex> un(*CPlayerInterface::pim);
|
|
|
PlayerColor colorUsed = color.get_value_or(PlayerColor::UNFLAGGABLE);
|
|
@@ -903,7 +937,7 @@ void CClient::installNewPlayerInterface(std::shared_ptr<CGameInterface> gameInte
|
|
|
battleCallbacks[colorUsed] = cb;
|
|
|
gameInterface->init(cb);
|
|
|
|
|
|
- installNewBattleInterface(gameInterface, color, false);
|
|
|
+ installNewBattleInterface(gameInterface, color, battlecb);
|
|
|
}
|
|
|
|
|
|
void CClient::installNewBattleInterface(std::shared_ptr<CBattleGameInterface> battleInterface, boost::optional<PlayerColor> color, bool needCallback /*= true*/)
|