1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-11-24 08:32:34 +02:00

Add ChangeFormation netpack to avoid MP desyncs

Previous code was working fine for single client, but would cause desync in multiplayer. Fix issue 2460.
This commit is contained in:
Arseniy Shestakov 2016-09-08 19:29:15 +03:00
parent a109580b91
commit d06d07a39b
5 changed files with 33 additions and 3 deletions

View File

@ -226,7 +226,6 @@ void CCallback::trade(const CGObjectInstance *market, EMarketMode::EMarketMode m
void CCallback::setFormation(const CGHeroInstance * hero, bool tight)
{
const_cast<CGHeroInstance*>(hero)-> formation = tight;
SetFormation pack(hero->id,tight);
sendRequest(&pack);
}

View File

@ -535,6 +535,20 @@ struct UpdateCastleEvents : public CPackForClient //125
}
};
struct ChangeFormation : public CPackForClient //126
{
ChangeFormation(){type = 126;}
ObjectInstanceID hid;
ui8 formation;
DLL_LINKAGE void applyGs(CGameState *gs);
template <typename Handler> void serialize(Handler &h, const int version)
{
h & hid & formation;
}
};
struct RemoveObject : public CPackForClient //500
{
RemoveObject(){type = 500;};

View File

@ -157,6 +157,11 @@ DLL_LINKAGE void UpdateCastleEvents::applyGs(CGameState *gs)
t->events = events;
}
DLL_LINKAGE void ChangeFormation::applyGs(CGameState *gs)
{
gs->getHero(hid)->setFormation(formation);
}
DLL_LINKAGE void HeroVisitCastle::applyGs( CGameState *gs )
{
CGHeroInstance *h = gs->getHero(hid);

View File

@ -227,6 +227,7 @@ void registerTypesClientPacks1(Serializer &s)
s.template registerType<CPackForClient, UpdateArtHandlerLists>();
s.template registerType<CPackForClient, UpdateMapEvents>();
s.template registerType<CPackForClient, UpdateCastleEvents>();
s.template registerType<CPackForClient, ChangeFormation>();
s.template registerType<CPackForClient, RemoveObject>();
s.template registerType<CPackForClient, TryMoveHero>();
//s.template registerType<CPackForClient, SetGarrisons>();

View File

@ -3501,9 +3501,20 @@ bool CGameHandler::sendResources(ui32 val, PlayerColor player, Res::ERes r1, Pla
return true;
}
bool CGameHandler::setFormation( ObjectInstanceID hid, ui8 formation )
bool CGameHandler::setFormation(ObjectInstanceID hid, ui8 formation)
{
gs->getHero(hid)-> formation = formation;
const CGHeroInstance *h = getHero(hid);
if(!h)
{
logGlobal->error("Hero doesn't exist!");
return false;
}
ChangeFormation cf;
cf.hid = hid;
cf.formation = formation;
sendAndApply(&cf);
return true;
}