Browse Source

Add PrepareHeroLevelUp netpack to keep secondary skills RNG in sync

Arseniy Shestakov 9 years ago
parent
commit
53502e84e3
4 changed files with 40 additions and 3 deletions
  1. 17 0
      lib/NetPacks.h
  2. 15 0
      lib/NetPacksLib.cpp
  3. 1 0
      lib/registerTypes/RegisterTypes.h
  4. 7 3
      server/CGameHandler.cpp

+ 17 - 0
lib/NetPacks.h

@@ -1093,6 +1093,23 @@ struct ChangeObjectVisitors : public CPackForClient // 1003
 	}
 	}
 };
 };
 
 
+struct PrepareHeroLevelUp : public CPackForClient//1999
+{
+	DLL_LINKAGE void applyGs(CGameState *gs);
+
+	const CGHeroInstance *hero;
+
+	/// Do not serialize, used by server only
+	std::vector<SecondarySkill> skills;
+
+	PrepareHeroLevelUp(){type = 1999;};
+
+	template <typename Handler> void serialize(Handler &h, const int version)
+	{
+		h & hero;
+	}
+};
+
 struct HeroLevelUp : public Query//2000
 struct HeroLevelUp : public Query//2000
 {
 {
 	void applyCl(CClient *cl);
 	void applyCl(CClient *cl);

+ 15 - 0
lib/NetPacksLib.cpp

@@ -1162,6 +1162,21 @@ DLL_LINKAGE void SetObjectProperty::applyGs( CGameState *gs )
 	}
 	}
 }
 }
 
 
+DLL_LINKAGE void PrepareHeroLevelUp::applyGs(CGameState *gs)
+{
+	CGHeroInstance * h = gs->getHero(hero->id);
+	auto proposedSkills = h->getLevelUpProposedSecondarySkills();
+
+	if(skills.size() == 1 || hero->tempOwner == PlayerColor::NEUTRAL) //choose skill automatically
+	{
+		skills.push_back(*RandomGeneratorUtil::nextItem(proposedSkills, h->skillsInfo.rand));
+	}
+	else
+	{
+		skills = proposedSkills;
+	}
+}
+
 DLL_LINKAGE void HeroLevelUp::applyGs( CGameState *gs )
 DLL_LINKAGE void HeroLevelUp::applyGs( CGameState *gs )
 {
 {
 	CGHeroInstance * h = gs->getHero(hero->id);
 	CGHeroInstance * h = gs->getHero(hero->id);

+ 1 - 0
lib/registerTypes/RegisterTypes.h

@@ -253,6 +253,7 @@ void registerTypesClientPacks1(Serializer &s)
 	s.template registerType<CPackForClient, SetCommanderProperty>();
 	s.template registerType<CPackForClient, SetCommanderProperty>();
 	s.template registerType<CPackForClient, ChangeObjectVisitors>();
 	s.template registerType<CPackForClient, ChangeObjectVisitors>();
 	s.template registerType<CPackForClient, ShowWorldViewEx>();
 	s.template registerType<CPackForClient, ShowWorldViewEx>();
+	s.template registerType<CPackForClient, PrepareHeroLevelUp>();
 }
 }
 
 
 template<typename Serializer>
 template<typename Serializer>

+ 7 - 3
server/CGameHandler.cpp

@@ -213,20 +213,24 @@ void CGameHandler::levelUpHero(const CGHeroInstance * hero)
 	sps.val = 1;
 	sps.val = 1;
 	sendAndApply(&sps);
 	sendAndApply(&sps);
 
 
+	PrepareHeroLevelUp pre;
+	pre.hero = hero;
+	sendAndApply(&pre);
+
 	HeroLevelUp hlu;
 	HeroLevelUp hlu;
 	hlu.hero = hero;
 	hlu.hero = hero;
 	hlu.primskill = primarySkill;
 	hlu.primskill = primarySkill;
-	hlu.skills = hero->getLevelUpProposedSecondarySkills();
+	hlu.skills = pre.skills;
 
 
 	if(hlu.skills.size() == 0)
 	if(hlu.skills.size() == 0)
 	{
 	{
 		sendAndApply(&hlu);
 		sendAndApply(&hlu);
 		levelUpHero(hero);
 		levelUpHero(hero);
 	}
 	}
-	else if(hlu.skills.size() == 1  ||  hero->tempOwner == PlayerColor::NEUTRAL)  //choose skill automatically
+	else if(hlu.skills.size() == 1)
 	{
 	{
 		sendAndApply(&hlu);
 		sendAndApply(&hlu);
-		levelUpHero(hero, *RandomGeneratorUtil::nextItem(hlu.skills, hero->skillsInfo.rand));
+		levelUpHero(hero, pre.skills.front());
 	}
 	}
 	else if(hlu.skills.size() > 1)
 	else if(hlu.skills.size() > 1)
 	{
 	{