浏览代码

Fix level up crashes: 1) Crash on double level up. 2) Crash on custom class level up.

Dmitry Orlov 5 年之前
父节点
当前提交
b25baf66be
共有 5 个文件被更改,包括 33 次插入6 次删除
  1. 7 0
      lib/CHeroHandler.h
  2. 1 0
      lib/CSkillHandler.cpp
  3. 12 2
      server/CGameHandler.cpp
  4. 11 2
      server/CQuery.cpp
  5. 2 2
      server/CQuery.h

+ 7 - 0
lib/CHeroHandler.h

@@ -195,6 +195,13 @@ public:
 		h & imageBattleFemale;
 		h & imageMapMale;
 		h & imageMapFemale;
+
+		if(!h.saving)
+		{
+			for(auto i = 0; i < secSkillProbability.size(); i++)
+				if(secSkillProbability[i] < 0)
+					secSkillProbability[i] = 0;
+		}
 	}
 	EAlignment::EAlignment getAlignment() const;
 };

+ 1 - 0
lib/CSkillHandler.cpp

@@ -34,6 +34,7 @@ CSkill::LevelInfo::~LevelInfo()
 CSkill::CSkill(SecondarySkill id, std::string identifier)
 	: id(id), identifier(identifier)
 {
+	gainChance[0] = gainChance[1] = 0; //affects CHeroClassHandler::afterLoadFinalization()
 	levels.resize(NSecondarySkill::levels.size() - 1);
 }
 

+ 12 - 2
server/CGameHandler.cpp

@@ -1812,7 +1812,7 @@ void CGameHandler::newTurn()
 				setPortalDwelling(t, true, (n.specialWeek == NewTurn::PLAGUE ? true : false)); //set creatures for Portal of Summoning
 
 			if (!firstTurn)
-				if (t->hasBuilt(BuildingID::TREASURY, ETownType::RAMPART) && player < PlayerColor::PLAYER_LIMIT)
+				if (t->hasBuilt(BuildingSubID::TREASURY) && player < PlayerColor::PLAYER_LIMIT)
 						n.res[player][Res::GOLD] += hadGold.at(player)/10; //give 10% of starting gold
 
 			if (!vstd::contains(n.cres, t->id))
@@ -3848,8 +3848,18 @@ bool CGameHandler::queryReply(QueryID qid, const JsonNode & answer, PlayerColor
 	logGlobal->trace(answer.toJson());
 
 	auto topQuery = queries.topQuery(player);
+
 	COMPLAIN_RET_FALSE_IF(!topQuery, "This player doesn't have any queries!");
-	COMPLAIN_RET_FALSE_IF(topQuery->queryID != qid, "This player top query has different ID!");
+
+	if(topQuery->queryID != qid)
+	{
+		auto currentQuery = queries.getQuery(qid);
+
+		if(currentQuery != nullptr && currentQuery->endsByPlayerAnswer())
+			currentQuery->setReply(answer);
+
+		COMPLAIN_RET("This player top query has different ID!"); //topQuery->queryID != qid
+	}
 	COMPLAIN_RET_FALSE_IF(!topQuery->endsByPlayerAnswer(), "This query cannot be ended by player's answer!");
 
 	topQuery->setReply(answer);

+ 11 - 2
server/CQuery.cpp

@@ -248,10 +248,10 @@ std::vector<std::shared_ptr<const CQuery>> Queries::allQueries() const
 	return ret;
 }
 
-std::vector<std::shared_ptr<CQuery>> Queries::allQueries()
+std::vector<QueryPtr> Queries::allQueries()
 {
 	//TODO code duplication with const function :(
-	std::vector<std::shared_ptr<CQuery>> ret;
+	std::vector<QueryPtr> ret;
 	for(auto & playerQueries : queries)
 		for(auto & query : playerQueries.second)
 			ret.push_back(query);
@@ -259,6 +259,15 @@ std::vector<std::shared_ptr<CQuery>> Queries::allQueries()
 	return ret;
 }
 
+QueryPtr Queries::getQuery(QueryID queryID)
+{
+	for(auto & playerQueries : queries)
+		for(auto & query : playerQueries.second)
+			if(query->queryID == queryID)
+				return query;
+	return nullptr;
+}
+
 void CBattleQuery::notifyObjectAboutRemoval(const CObjectVisitQuery & objectVisit) const
 {
 	assert(result);

+ 2 - 2
server/CQuery.h

@@ -219,7 +219,7 @@ public:
 	QueryPtr topQuery(PlayerColor player);
 
 	std::vector<std::shared_ptr<const CQuery>> allQueries() const;
-	std::vector<std::shared_ptr<CQuery>> allQueries();
+	std::vector<QueryPtr> allQueries();
+	QueryPtr getQuery(QueryID queryID);
 	//void removeQuery
-
 };