mirror of
				https://github.com/vcmi/vcmi.git
				synced 2025-10-31 00:07:39 +02:00 
			
		
		
		
	Merge pull request #681 from ShubusCorporation/do/fix/hero_classes_initial_values
Fix: Some map objects sometimes do not increment some primary skills of some heroes
This commit is contained in:
		
							
								
								
									
										3
									
								
								AUTHORS
									
									
									
									
									
								
							
							
						
						
									
										3
									
								
								AUTHORS
									
									
									
									
									
								
							| @@ -75,3 +75,6 @@ Andrzej Żak aka godric3 | ||||
|     | ||||
| Andrii Danylchenko | ||||
|    * VCAI improvements | ||||
|  | ||||
| Dmitry Orlov, <shubus.corporation@gmail.com> | ||||
|    * special buildings support in fan towns, new features and bug fixes | ||||
|   | ||||
| @@ -96,6 +96,24 @@ bool CObstacleInfo::isAppropriate(ETerrainType terrainType, int specialBattlefie | ||||
| 	return vstd::contains(allowedTerrains, terrainType); | ||||
| } | ||||
|  | ||||
| void CHeroClassHandler::fillPrimarySkillData(const JsonNode & node, CHeroClass * heroClass, PrimarySkill::PrimarySkill pSkill) | ||||
| { | ||||
| 	const auto & skillName = PrimarySkill::names[pSkill]; | ||||
| 	auto currentPrimarySkillValue = (int)node["primarySkills"][skillName].Integer(); | ||||
| 	//minimal value is 0 for attack and defense and 1 for spell power and knowledge | ||||
| 	auto primarySkillLegalMinimum = (pSkill == PrimarySkill::ATTACK || pSkill == PrimarySkill::DEFENSE) ? 0 : 1; | ||||
|  | ||||
| 	if(currentPrimarySkillValue < primarySkillLegalMinimum) | ||||
| 	{ | ||||
| 		logMod->error("Hero class '%s' has incorrect initial value '%d' for skill '%s'. Value '%d' will be used instead.", | ||||
| 			heroClass->identifier, currentPrimarySkillValue, skillName, primarySkillLegalMinimum); | ||||
| 		currentPrimarySkillValue = primarySkillLegalMinimum; | ||||
| 	} | ||||
| 	heroClass->primarySkillInitial.push_back(currentPrimarySkillValue); | ||||
| 	heroClass->primarySkillLowLevel.push_back((int)node["lowLevelChance"][skillName].Float()); | ||||
| 	heroClass->primarySkillHighLevel.push_back((int)node["highLevelChance"][skillName].Float()); | ||||
| } | ||||
|  | ||||
| CHeroClass * CHeroClassHandler::loadFromJson(const JsonNode & node, const std::string & identifier) | ||||
| { | ||||
| 	std::string affinityStr[2] = { "might", "magic" }; | ||||
| @@ -111,12 +129,10 @@ CHeroClass * CHeroClassHandler::loadFromJson(const JsonNode & node, const std::s | ||||
| 	heroClass->name = node["name"].String(); | ||||
| 	heroClass->affinity = vstd::find_pos(affinityStr, node["affinity"].String()); | ||||
|  | ||||
| 	for(const std::string & pSkill : PrimarySkill::names) | ||||
| 	{ | ||||
| 		heroClass->primarySkillInitial.push_back((int)node["primarySkills"][pSkill].Float()); | ||||
| 		heroClass->primarySkillLowLevel.push_back((int)node["lowLevelChance"][pSkill].Float()); | ||||
| 		heroClass->primarySkillHighLevel.push_back((int)node["highLevelChance"][pSkill].Float()); | ||||
| 	} | ||||
| 	fillPrimarySkillData(node, heroClass, PrimarySkill::ATTACK); | ||||
| 	fillPrimarySkillData(node, heroClass, PrimarySkill::DEFENSE); | ||||
| 	fillPrimarySkillData(node, heroClass, PrimarySkill::SPELL_POWER); | ||||
| 	fillPrimarySkillData(node, heroClass, PrimarySkill::KNOWLEDGE); | ||||
|  | ||||
| 	for(auto skillPair : node["secondarySkills"].Struct()) | ||||
| 	{ | ||||
|   | ||||
| @@ -236,6 +236,7 @@ struct DLL_LINKAGE CObstacleInfo | ||||
|  | ||||
| class DLL_LINKAGE CHeroClassHandler : public IHandlerBase | ||||
| { | ||||
| 	void fillPrimarySkillData(const JsonNode & node, CHeroClass * heroClass, PrimarySkill::PrimarySkill pSkill); | ||||
| 	CHeroClass *loadFromJson(const JsonNode & node, const std::string & identifier); | ||||
| public: | ||||
| 	std::vector< ConstTransitivePtr<CHeroClass> > heroClasses; | ||||
|   | ||||
| @@ -786,13 +786,9 @@ int IBonusBearer::getPrimSkillLevel(PrimarySkill::PrimarySkill id) const | ||||
| { | ||||
| 	static const CSelector selectorAllSkills = Selector::type()(Bonus::PRIMARY_SKILL); | ||||
| 	static const std::string keyAllSkills = "type_PRIMARY_SKILL"; | ||||
|  | ||||
| 	auto allSkills = getBonuses(selectorAllSkills, keyAllSkills); | ||||
|  | ||||
| 	int ret = allSkills->valOfBonuses(Selector::subtype()(id)); | ||||
|  | ||||
| 	vstd::amax(ret, id/2); //minimal value is 0 for attack and defense and 1 for spell power and knowledge | ||||
| 	return ret; | ||||
| 	auto ret = allSkills->valOfBonuses(Selector::subtype()(id)); | ||||
| 	return ret; //sp=0 works in old saves | ||||
| } | ||||
|  | ||||
| si32 IBonusBearer::magicResistance() const | ||||
|   | ||||
| @@ -167,10 +167,14 @@ std::string CMapGenerator::getMapDescription() const | ||||
| 	const std::string monsterStrengthStr[3] = { "weak", "normal", "strong" }; | ||||
|  | ||||
| 	int monsterStrengthIndex = mapGenOptions->getMonsterStrength() - EMonsterStrength::GLOBAL_WEAK; //does not start from 0 | ||||
| 	const auto * mapTemplate = mapGenOptions->getMapTemplate(); | ||||
|  | ||||
| 	if(!mapTemplate) | ||||
| 		throw rmgException("Map template for Random Map Generator is not found. Could not start the game."); | ||||
|  | ||||
|     std::stringstream ss; | ||||
|     ss << boost::str(boost::format(std::string("Map created by the Random Map Generator.\nTemplate was %s, Random seed was %d, size %dx%d") + | ||||
|         ", levels %s, players %d, computers %d, water %s, monster %s, VCMI map") % mapGenOptions->getMapTemplate()->getName() % | ||||
|         ", levels %s, players %d, computers %d, water %s, monster %s, VCMI map") % mapTemplate->getName() % | ||||
| 		randomSeed % map->width % map->height % (map->twoLevel ? "2" : "1") % static_cast<int>(mapGenOptions->getPlayerCount()) % | ||||
| 		static_cast<int>(mapGenOptions->getCompOnlyPlayerCount()) % waterContentStr[mapGenOptions->getWaterContent()] % | ||||
| 		monsterStrengthStr[monsterStrengthIndex]); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user