From 388ed88b5d8f8dd43f3cbf23de01a128d408b305 Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Mon, 2 Jan 2023 15:58:56 +0200 Subject: [PATCH] All artifact strings now pass through translator --- AI/Nullkiller/Engine/PriorityEvaluator.cpp | 2 +- AI/Nullkiller/Goals/AbstractGoal.cpp | 2 +- AI/VCAI/Goals/AbstractGoal.cpp | 2 +- client/CPlayerInterface.cpp | 4 +- client/battle/BattleWindow.cpp | 2 +- client/lobby/CBonusSelection.cpp | 2 +- client/widgets/CArtifactHolder.cpp | 26 ++++---- client/widgets/CComponent.cpp | 2 +- client/windows/CCreatureWindow.cpp | 2 +- client/windows/CTradeWindow.cpp | 14 ++-- include/vcmi/Artifact.h | 11 +++- lib/CArtHandler.cpp | 76 ++++++++++++++-------- lib/CArtHandler.h | 27 ++++---- lib/CGameState.cpp | 10 +-- lib/CStack.cpp | 2 +- lib/HeroBonus.cpp | 2 +- lib/NetPacksLib.cpp | 14 ++-- lib/mapObjects/CGMarket.cpp | 2 +- lib/mapObjects/CGTownInstance.cpp | 2 +- lib/mapObjects/CRewardableObject.cpp | 4 +- lib/mapObjects/MiscObjects.cpp | 16 +---- lib/mapping/CMap.cpp | 2 +- lib/mapping/MapFormatH3M.cpp | 2 +- lib/rmg/CMapGenerator.cpp | 4 +- lib/serializer/CSerializer.cpp | 2 +- mapeditor/inspector/questwidget.cpp | 2 +- mapeditor/inspector/rewardswidget.cpp | 2 +- mapeditor/mapsettings.cpp | 2 +- server/CGameHandler.cpp | 20 +++--- 29 files changed, 142 insertions(+), 118 deletions(-) diff --git a/AI/Nullkiller/Engine/PriorityEvaluator.cpp b/AI/Nullkiller/Engine/PriorityEvaluator.cpp index b0abfffac..18c976e7a 100644 --- a/AI/Nullkiller/Engine/PriorityEvaluator.cpp +++ b/AI/Nullkiller/Engine/PriorityEvaluator.cpp @@ -191,7 +191,7 @@ int getDwellingArmyCost(const CGObjectInstance * target) uint64_t evaluateArtifactArmyValue(CArtifactInstance * art) { - if(art->artType->id == ArtifactID::SPELL_SCROLL) + if(art->artType->getId() == ArtifactID::SPELL_SCROLL) return 1500; auto statsValue = diff --git a/AI/Nullkiller/Goals/AbstractGoal.cpp b/AI/Nullkiller/Goals/AbstractGoal.cpp index 9798b8650..e188b78d1 100644 --- a/AI/Nullkiller/Goals/AbstractGoal.cpp +++ b/AI/Nullkiller/Goals/AbstractGoal.cpp @@ -60,7 +60,7 @@ std::string AbstractGoal::toString() const //TODO: virtualize desc = "GATHER TROOPS"; break; case GET_ART_TYPE: - desc = "GET ARTIFACT OF TYPE " + VLC->arth->objects[aid]->getName(); + desc = "GET ARTIFACT OF TYPE " + VLC->arth->objects[aid]->getNameTranslated(); break; case DIG_AT_TILE: desc = "DIG AT TILE " + tile.toString(); diff --git a/AI/VCAI/Goals/AbstractGoal.cpp b/AI/VCAI/Goals/AbstractGoal.cpp index b197a894a..b469c8008 100644 --- a/AI/VCAI/Goals/AbstractGoal.cpp +++ b/AI/VCAI/Goals/AbstractGoal.cpp @@ -91,7 +91,7 @@ std::string AbstractGoal::name() const //TODO: virtualize } break; case GET_ART_TYPE: - desc = "GET ARTIFACT OF TYPE " + VLC->artifacts()->getByIndex(aid)->getName(); + desc = "GET ARTIFACT OF TYPE " + VLC->artifacts()->getByIndex(aid)->getNameTranslated(); break; case VISIT_TILE: desc = "VISIT TILE " + tile.toString(); diff --git a/client/CPlayerInterface.cpp b/client/CPlayerInterface.cpp index 03616dc55..d4df5435b 100644 --- a/client/CPlayerInterface.cpp +++ b/client/CPlayerInterface.cpp @@ -1363,14 +1363,14 @@ void CPlayerInterface::showGarrisonDialog( const CArmedInstance *up, const CGHer */ void CPlayerInterface::showArtifactAssemblyDialog(const Artifact * artifact, const Artifact * assembledArtifact, CFunctionList onYes) { - std::string text = artifact->getDescription(); + std::string text = artifact->getDescriptionTranslated(); text += "\n\n"; std::vector> scs; if(assembledArtifact) { // You possess all of the components to... - text += boost::str(boost::format(CGI->generaltexth->allTexts[732]) % assembledArtifact->getName()); + text += boost::str(boost::format(CGI->generaltexth->allTexts[732]) % assembledArtifact->getNameTranslated()); // Picture of assembled artifact at bottom. auto sc = std::make_shared(CComponent::artifact, assembledArtifact->getIndex(), 0); diff --git a/client/battle/BattleWindow.cpp b/client/battle/BattleWindow.cpp index c0f0b0ee0..f47a559ac 100644 --- a/client/battle/BattleWindow.cpp +++ b/client/battle/BattleWindow.cpp @@ -420,7 +420,7 @@ void BattleWindow::bSpellf() //%s wields the %s, an ancient artifact which creates a p dead to all magic. LOCPLINT->showInfoDialog(boost::str(boost::format(CGI->generaltexth->allTexts[683]) - % heroName % CGI->artifacts()->getByIndex(artID)->getName())); + % heroName % CGI->artifacts()->getByIndex(artID)->getNameTranslated())); } } } diff --git a/client/lobby/CBonusSelection.cpp b/client/lobby/CBonusSelection.cpp index 796b60fb5..27d943c5c 100644 --- a/client/lobby/CBonusSelection.cpp +++ b/client/lobby/CBonusSelection.cpp @@ -209,7 +209,7 @@ void CBonusSelection::createBonusesIcons() } case CScenarioTravel::STravelBonus::ARTIFACT: desc = CGI->generaltexth->allTexts[715]; - boost::algorithm::replace_first(desc, "%s", CGI->artifacts()->getByIndex(bonDescs[i].info2)->getName()); + boost::algorithm::replace_first(desc, "%s", CGI->artifacts()->getByIndex(bonDescs[i].info2)->getNameTranslated()); break; case CScenarioTravel::STravelBonus::SPELL_SCROLL: desc = CGI->generaltexth->allTexts[716]; diff --git a/client/widgets/CArtifactHolder.cpp b/client/widgets/CArtifactHolder.cpp index 177d22eab..600059c55 100644 --- a/client/widgets/CArtifactHolder.cpp +++ b/client/widgets/CArtifactHolder.cpp @@ -125,13 +125,13 @@ void CHeroArtPlace::clickLeft(tribool down, bool previousState) // If clicked on spellbook, open it only if no artifact is held at the moment. if(ourArt && !down && previousState && !ourOwner->commonInfo->src.AOH) { - if(ourArt->artType->id == ArtifactID::SPELLBOOK) - GH.pushIntT(ourOwner->curHero, LOCPLINT, LOCPLINT->battleInt.get()); + if(ourArt->artType->getId() == ArtifactID::SPELLBOOK) + GH.pushIntT(ourOwner->curHero, LOCPLINT, LOCPLINT->battleInt.get()); } if (!down && previousState) { - if(ourArt && ourArt->artType->id == ArtifactID::SPELLBOOK) + if(ourArt && ourArt->artType->getId() == ArtifactID::SPELLBOOK) return; //this is handled separately if(!ourOwner->commonInfo->src.AOH) //nothing has been clicked @@ -139,7 +139,7 @@ void CHeroArtPlace::clickLeft(tribool down, bool previousState) if(ourArt //to prevent selecting empty slots (bugfix to what GrayFace reported) && ourOwner->curHero->tempOwner == LOCPLINT->playerID)//can't take art from another player { - if(ourArt->artType->id == ArtifactID::CATAPULT) //catapult cannot be highlighted + if(ourArt->artType->getId() == ArtifactID::CATAPULT) //catapult cannot be highlighted { std::vector> catapult(1, std::make_shared(CComponent::artifact, 3, 0)); LOCPLINT->showInfoDialog(CGI->generaltexth->allTexts[312], catapult); //The Catapult must be equipped. @@ -164,7 +164,7 @@ void CHeroArtPlace::clickLeft(tribool down, bool previousState) { const CArtifact * const cur = ourOwner->commonInfo->src.art->artType; - if(cur->id == ArtifactID::CATAPULT) + if(cur->getId() == ArtifactID::CATAPULT) { //should not happen, catapult cannot be selected logGlobal->error("Attempt to move Catapult"); @@ -172,7 +172,7 @@ void CHeroArtPlace::clickLeft(tribool down, bool previousState) else if(cur->isBig()) { //war machines cannot go to backpack - LOCPLINT->showInfoDialog(boost::str(boost::format(CGI->generaltexth->allTexts[153]) % cur->getName())); + LOCPLINT->showInfoDialog(boost::str(boost::format(CGI->generaltexth->allTexts[153]) % cur->getNameTranslated())); } else { @@ -217,10 +217,10 @@ bool CHeroArtPlace::askToAssemble(const CArtifactInstance *art, ArtifactPosition LOCPLINT->showArtifactAssemblyDialog( art->artType, combination, - std::bind(&CCallback::assembleArtifacts, LOCPLINT->cb.get(), hero, slot, true, combination->id)); + std::bind(&CCallback::assembleArtifacts, LOCPLINT->cb.get(), hero, slot, true, combination->getId())); if(assemblyPossibilities.size() > 2) - logGlobal->warn("More than one possibility of assembling on %s... taking only first", art->artType->getName()); + logGlobal->warn("More than one possibility of assembling on %s... taking only first", art->artType->getNameTranslated()); return true; } return false; @@ -388,7 +388,7 @@ void CHeroArtPlace::setArtifact(const CArtifactInstance *art) text = art->getEffectiveDescription(ourOwner->curHero); - if(art->artType->id == ArtifactID::SPELL_SCROLL) + if(art->artType->getId() == ArtifactID::SPELL_SCROLL) { int spellID = art->getGivenSpellID(); if(spellID >= 0) @@ -402,14 +402,14 @@ void CHeroArtPlace::setArtifact(const CArtifactInstance *art) else { baseType = CComponent::artifact; - type = art->artType->id; + type = art->artType->getId(); bonusValue = 0; } if (locked) // Locks should appear as empty. hoverText = CGI->generaltexth->allTexts[507]; else - hoverText = boost::str(boost::format(CGI->generaltexth->heroscrn[1]) % ourArt->artType->getName()); + hoverText = boost::str(boost::format(CGI->generaltexth->heroscrn[1]) % ourArt->artType->getNameTranslated()); } void CArtifactsOfHero::SCommonPart::reset() @@ -1066,7 +1066,7 @@ void CCommanderArtPlace::setArtifact(const CArtifactInstance * art) text = art->getEffectiveDescription(); - if (art->artType->id == ArtifactID::SPELL_SCROLL) + if (art->artType->getId() == ArtifactID::SPELL_SCROLL) { int spellID = art->getGivenSpellID(); if (spellID >= 0) @@ -1080,7 +1080,7 @@ void CCommanderArtPlace::setArtifact(const CArtifactInstance * art) else { baseType = CComponent::artifact; - type = art->artType->id; + type = art->artType->getId(); bonusValue = 0; } } diff --git a/client/widgets/CComponent.cpp b/client/widgets/CComponent.cpp index 1bf52cca0..8a4599468 100644 --- a/client/widgets/CComponent.cpp +++ b/client/widgets/CComponent.cpp @@ -206,7 +206,7 @@ std::string CComponent::getSubtitleInternal() else return val > 1 ? creature->getNamePluralTranslated() : creature->getNameSingularTranslated(); } - case artifact: return CGI->artifacts()->getByIndex(subtype)->getName(); + case artifact: return CGI->artifacts()->getByIndex(subtype)->getNameTranslated(); case experience: { if(subtype == 1) //+1 level - tree of knowledge diff --git a/client/windows/CCreatureWindow.cpp b/client/windows/CCreatureWindow.cpp index bcbf999a0..d3aa2846b 100644 --- a/client/windows/CCreatureWindow.cpp +++ b/client/windows/CCreatureWindow.cpp @@ -597,7 +597,7 @@ CStackWindow::MainSection::MainSection(CStackWindow * owner, int yOffset, bool s { parent->stackArtifactIcon = std::make_shared("ARTIFACT", art->artType->iconIndex, 0, pos.x, pos.y); parent->stackArtifactHelp = std::make_shared(Rect(pos, Point(44, 44)), CComponent::artifact); - parent->stackArtifactHelp->type = art->artType->id; + parent->stackArtifactHelp->type = art->artType->getId(); if(parent->info->owner) { diff --git a/client/windows/CTradeWindow.cpp b/client/windows/CTradeWindow.cpp index 545ea8a35..9420f18b4 100644 --- a/client/windows/CTradeWindow.cpp +++ b/client/windows/CTradeWindow.cpp @@ -250,7 +250,7 @@ void CTradeWindow::CTradeableItem::hover(bool on) if(id < 0) GH.statusbar->write(CGI->generaltexth->zelp[582].first); else - GH.statusbar->write(CGI->artifacts()->getByIndex(id)->getName()); + GH.statusbar->write(CGI->artifacts()->getByIndex(id)->getNameTranslated()); break; } } @@ -269,7 +269,7 @@ void CTradeWindow::CTradeableItem::clickRight(tribool down, bool previousState) case ARTIFACT_PLACEHOLDER: //TODO: it's would be better for market to contain actual CArtifactInstance and not just ids of certain artifact type so we can use getEffectiveDescription. if(id >= 0) - adventureInt->handleRightClick(CGI->artifacts()->getByIndex(id)->getDescription(), down); + adventureInt->handleRightClick(CGI->artifacts()->getByIndex(id)->getDescriptionTranslated(), down); break; } } @@ -290,7 +290,7 @@ std::string CTradeWindow::CTradeableItem::getName(int number) const return CGI->creh->objects[id]->getNamePluralTranslated(); case ARTIFACT_TYPE: case ARTIFACT_INSTANCE: - return CGI->artifacts()->getByIndex(id)->getName(); + return CGI->artifacts()->getByIndex(id)->getNameTranslated(); } logGlobal->error("Invalid trade item type: %d", (int)type); return ""; @@ -313,7 +313,7 @@ void CTradeWindow::CTradeableItem::setArtInstance(const CArtifactInstance *art) assert(type == ARTIFACT_PLACEHOLDER || type == ARTIFACT_INSTANCE); hlp = art; if(art) - setID(art->artType->id); + setID(art->artType->getId()); else setID(-1); } @@ -1397,7 +1397,7 @@ void CAltarWindow::calcTotalExp() for(const CArtifactInstance *art : arts->artifactsOnAltar) { int dmp, valOfArt; - market->getOffer(art->artType->id, 0, dmp, valOfArt, mode); + market->getOffer(art->artType->getId(), 0, dmp, valOfArt, mode); val += valOfArt; //WAS val += valOfArt * arts->artifactsOnAltar.count(*i); } } @@ -1470,7 +1470,7 @@ void CAltarWindow::showAll(SDL_Surface * to) artIcon->showAll(to); int dmp, val; - market->getOffer(arts->commonInfo->src.art->artType->id, 0, dmp, val, EMarketMode::ARTIFACT_EXP); + market->getOffer(arts->commonInfo->src.art->artType->getId(), 0, dmp, val, EMarketMode::ARTIFACT_EXP); val = static_cast(hero->calculateXp(val)); printAtMiddleLoc(boost::lexical_cast(val), 304, 498, FONT_SMALL, Colors::WHITE, to); } @@ -1496,7 +1496,7 @@ bool CAltarWindow::putOnAltar(std::shared_ptr altarSlot, const C } int dmp, val; - market->getOffer(art->artType->id, 0, dmp, val, EMarketMode::ARTIFACT_EXP); + market->getOffer(art->artType->getId(), 0, dmp, val, EMarketMode::ARTIFACT_EXP); val = static_cast(hero->calculateXp(val)); arts->artifactsOnAltar.insert(art); diff --git a/include/vcmi/Artifact.h b/include/vcmi/Artifact.h index f9f7ad89e..fda53de1a 100644 --- a/include/vcmi/Artifact.h +++ b/include/vcmi/Artifact.h @@ -19,13 +19,20 @@ class CreatureID; class DLL_LINKAGE Artifact : public EntityWithBonuses { + using EntityWithBonuses::getName; public: virtual bool isBig() const = 0; virtual bool isTradable() const = 0; - virtual const std::string & getDescription() const = 0; - virtual const std::string & getEventText() const = 0; virtual uint32_t getPrice() const = 0; virtual CreatureID getWarMachine() const = 0; + + virtual std::string getDescriptionTranslated() const = 0; + virtual std::string getEventTranslated() const = 0; + virtual std::string getNameTranslated() const = 0; + + virtual std::string getDescriptionTextID() const = 0; + virtual std::string getEventTextID() const = 0; + virtual std::string getNameTextID() const = 0; }; VCMI_LIB_NAMESPACE_END diff --git a/lib/CArtHandler.cpp b/lib/CArtHandler.cpp index 4f321aad3..2ca86712f 100644 --- a/lib/CArtHandler.cpp +++ b/lib/CArtHandler.cpp @@ -62,7 +62,7 @@ int32_t CArtifact::getIconIndex() const const std::string & CArtifact::getName() const { - return name; + return identifier; } const std::string & CArtifact::getJsonKey() const @@ -86,13 +86,34 @@ const IBonusBearer * CArtifact::accessBonuses() const return this; } -const std::string & CArtifact::getDescription() const +std::string CArtifact::getDescriptionTranslated() const { - return description; + return VLC->generaltexth->translate(getDescriptionTextID()); } -const std::string & CArtifact::getEventText() const + +std::string CArtifact::getEventTranslated() const { - return eventText; + return VLC->generaltexth->translate(getEventTextID()); +} + +std::string CArtifact::getNameTranslated() const +{ + return VLC->generaltexth->translate(getNameTextID()); +} + +std::string CArtifact::getDescriptionTextID() const +{ + return TextIdentifier("object", modScope, identifier, "description").get(); +} + +std::string CArtifact::getEventTextID() const +{ + return TextIdentifier("object", modScope, identifier, "event").get(); +} + +std::string CArtifact::getNameTextID() const +{ + return TextIdentifier("object", modScope, identifier, "name").get(); } uint32_t CArtifact::getPrice() const @@ -167,7 +188,7 @@ void CArtifact::addNewBonus(const std::shared_ptr& b) { b->source = Bonus::ARTIFACT; b->duration = Bonus::PERMANENT; - b->description = name; + b->description = getNameTranslated(); CBonusSystemNode::addNewBonus(b); } @@ -323,10 +344,13 @@ CArtifact * CArtHandler::loadFromJson(const std::string & scope, const JsonNode } art->id = ArtifactID(index); art->identifier = identifier; + art->modScope = scope; + const JsonNode & text = node["text"]; - art->name = text["name"].String(); - art->description = text["description"].String(); - art->eventText = text["event"].String(); + + VLC->generaltexth->registerString(art->getNameTextID(), text["name"].String()); + VLC->generaltexth->registerString(art->getDescriptionTextID(), text["description"].String()); + VLC->generaltexth->registerString(art->getEventTextID(), text["event"].String()); const JsonNode & graphics = node["graphics"]; art->image = graphics["image"].String(); @@ -734,7 +758,7 @@ void CArtifactInstance::setType( CArtifact *Art ) std::string CArtifactInstance::nodeName() const { - return "Artifact instance of " + (artType ? artType->getName() : std::string("uninitialized")) + " type"; + return "Artifact instance of " + (artType ? artType->getJsonKey() : std::string("uninitialized")) + " type"; } CArtifactInstance *CArtifactInstance::createScroll(SpellID sid) @@ -756,9 +780,9 @@ std::string CArtifactInstance::getEffectiveDescription(const CGHeroInstance * he { std::string text = artType->getDescription(); if (!vstd::contains(text, '{')) - text = '{' + artType->getName() + "}\n\n" + text; //workaround for new artifacts with single name, turns it to H3-style + text = '{' + artType->getNameTranslated() + "}\n\n" + text; //workaround for new artifacts with single name, turns it to H3-style - if(artType->id == ArtifactID::SPELL_SCROLL) + if(artType->getId() == ArtifactID::SPELL_SCROLL) { // we expect scroll description to be like this: This scroll contains the [spell name] spell which is added into your spell book for as long as you carry the scroll. // so we want to replace text in [...] with a spell name @@ -777,12 +801,12 @@ std::string CArtifactInstance::getEffectiveDescription(const CGHeroInstance * he std::string artList; auto combinedArt = artType->constituentOf[0]; text += "\n\n"; - text += "{" + combinedArt->getName() + "}"; + text += "{" + combinedArt->getNameTranslated() + "}"; int wornArtifacts = 0; for(auto a : *combinedArt->constituents) //TODO: can the artifact be a part of more than one set? { - artList += "\n" + a->getName(); - if (hero->hasArt(a->id, true)) + artList += "\n" + a->getNameTranslated(); + if (hero->hasArt(a->getId(), true)) wornArtifacts++; } text += " (" + boost::str(boost::format("%d") % wornArtifacts) + " / " + @@ -841,7 +865,7 @@ bool CArtifactInstance::canBePutAt(const CArtifactSet *artSet, ArtifactPosition auto possibleSlots = artType->possibleSlots.find(artSet->bearerType()); if(possibleSlots == artType->possibleSlots.end()) { - logMod->warn("Warning: artifact %s doesn't have defined allowed slots for bearer of type %s", artType->getName(), artSet->bearerType()); + logMod->warn("Warning: artifact %s doesn't have defined allowed slots for bearer of type %s", artType->getNameTranslated(), artSet->bearerType()); return false; } @@ -889,7 +913,7 @@ std::vector CArtifactInstance::assemblyPossibilities(const CA if(equipped) { // Search for equipped arts - if (!h->hasArt(constituent->id, true, false, false)) + if (!h->hasArt(constituent->getId(), true, false, false)) { possible = false; break; @@ -898,7 +922,7 @@ std::vector CArtifactInstance::assemblyPossibilities(const CA else { // Search in backpack - if(!h->hasArtBackpack(constituent->id)) + if(!h->hasArtBackpack(constituent->getId())) { possible = false; break; @@ -1061,14 +1085,14 @@ void CCombinedArtifactInstance::createConstituents() for(const CArtifact * art : *artType->constituents) { - addAsConstituent(CArtifactInstance::createNewArtifactInstance(art->id), ArtifactPosition::PRE_FIRST); + addAsConstituent(CArtifactInstance::createNewArtifactInstance(art->getId()), ArtifactPosition::PRE_FIRST); } } void CCombinedArtifactInstance::addAsConstituent(CArtifactInstance *art, ArtifactPosition slot) { assert(vstd::contains_if(*artType->constituents, [=](const CArtifact * constituent){ - return constituent->id == art->artType->id; + return constituent->getId() == art->artType->getId(); })); assert(art->getParentNodes().size() == 1 && art->getParentNodes().front() == art->artType); constituentsInfo.push_back(ConstituentInfo(art, slot)); @@ -1227,7 +1251,7 @@ std::vector CArtifactSet::getAllArtPositions(ArtifactID aid, b { std::vector result; for(auto & slotInfo : artifactsWorn) - if(slotInfo.second.artifact->artType->id == aid && (allowLocked || !slotInfo.second.locked)) + if(slotInfo.second.artifact->artType->getId() == aid && (allowLocked || !slotInfo.second.locked)) result.push_back(slotInfo.first); if(onlyWorn) @@ -1248,7 +1272,7 @@ std::vector CArtifactSet::getBackpackArtPositions(ArtifactID a for(auto & artInfo : artifactsInBackpack) { auto * art = artInfo.getArt(); - if(art && art->artType->id == aid) + if(art && art->artType->getId() == aid) result.emplace_back(backpackPosition); backpackPosition++; } @@ -1318,7 +1342,7 @@ CArtifactSet::searchForConstituent(ArtifactID aid) const auto ass = static_cast(art.get()); for(auto& ci : ass->constituentsInfo) { - if(ci.art->artType->id == aid) + if(ci.art->artType->getId() == aid) { return {ass, ci.art}; } @@ -1468,12 +1492,12 @@ void CArtifactSet::serializeJsonHero(JsonSerializeFormat & handler, CMap * map) { backpackTemp.reserve(artifactsInBackpack.size()); for(const ArtSlotInfo & info : artifactsInBackpack) - backpackTemp.push_back(info.artifact->artType->id); + backpackTemp.push_back(info.artifact->artType->getId()); } handler.serializeIdArray(NArtifactPosition::backpack, backpackTemp); if(!handler.saving) { - for(const ArtifactID & artifactID : backpackTemp) + for(const ArtifactID & artifactID : backpackTemp) { auto artifact = CArtifactInstance::createArtifact(map, artifactID.toEnum()); auto slot = ArtifactPosition(GameConstants::BACKPACK_START + (si32)artifactsInBackpack.size()); @@ -1503,7 +1527,7 @@ void CArtifactSet::serializeJsonSlot(JsonSerializeFormat & handler, const Artifa if(info != nullptr && !info->locked) { - artifactID = info->artifact->artType->id; + artifactID = info->artifact->artType->getId(); handler.serializeId(NArtifactPosition::namesHero[slot.num], artifactID, ArtifactID::NONE); } } diff --git a/lib/CArtHandler.h b/lib/CArtHandler.h index 504c362c7..0ef065344 100644 --- a/lib/CArtHandler.h +++ b/lib/CArtHandler.h @@ -45,13 +45,16 @@ namespace ArtBearer class DLL_LINKAGE CArtifact : public Artifact, public CBonusSystemNode //container for artifacts { -protected: - std::string name, description; //set if custom - std::string eventText; //short story displayed upon picking + ArtifactID id; + + std::string modScope; + std::string identifier; + + const std::string & getName() const override; + public: enum EartClass {ART_SPECIAL=1, ART_TREASURE=2, ART_MINOR=4, ART_MAJOR=8, ART_RELIC=16}; //artifact classes - std::string identifier; std::string image; std::string large; // big image for custom artifacts, used in drag & drop std::string advMapDef; //used for adventure map object @@ -61,19 +64,23 @@ public: std::unique_ptr > constituents; // Artifacts IDs a combined artifact consists of, or nullptr. std::vector constituentOf; // Reverse map of constituents - combined arts that include this art EartClass aClass; - ArtifactID id; CreatureID warMachine; 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; ArtifactID getId() const override; virtual const IBonusBearer * accessBonuses() const override; - const std::string & getEventText() const override; - const std::string & getDescription() const override; + std::string getDescriptionTranslated() const override; + std::string getEventTranslated() const override; + std::string getNameTranslated() const override; + + std::string getDescriptionTextID() const override; + std::string getEventTextID() const override; + std::string getNameTextID() const override; + uint32_t getPrice() const override; CreatureID getWarMachine() const override; bool isBig() const override; @@ -91,9 +98,6 @@ public: template void serialize(Handler &h, const int version) { h & static_cast(*this); - h & name; - h & description; - h & eventText; h & image; h & large; h & advMapDef; @@ -104,6 +108,7 @@ public: h & constituentOf; h & aClass; h & id; + h & modScope; h & identifier; h & warMachine; } diff --git a/lib/CGameState.cpp b/lib/CGameState.cpp index 8ba1e26f8..8fcd22251 100644 --- a/lib/CGameState.cpp +++ b/lib/CGameState.cpp @@ -75,7 +75,7 @@ void MetaString::getLocalString(const std::pair &txt, std::string &dst { auto art = ArtifactID(ser).toArtifact(VLC->artifacts()); if(art) - dst = art->getName(); + dst = art->getNameTranslated(); else dst = "#!#"; } @@ -83,7 +83,7 @@ void MetaString::getLocalString(const std::pair &txt, std::string &dst { auto art = ArtifactID(ser).toArtifact(VLC->artifacts()); if(art) - dst = art->getDescription(); + dst = art->getDescriptionTranslated(); else dst = "#!#"; } @@ -91,7 +91,7 @@ void MetaString::getLocalString(const std::pair &txt, std::string &dst { auto art = ArtifactID(ser).toArtifact(VLC->artifacts()); if(art) - dst = art->getEventText(); + dst = art->getEventTranslated(); else dst = "#!#"; } @@ -1304,7 +1304,7 @@ void CGameState::prepareCrossoverHeroes(std::vectorartType->id; + int id = art->artType->getId(); assert( 8*18 > id );//number of arts that fits into h3m format bool takeable = travelOptions.artifsKeptByHero[id / 8] & ( 1 << (id%8) ); @@ -2891,7 +2891,7 @@ void CGameState::replaceHeroesPlaceholders(const std::vectorartType = VLC->arth->objects[art->artType->id]; + art->artType = VLC->arth->objects[art->artType->getId()]; gs->map->artInstances.push_back(art); art->id = ArtifactInstanceID((si32)gs->map->artInstances.size() - 1); }; diff --git a/lib/CStack.cpp b/lib/CStack.cpp index 45ad53d1f..0c2283aa0 100644 --- a/lib/CStack.cpp +++ b/lib/CStack.cpp @@ -365,7 +365,7 @@ bool CStack::unitHasAmmoCart(const battle::Unit * unit) const auto ownerHero = battle->battleGetOwnerHero(unit); if(ownerHero && ownerHero->artifactsWorn.find(ArtifactPosition::MACH2) != ownerHero->artifactsWorn.end()) { - if(battle->battleGetOwnerHero(unit)->artifactsWorn.at(ArtifactPosition::MACH2).artifact->artType->id == ArtifactID::AMMO_CART) + if(battle->battleGetOwnerHero(unit)->artifactsWorn.at(ArtifactPosition::MACH2).artifact->artType->getId() == ArtifactID::AMMO_CART) { return true; } diff --git a/lib/HeroBonus.cpp b/lib/HeroBonus.cpp index d85364e46..8c56f9f3c 100644 --- a/lib/HeroBonus.cpp +++ b/lib/HeroBonus.cpp @@ -1594,7 +1594,7 @@ std::string Bonus::Description() const switch(source) { case ARTIFACT: - str << ArtifactID(sid).toArtifact(VLC->artifacts())->getName(); + str << ArtifactID(sid).toArtifact(VLC->artifacts())->getNameTranslated(); break; case SPELL_EFFECT: str << SpellID(sid).toSpell(VLC->spells())->getNameTranslated(); diff --git a/lib/NetPacksLib.cpp b/lib/NetPacksLib.cpp index 88dcb408b..5d5cf5ea9 100644 --- a/lib/NetPacksLib.cpp +++ b/lib/NetPacksLib.cpp @@ -419,7 +419,7 @@ DLL_LINKAGE void RemoveObject::applyGs(CGameState *gs) beatenHero->tempOwner = PlayerColor::NEUTRAL; //no one owns beaten hero vstd::erase_if(beatenHero->artifactsInBackpack, [](const ArtSlotInfo& asi) { - return asi.artifact->artType->id == ArtifactID::GRAIL; + return asi.artifact->artType->getId() == ArtifactID::GRAIL; }); if(beatenHero->visitedTown) @@ -1061,7 +1061,7 @@ DLL_LINKAGE void EraseArtifact::applyGs(CGameState *gs) auto slot = al.getSlot(); if(slot->locked) { - logGlobal->debug("Erasing locked artifact: %s", slot->artifact->artType->getName()); + logGlobal->debug("Erasing locked artifact: %s", slot->artifact->artType->getNameTranslated()); DisassembledArtifact dis; dis.al.artHolder = al.artHolder; auto aset = al.getHolderArtSet(); @@ -1081,12 +1081,12 @@ DLL_LINKAGE void EraseArtifact::applyGs(CGameState *gs) } } assert(found && "Failed to determine the assembly this locked artifact belongs to"); - logGlobal->debug("Found the corresponding assembly: %s", dis.al.getSlot()->artifact->artType->getName()); + logGlobal->debug("Found the corresponding assembly: %s", dis.al.getSlot()->artifact->artType->getNameTranslated()); dis.applyGs(gs); } else { - logGlobal->debug("Erasing artifact %s", slot->artifact->artType->getName()); + logGlobal->debug("Erasing artifact %s", slot->artifact->artType->getNameTranslated()); } al.removeArtifact(); } @@ -1178,7 +1178,7 @@ DLL_LINKAGE void AssembledArtifact::applyGs(CGameState *gs) bool combineEquipped = !ArtifactUtils::isSlotBackpack(al.slot); assert(vstd::contains_if(transformedArt->assemblyPossibilities(artSet, combineEquipped), [=](const CArtifact * art)->bool { - return art->id == builtArt->id; + return art->getId() == builtArt->getId(); })); MAYBE_UNUSED(transformedArt); @@ -1187,8 +1187,8 @@ DLL_LINKAGE void AssembledArtifact::applyGs(CGameState *gs) // Retrieve all constituents for(const CArtifact * constituent : *builtArt->constituents) { - ArtifactPosition pos = combineEquipped ? artSet->getArtPos(constituent->id, true, false) : - artSet->getArtBackpackPos(constituent->id); + ArtifactPosition pos = combineEquipped ? artSet->getArtPos(constituent->getId(), true, false) : + artSet->getArtBackpackPos(constituent->getId()); assert(pos >= 0); CArtifactInstance * constituentInstance = artSet->getArt(pos); diff --git a/lib/mapObjects/CGMarket.cpp b/lib/mapObjects/CGMarket.cpp index 95687a963..9d1ee89f7 100644 --- a/lib/mapObjects/CGMarket.cpp +++ b/lib/mapObjects/CGMarket.cpp @@ -275,7 +275,7 @@ std::vector CGBlackMarket::availableItemsIds(EMarketMode::EMarketMode mode) std::vector ret; for(const CArtifact *a : artifacts) if(a) - ret.push_back(a->id); + ret.push_back(a->getId()); else ret.push_back(-1); return ret; diff --git a/lib/mapObjects/CGTownInstance.cpp b/lib/mapObjects/CGTownInstance.cpp index deae9b107..48ac932d4 100644 --- a/lib/mapObjects/CGTownInstance.cpp +++ b/lib/mapObjects/CGTownInstance.cpp @@ -1145,7 +1145,7 @@ std::vector CGTownInstance::availableItemsIds(EMarketMode::EMarketMode mode std::vector ret; for(const CArtifact *a : merchantArtifacts) if(a) - ret.push_back(a->id); + ret.push_back(a->getId()); else ret.push_back(-1); return ret; diff --git a/lib/mapObjects/CRewardableObject.cpp b/lib/mapObjects/CRewardableObject.cpp index 0b8e73f52..64ab68008 100644 --- a/lib/mapObjects/CRewardableObject.cpp +++ b/lib/mapObjects/CRewardableObject.cpp @@ -861,7 +861,7 @@ void CGOnceVisitable::initObj(CRandomGenerator & rand) info[0].reward.bonuses.push_back(bonus); info[0].limiter.numOfGrants = 1; info[0].message.addTxt(MetaString::ADVOB_TXT, 162); - info[0].message.addReplacement(VLC->arth->objects[info[0].reward.artifacts.back()]->getName()); + info[0].message.addReplacement(VLC->arth->objects[info[0].reward.artifacts.back()]->getNameTranslated()); } break; case Obj::WAGON: @@ -876,7 +876,7 @@ void CGOnceVisitable::initObj(CRandomGenerator & rand) loadRandomArtifact(rand, info[0], 10, 10, 0, 0); info[0].limiter.numOfGrants = 1; info[0].message.addTxt(MetaString::ADVOB_TXT, 155); - info[0].message.addReplacement(VLC->arth->objects[info[0].reward.artifacts.back()]->getName()); + info[0].message.addReplacement(VLC->arth->objects[info[0].reward.artifacts.back()]->getNameTranslated()); } else if(hlp < 90) //2 - 5 of non-gold resource { diff --git a/lib/mapObjects/MiscObjects.cpp b/lib/mapObjects/MiscObjects.cpp index 092f64537..85f568957 100644 --- a/lib/mapObjects/MiscObjects.cpp +++ b/lib/mapObjects/MiscObjects.cpp @@ -1320,7 +1320,7 @@ void CGArtifact::initObj(CRandomGenerator & rand) std::string CGArtifact::getObjectName() const { - return VLC->artifacts()->getByIndex(subID)->getName(); + return VLC->artifacts()->getByIndex(subID)->getNameTranslated(); } void CGArtifact::onHeroVisit(const CGHeroInstance * h) const @@ -1337,19 +1337,7 @@ void CGArtifact::onHeroVisit(const CGHeroInstance * h) const if(message.length()) iw.text << message; else - { - auto artifact = ArtifactID(subID).toArtifact(VLC->artifacts()); - - if((artifact != nullptr) && (!artifact->getEventText().empty())) - { - iw.text.addTxt(MetaString::ART_EVNTS, subID); - } - else //fix for mod artifacts with no event text - { - iw.text.addTxt(MetaString::ADVOB_TXT, 183); //% has found treasure - iw.text.addReplacement(h->getNameTranslated()); - } - } + iw.text.addTxt(MetaString::ART_EVNTS, subID); } break; case Obj::SPELL_SCROLL: diff --git a/lib/mapping/CMap.cpp b/lib/mapping/CMap.cpp index 63c15b15c..82aa93516 100644 --- a/lib/mapping/CMap.cpp +++ b/lib/mapping/CMap.cpp @@ -539,7 +539,7 @@ void CMap::checkForObjectives() switch (cond.condition) { case EventCondition::HAVE_ARTIFACT: - boost::algorithm::replace_first(event.onFulfill, "%s", VLC->arth->objects[cond.objectType]->getName()); + boost::algorithm::replace_first(event.onFulfill, "%s", VLC->arth->objects[cond.objectType]->getNameTranslated()); break; case EventCondition::HAVE_CREATURES: diff --git a/lib/mapping/MapFormatH3M.cpp b/lib/mapping/MapFormatH3M.cpp index 652f97ff0..4d8a0d0e6 100644 --- a/lib/mapping/MapFormatH3M.cpp +++ b/lib/mapping/MapFormatH3M.cpp @@ -679,7 +679,7 @@ void CMapLoaderH3M::readAllowedArtifacts() // combo if (artifact->constituents) { - map->allowedArtifact[artifact->id] = false; + map->allowedArtifact[artifact->getId()] = false; } } if (map->version == EMapFormat::ROE) diff --git a/lib/rmg/CMapGenerator.cpp b/lib/rmg/CMapGenerator.cpp index 9ed865dec..760204810 100644 --- a/lib/rmg/CMapGenerator.cpp +++ b/lib/rmg/CMapGenerator.cpp @@ -112,8 +112,8 @@ void CMapGenerator::initQuestArtsRemaining() { for (auto art : VLC->arth->objects) { - if (art->aClass == CArtifact::ART_TREASURE && VLC->arth->legalArtifact(art->id) && art->constituentOf.empty()) //don't use parts of combined artifacts - questArtifacts.push_back(art->id); + if (art->aClass == CArtifact::ART_TREASURE && VLC->arth->legalArtifact(art->getId()) && art->constituentOf.empty()) //don't use parts of combined artifacts + questArtifacts.push_back(art->getId()); } } diff --git a/lib/serializer/CSerializer.cpp b/lib/serializer/CSerializer.cpp index 153c0c22a..a7956651b 100644 --- a/lib/serializer/CSerializer.cpp +++ b/lib/serializer/CSerializer.cpp @@ -40,7 +40,7 @@ void CSerializer::addStdVecItems(CGameState *gs, LibClasses *lib) registerVectoredType(&lib->creh->objects, [](const CCreature &cre){ return cre.idNumber; }); registerVectoredType(&lib->arth->objects, - [](const CArtifact &art){ return art.id; }); + [](const CArtifact &art){ return art.getId(); }); registerVectoredType(&gs->map->artInstances, [](const CArtifactInstance &artInst){ return artInst.id; }); registerVectoredType(&gs->map->quests, diff --git a/mapeditor/inspector/questwidget.cpp b/mapeditor/inspector/questwidget.cpp index 953408c6a..747a9c7a7 100644 --- a/mapeditor/inspector/questwidget.cpp +++ b/mapeditor/inspector/questwidget.cpp @@ -68,7 +68,7 @@ void QuestWidget::obtainData() case CQuest::Emission::MISSION_ART: activeId = true; for(int i = 0; i < map.allowedArtifact.size(); ++i) - ui->targetId->addItem(QString::fromStdString(VLC->arth->objects.at(i)->getName())); + ui->targetId->addItem(QString::fromStdString(VLC->arth->objects.at(i)->getNameTranslated())); if(!seerhut.quest->m5arts.empty()) ui->targetId->setCurrentIndex(seerhut.quest->m5arts.front()); //TODO: support multiple artifacts diff --git a/mapeditor/inspector/rewardswidget.cpp b/mapeditor/inspector/rewardswidget.cpp index f6607aeb1..1210e7ce9 100644 --- a/mapeditor/inspector/rewardswidget.cpp +++ b/mapeditor/inspector/rewardswidget.cpp @@ -82,7 +82,7 @@ QList RewardsWidget::getListForType(RewardType typeId) for(int i = 0; i < map.allowedArtifact.size(); ++i) { if(map.allowedArtifact[i]) - result.append(QString::fromStdString(VLC->arth->objects.at(i)->getName())); + result.append(QString::fromStdString(VLC->arth->objects.at(i)->getNameTranslated())); } break; diff --git a/mapeditor/mapsettings.cpp b/mapeditor/mapsettings.cpp index 000318f0c..498f4c33a 100644 --- a/mapeditor/mapsettings.cpp +++ b/mapeditor/mapsettings.cpp @@ -50,7 +50,7 @@ MapSettings::MapSettings(MapController & ctrl, QWidget *parent) : } for(int i = 0; i < controller.map()->allowedArtifact.size(); ++i) { - auto * item = new QListWidgetItem(QString::fromStdString(VLC->arth->objects[i]->getName())); + auto * item = new QListWidgetItem(QString::fromStdString(VLC->arth->objects[i]->getNameTranslated())); item->setData(Qt::UserRole, QVariant::fromValue(i)); item->setFlags(item->flags() | Qt::ItemIsUserCheckable); item->setCheckState(controller.map()->allowedArtifact[i] ? Qt::Checked : Qt::Unchecked); diff --git a/server/CGameHandler.cpp b/server/CGameHandler.cpp index 2e67078bf..3a292acf2 100644 --- a/server/CGameHandler.cpp +++ b/server/CGameHandler.cpp @@ -774,7 +774,7 @@ void CGameHandler::endBattle(int3 tile, const CGHeroInstance * heroAttacker, con ma.src = ArtifactLocation(finishingBattle->loserHero, artSlot.first); const CArtifactInstance * art = ma.src.getArt(); if (art && !art->artType->isBig() && - art->artType->id != ArtifactID::SPELLBOOK) + art->artType->getId() != ArtifactID::SPELLBOOK) // don't move war machines or locked arts (spellbook) { sendMoveArtifact(art, &ma); @@ -787,7 +787,7 @@ void CGameHandler::endBattle(int3 tile, const CGHeroInstance * heroAttacker, con ma.src = ArtifactLocation(finishingBattle->loserHero, ArtifactPosition(GameConstants::BACKPACK_START)); //backpack automatically shifts arts to beginning const CArtifactInstance * art = ma.src.getArt(); - if (art->artType->id != ArtifactID::GRAIL) //grail may not be won + if (art->artType->getId() != ArtifactID::GRAIL) //grail may not be won { sendMoveArtifact(art, &ma); } @@ -834,8 +834,8 @@ void CGameHandler::endBattle(int3 tile, const CGHeroInstance * heroAttacker, con for (auto art : arts) //TODO; separate function to display loot for various ojects? { iw.components.push_back(Component( - Component::ARTIFACT, art->artType->id, - art->artType->id == ArtifactID::SPELL_SCROLL? art->getGivenSpellID() : 0, 0)); + Component::ARTIFACT, art->artType->getId(), + art->artType->getId() == ArtifactID::SPELL_SCROLL? art->getGivenSpellID() : 0, 0)); if (iw.components.size() >= 14) { sendAndApply(&iw); @@ -3917,7 +3917,7 @@ bool CGameHandler::moveArtifact(const ArtifactLocation &al1, const ArtifactLocat try { auto hero = boost::get>(dst.artHolder); - if(ArtifactUtils::checkSpellbookIsNeeded(hero, srcArtifact->artType->id, dst.slot)) + if(ArtifactUtils::checkSpellbookIsNeeded(hero, srcArtifact->artType->getId(), dst.slot)) giveHeroNewArtifact(hero, VLC->arth->objects[ArtifactID::SPELLBOOK], ArtifactPosition::SPELLBOOK); } catch (boost::bad_get const &) @@ -3964,7 +3964,7 @@ bool CGameHandler::bulkMoveArtifacts(ObjectInstanceID srcHero, ObjectInstanceID auto art = artifact.second.getArt(); assert(art); - if(ArtifactUtils::checkSpellbookIsNeeded(dstHero, art->artType->id, artifact.first)) + if(ArtifactUtils::checkSpellbookIsNeeded(dstHero, art->artType->getId(), artifact.first)) giveHeroNewArtifact(dstHero, VLC->arth->objects[ArtifactID::SPELLBOOK], ArtifactPosition::SPELLBOOK); } }; @@ -4001,7 +4001,7 @@ bool CGameHandler::bulkMoveArtifacts(ObjectInstanceID srcHero, ObjectInstanceID artFittingSet.putArtifact(dstSlot, static_cast>(artifact)); slotsSrcDst.push_back(BulkMoveArtifacts::LinkedSlots(srcSlot, dstSlot)); - if(ArtifactUtils::checkSpellbookIsNeeded(pdstHero, artifact->artType->id, dstSlot)) + if(ArtifactUtils::checkSpellbookIsNeeded(pdstHero, artifact->artType->getId(), dstSlot)) giveHeroNewArtifact(pdstHero, VLC->arth->objects[ArtifactID::SPELLBOOK], ArtifactPosition::SPELLBOOK); }; @@ -4144,7 +4144,7 @@ bool CGameHandler::buyArtifact(const IMarket *m, const CGHeroInstance *h, Res::E bool found = false; for (const CArtifact *&art : saa.arts) { - if (art && art->id == aid) + if (art && art->getId() == aid) { art = nullptr; found = true; @@ -4169,7 +4169,7 @@ bool CGameHandler::sellArtifact(const IMarket *m, const CGHeroInstance *h, Artif COMPLAIN_RET_FALSE_IF((!art->artType->isTradable()), "Cannot sell a war machine or spellbook!"); int resVal = 0, dump = 1; - m->getOffer(art->artType->id, rid, dump, resVal, EMarketMode::ARTIFACT_RESOURCE); + m->getOffer(art->artType->getId(), rid, dump, resVal, EMarketMode::ARTIFACT_RESOURCE); removeArtifact(ArtifactLocation(h, h->getArtPos(art))); giveResource(h->tempOwner, rid, resVal); @@ -6327,7 +6327,7 @@ bool CGameHandler::sacrificeArtifact(const IMarket * m, const CGHeroInstance * h COMPLAIN_RET("No artifact at position to sacrifice!"); } - si32 typId = art->artType->id; + si32 typId = art->artType->getId(); int dmp, expToGive; m->getOffer(typId, 0, dmp, expToGive, EMarketMode::ARTIFACT_EXP);