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

Full rework of pre-game interface and networking

New features for players:
* Loading for multiplayer. Any save could be used for multiplayer.
* Restart for multiplayer. All clients will restart together.
* Loading from single save.
* Hotseat mixed with network game. Multiple players per client.
* Now connection to server could be cancelled.
* Return to menu on disconnections instead of crashes.
* Restoring of last selected map, save or campaign on next run.

TLDR on important changes in engine code:
* UI: work with server separated from UI
* UI: all explitic blitting replaced with IntObject's
* UI: all new code use smart pointers instead of DISPOSE
* Gameplay always start through lobby controlled by server.
* Threads receiving netpacks now shared for lobby and gameplay.
* Campaigns: heroes for crossover now serialized as JsonNode.
This commit is contained in:
Arseniy Shestakov
2018-01-05 20:21:07 +03:00
parent 14f03e22da
commit ac66fc7f42
85 changed files with 8808 additions and 7938 deletions

View File

@ -56,40 +56,6 @@ DLL_LINKAGE void SetSecSkill::applyGs(CGameState *gs)
hero->setSecSkillLevel(which, val, abs);
}
DLL_LINKAGE SelectMap::SelectMap(const CMapInfo &src)
{
mapInfo = &src;
free = false;
}
DLL_LINKAGE SelectMap::SelectMap()
{
mapInfo = nullptr;
free = true;
}
DLL_LINKAGE SelectMap::~SelectMap()
{
if(free)
delete mapInfo;
}
DLL_LINKAGE UpdateStartOptions::UpdateStartOptions(StartInfo &src)
{
options = &src;
free = false;
}
DLL_LINKAGE UpdateStartOptions::UpdateStartOptions()
{
options = nullptr;
free = true;
}
DLL_LINKAGE UpdateStartOptions::~UpdateStartOptions()
{
if(free)
delete options;
}
DLL_LINKAGE void SetCommanderProperty::applyGs(CGameState *gs)
{
CCommanderInstance * commander = gs->getHero(heroid)->commander;
@ -346,8 +312,43 @@ DLL_LINKAGE void ChangeObjectVisitors::applyGs(CGameState *gs)
DLL_LINKAGE void PlayerEndsGame::applyGs(CGameState *gs)
{
PlayerState *p = gs->getPlayer(player);
if(victoryLossCheckResult.victory()) p->status = EPlayerStatus::WINNER;
else p->status = EPlayerStatus::LOSER;
if(victoryLossCheckResult.victory())
{
p->status = EPlayerStatus::WINNER;
// TODO: Campaign-specific code might as well go somewhere else
if(p->human && gs->scenarioOps->campState)
{
std::vector<CGHeroInstance *> crossoverHeroes;
for (CGHeroInstance * hero : gs->map->heroesOnMap)
{
if (hero->tempOwner == player)
{
// keep all heroes from the winning player
crossoverHeroes.push_back(hero);
}
else if (vstd::contains(gs->scenarioOps->campState->getCurrentScenario().keepHeroes, HeroTypeID(hero->subID)))
{
// keep hero whether lost or won (like Xeron in AB campaign)
crossoverHeroes.push_back(hero);
}
}
// keep lost heroes which are in heroes pool
for (auto & heroPair : gs->hpool.heroesPool)
{
if (vstd::contains(gs->scenarioOps->campState->getCurrentScenario().keepHeroes, HeroTypeID(heroPair.first)))
{
crossoverHeroes.push_back(heroPair.second.get());
}
}
gs->scenarioOps->campState->setCurrentMapAsConquered(crossoverHeroes);
}
}
else
{
p->status = EPlayerStatus::LOSER;
}
}
DLL_LINKAGE void RemoveBonus::applyGs(CGameState *gs)