1
0
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:
Henning Koehler
2017-08-25 13:35:02 +12:00
parent 8c7895239e
commit 0357a4fe3b
12 changed files with 128 additions and 48 deletions

View File

@@ -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];
}

View File

@@ -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;

View File

@@ -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:

View File

@@ -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);
} }

View File

@@ -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;
} }

View File

@@ -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));
} }
} }

View File

@@ -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"
}
}
} }
}, },

View File

@@ -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"
}
]
}
} }
} }

View File

@@ -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);
} }

View File

@@ -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 << ")";

View File

@@ -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>

View File

@@ -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