1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-06-15 00:05:02 +02:00

Client: implement spectator mode via command-line options

If running with --spectate/-s CPlayerInterface will appear even without human players.
Following command-line options also available:
 --spectate-ignore-hero
 --spectate-hero-speed=N
 --spectate-battle-speed=N
 --spectate-skip-battle
 --spectate-skip-battle-result
Boolean options can also be changed in runtime via client console:
 set spectate-ignore-hero on / off
Spectator mode also:
 - Work with --onlyAI option when starting game or loading saves.
 - Allow to use any cheat codes.
 - Give recon on towns and heroes.
This commit is contained in:
Arseniy Shestakov
2017-06-03 08:25:10 +03:00
parent d95c74941b
commit 18161d3688
24 changed files with 196 additions and 54 deletions

View File

@ -245,6 +245,9 @@ void CPlayerInterface::heroMoved(const TryMoveHero & details)
if (LOCPLINT != this)
return;
if(settings["session"]["spectate"].Bool() && settings["session"]["spectate-ignore-hero"].Bool())
return;
const CGHeroInstance * hero = cb->getHero(details.id); //object representing this hero
int3 hp = details.start;
@ -321,7 +324,12 @@ void CPlayerInterface::heroMoved(const TryMoveHero & details)
}
ui32 speed;
if (makingTurn) // our turn, our hero moves
if(settings["session"]["spectate"].Bool())
{
if(!settings["session"]["spectate-hero-speed"].isNull())
speed = settings["session"]["spectate-hero-speed"].Integer();
}
else if (makingTurn) // our turn, our hero moves
speed = settings["adventure"]["heroSpeed"].Float();
else
speed = settings["adventure"]["enemySpeed"].Float();
@ -334,7 +342,6 @@ void CPlayerInterface::heroMoved(const TryMoveHero & details)
return; // no animation
}
adventureInt->centerOn(hero); //actualizing screen pos
adventureInt->minimap.redraw();
adventureInt->heroList.redraw();
@ -471,6 +478,14 @@ int3 CPlayerInterface::repairScreenPos(int3 pos)
pos.y = CGI->mh->sizes.y - adventureInt->terrain.tilesh + CGI->mh->frameH;
return pos;
}
void CPlayerInterface::activateForSpectator()
{
adventureInt->state = CAdvMapInt::INGAME;
adventureInt->activate();
adventureInt->minimap.activate();
}
void CPlayerInterface::heroPrimarySkillChanged(const CGHeroInstance * hero, int which, si64 val)
{
EVENT_HANDLER_CALLED_BY_CLIENT;
@ -1637,7 +1652,8 @@ void CPlayerInterface::update()
}
//in some conditions we may receive calls before selection is initialized - we must ignore them
if (adventureInt && !adventureInt->selection && GH.topInt() == adventureInt)
if(adventureInt && GH.topInt() == adventureInt
&& (!adventureInt->selection && !settings["session"]["spectate"].Bool()))
{
return;
}
@ -2131,7 +2147,7 @@ void CPlayerInterface::gameOver(PlayerColor player, const EVictoryLossCheckResul
--howManyPeople;
if (howManyPeople == 0) //all human players eliminated
if(howManyPeople == 0 && !settings["session"]["spectate"].Bool()) //all human players eliminated
{
if (adventureInt)
{
@ -2152,7 +2168,7 @@ void CPlayerInterface::gameOver(PlayerColor player, const EVictoryLossCheckResul
}
else
{
if (howManyPeople == 0) //all human players eliminated
if(howManyPeople == 0 && !settings["session"]["spectate"].Bool()) //all human players eliminated
{
requestReturningToMainMenu();
}