mirror of
				https://github.com/vcmi/vcmi.git
				synced 2025-10-31 00:07:39 +02:00 
			
		
		
		
	enabled config of skill descriptions
This commit is contained in:
		| @@ -9,6 +9,8 @@ | |||||||
|  */ |  */ | ||||||
| #include "StdInc.h" | #include "StdInc.h" | ||||||
| #include "CGameInfo.h" | #include "CGameInfo.h" | ||||||
|  | #include "CSkillHandler.h" | ||||||
|  | #include "CGeneralTextHandler.h" | ||||||
|  |  | ||||||
| #include "../lib/VCMI_Lib.h" | #include "../lib/VCMI_Lib.h" | ||||||
|  |  | ||||||
| @@ -32,5 +34,14 @@ void CGameInfo::setFromLib() | |||||||
| 	heroh = VLC->heroh; | 	heroh = VLC->heroh; | ||||||
| 	objh = VLC->objh; | 	objh = VLC->objh; | ||||||
| 	spellh = VLC->spellh; | 	spellh = VLC->spellh; | ||||||
|  | 	skillh = VLC->skillh; | ||||||
| 	objtypeh = VLC->objtypeh; | 	objtypeh = VLC->objtypeh; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | const std::string & CGameInfo::skillInfo(int skill, int level) const | ||||||
|  | { | ||||||
|  | 	const std::string & desc = (*skillh)[SecondarySkill(skill)]->getDescription(level); | ||||||
|  | 	if(desc.size() > 0) | ||||||
|  | 		return desc; | ||||||
|  | 	return generaltexth->skillInfoTexts[skill][level-1]; | ||||||
|  | } | ||||||
|   | |||||||
| @@ -18,6 +18,7 @@ class CArtHandler; | |||||||
| class CHeroHandler; | class CHeroHandler; | ||||||
| class CCreatureHandler; | class CCreatureHandler; | ||||||
| class CSpellHandler; | class CSpellHandler; | ||||||
|  | class CSkillHandler; | ||||||
| class CBuildingHandler; | class CBuildingHandler; | ||||||
| class CObjectHandler; | class CObjectHandler; | ||||||
| class CSoundHandler; | class CSoundHandler; | ||||||
| @@ -55,6 +56,7 @@ public: | |||||||
| 	ConstTransitivePtr<CHeroHandler> heroh; | 	ConstTransitivePtr<CHeroHandler> heroh; | ||||||
| 	ConstTransitivePtr<CCreatureHandler> creh; | 	ConstTransitivePtr<CCreatureHandler> creh; | ||||||
| 	ConstTransitivePtr<CSpellHandler> spellh; | 	ConstTransitivePtr<CSpellHandler> spellh; | ||||||
|  | 	ConstTransitivePtr<CSkillHandler> skillh; | ||||||
| 	ConstTransitivePtr<CObjectHandler> objh; | 	ConstTransitivePtr<CObjectHandler> objh; | ||||||
| 	ConstTransitivePtr<CObjectClassesHandler> objtypeh; | 	ConstTransitivePtr<CObjectClassesHandler> objtypeh; | ||||||
| 	CGeneralTextHandler * generaltexth; | 	CGeneralTextHandler * generaltexth; | ||||||
| @@ -66,5 +68,6 @@ public: | |||||||
| 	friend class CClient; | 	friend class CClient; | ||||||
|  |  | ||||||
| 	CGameInfo(); | 	CGameInfo(); | ||||||
|  | 	const std::string & skillInfo(int skill, int level) const; | ||||||
| }; | }; | ||||||
| extern const CGameInfo* CGI; | extern const CGameInfo* CGI; | ||||||
|   | |||||||
| @@ -148,7 +148,7 @@ std::string CComponent::getDescription() | |||||||
| 	{ | 	{ | ||||||
| 	case primskill:  return (subtype < 4)? CGI->generaltexth->arraytxt[2+subtype] //Primary skill | 	case primskill:  return (subtype < 4)? CGI->generaltexth->arraytxt[2+subtype] //Primary skill | ||||||
| 										 : CGI->generaltexth->allTexts[149]; //mana | 										 : CGI->generaltexth->allTexts[149]; //mana | ||||||
| 	case secskill:   return CGI->generaltexth->skillInfoTexts[subtype][val-1]; | 	case secskill:   return CGI->skillInfo(subtype,val); | ||||||
| 	case resource:   return CGI->generaltexth->allTexts[242]; | 	case resource:   return CGI->generaltexth->allTexts[242]; | ||||||
| 	case creature:   return ""; | 	case creature:   return ""; | ||||||
| 	case artifact: | 	case artifact: | ||||||
|   | |||||||
| @@ -240,7 +240,7 @@ void CHeroWindow::update(const CGHeroInstance * hero, bool redrawNeeded) | |||||||
| 			level = curHero->getSecSkillLevel(SecondarySkill(curHero->secSkills[g].first)); | 			level = curHero->getSecSkillLevel(SecondarySkill(curHero->secSkills[g].first)); | ||||||
| 		secSkillAreas[g]->type = skill; | 		secSkillAreas[g]->type = skill; | ||||||
| 		secSkillAreas[g]->bonusValue = level; | 		secSkillAreas[g]->bonusValue = level; | ||||||
| 		secSkillAreas[g]->text = CGI->generaltexth->skillInfoTexts[skill][level-1]; | 		secSkillAreas[g]->text = CGI->skillInfo(skill,level); | ||||||
| 		secSkillAreas[g]->hoverText = boost::str(boost::format(heroscrn[21]) % CGI->generaltexth->levels[level-1] % CGI->generaltexth->skillName[skill]); | 		secSkillAreas[g]->hoverText = boost::str(boost::format(heroscrn[21]) % CGI->generaltexth->levels[level-1] % CGI->generaltexth->skillName[skill]); | ||||||
| 		secSkillImages[g]->setFrame(skill*3 + level + 2); | 		secSkillImages[g]->setFrame(skill*3 + level + 2); | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -281,7 +281,7 @@ bool InfoBoxAbstractHeroData::prepareMessage(std::string &text, CComponent **com | |||||||
| 			if (!value) | 			if (!value) | ||||||
| 				return false; | 				return false; | ||||||
|  |  | ||||||
| 			text = CGI->generaltexth->skillInfoTexts[subID][value-1]; | 			text = CGI->skillInfo(subID,value); | ||||||
| 			*comp = new CComponent(CComponent::secskill, subID, value); | 			*comp = new CComponent(CComponent::secskill, subID, value); | ||||||
| 			return true; | 			return true; | ||||||
| 		} | 		} | ||||||
|   | |||||||
| @@ -944,7 +944,7 @@ CExchangeWindow::CExchangeWindow(ObjectInstanceID hero1, ObjectInstanceID hero2, | |||||||
|  |  | ||||||
| 			secSkillAreas[b][g]->type = skill; | 			secSkillAreas[b][g]->type = skill; | ||||||
| 			secSkillAreas[b][g]->bonusValue = level; | 			secSkillAreas[b][g]->bonusValue = level; | ||||||
| 			secSkillAreas[b][g]->text = CGI->generaltexth->skillInfoTexts[skill][level-1]; | 			secSkillAreas[b][g]->text = CGI->skillInfo(skill,level); | ||||||
|  |  | ||||||
| 			secSkillAreas[b][g]->hoverText = CGI->generaltexth->heroscrn[21]; | 			secSkillAreas[b][g]->hoverText = CGI->generaltexth->heroscrn[21]; | ||||||
| 			boost::algorithm::replace_first(secSkillAreas[b][g]->hoverText, "%s", CGI->generaltexth->levels[level - 1]); | 			boost::algorithm::replace_first(secSkillAreas[b][g]->hoverText, "%s", CGI->generaltexth->levels[level - 1]); | ||||||
| @@ -1222,7 +1222,7 @@ void CUniversityWindow::CItem::clickRight(tribool down, bool previousState) | |||||||
| { | { | ||||||
| 	if(down) | 	if(down) | ||||||
| 	{ | 	{ | ||||||
| 		CRClickPopup::createAndPush(CGI->generaltexth->skillInfoTexts[ID][0], | 		CRClickPopup::createAndPush(CGI->skillInfo(ID, 1), | ||||||
| 				new CComponent(CComponent::secskill, ID, 1)); | 				new CComponent(CComponent::secskill, ID, 1)); | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|   | |||||||
| @@ -9,10 +9,20 @@ | |||||||
| 	"definitions" : { | 	"definitions" : { | ||||||
|  |  | ||||||
|         "skillBonus":{ |         "skillBonus":{ | ||||||
|  |             "type": "object", | ||||||
|             "description": "Set of bonuses provided by skill at given level", |             "description": "Set of bonuses provided by skill at given level", | ||||||
|             "type": "array", |             "required" : ["effects"], | ||||||
|             "items":{ |             "properties": { | ||||||
|                 "$ref" : "vcmi:bonus" |                 "description": { | ||||||
|  |                     "type": "string", | ||||||
|  |                     "description": "localizable description" | ||||||
|  |                 }, | ||||||
|  |                 "effects": { | ||||||
|  |                     "type": "array", | ||||||
|  |                     "items": { | ||||||
|  |                         "$ref" : "vcmi:bonus" | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|             } |             } | ||||||
|         }, |         }, | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,29 +1,38 @@ | |||||||
| { | { | ||||||
|     "estates" : { |     "estates" : { | ||||||
|         "index" : 13, |         "index" : 13, | ||||||
|         "basic" : [ |         "basic" : { | ||||||
|             { |             "description" : "Hero generates 250 gold each day.", | ||||||
|                 "subtype" : 13, |             "effects" : [ | ||||||
|                 "type" : "SECONDARY_SKILL_PREMY", |                 { | ||||||
|                 "val" : 250, |                     "subtype" : 13, | ||||||
|                 "valueType" : "BASE_NUMBER" |                     "type" : "SECONDARY_SKILL_PREMY", | ||||||
|             } |                     "val" : 250, | ||||||
|         ], |                     "valueType" : "BASE_NUMBER" | ||||||
|         "advanced" : [ |                 } | ||||||
|             { |             ] | ||||||
|                 "subtype" : 13, |         }, | ||||||
|                 "type" : "SECONDARY_SKILL_PREMY", |         "advanced" : { | ||||||
|                 "val" : 500, |             "description" : "Hero generates 500 gold each day.", | ||||||
|                 "valueType" : "BASE_NUMBER" |             "effects" : [ | ||||||
|             } |                 { | ||||||
|         ], |                     "subtype" : 13, | ||||||
|         "expert" : [ |                     "type" : "SECONDARY_SKILL_PREMY", | ||||||
|             { |                     "val" : 500, | ||||||
|                 "subtype" : 13, |                     "valueType" : "BASE_NUMBER" | ||||||
|                 "type" : "SECONDARY_SKILL_PREMY", |                 } | ||||||
|                 "val" : 1000, |             ] | ||||||
|                 "valueType" : "BASE_NUMBER" |         }, | ||||||
|             } |         "expert" : { | ||||||
|         ] |             "description" : "Hero generates 1000 gold each day.", | ||||||
|  |             "effects" : [ | ||||||
|  |                 { | ||||||
|  |                     "subtype" : 13, | ||||||
|  |                     "type" : "SECONDARY_SKILL_PREMY", | ||||||
|  |                     "val" : 1000, | ||||||
|  |                     "valueType" : "BASE_NUMBER" | ||||||
|  |                 } | ||||||
|  |             ] | ||||||
|  |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -377,6 +377,7 @@ bool CContentHandler::ContentTypeHandler::loadMod(std::string modName, bool vali | |||||||
| 	if (!modInfo.patches.isNull()) | 	if (!modInfo.patches.isNull()) | ||||||
| 		JsonUtils::merge(modInfo.modData, modInfo.patches); | 		JsonUtils::merge(modInfo.modData, modInfo.patches); | ||||||
|  |  | ||||||
|  | 	CLogger * logger = CLogger::getLogger(CLoggerDomain("mod")); | ||||||
| 	for(auto & entry : modInfo.modData.Struct()) | 	for(auto & entry : modInfo.modData.Struct()) | ||||||
| 	{ | 	{ | ||||||
| 		const std::string & name = entry.first; | 		const std::string & name = entry.first; | ||||||
| @@ -389,6 +390,7 @@ bool CContentHandler::ContentTypeHandler::loadMod(std::string modName, bool vali | |||||||
|  |  | ||||||
| 			if (originalData.size() > index) | 			if (originalData.size() > index) | ||||||
| 			{ | 			{ | ||||||
|  | 				logger->traceStream() << "found original data in loadMod(" << name << ") at index " << index; | ||||||
| 				JsonUtils::merge(originalData[index], data); | 				JsonUtils::merge(originalData[index], data); | ||||||
| 				performValidate(originalData[index],name); | 				performValidate(originalData[index],name); | ||||||
| 				handler->loadObject(modName, name, originalData[index], index); | 				handler->loadObject(modName, name, originalData[index], index); | ||||||
| @@ -396,8 +398,8 @@ bool CContentHandler::ContentTypeHandler::loadMod(std::string modName, bool vali | |||||||
| 			} | 			} | ||||||
| 			else | 			else | ||||||
| 			{ | 			{ | ||||||
| 				logGlobal->debugStream() << "no original data in loadMod(" << name << ")"; | 				logger->debugStream() << "no original data in loadMod(" << name << ") at index " << index; | ||||||
| 				logGlobal->traceStream() << data; | 				logger->traceStream() << data; | ||||||
| 				performValidate(data, name); | 				performValidate(data, name); | ||||||
| 				handler->loadObject(modName, name, data, index); | 				handler->loadObject(modName, name, data, index); | ||||||
| 			} | 			} | ||||||
|   | |||||||
| @@ -27,16 +27,24 @@ | |||||||
| #include "battle/CBattleInfoCallback.h" | #include "battle/CBattleInfoCallback.h" | ||||||
|  |  | ||||||
| ///CSkill | ///CSkill | ||||||
|  | CSkill::LevelInfo::LevelInfo() : description("") | ||||||
|  | { | ||||||
|  | } | ||||||
|  |  | ||||||
|  | CSkill::LevelInfo::~LevelInfo() | ||||||
|  | { | ||||||
|  | } | ||||||
|  |  | ||||||
| CSkill::CSkill(SecondarySkill id) : id(id) | CSkill::CSkill(SecondarySkill id) : id(id) | ||||||
| { | { | ||||||
|     if(id == SecondarySkill::DEFAULT) |     if(id == SecondarySkill::DEFAULT) | ||||||
|         identifier = "default"; |         identifier = "default"; | ||||||
|     else |     else | ||||||
|         identifier = NSecondarySkill::names[id]; |         identifier = NSecondarySkill::names[id]; | ||||||
|     // init bonus levels |     // init levels | ||||||
|     BonusList emptyList; |     LevelInfo emptyLevel; | ||||||
|     for(auto level : NSecondarySkill::levels) |     for(int level = 1; level < NSecondarySkill::levels.size(); level++) | ||||||
|         bonusByLevel.push_back(emptyList); |         levels.push_back(emptyLevel); | ||||||
| } | } | ||||||
|  |  | ||||||
| CSkill::~CSkill() | CSkill::~CSkill() | ||||||
| @@ -48,18 +56,32 @@ void CSkill::addNewBonus(const std::shared_ptr<Bonus>& b, int level) | |||||||
|     b->source = Bonus::SECONDARY_SKILL; |     b->source = Bonus::SECONDARY_SKILL; | ||||||
|     b->duration = Bonus::PERMANENT; |     b->duration = Bonus::PERMANENT; | ||||||
|     b->description = identifier; |     b->description = identifier; | ||||||
|     bonusByLevel[level].push_back(b); |     levels[level-1].effects.push_back(b); | ||||||
| } | } | ||||||
|  |  | ||||||
| BonusList CSkill::getBonus(int level) | void CSkill::setDescription(const std::string & desc, int level) | ||||||
| { | { | ||||||
|     return bonusByLevel[level]; |     levels[level-1].description = desc; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | const std::vector<std::shared_ptr<Bonus>> & CSkill::getBonus(int level) const | ||||||
|  | { | ||||||
|  |     return levels[level-1].effects; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | const std::string & CSkill::getDescription(int level) const | ||||||
|  | { | ||||||
|  |     return levels[level-1].description; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | DLL_LINKAGE std::ostream & operator<<(std::ostream &out, const CSkill::LevelInfo &info) | ||||||
|  | { | ||||||
|  |     return out << "(\"" << info.description << "\"," << info.effects << ")"; | ||||||
| } | } | ||||||
|  |  | ||||||
| DLL_LINKAGE std::ostream & operator<<(std::ostream &out, const CSkill &skill) | DLL_LINKAGE std::ostream & operator<<(std::ostream &out, const CSkill &skill) | ||||||
| { | { | ||||||
| 	out << "Skill(" << (int)skill.id << "," << skill.identifier << "): " << skill.bonusByLevel; |     return out << "Skill(" << (int)skill.id << "," << skill.identifier << "): " << skill.levels; | ||||||
| 	return out; |  | ||||||
| } | } | ||||||
|  |  | ||||||
| ///CSkillHandler | ///CSkillHandler | ||||||
| @@ -108,12 +130,18 @@ CSkill * CSkillHandler::loadFromJson(const JsonNode & json, const std::string & | |||||||
|     for(int level = 1; level < NSecondarySkill::levels.size(); level++) |     for(int level = 1; level < NSecondarySkill::levels.size(); level++) | ||||||
|     { |     { | ||||||
|         const std::string & levelName = NSecondarySkill::levels[level]; // basic, advanced, expert |         const std::string & levelName = NSecondarySkill::levels[level]; // basic, advanced, expert | ||||||
|         for(auto b : json[levelName].Vector()) |         const JsonNode & levelNode = json[levelName]; | ||||||
|  |         // parse bonus effects | ||||||
|  |         for(auto b : levelNode["effects"].Vector()) | ||||||
|         { |         { | ||||||
|             auto bonus = JsonUtils::parseBonus(b); |             auto bonus = JsonUtils::parseBonus(b); | ||||||
|             bonus->sid = skill->id; |             bonus->sid = skill->id; | ||||||
|             skill->addNewBonus(bonus, level); |             skill->addNewBonus(bonus, level); | ||||||
|         } |         } | ||||||
|  |         // parse skill description - tracked separately | ||||||
|  |         if(vstd::contains(levelNode.Struct(), "description") && !levelNode["description"].isNull()) | ||||||
|  |             //CGI->generaltexth->skillInfoTexts[skill->id][level-1] = levelNode["description"].String(); | ||||||
|  |             skill->setDescription(levelNode["description"].String(), level); | ||||||
|     } |     } | ||||||
|     CLogger * logger = CLogger::getLogger(CLoggerDomain(getTypeName())); |     CLogger * logger = CLogger::getLogger(CLoggerDomain(getTypeName())); | ||||||
|     logger->debugStream() << "loaded secondary skill " << identifier << "(" << (int)skill->id << ")"; |     logger->debugStream() << "loaded secondary skill " << identifier << "(" << (int)skill->id << ")"; | ||||||
|   | |||||||
| @@ -21,14 +21,30 @@ class JsonSerializeFormat; | |||||||
| class DLL_LINKAGE CSkill // secondary skill | class DLL_LINKAGE CSkill // secondary skill | ||||||
| { | { | ||||||
| protected: | protected: | ||||||
|     std::vector<BonusList> bonusByLevel; // bonuses provided by none, basic, advanced and expert level | 	struct LevelInfo | ||||||
|  | 	{ | ||||||
|  | 		std::string description; //descriptions of spell for skill level | ||||||
|  | 		std::vector<std::shared_ptr<Bonus>> effects; | ||||||
|  |  | ||||||
|  | 		LevelInfo(); | ||||||
|  | 		~LevelInfo(); | ||||||
|  |  | ||||||
|  | 		template <typename Handler> void serialize(Handler &h, const int version) | ||||||
|  | 		{ | ||||||
|  | 			h & description & effects; | ||||||
|  | 		} | ||||||
|  | 	}; | ||||||
|  |  | ||||||
|  | 	std::vector<LevelInfo> levels; // bonuses provided by basic, advanced and expert level | ||||||
|  |  | ||||||
| public: | public: | ||||||
|     CSkill(SecondarySkill id = SecondarySkill::DEFAULT); |     CSkill(SecondarySkill id = SecondarySkill::DEFAULT); | ||||||
|     ~CSkill(); |     ~CSkill(); | ||||||
|  |  | ||||||
|     void addNewBonus(const std::shared_ptr<Bonus>& b, int level); |     void addNewBonus(const std::shared_ptr<Bonus>& b, int level); | ||||||
|     BonusList getBonus(int level); |     void setDescription(const std::string & desc, int level); | ||||||
|  |     const std::vector<std::shared_ptr<Bonus>> & getBonus(int level) const; | ||||||
|  |     const std::string & getDescription(int level) const; | ||||||
|  |  | ||||||
|     SecondarySkill id; |     SecondarySkill id; | ||||||
|     std::string identifier; |     std::string identifier; | ||||||
| @@ -36,11 +52,12 @@ public: | |||||||
|     template <typename Handler> void serialize(Handler &h, const int version) |     template <typename Handler> void serialize(Handler &h, const int version) | ||||||
|     { |     { | ||||||
|         h & id & identifier; |         h & id & identifier; | ||||||
|         h & bonusByLevel; |         h & levels; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     friend class CSkillHandler; |     friend class CSkillHandler; | ||||||
|     friend std::ostream & operator<<(std::ostream &out, const CSkill &skill); |     friend std::ostream & operator<<(std::ostream &out, const CSkill &skill); | ||||||
|  |     friend std::ostream & operator<<(std::ostream &out, const CSkill::LevelInfo &info); | ||||||
| }; | }; | ||||||
|  |  | ||||||
| class DLL_LINKAGE CSkillHandler: public CHandlerBase<SecondarySkill, CSkill> | class DLL_LINKAGE CSkillHandler: public CHandlerBase<SecondarySkill, CSkill> | ||||||
|   | |||||||
| @@ -766,7 +766,7 @@ void CGHeroInstance::recreateSecondarySkillsBonuses() | |||||||
|  |  | ||||||
| void CGHeroInstance::updateSkill(SecondarySkill which, int val) | void CGHeroInstance::updateSkill(SecondarySkill which, int val) | ||||||
| { | { | ||||||
| 	BonusList skillBonus = (*VLC->skillh)[which]->getBonus(val); | 	auto skillBonus = (*VLC->skillh)[which]->getBonus(val); | ||||||
| 	for (auto b : skillBonus) | 	for (auto b : skillBonus) | ||||||
| 	{ | 	{ | ||||||
| 		// TODO: add standard method for joining bonuses, should match on valType as well | 		// TODO: add standard method for joining bonuses, should match on valType as well | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user