瀏覽代碼

enabled config of skill descriptions

Henning Koehler 8 年之前
父節點
當前提交
0357a4fe3b

+ 11 - 0
client/CGameInfo.cpp

@@ -9,6 +9,8 @@
  */
 #include "StdInc.h"
 #include "CGameInfo.h"
+#include "CSkillHandler.h"
+#include "CGeneralTextHandler.h"
 
 #include "../lib/VCMI_Lib.h"
 
@@ -32,5 +34,14 @@ void CGameInfo::setFromLib()
 	heroh = VLC->heroh;
 	objh = VLC->objh;
 	spellh = VLC->spellh;
+	skillh = VLC->skillh;
 	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];
+}

+ 3 - 0
client/CGameInfo.h

@@ -18,6 +18,7 @@ class CArtHandler;
 class CHeroHandler;
 class CCreatureHandler;
 class CSpellHandler;
+class CSkillHandler;
 class CBuildingHandler;
 class CObjectHandler;
 class CSoundHandler;
@@ -55,6 +56,7 @@ public:
 	ConstTransitivePtr<CHeroHandler> heroh;
 	ConstTransitivePtr<CCreatureHandler> creh;
 	ConstTransitivePtr<CSpellHandler> spellh;
+	ConstTransitivePtr<CSkillHandler> skillh;
 	ConstTransitivePtr<CObjectHandler> objh;
 	ConstTransitivePtr<CObjectClassesHandler> objtypeh;
 	CGeneralTextHandler * generaltexth;
@@ -66,5 +68,6 @@ public:
 	friend class CClient;
 
 	CGameInfo();
+	const std::string & skillInfo(int skill, int level) const;
 };
 extern const CGameInfo* CGI;

+ 1 - 1
client/widgets/CComponent.cpp

@@ -148,7 +148,7 @@ std::string CComponent::getDescription()
 	{
 	case primskill:  return (subtype < 4)? CGI->generaltexth->arraytxt[2+subtype] //Primary skill
 										 : 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 creature:   return "";
 	case artifact:

+ 1 - 1
client/windows/CHeroWindow.cpp

@@ -240,7 +240,7 @@ void CHeroWindow::update(const CGHeroInstance * hero, bool redrawNeeded)
 			level = curHero->getSecSkillLevel(SecondarySkill(curHero->secSkills[g].first));
 		secSkillAreas[g]->type = skill;
 		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]);
 		secSkillImages[g]->setFrame(skill*3 + level + 2);
 	}

+ 1 - 1
client/windows/CKingdomInterface.cpp

@@ -281,7 +281,7 @@ bool InfoBoxAbstractHeroData::prepareMessage(std::string &text, CComponent **com
 			if (!value)
 				return false;
 
-			text = CGI->generaltexth->skillInfoTexts[subID][value-1];
+			text = CGI->skillInfo(subID,value);
 			*comp = new CComponent(CComponent::secskill, subID, value);
 			return true;
 		}

+ 2 - 2
client/windows/GUIClasses.cpp

@@ -944,7 +944,7 @@ CExchangeWindow::CExchangeWindow(ObjectInstanceID hero1, ObjectInstanceID hero2,
 
 			secSkillAreas[b][g]->type = skill;
 			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];
 			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)
 	{
-		CRClickPopup::createAndPush(CGI->generaltexth->skillInfoTexts[ID][0],
+		CRClickPopup::createAndPush(CGI->skillInfo(ID, 1),
 				new CComponent(CComponent::secskill, ID, 1));
 	}
 }

+ 13 - 3
config/schemas/skill.json

@@ -9,10 +9,20 @@
 	"definitions" : {
 
         "skillBonus":{
+            "type": "object",
             "description": "Set of bonuses provided by skill at given level",
-            "type": "array",
-            "items":{
-                "$ref" : "vcmi:bonus"
+            "required" : ["effects"],
+            "properties": {
+                "description": {
+                    "type": "string",
+                    "description": "localizable description"
+                },
+                "effects": {
+                    "type": "array",
+                    "items": {
+                        "$ref" : "vcmi:bonus"
+                    }
+                }
             }
         },
 

+ 33 - 24
config/skills.json

@@ -1,29 +1,38 @@
 {
     "estates" : {
         "index" : 13,
-        "basic" : [
-            {
-                "subtype" : 13,
-                "type" : "SECONDARY_SKILL_PREMY",
-                "val" : 250,
-                "valueType" : "BASE_NUMBER"
-            }
-        ],
-        "advanced" : [
-            {
-                "subtype" : 13,
-                "type" : "SECONDARY_SKILL_PREMY",
-                "val" : 500,
-                "valueType" : "BASE_NUMBER"
-            }
-        ],
-        "expert" : [
-            {
-                "subtype" : 13,
-                "type" : "SECONDARY_SKILL_PREMY",
-                "val" : 1000,
-                "valueType" : "BASE_NUMBER"
-            }
-        ]
+        "basic" : {
+            "description" : "Hero generates 250 gold each day.",
+            "effects" : [
+                {
+                    "subtype" : 13,
+                    "type" : "SECONDARY_SKILL_PREMY",
+                    "val" : 250,
+                    "valueType" : "BASE_NUMBER"
+                }
+            ]
+        },
+        "advanced" : {
+            "description" : "Hero generates 500 gold each day.",
+            "effects" : [
+                {
+                    "subtype" : 13,
+                    "type" : "SECONDARY_SKILL_PREMY",
+                    "val" : 500,
+                    "valueType" : "BASE_NUMBER"
+                }
+            ]
+        },
+        "expert" : {
+            "description" : "Hero generates 1000 gold each day.",
+            "effects" : [
+                {
+                    "subtype" : 13,
+                    "type" : "SECONDARY_SKILL_PREMY",
+                    "val" : 1000,
+                    "valueType" : "BASE_NUMBER"
+                }
+            ]
+        }
     }
 }

+ 4 - 2
lib/CModHandler.cpp

@@ -377,6 +377,7 @@ bool CContentHandler::ContentTypeHandler::loadMod(std::string modName, bool vali
 	if (!modInfo.patches.isNull())
 		JsonUtils::merge(modInfo.modData, modInfo.patches);
 
+	CLogger * logger = CLogger::getLogger(CLoggerDomain("mod"));
 	for(auto & entry : modInfo.modData.Struct())
 	{
 		const std::string & name = entry.first;
@@ -389,6 +390,7 @@ bool CContentHandler::ContentTypeHandler::loadMod(std::string modName, bool vali
 
 			if (originalData.size() > index)
 			{
+				logger->traceStream() << "found original data in loadMod(" << name << ") at index " << index;
 				JsonUtils::merge(originalData[index], data);
 				performValidate(originalData[index],name);
 				handler->loadObject(modName, name, originalData[index], index);
@@ -396,8 +398,8 @@ bool CContentHandler::ContentTypeHandler::loadMod(std::string modName, bool vali
 			}
 			else
 			{
-				logGlobal->debugStream() << "no original data in loadMod(" << name << ")";
-				logGlobal->traceStream() << data;
+				logger->debugStream() << "no original data in loadMod(" << name << ") at index " << index;
+				logger->traceStream() << data;
 				performValidate(data, name);
 				handler->loadObject(modName, name, data, index);
 			}

+ 38 - 10
lib/CSkillHandler.cpp

@@ -27,16 +27,24 @@
 #include "battle/CBattleInfoCallback.h"
 
 ///CSkill
+CSkill::LevelInfo::LevelInfo() : description("")
+{
+}
+
+CSkill::LevelInfo::~LevelInfo()
+{
+}
+
 CSkill::CSkill(SecondarySkill id) : id(id)
 {
     if(id == SecondarySkill::DEFAULT)
         identifier = "default";
     else
         identifier = NSecondarySkill::names[id];
-    // init bonus levels
-    BonusList emptyList;
-    for(auto level : NSecondarySkill::levels)
-        bonusByLevel.push_back(emptyList);
+    // init levels
+    LevelInfo emptyLevel;
+    for(int level = 1; level < NSecondarySkill::levels.size(); level++)
+        levels.push_back(emptyLevel);
 }
 
 CSkill::~CSkill()
@@ -48,18 +56,32 @@ void CSkill::addNewBonus(const std::shared_ptr<Bonus>& b, int level)
     b->source = Bonus::SECONDARY_SKILL;
     b->duration = Bonus::PERMANENT;
     b->description = identifier;
-    bonusByLevel[level].push_back(b);
+    levels[level-1].effects.push_back(b);
+}
+
+void CSkill::setDescription(const std::string & desc, int 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;
 }
 
-BonusList CSkill::getBonus(int level)
+DLL_LINKAGE std::ostream & operator<<(std::ostream &out, const CSkill::LevelInfo &info)
 {
-    return bonusByLevel[level];
+    return out << "(\"" << info.description << "\"," << info.effects << ")";
 }
 
 DLL_LINKAGE std::ostream & operator<<(std::ostream &out, const CSkill &skill)
 {
-	out << "Skill(" << (int)skill.id << "," << skill.identifier << "): " << skill.bonusByLevel;
-	return out;
+    return out << "Skill(" << (int)skill.id << "," << skill.identifier << "): " << skill.levels;
 }
 
 ///CSkillHandler
@@ -108,12 +130,18 @@ CSkill * CSkillHandler::loadFromJson(const JsonNode & json, const std::string &
     for(int level = 1; level < NSecondarySkill::levels.size(); level++)
     {
         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);
             bonus->sid = skill->id;
             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()));
     logger->debugStream() << "loaded secondary skill " << identifier << "(" << (int)skill->id << ")";

+ 20 - 3
lib/CSkillHandler.h

@@ -21,14 +21,30 @@ class JsonSerializeFormat;
 class DLL_LINKAGE CSkill // secondary skill
 {
 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:
     CSkill(SecondarySkill id = SecondarySkill::DEFAULT);
     ~CSkill();
 
     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;
     std::string identifier;
@@ -36,11 +52,12 @@ public:
     template <typename Handler> void serialize(Handler &h, const int version)
     {
         h & id & identifier;
-        h & bonusByLevel;
+        h & levels;
     }
 
     friend class CSkillHandler;
     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>

+ 1 - 1
lib/mapObjects/CGHeroInstance.cpp

@@ -766,7 +766,7 @@ void CGHeroInstance::recreateSecondarySkillsBonuses()
 
 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)
 	{
 		// TODO: add standard method for joining bonuses, should match on valType as well