From e22f6283c2043731068b9d02db225963fdf15ecb Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Sun, 1 Jan 2023 22:20:41 +0200 Subject: [PATCH] Secondary skills strings are now passed through translator --- client/lobby/CBonusSelection.cpp | 2 +- client/widgets/CComponent.cpp | 4 +-- client/windows/CHeroWindow.cpp | 4 +-- client/windows/CKingdomInterface.cpp | 6 ++-- client/windows/GUIClasses.cpp | 18 ++++++------ include/vcmi/SkillService.h | 4 +-- lib/CGameState.cpp | 2 +- lib/CHeroHandler.cpp | 2 +- lib/CSkillHandler.cpp | 41 +++++++++++++++++---------- lib/CSkillHandler.h | 24 +++++++++------- lib/HeroBonus.cpp | 2 +- lib/mapObjects/CGHeroInstance.cpp | 2 +- lib/mapObjects/MiscObjects.cpp | 2 +- mapeditor/inspector/rewardswidget.cpp | 2 +- mapeditor/mapsettings.cpp | 2 +- 15 files changed, 65 insertions(+), 52 deletions(-) diff --git a/client/lobby/CBonusSelection.cpp b/client/lobby/CBonusSelection.cpp index 5ab2a1ae6..e89efd322 100644 --- a/client/lobby/CBonusSelection.cpp +++ b/client/lobby/CBonusSelection.cpp @@ -252,7 +252,7 @@ void CBonusSelection::createBonusesIcons() desc = CGI->generaltexth->allTexts[718]; boost::algorithm::replace_first(desc, "%s", CGI->generaltexth->levels[bonDescs[i].info3 - 1]); //skill level - boost::algorithm::replace_first(desc, "%s", CGI->skillh->skillName(bonDescs[i].info2)); //skill name + boost::algorithm::replace_first(desc, "%s", CGI->skillh->getByIndex(bonDescs[i].info2)->getNameTranslated()); //skill name picNumber = bonDescs[i].info2 * 3 + bonDescs[i].info3 - 1; break; diff --git a/client/widgets/CComponent.cpp b/client/widgets/CComponent.cpp index 7ed7ce5a5..65b26fbc3 100644 --- a/client/widgets/CComponent.cpp +++ b/client/widgets/CComponent.cpp @@ -151,7 +151,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->skillh->skillInfo(subtype, val); + case secskill: return CGI->skillh->getByIndex(subtype)->getDescriptionTranslated(val); case resource: return CGI->generaltexth->allTexts[242]; case creature: return ""; case artifact: @@ -196,7 +196,7 @@ std::string CComponent::getSubtitleInternal() switch(compType) { case primskill: return boost::str(boost::format("%+d %s") % val % (subtype < 4 ? CGI->generaltexth->primarySkillNames[subtype] : CGI->generaltexth->allTexts[387])); - case secskill: return CGI->generaltexth->levels[val-1] + "\n" + CGI->skillh->skillName(subtype); + case secskill: return CGI->generaltexth->levels[val-1] + "\n" + CGI->skillh->getByIndex(subtype)->getNameTranslated(); case resource: return boost::lexical_cast(val); case creature: return (val? boost::lexical_cast(val) + " " : "") + CGI->creh->objects[subtype]->*(val != 1 ? &CCreature::namePl : &CCreature::nameSing); case artifact: return CGI->artifacts()->getByIndex(subtype)->getName(); diff --git a/client/windows/CHeroWindow.cpp b/client/windows/CHeroWindow.cpp index 62e8d0f11..39401c45e 100644 --- a/client/windows/CHeroWindow.cpp +++ b/client/windows/CHeroWindow.cpp @@ -263,12 +263,12 @@ void CHeroWindow::update(const CGHeroInstance * hero, bool redrawNeeded) { int skill = curHero->secSkills[g].first; int level = curHero->getSecSkillLevel(SecondarySkill(curHero->secSkills[g].first)); - std::string skillName = CGI->skillh->skillName(skill); + std::string skillName = CGI->skillh->getByIndex(skill)->getNameTranslated(); std::string skillValue = CGI->generaltexth->levels[level-1]; secSkillAreas[g]->type = skill; secSkillAreas[g]->bonusValue = level; - secSkillAreas[g]->text = CGI->skillh->skillInfo(skill, level); + secSkillAreas[g]->text = CGI->skillh->getByIndex(skill)->getDescriptionTranslated(level); secSkillAreas[g]->hoverText = boost::str(boost::format(heroscrn[21]) % skillValue % skillName); secSkillImages[g]->setFrame(skill*3 + level + 2); secSkillNames[g]->setText(skillName); diff --git a/client/windows/CKingdomInterface.cpp b/client/windows/CKingdomInterface.cpp index c7d19c3f0..fc4729c66 100644 --- a/client/windows/CKingdomInterface.cpp +++ b/client/windows/CKingdomInterface.cpp @@ -166,7 +166,7 @@ std::string InfoBoxAbstractHeroData::getNameText() return CGI->heroh->objects[getSubID()]->specName; case HERO_SECONDARY_SKILL: if (getValue()) - return CGI->skillh->skillName(getSubID()); + return CGI->skillh->getByIndex(getSubID())->getNameTranslated(); else return ""; default: @@ -274,7 +274,7 @@ void InfoBoxAbstractHeroData::prepareMessage(std::string & text, std::shared_ptr int subID = getSubID(); if(value) { - text = CGI->skillh->skillInfo(subID, (int)value); + text = CGI->skillh->getByIndex(subID)->getDescriptionTranslated((int)value); comp = std::make_shared(CComponent::secskill, subID, (int)value); } break; @@ -355,7 +355,7 @@ std::string InfoBoxHeroData::getHoverText() if (hero->secSkills.size() > index) { std::string level = CGI->generaltexth->levels[hero->secSkills[index].second-1]; - std::string skill = CGI->skillh->skillName(hero->secSkills[index].first); + std::string skill = CGI->skillh->getByIndex(hero->secSkills[index].first)->getNameTranslated(); return boost::str(boost::format(CGI->generaltexth->heroscrn[21]) % level % skill); } else diff --git a/client/windows/GUIClasses.cpp b/client/windows/GUIClasses.cpp index d139776d9..3fd6a588b 100644 --- a/client/windows/GUIClasses.cpp +++ b/client/windows/GUIClasses.cpp @@ -1166,11 +1166,11 @@ CExchangeWindow::CExchangeWindow(ObjectInstanceID hero1, ObjectInstanceID hero2, secSkillAreas[b][g]->type = skill; secSkillAreas[b][g]->bonusValue = level; - secSkillAreas[b][g]->text = CGI->skillh->skillInfo(skill, level); + secSkillAreas[b][g]->text = CGI->skillh->getByIndex(skill)->getDescriptionTranslated(level); 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->skillh->skillName(skill)); + boost::algorithm::replace_first(secSkillAreas[b][g]->hoverText, "%s", CGI->skillh->getByIndex(skill)->getNameTranslated()); } heroAreas[b] = std::make_shared(257 + 228*b, 13, hero); @@ -1516,7 +1516,7 @@ CUniversityWindow::CItem::CItem(CUniversityWindow * _parent, int _ID, int X, int icon = std::make_shared("SECSKILL", _ID * 3 + 3, 0); - name = std::make_shared(22, -13, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, CGI->skillh->skillName(ID)); + name = std::make_shared(22, -13, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, CGI->skillh->getByIndex(ID)->getNameTranslated()); level = std::make_shared(22, 57, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, CGI->generaltexth->levels[0]); pos.h = icon->pos.h; @@ -1536,14 +1536,14 @@ void CUniversityWindow::CItem::clickRight(tribool down, bool previousState) { if(down) { - CRClickPopup::createAndPush(CGI->skillh->skillInfo(ID, 1), std::make_shared(CComponent::secskill, ID, 1)); + CRClickPopup::createAndPush(CGI->skillh->getByIndex(ID)->getDescriptionTranslated(1), std::make_shared(CComponent::secskill, ID, 1)); } } void CUniversityWindow::CItem::hover(bool on) { if(on) - GH.statusbar->write(CGI->skillh->skillName(ID)); + GH.statusbar->write(CGI->skillh->getByIndex(ID)->getNameTranslated()); else GH.statusbar->clear(); } @@ -1625,12 +1625,12 @@ CUnivConfirmWindow::CUnivConfirmWindow(CUniversityWindow * owner_, int SKILL, bo std::string text = CGI->generaltexth->allTexts[608]; boost::replace_first(text, "%s", CGI->generaltexth->levels[0]); - boost::replace_first(text, "%s", CGI->skillh->skillName(SKILL)); + boost::replace_first(text, "%s", CGI->skillh->getByIndex(SKILL)->getNameTranslated()); boost::replace_first(text, "%d", "2000"); clerkSpeech = std::make_shared(text, Rect(24, 129, 413, 70), 0, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE); - name = std::make_shared(230, 37, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, CGI->skillh->skillName(SKILL)); + name = std::make_shared(230, 37, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, CGI->skillh->getByIndex(SKILL)->getNameTranslated()); icon = std::make_shared("SECSKILL", SKILL*3+3, 0, 211, 51); level = std::make_shared(230, 107, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, CGI->generaltexth->levels[1]); @@ -1638,11 +1638,11 @@ CUnivConfirmWindow::CUnivConfirmWindow(CUniversityWindow * owner_, int SKILL, bo cost = std::make_shared(230, 267, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, "2000"); std::string hoverText = CGI->generaltexth->allTexts[609]; - boost::replace_first(hoverText, "%s", CGI->generaltexth->levels[0]+ " " + CGI->skillh->skillName(SKILL)); + boost::replace_first(hoverText, "%s", CGI->generaltexth->levels[0]+ " " + CGI->skillh->getByIndex(SKILL)->getNameTranslated()); text = CGI->generaltexth->zelp[633].second; boost::replace_first(text, "%s", CGI->generaltexth->levels[0]); - boost::replace_first(text, "%s", CGI->skillh->skillName(SKILL)); + boost::replace_first(text, "%s", CGI->skillh->getByIndex(SKILL)->getNameTranslated()); boost::replace_first(text, "%d", "2000"); confirm = std::make_shared(Point(148, 299), "IBY6432.DEF", CButton::tooltip(hoverText, text), [=](){makeDeal(SKILL);}, SDLK_RETURN); diff --git a/include/vcmi/SkillService.h b/include/vcmi/SkillService.h index 6e8618898..ce0fa8b12 100644 --- a/include/vcmi/SkillService.h +++ b/include/vcmi/SkillService.h @@ -15,9 +15,9 @@ VCMI_LIB_NAMESPACE_BEGIN class SecondarySkill; -class Skill; +class CSkill; -class DLL_LINKAGE SkillService : public EntityServiceT +class DLL_LINKAGE SkillService : public EntityServiceT { public: }; diff --git a/lib/CGameState.cpp b/lib/CGameState.cpp index f76de8821..202d73036 100644 --- a/lib/CGameState.cpp +++ b/lib/CGameState.cpp @@ -133,7 +133,7 @@ void MetaString::getLocalString(const std::pair &txt, std::string &dst } else if(type == SEC_SKILL_NAME) { - dst = VLC->skillh->skillName(ser); + dst = VLC->skillh->getByIndex(ser)->getNameTranslated(); } else { diff --git a/lib/CHeroHandler.cpp b/lib/CHeroHandler.cpp index 469acafa9..e1721d0f7 100644 --- a/lib/CHeroHandler.cpp +++ b/lib/CHeroHandler.cpp @@ -316,7 +316,7 @@ void CHeroClassHandler::afterLoadFinalization() if(heroClass->secSkillProbability[skillID] < 0) { const CSkill * skill = (*VLC->skillh)[SecondarySkill(skillID)]; - logMod->trace("%s: no probability for %s, using default", heroClass->identifier, skill->identifier); + logMod->trace("%s: no probability for %s, using default", heroClass->identifier, skill->getJsonKey()); heroClass->secSkillProbability[skillID] = skill->gainChance[heroClass->affinity]; } } diff --git a/lib/CSkillHandler.cpp b/lib/CSkillHandler.cpp index 8a1a70c72..d8a630c24 100644 --- a/lib/CSkillHandler.cpp +++ b/lib/CSkillHandler.cpp @@ -56,7 +56,18 @@ int32_t CSkill::getIconIndex() const const std::string & CSkill::getName() const { - return name; + return identifier; +} + +std::string CSkill::getNameTextID() const +{ + TextIdentifier id("skill", modScope, identifier, "name"); + return id.get(); +} + +std::string CSkill::getNameTranslated() const +{ + return VLC->generaltexth->translate(getNameTextID()); } const std::string & CSkill::getJsonKey() const @@ -64,6 +75,17 @@ const std::string & CSkill::getJsonKey() const return identifier; } +std::string CSkill::getDescriptionTextID(int level) const +{ + TextIdentifier id("skill", modScope, identifier, "description", NSecondarySkill::levels[level]); + return id.get(); +} + +std::string CSkill::getDescriptionTranslated(int level) const +{ + return VLC->generaltexth->translate(getDescriptionTextID(level)); +} + void CSkill::registerIcons(const IconRegistar & cb) const { for(int level = 1; level <= 3; level++) @@ -86,7 +108,7 @@ void CSkill::addNewBonus(const std::shared_ptr & b, int level) b->source = Bonus::SECONDARY_SKILL; b->sid = id; b->duration = Bonus::PERMANENT; - b->description = name; + b->description = getNameTextID(); levels[level-1].effects.push_back(b); } @@ -104,7 +126,6 @@ CSkill::LevelInfo & CSkill::at(int level) DLL_LINKAGE std::ostream & operator<<(std::ostream & out, const CSkill::LevelInfo & info) { - out << "(\"" << info.description << "\", ["; for(int i=0; i < info.effects.size(); i++) out << (i ? "," : "") << info.effects[i]->Description(); return out << "])"; @@ -187,21 +208,11 @@ const std::vector & CSkillHandler::getTypeNames() const return typeNames; } -const std::string & CSkillHandler::skillInfo(int skill, int level) const -{ - return objects[skill]->at(level).description; -} - -const std::string & CSkillHandler::skillName(int skill) const -{ - return objects[skill]->name; -} - CSkill * CSkillHandler::loadFromJson(const std::string & scope, const JsonNode & json, const std::string & identifier, size_t index) { CSkill * skill = new CSkill(SecondarySkill((si32)index), identifier); - skill->name = json["name"].String(); + VLC->generaltexth->registerString(skill->getNameTextID(), json["name"].String()); switch(json["gainChance"].getType()) { case JsonNode::JsonType::DATA_INTEGER: @@ -226,7 +237,7 @@ CSkill * CSkillHandler::loadFromJson(const std::string & scope, const JsonNode & skill->addNewBonus(bonus, level); } CSkill::LevelInfo & skillAtLevel = skill->at(level); - skillAtLevel.description = levelNode["description"].String(); + VLC->generaltexth->registerString(skill->getDescriptionTextID(level), levelNode["description"].String()); skillAtLevel.iconSmall = levelNode["images"]["small"].String(); skillAtLevel.iconMedium = levelNode["images"]["medium"].String(); skillAtLevel.iconLarge = levelNode["images"]["large"].String(); diff --git a/lib/CSkillHandler.h b/lib/CSkillHandler.h index 2d06c3f3c..e771a25ca 100644 --- a/lib/CSkillHandler.h +++ b/lib/CSkillHandler.h @@ -25,7 +25,6 @@ class DLL_LINKAGE CSkill : public Skill public: struct LevelInfo { - std::string description; //descriptions of spell for skill level std::string iconSmall; std::string iconMedium; std::string iconLarge; @@ -36,7 +35,6 @@ public: template void serialize(Handler & h, const int version) { - h & description; h & iconSmall; h & iconMedium; h & iconLarge; @@ -48,25 +46,33 @@ private: std::vector levels; // bonuses provided by basic, advanced and expert level void addNewBonus(const std::shared_ptr & b, int level); + SecondarySkill id; + std::string modScope; + std::string identifier; + + const std::string & getName() const override; + public: CSkill(SecondarySkill id = SecondarySkill::DEFAULT, std::string identifier = "default"); ~CSkill(); int32_t getIndex() const override; int32_t getIconIndex() const override; - const std::string & getName() const override; const std::string & getJsonKey() const override; void registerIcons(const IconRegistar & cb) const override; SecondarySkill getId() const override; + std::string getNameTextID() const; + std::string getNameTranslated() const; + + std::string getDescriptionTextID(int level) const; + std::string getDescriptionTranslated(int level) const; + const LevelInfo & at(int level) const; LevelInfo & at(int level); std::string toString() const; - SecondarySkill id; - std::string identifier; - std::string name; //as displayed in GUI std::array gainChance; // gainChance[0/1] = default gain chance on level-up for might/magic heroes void updateFrom(const JsonNode & data); @@ -76,7 +82,6 @@ public: { h & id; h & identifier; - h & name; h & gainChance; h & levels; } @@ -86,7 +91,7 @@ public: friend DLL_LINKAGE std::ostream & operator<<(std::ostream & out, const CSkill::LevelInfo & info); }; -class DLL_LINKAGE CSkillHandler: public CHandlerBase +class DLL_LINKAGE CSkillHandler: public CHandlerBase { public: CSkillHandler(); @@ -99,9 +104,6 @@ public: std::vector getDefaultAllowed() const override; - const std::string & skillInfo(int skill, int level) const; - const std::string & skillName(int skill) const; - ///json serialization helpers static si32 decodeSkill(const std::string & identifier); static std::string encodeSkill(const si32 index); diff --git a/lib/HeroBonus.cpp b/lib/HeroBonus.cpp index 760aafd66..3ac8cf3b7 100644 --- a/lib/HeroBonus.cpp +++ b/lib/HeroBonus.cpp @@ -1603,7 +1603,7 @@ std::string Bonus::Description() const str << VLC->creh->objects[sid]->namePl; break; case SECONDARY_SKILL: - str << VLC->skillh->skillName(sid); + str << VLC->skillh->getByIndex(sid)->getNameTranslated(); break; case HERO_SPECIAL: str << VLC->heroh->objects[sid]->name; diff --git a/lib/mapObjects/CGHeroInstance.cpp b/lib/mapObjects/CGHeroInstance.cpp index 4bbb931b6..d2e153bbb 100644 --- a/lib/mapObjects/CGHeroInstance.cpp +++ b/lib/mapObjects/CGHeroInstance.cpp @@ -1522,7 +1522,7 @@ void CGHeroInstance::serializeCommonOptions(JsonSerializeFormat & handler) if(rawId < 0 || rawId >= VLC->skillh->size()) logGlobal->error("Invalid secondary skill %d", rawId); - handler.serializeEnum((*VLC->skillh)[SecondarySkill(rawId)]->identifier, p.second, 0, NSecondarySkill::levels); + handler.serializeEnum((*VLC->skillh)[SecondarySkill(rawId)]->getJsonKey(), p.second, 0, NSecondarySkill::levels); } } } diff --git a/lib/mapObjects/MiscObjects.cpp b/lib/mapObjects/MiscObjects.cpp index 575eb5002..84b3cda6e 100644 --- a/lib/mapObjects/MiscObjects.cpp +++ b/lib/mapObjects/MiscObjects.cpp @@ -1498,7 +1498,7 @@ std::string CGWitchHut::getHoverText(PlayerColor player) const if(wasVisited(player)) { hoverName += "\n" + VLC->generaltexth->allTexts[356]; // + (learn %s) - boost::algorithm::replace_first(hoverName, "%s", VLC->skillh->skillName(ability)); + boost::algorithm::replace_first(hoverName, "%s", VLC->skillh->getByIndex(ability)->getNameTranslated()); } return hoverName; } diff --git a/mapeditor/inspector/rewardswidget.cpp b/mapeditor/inspector/rewardswidget.cpp index a6f098a41..9de126b24 100644 --- a/mapeditor/inspector/rewardswidget.cpp +++ b/mapeditor/inspector/rewardswidget.cpp @@ -74,7 +74,7 @@ QList RewardsWidget::getListForType(RewardType typeId) for(int i = 0; i < map.allowedAbilities.size(); ++i) { if(map.allowedAbilities[i]) - result.append(QString::fromStdString(VLC->skillh->objects.at(i)->getName())); + result.append(QString::fromStdString(VLC->skillh->objects.at(i)->getNameTranslated())); } break; diff --git a/mapeditor/mapsettings.cpp b/mapeditor/mapsettings.cpp index eb60ef0f5..232eeb806 100644 --- a/mapeditor/mapsettings.cpp +++ b/mapeditor/mapsettings.cpp @@ -34,7 +34,7 @@ MapSettings::MapSettings(MapController & ctrl, QWidget *parent) : for(int i = 0; i < controller.map()->allowedAbilities.size(); ++i) { - auto * item = new QListWidgetItem(QString::fromStdString(VLC->skillh->objects[i]->getName())); + auto * item = new QListWidgetItem(QString::fromStdString(VLC->skillh->objects[i]->getNameTranslated())); item->setData(Qt::UserRole, QVariant::fromValue(i)); item->setFlags(item->flags() | Qt::ItemIsUserCheckable); item->setCheckState(controller.map()->allowedAbilities[i] ? Qt::Checked : Qt::Unchecked);