diff --git a/AI/Nullkiller/AIGateway.cpp b/AI/Nullkiller/AIGateway.cpp index 3cfd446b6..4689a4581 100644 --- a/AI/Nullkiller/AIGateway.cpp +++ b/AI/Nullkiller/AIGateway.cpp @@ -283,7 +283,7 @@ void AIGateway::heroExchangeStarted(ObjectInstanceID hero1, ObjectInstanceID her auto firstHero = cb->getHero(hero1); auto secondHero = cb->getHero(hero2); - status.addQuery(query, boost::str(boost::format("Exchange between heroes %s (%d) and %s (%d)") % firstHero->name % firstHero->tempOwner % secondHero->name % secondHero->tempOwner)); + status.addQuery(query, boost::str(boost::format("Exchange between heroes %s (%d) and %s (%d)") % firstHero->getNameTranslated() % firstHero->tempOwner % secondHero->getNameTranslated() % secondHero->tempOwner)); requestActionASAP([=]() { @@ -544,7 +544,7 @@ void AIGateway::heroGotLevel(const CGHeroInstance * hero, PrimarySkill::PrimaryS LOG_TRACE_PARAMS(logAi, "queryID '%i'", queryID); NET_EVENT_HANDLER; - status.addQuery(queryID, boost::str(boost::format("Hero %s got level %d") % hero->name % hero->level)); + status.addQuery(queryID, boost::str(boost::format("Hero %s got level %d") % hero->getNameTranslated() % hero->level)); HeroPtr hPtr = hero; requestActionASAP([=]() @@ -787,7 +787,7 @@ void AIGateway::makeTurn() for (auto h : cb->getHeroesInfo()) { if (h->movement) - logAi->warn("Hero %s has %d MP left", h->name, h->movement); + logAi->warn("Hero %s has %d MP left", h->getNameTranslated(), h->movement); } #if NKAI_TRACE_LEVEL == 0 } @@ -808,7 +808,7 @@ void AIGateway::makeTurn() void AIGateway::performObjectInteraction(const CGObjectInstance * obj, HeroPtr h) { - LOG_TRACE_PARAMS(logAi, "Hero %s and object %s at %s", h->name % obj->getObjectName() % obj->pos.toString()); + LOG_TRACE_PARAMS(logAi, "Hero %s and object %s at %s", h->getNameTranslated() % obj->getObjectName() % obj->pos.toString()); switch(obj->ID) { case Obj::CREATURE_GENERATOR1: @@ -1070,7 +1070,7 @@ void AIGateway::battleStart(const CCreatureSet * army1, const CCreatureSet * arm assert(playerID > PlayerColor::PLAYER_LIMIT || status.getBattle() == UPCOMING_BATTLE); status.setBattle(ONGOING_BATTLE); const CGObjectInstance * presumedEnemy = vstd::backOrNull(cb->getVisitableObjs(tile)); //may be nullptr in some very are cases -> eg. visited monolith and fighting with an enemy at the FoW covered exit - battlename = boost::str(boost::format("Starting battle of %s attacking %s at %s") % (hero1 ? hero1->name : "a army") % (presumedEnemy ? presumedEnemy->getObjectName() : "unknown enemy") % tile.toString()); + battlename = boost::str(boost::format("Starting battle of %s attacking %s at %s") % (hero1 ? hero1->getNameTranslated() : "a army") % (presumedEnemy ? presumedEnemy->getObjectName() : "unknown enemy") % tile.toString()); CAdventureAI::battleStart(army1, army2, tile, hero1, hero2, side); } @@ -1172,7 +1172,7 @@ bool AIGateway::moveHeroToTile(int3 dst, HeroPtr h) } }; - logAi->debug("Moving hero %s to tile %s", h->name, dst.toString()); + logAi->debug("Moving hero %s to tile %s", h->getNameTranslated(), dst.toString()); int3 startHpos = h->visitablePos(); bool ret = false; if(startHpos == dst) @@ -1192,7 +1192,7 @@ bool AIGateway::moveHeroToTile(int3 dst, HeroPtr h) cb->getPathsInfo(h.get())->getPath(path, dst); if(path.nodes.empty()) { - logAi->error("Hero %s cannot reach %s.", h->name, dst.toString()); + logAi->error("Hero %s cannot reach %s.", h->getNameTranslated(), dst.toString()); return true; } int i = (int)path.nodes.size() - 1; @@ -1344,7 +1344,7 @@ bool AIGateway::moveHeroToTile(int3 dst, HeroPtr h) throw cannotFulfillGoalException("Invalid path found!"); } - logAi->debug("Hero %s moved from %s to %s. Returning %d.", h->name, startHpos.toString(), h->visitablePos().toString(), ret); + logAi->debug("Hero %s moved from %s to %s. Returning %d.", h->getNameTranslated(), startHpos.toString(), h->visitablePos().toString(), ret); } return ret; } diff --git a/AI/Nullkiller/AIUtility.cpp b/AI/Nullkiller/AIUtility.cpp index 56c668ad2..86d25e84d 100644 --- a/AI/Nullkiller/AIUtility.cpp +++ b/AI/Nullkiller/AIUtility.cpp @@ -69,7 +69,7 @@ HeroPtr::HeroPtr(const CGHeroInstance * H) } h = H; - name = h->name; + name = h->getNameTranslated(); hid = H->id; // infosCount[ai->playerID][hid]++; } diff --git a/AI/Nullkiller/Analyzers/HeroManager.cpp b/AI/Nullkiller/Analyzers/HeroManager.cpp index 76abf65b9..92467c2cb 100644 --- a/AI/Nullkiller/Analyzers/HeroManager.cpp +++ b/AI/Nullkiller/Analyzers/HeroManager.cpp @@ -70,7 +70,7 @@ float HeroManager::evaluateSecSkill(SecondarySkill skill, const CGHeroInstance * float HeroManager::evaluateSpeciality(const CGHeroInstance * hero) const { - auto heroSpecial = Selector::source(Bonus::HERO_SPECIAL, hero->type->ID.getNum()); + auto heroSpecial = Selector::source(Bonus::HERO_SPECIAL, hero->type->getIndex()); auto secondarySkillBonus = Selector::type()(Bonus::SECONDARY_SKILL_PREMY); auto specialSecondarySkillBonuses = hero->getBonuses(heroSpecial.And(secondarySkillBonus)); float specialityScore = 0.0f; @@ -172,7 +172,7 @@ void HeroManager::update() for(auto hero : myHeroes) { - logAi->trace("Hero %s has role %s", hero->name, heroRoles[hero] == HeroRole::MAIN ? "main" : "scout"); + logAi->trace("Hero %s has role %s", hero->getNameTranslated(), heroRoles[hero] == HeroRole::MAIN ? "main" : "scout"); } } diff --git a/AI/Nullkiller/Behaviors/DefenceBehavior.cpp b/AI/Nullkiller/Behaviors/DefenceBehavior.cpp index 5ca3f1f4e..2ff3d1942 100644 --- a/AI/Nullkiller/Behaviors/DefenceBehavior.cpp +++ b/AI/Nullkiller/Behaviors/DefenceBehavior.cpp @@ -78,7 +78,7 @@ void DefenceBehavior::evaluateDefence(Goals::TGoalVec & tasks, const CGTownInsta logAi->trace( "Hero %s in garrison of town %s is suposed to defend the town", - town->garrisonHero->name, + town->garrisonHero->getNameTranslated(), town->name); return; @@ -101,7 +101,7 @@ void DefenceBehavior::evaluateDefence(Goals::TGoalVec & tasks, const CGTownInsta town->name, treat.danger, std::to_string(treat.turn), - treat.hero->name); + treat.hero->getNameTranslated()); bool treatIsUnderControl = false; diff --git a/AI/Nullkiller/Goals/AbstractGoal.cpp b/AI/Nullkiller/Goals/AbstractGoal.cpp index 9433dfad2..9798b8650 100644 --- a/AI/Nullkiller/Goals/AbstractGoal.cpp +++ b/AI/Nullkiller/Goals/AbstractGoal.cpp @@ -69,7 +69,7 @@ std::string AbstractGoal::toString() const //TODO: virtualize return boost::lexical_cast(goalType); } if(hero.get(true)) //FIXME: used to crash when we lost hero and failed goal - desc += " (" + hero->name + ")"; + desc += " (" + hero->getNameTranslated() + ")"; return desc; } diff --git a/AI/Nullkiller/Goals/AdventureSpellCast.cpp b/AI/Nullkiller/Goals/AdventureSpellCast.cpp index 8661f8cee..c5d44f577 100644 --- a/AI/Nullkiller/Goals/AdventureSpellCast.cpp +++ b/AI/Nullkiller/Goals/AdventureSpellCast.cpp @@ -33,7 +33,7 @@ void AdventureSpellCast::accept(AIGateway * ai) auto spell = getSpell(); - logAi->trace("Decomposing adventure spell cast of %s for hero %s", spell->getNameTranslated(), hero->name); + logAi->trace("Decomposing adventure spell cast of %s for hero %s", spell->getNameTranslated(), hero->getNameTranslated()); if(!spell->isAdventure()) throw cannotFulfillGoalException(spell->getNameTranslated() + " is not an adventure spell."); @@ -45,7 +45,7 @@ void AdventureSpellCast::accept(AIGateway * ai) throw cannotFulfillGoalException("Hero has not enough mana to cast " + spell->getNameTranslated()); if(spellID == SpellID::TOWN_PORTAL && town && town->visitingHero) - throw cannotFulfillGoalException("The town is already occupied by " + town->visitingHero->name); + throw cannotFulfillGoalException("The town is already occupied by " + town->visitingHero->getNameTranslated()); if(town && spellID == SpellID::TOWN_PORTAL) { diff --git a/AI/Nullkiller/Goals/ExchangeSwapTownHeroes.cpp b/AI/Nullkiller/Goals/ExchangeSwapTownHeroes.cpp index ff7ac5245..6ac8a6355 100644 --- a/AI/Nullkiller/Goals/ExchangeSwapTownHeroes.cpp +++ b/AI/Nullkiller/Goals/ExchangeSwapTownHeroes.cpp @@ -54,13 +54,13 @@ void ExchangeSwapTownHeroes::accept(AIGateway * ai) if(currentGarrisonHero.get() != town->visitingHero.get()) { - logAi->error("VisitingHero is empty, expected %s", currentGarrisonHero->name); + logAi->error("VisitingHero is empty, expected %s", currentGarrisonHero->getNameTranslated()); return; } ai->buildArmyIn(town); ai->nullkiller->unlockHero(currentGarrisonHero.get()); - logAi->debug("Extracted hero %s from garrison of %s", currentGarrisonHero->name, town->name); + logAi->debug("Extracted hero %s from garrison of %s", currentGarrisonHero->getNameTranslated(), town->name); return; } @@ -91,7 +91,7 @@ void ExchangeSwapTownHeroes::accept(AIGateway * ai) ai->makePossibleUpgrades(town->visitingHero); } - logAi->debug("Put hero %s to garrison of %s", garrisonHero->name, town->name); + logAi->debug("Put hero %s to garrison of %s", garrisonHero->getNameTranslated(), town->name); } } diff --git a/AI/Nullkiller/Goals/ExecuteHeroChain.cpp b/AI/Nullkiller/Goals/ExecuteHeroChain.cpp index c36cb7ee5..9f1839bf8 100644 --- a/AI/Nullkiller/Goals/ExecuteHeroChain.cpp +++ b/AI/Nullkiller/Goals/ExecuteHeroChain.cpp @@ -75,7 +75,7 @@ void ExecuteHeroChain::accept(AIGateway * ai) continue; } - logAi->debug("Executing chain node %d. Moving hero %s to %s", i, hero->name, node.coord.toString()); + logAi->debug("Executing chain node %d. Moving hero %s to %s", i, hero->getNameTranslated(), node.coord.toString()); try { @@ -111,7 +111,7 @@ void ExecuteHeroChain::accept(AIGateway * ai) { logAi->error( "Unable to complete chain. Expected hero %s to arrive to %s in 0 turns but he cannot do this", - hero->name, + hero->getNameTranslated(), node.coord.toString()); return; @@ -143,7 +143,7 @@ void ExecuteHeroChain::accept(AIGateway * ai) if(isOk && path.nodes.back().turns > 0) { - logAi->warn("Hero %s has %d mp which is not enough to continue his way towards %s.", hero->name, hero->movement, node.coord.toString()); + logAi->warn("Hero %s has %d mp which is not enough to continue his way towards %s.", hero->getNameTranslated(), hero->movement, node.coord.toString()); ai->nullkiller->lockHero(hero, HeroLockedReason::HERO_CHAIN); return; @@ -162,7 +162,7 @@ void ExecuteHeroChain::accept(AIGateway * ai) { logAi->error( "Enable to complete chain. Expected hero %s to arive to %s but he is at %s", - hero->name, + hero->getNameTranslated(), node.coord.toString(), hero->visitablePos().toString()); @@ -187,14 +187,14 @@ void ExecuteHeroChain::accept(AIGateway * ai) std::string ExecuteHeroChain::toString() const { - return "ExecuteHeroChain " + targetName + " by " + chainPath.targetHero->name; + return "ExecuteHeroChain " + targetName + " by " + chainPath.targetHero->getNameTranslated(); } bool ExecuteHeroChain::moveHeroToTile(const CGHeroInstance * hero, const int3 & tile) { if(tile == hero->visitablePos() && cb->getVisitableObjs(hero->visitablePos()).size() < 2) { - logAi->warn("Why do I want to move hero %s to tile %s? Already standing on that tile! ", hero->name, tile.toString()); + logAi->warn("Why do I want to move hero %s to tile %s? Already standing on that tile! ", hero->getNameTranslated(), tile.toString()); return true; } diff --git a/AI/Nullkiller/Pathfinding/AINodeStorage.cpp b/AI/Nullkiller/Pathfinding/AINodeStorage.cpp index 78dff15ec..7709dc0ad 100644 --- a/AI/Nullkiller/Pathfinding/AINodeStorage.cpp +++ b/AI/Nullkiller/Pathfinding/AINodeStorage.cpp @@ -1437,10 +1437,10 @@ std::string AIPath::toString() const { std::stringstream str; - str << targetHero->name << "[" << std::hex << chainMask << std::dec << "]" << ", turn " << (int)(turn()) << ": "; + str << targetHero->getNameTranslated() << "[" << std::hex << chainMask << std::dec << "]" << ", turn " << (int)(turn()) << ": "; for(auto node : nodes) - str << node.targetHero->name << "[" << std::hex << node.chainMask << std::dec << "]" << "->" << node.coord.toString() << "; "; + str << node.targetHero->getNameTranslated() << "[" << std::hex << node.chainMask << std::dec << "]" << "->" << node.coord.toString() << "; "; return str.str(); } diff --git a/AI/Nullkiller/Pathfinding/Actions/BuyArmyAction.cpp b/AI/Nullkiller/Pathfinding/Actions/BuyArmyAction.cpp index 3a15f7e4c..27d3b1cfa 100644 --- a/AI/Nullkiller/Pathfinding/Actions/BuyArmyAction.cpp +++ b/AI/Nullkiller/Pathfinding/Actions/BuyArmyAction.cpp @@ -27,7 +27,7 @@ namespace AIPathfinding if(!hero->visitedTown) { throw cannotFulfillGoalException( - hero->name + " being at " + hero->visitablePos().toString() + " has no town to recruit creatures."); + hero->getNameTranslated() + " being at " + hero->visitablePos().toString() + " has no town to recruit creatures."); } ai->recruitCreatures(hero->visitedTown, hero); diff --git a/AI/Nullkiller/Pathfinding/Actors.cpp b/AI/Nullkiller/Pathfinding/Actors.cpp index dcea063e1..9734d5655 100644 --- a/AI/Nullkiller/Pathfinding/Actors.cpp +++ b/AI/Nullkiller/Pathfinding/Actors.cpp @@ -80,7 +80,7 @@ int ChainActor::maxMovePoints(CGPathNode::ELayer layer) std::string ChainActor::toString() const { - return hero->name; + return hero->getNameTranslated(); } ObjectActor::ObjectActor(const CGObjectInstance * obj, const CCreatureSet * army, uint64_t chainMask, int initialTurn) diff --git a/AI/VCAI/AIUtility.cpp b/AI/VCAI/AIUtility.cpp index ffee1b621..69cfd3b7e 100644 --- a/AI/VCAI/AIUtility.cpp +++ b/AI/VCAI/AIUtility.cpp @@ -69,7 +69,7 @@ HeroPtr::HeroPtr(const CGHeroInstance * H) } h = H; - name = h->name; + name = h->getNameTranslated(); hid = H->id; // infosCount[ai->playerID][hid]++; } diff --git a/AI/VCAI/Goals/AbstractGoal.cpp b/AI/VCAI/Goals/AbstractGoal.cpp index 2021d5071..b197a894a 100644 --- a/AI/VCAI/Goals/AbstractGoal.cpp +++ b/AI/VCAI/Goals/AbstractGoal.cpp @@ -106,7 +106,7 @@ std::string AbstractGoal::name() const //TODO: virtualize return boost::lexical_cast(goalType); } if(hero.get(true)) //FIXME: used to crash when we lost hero and failed goal - desc += " (" + hero->name + ")"; + desc += " (" + hero->getNameTranslated() + ")"; return desc; } diff --git a/AI/VCAI/Goals/AdventureSpellCast.cpp b/AI/VCAI/Goals/AdventureSpellCast.cpp index 927eee3d1..d64c39c40 100644 --- a/AI/VCAI/Goals/AdventureSpellCast.cpp +++ b/AI/VCAI/Goals/AdventureSpellCast.cpp @@ -33,7 +33,7 @@ TSubgoal AdventureSpellCast::whatToDoToAchieve() auto spell = getSpell(); - logAi->trace("Decomposing adventure spell cast of %s for hero %s", spell->getName(), hero->name); + logAi->trace("Decomposing adventure spell cast of %s for hero %s", spell->getName(), hero->getNameTranslated()); if(!spell->isAdventure()) throw cannotFulfillGoalException(spell->getName() + " is not an adventure spell."); @@ -45,7 +45,7 @@ TSubgoal AdventureSpellCast::whatToDoToAchieve() throw cannotFulfillGoalException("Hero has not enough mana to cast " + spell->getName()); if(spellID == SpellID::TOWN_PORTAL && town && town->visitingHero) - throw cannotFulfillGoalException("The town is already occupied by " + town->visitingHero->name); + throw cannotFulfillGoalException("The town is already occupied by " + town->visitingHero->getNameTranslated()); return iAmElementar(); } diff --git a/AI/VCAI/Goals/CompleteQuest.cpp b/AI/VCAI/Goals/CompleteQuest.cpp index 57c2a62c4..9fc6a326f 100644 --- a/AI/VCAI/Goals/CompleteQuest.cpp +++ b/AI/VCAI/Goals/CompleteQuest.cpp @@ -92,7 +92,7 @@ TSubgoal CompleteQuest::whatToDoToAchieve() result->name(), result->tile.toString(), result->objid, - result->hero.validAndSet() ? result->hero->name : "not specified"); + result->hero.validAndSet() ? result->hero->getNameTranslated() : "not specified"); return result; } @@ -273,4 +273,4 @@ TGoalVec CompleteQuest::missionDestroyObj() const } return solutions; -} \ No newline at end of file +} diff --git a/AI/VCAI/Goals/Explore.cpp b/AI/VCAI/Goals/Explore.cpp index 14cdce7c4..89b97da1c 100644 --- a/AI/VCAI/Goals/Explore.cpp +++ b/AI/VCAI/Goals/Explore.cpp @@ -240,7 +240,7 @@ bool Explore::operator==(const Explore & other) const std::string Explore::completeMessage() const { - return "Hero " + hero.get()->name + " completed exploration"; + return "Hero " + hero.get()->getNameTranslated() + " completed exploration"; } TSubgoal Explore::whatToDoToAchieve() @@ -339,7 +339,7 @@ TGoalVec Explore::getAllPossibleSubgoals() { for(auto h : heroes) { - logAi->trace("Exploration searching for a new point for hero %s", h->name); + logAi->trace("Exploration searching for a new point for hero %s", h->getNameTranslated()); TSubgoal goal = explorationNewPoint(h); diff --git a/AI/VCAI/Goals/GatherArmy.cpp b/AI/VCAI/Goals/GatherArmy.cpp index e81a41413..d692944a3 100644 --- a/AI/VCAI/Goals/GatherArmy.cpp +++ b/AI/VCAI/Goals/GatherArmy.cpp @@ -33,7 +33,7 @@ bool GatherArmy::operator==(const GatherArmy & other) const std::string GatherArmy::completeMessage() const { - return "Hero " + hero.get()->name + " gathered army of value " + boost::lexical_cast(value); + return "Hero " + hero.get()->getNameTranslated() + " gathered army of value " + boost::lexical_cast(value); } TSubgoal GatherArmy::whatToDoToAchieve() diff --git a/AI/VCAI/Goals/GatherTroops.cpp b/AI/VCAI/Goals/GatherTroops.cpp index 642429dd7..9c70cba67 100644 --- a/AI/VCAI/Goals/GatherTroops.cpp +++ b/AI/VCAI/Goals/GatherTroops.cpp @@ -56,7 +56,7 @@ TSubgoal GatherTroops::whatToDoToAchieve() { if(getCreaturesCount(hero) >= this->value) { - logAi->trace("Completing GATHER_TROOPS by hero %s", hero->name); + logAi->trace("Completing GATHER_TROOPS by hero %s", hero->getNameTranslated()); throw goalFulfilledException(sptr(*this)); } diff --git a/AI/VCAI/Goals/VisitHero.cpp b/AI/VCAI/Goals/VisitHero.cpp index f0498db58..09ae2bba8 100644 --- a/AI/VCAI/Goals/VisitHero.cpp +++ b/AI/VCAI/Goals/VisitHero.cpp @@ -33,7 +33,7 @@ bool VisitHero::operator==(const VisitHero & other) const std::string VisitHero::completeMessage() const { - return "hero " + hero.get()->name + " visited hero " + boost::lexical_cast(objid); + return "hero " + hero.get()->getNameTranslated() + " visited hero " + boost::lexical_cast(objid); } TSubgoal VisitHero::whatToDoToAchieve() diff --git a/AI/VCAI/Goals/VisitObj.cpp b/AI/VCAI/Goals/VisitObj.cpp index 4cbfd1465..7ebaba442 100644 --- a/AI/VCAI/Goals/VisitObj.cpp +++ b/AI/VCAI/Goals/VisitObj.cpp @@ -33,7 +33,7 @@ bool VisitObj::operator==(const VisitObj & other) const std::string VisitObj::completeMessage() const { - return "hero " + hero.get()->name + " captured Object ID = " + boost::lexical_cast(objid); + return "hero " + hero.get()->getNameTranslated() + " captured Object ID = " + boost::lexical_cast(objid); } TGoalVec VisitObj::getAllPossibleSubgoals() diff --git a/AI/VCAI/Goals/VisitTile.cpp b/AI/VCAI/Goals/VisitTile.cpp index c53b90665..c804a2800 100644 --- a/AI/VCAI/Goals/VisitTile.cpp +++ b/AI/VCAI/Goals/VisitTile.cpp @@ -33,7 +33,7 @@ bool VisitTile::operator==(const VisitTile & other) const std::string VisitTile::completeMessage() const { - return "Hero " + hero.get()->name + " visited tile " + tile.toString(); + return "Hero " + hero.get()->getNameTranslated() + " visited tile " + tile.toString(); } TSubgoal VisitTile::whatToDoToAchieve() diff --git a/AI/VCAI/Pathfinding/AIPathfinder.cpp b/AI/VCAI/Pathfinding/AIPathfinder.cpp index bec15a66f..0b52a9ece 100644 --- a/AI/VCAI/Pathfinding/AIPathfinder.cpp +++ b/AI/VCAI/Pathfinding/AIPathfinder.cpp @@ -55,7 +55,7 @@ void AIPathfinder::updatePaths(std::vector heroes) auto calculatePaths = [&](const CGHeroInstance * hero, std::shared_ptr config) { - logAi->debug("Recalculate paths for %s", hero->name); + logAi->debug("Recalculate paths for %s", hero->getNameTranslated()); cb->calculatePaths(config); }; diff --git a/AI/VCAI/VCAI.cpp b/AI/VCAI/VCAI.cpp index 3f9f8143f..1842ee35b 100644 --- a/AI/VCAI/VCAI.cpp +++ b/AI/VCAI/VCAI.cpp @@ -303,7 +303,7 @@ void VCAI::heroExchangeStarted(ObjectInstanceID hero1, ObjectInstanceID hero2, Q auto firstHero = cb->getHero(hero1); auto secondHero = cb->getHero(hero2); - status.addQuery(query, boost::str(boost::format("Exchange between heroes %s (%d) and %s (%d)") % firstHero->name % firstHero->tempOwner % secondHero->name % secondHero->tempOwner)); + status.addQuery(query, boost::str(boost::format("Exchange between heroes %s (%d) and %s (%d)") % firstHero->getNameTranslated() % firstHero->tempOwner % secondHero->getNameTranslated() % secondHero->tempOwner)); requestActionASAP([=]() { @@ -617,7 +617,7 @@ void VCAI::heroGotLevel(const CGHeroInstance * hero, PrimarySkill::PrimarySkill { LOG_TRACE_PARAMS(logAi, "queryID '%i'", queryID); NET_EVENT_HANDLER; - status.addQuery(queryID, boost::str(boost::format("Hero %s got level %d") % hero->name % hero->level)); + status.addQuery(queryID, boost::str(boost::format("Hero %s got level %d") % hero->getNameTranslated() % hero->level)); requestActionASAP([=](){ answerQuery(queryID, 0); }); } @@ -814,7 +814,7 @@ void VCAI::makeTurn() for (auto h : cb->getHeroesInfo()) { if (h->movement) - logAi->warn("Hero %s has %d MP left", h->name, h->movement); + logAi->warn("Hero %s has %d MP left", h->getNameTranslated(), h->movement); } } catch (boost::thread_interrupted & e) @@ -1034,7 +1034,7 @@ void VCAI::mainLoop() void VCAI::performObjectInteraction(const CGObjectInstance * obj, HeroPtr h) { - LOG_TRACE_PARAMS(logAi, "Hero %s and object %s at %s", h->name % obj->getObjectName() % obj->pos.toString()); + LOG_TRACE_PARAMS(logAi, "Hero %s and object %s at %s", h->getNameTranslated() % obj->getObjectName() % obj->pos.toString()); switch(obj->ID) { case Obj::CREATURE_GENERATOR1: @@ -1427,7 +1427,7 @@ void VCAI::wander(HeroPtr h) { //TODO pick the truly best const CGTownInstance * t = *boost::max_element(townsNotReachable, compareReinforcements); - logAi->debug("%s can't reach any town, we'll try to make our way to %s at %s", h->name, t->name, t->visitablePos().toString()); + logAi->debug("%s can't reach any town, we'll try to make our way to %s at %s", h->getNameTranslated(), t->name, t->visitablePos().toString()); int3 pos1 = h->pos; striveToGoal(sptr(Goals::ClearWayTo(t->visitablePos()).sethero(h))); //TODO: drop "strive", add to mainLoop //if out hero is stuck, we may need to request another hero to clear the way we see @@ -1581,7 +1581,7 @@ void VCAI::battleStart(const CCreatureSet * army1, const CCreatureSet * army2, i assert(playerID > PlayerColor::PLAYER_LIMIT || status.getBattle() == UPCOMING_BATTLE); status.setBattle(ONGOING_BATTLE); const CGObjectInstance * presumedEnemy = vstd::backOrNull(cb->getVisitableObjs(tile)); //may be nullptr in some very are cases -> eg. visited monolith and fighting with an enemy at the FoW covered exit - battlename = boost::str(boost::format("Starting battle of %s attacking %s at %s") % (hero1 ? hero1->name : "a army") % (presumedEnemy ? presumedEnemy->getObjectName() : "unknown enemy") % tile.toString()); + battlename = boost::str(boost::format("Starting battle of %s attacking %s at %s") % (hero1 ? hero1->getNameTranslated() : "a army") % (presumedEnemy ? presumedEnemy->getObjectName() : "unknown enemy") % tile.toString()); CAdventureAI::battleStart(army1, army2, tile, hero1, hero2, side); } @@ -1667,7 +1667,7 @@ void VCAI::validateVisitableObjs() }); for(auto & p : reservedHeroesMap) { - errorMsg = " shouldn't be on list for hero " + p.first->name + "!"; + errorMsg = " shouldn't be on list for hero " + p.first->getNameTranslated() + "!"; vstd::erase_if(p.second, shouldBeErased); } @@ -1808,7 +1808,7 @@ bool VCAI::moveHeroToTile(int3 dst, HeroPtr h) } }; - logAi->debug("Moving hero %s to tile %s", h->name, dst.toString()); + logAi->debug("Moving hero %s to tile %s", h->getNameTranslated(), dst.toString()); int3 startHpos = h->visitablePos(); bool ret = false; if(startHpos == dst) @@ -1828,7 +1828,7 @@ bool VCAI::moveHeroToTile(int3 dst, HeroPtr h) cb->getPathsInfo(h.get())->getPath(path, dst); if(path.nodes.empty()) { - logAi->error("Hero %s cannot reach %s.", h->name, dst.toString()); + logAi->error("Hero %s cannot reach %s.", h->getNameTranslated(), dst.toString()); throw goalFulfilledException(sptr(Goals::VisitTile(dst).sethero(h))); } int i = (int)path.nodes.size() - 1; @@ -1990,7 +1990,7 @@ bool VCAI::moveHeroToTile(int3 dst, HeroPtr h) throw cannotFulfillGoalException("Invalid path found!"); } evaluateGoal(h); //new hero position means new game situation - logAi->debug("Hero %s moved from %s to %s. Returning %d.", h->name, startHpos.toString(), h->visitablePos().toString(), ret); + logAi->debug("Hero %s moved from %s to %s. Returning %d.", h->getNameTranslated(), startHpos.toString(), h->visitablePos().toString(), ret); } return ret; } @@ -2027,7 +2027,7 @@ void VCAI::tryRealize(Goals::VisitTile & g) throw cannotFulfillGoalException("Cannot visit tile: hero is out of MPs!"); if(g.tile == g.hero->visitablePos() && cb->getVisitableObjs(g.hero->visitablePos()).size() < 2) { - logAi->warn("Why do I want to move hero %s to tile %s? Already standing on that tile! ", g.hero->name, g.tile.toString()); + logAi->warn("Why do I want to move hero %s to tile %s? Already standing on that tile! ", g.hero->getNameTranslated(), g.tile.toString()); throw goalFulfilledException(sptr(g)); } if(ai->moveHeroToTile(g.tile, g.hero.get())) @@ -2043,7 +2043,7 @@ void VCAI::tryRealize(Goals::VisitObj & g) throw cannotFulfillGoalException("Cannot visit object: hero is out of MPs!"); if(position == g.hero->visitablePos() && cb->getVisitableObjs(g.hero->visitablePos()).size() < 2) { - logAi->warn("Why do I want to move hero %s to tile %s? Already standing on that tile! ", g.hero->name, g.tile.toString()); + logAi->warn("Why do I want to move hero %s to tile %s? Already standing on that tile! ", g.hero->getNameTranslated(), g.tile.toString()); throw goalFulfilledException(sptr(g)); } if(ai->moveHeroToTile(position, g.hero.get())) @@ -2404,7 +2404,7 @@ void VCAI::performTypicalActions() if(!h) //hero might be lost. getUnblockedHeroes() called once on start of turn continue; - logAi->debug("Hero %s started wandering, MP=%d", h->name.c_str(), h->movement); + logAi->debug("Hero %s started wandering, MP=%d", h->getNameTranslated(), h->movement); makePossibleUpgrades(*h); pickBestArtifacts(*h); try diff --git a/client/CPlayerInterface.cpp b/client/CPlayerInterface.cpp index f0b364e4f..03616dc55 100644 --- a/client/CPlayerInterface.cpp +++ b/client/CPlayerInterface.cpp @@ -410,7 +410,7 @@ void CPlayerInterface::heroMoved(const TryMoveHero & details, bool verbose) void CPlayerInterface::heroKilled(const CGHeroInstance* hero) { EVENT_HANDLER_CALLED_BY_CLIENT; - LOG_TRACE_PARAMS(logGlobal, "Hero %s killed handler for player %s", hero->name % playerID); + LOG_TRACE_PARAMS(logGlobal, "Hero %s killed handler for player %s", hero->getNameTranslated() % playerID); const CArmedInstance *newSelection = nullptr; if (makingTurn) @@ -1268,7 +1268,7 @@ template void CPlayerInterface::serializeTempl( Handler &h, c if (p.second.nodes.size()) pathsMap[p.first] = p.second.endPos(); else - logGlobal->debug("%s has assigned an empty path! Ignoring it...", p.first->name); + logGlobal->debug("%s has assigned an empty path! Ignoring it...", p.first->getNameTranslated()); } h & pathsMap; } diff --git a/client/ClientCommandManager.cpp b/client/ClientCommandManager.cpp index e75688489..3113b4342 100644 --- a/client/ClientCommandManager.cpp +++ b/client/ClientCommandManager.cpp @@ -317,7 +317,7 @@ void ClientCommandManager::processCommand(const std::string &message, bool calle if(what == "hs") { for(const CGHeroInstance *h : LOCPLINT->cb->getHeroesInfo()) - if(h->type->ID.getNum() == id1) + if(h->type->getIndex() == id1) if(const CArtifactInstance *a = h->getArt(ArtifactPosition(id2))) printCommandMessage(a->nodeName()); } @@ -491,4 +491,4 @@ void ClientCommandManager::printCommandMessage(const std::string &commandMessage LOCPLINT->cingconsole->print(commandMessage); } } -} \ No newline at end of file +} diff --git a/client/battle/BattleInterfaceClasses.cpp b/client/battle/BattleInterfaceClasses.cpp index cad232cde..f6c4415df 100644 --- a/client/battle/BattleInterfaceClasses.cpp +++ b/client/battle/BattleInterfaceClasses.cpp @@ -613,7 +613,7 @@ BattleResultWindow::BattleResultWindow(const BattleResult & br, CPlayerInterface if (ourHero) { str += CGI->generaltexth->allTexts[305]; - boost::algorithm::replace_first(str, "%s", ourHero->name); + boost::algorithm::replace_first(str, "%s", ourHero->getNameTranslated()); boost::algorithm::replace_first(str, "%d", boost::lexical_cast(br.exp[weAreAttacker ? 0 : 1])); } diff --git a/client/battle/BattleWindow.cpp b/client/battle/BattleWindow.cpp index e12501cc9..c0f0b0ee0 100644 --- a/client/battle/BattleWindow.cpp +++ b/client/battle/BattleWindow.cpp @@ -274,10 +274,10 @@ void BattleWindow::bFleef() //calculating fleeing hero's name if (owner.attackingHeroInstance) if (owner.attackingHeroInstance->tempOwner == owner.curInt->cb->getMyColor()) - heroName = owner.attackingHeroInstance->name; + heroName = owner.attackingHeroInstance->getNameTranslated(); if (owner.defendingHeroInstance) if (owner.defendingHeroInstance->tempOwner == owner.curInt->cb->getMyColor()) - heroName = owner.defendingHeroInstance->name; + heroName = owner.defendingHeroInstance->getNameTranslated(); //calculating text auto txt = boost::format(CGI->generaltexth->allTexts[340]) % heroName; //The Shackles of War are present. %s can not retreat! @@ -416,7 +416,7 @@ void BattleWindow::bSpellf() const auto artID = ArtifactID(blockingBonus->sid); //If we have artifact, put name of our hero. Otherwise assume it's the enemy. //TODO check who *really* is source of bonus - std::string heroName = myHero->hasArt(artID) ? myHero->name : owner.enemyHero().name; + std::string heroName = myHero->hasArt(artID) ? myHero->getNameTranslated() : owner.enemyHero().name; //%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]) diff --git a/client/lobby/CBonusSelection.cpp b/client/lobby/CBonusSelection.cpp index e89efd322..023fd1183 100644 --- a/client/lobby/CBonusSelection.cpp +++ b/client/lobby/CBonusSelection.cpp @@ -318,7 +318,7 @@ void CBonusSelection::createBonusesIcons() } else { - boost::algorithm::replace_first(desc, "%s", CGI->heroh->objects[bonDescs[i].info2]->name); + boost::algorithm::replace_first(desc, "%s", CGI->heroh->objects[bonDescs[i].info2]->getNameTranslated()); } break; } diff --git a/client/lobby/OptionsTab.cpp b/client/lobby/OptionsTab.cpp index 6637d81d0..27563fade 100644 --- a/client/lobby/OptionsTab.cpp +++ b/client/lobby/OptionsTab.cpp @@ -201,7 +201,7 @@ std::string OptionsTab::CPlayerSettingsHelper::getName() if(!settings.heroName.empty()) return settings.heroName; auto index = settings.hero >= CGI->heroh->size() ? 0 : settings.hero; - return (*CGI->heroh)[index]->name; + return (*CGI->heroh)[index]->getNameTranslated(); } } } @@ -257,7 +257,7 @@ std::string OptionsTab::CPlayerSettingsHelper::getSubtitle() case HERO: { if(settings.hero >= 0) - return getName() + " - " + (*CGI->heroh)[heroIndex]->heroClass->name; + return getName() + " - " + (*CGI->heroh)[heroIndex]->heroClass->getNameTranslated(); return getName(); } @@ -398,7 +398,7 @@ void OptionsTab::CPlayerOptionTooltipBox::genHeroWindow() auto heroIndex = settings.hero >= CGI->heroh->size() ? 0 : settings.hero; imageSpeciality = std::make_shared("UN44", (*CGI->heroh)[heroIndex]->imageIndex, 0, pos.w / 2 - 22, 134); - labelSpecialityName = std::make_shared(pos.w / 2, 188, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, (*CGI->heroh)[heroIndex]->specName); + labelSpecialityName = std::make_shared(pos.w / 2, 188, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, (*CGI->heroh)[heroIndex]->getSpecialtyNameTranslated()); } void OptionsTab::CPlayerOptionTooltipBox::genBonusWindow() diff --git a/client/mapHandler.cpp b/client/mapHandler.cpp index 215781521..b7341d068 100644 --- a/client/mapHandler.cpp +++ b/client/mapHandler.cpp @@ -960,7 +960,7 @@ CMapHandler::AnimBitmapHolder CMapHandler::CMapBlitter::findHeroBitmap(const CGH { if(hero->tempOwner >= PlayerColor::PLAYER_LIMIT) //Neutral hero? { - logGlobal->error("A neutral hero (%s) at %s. Should not happen!", hero->name, hero->pos.toString()); + logGlobal->error("A neutral hero (%s) at %s. Should not happen!", hero->getNameTranslated(), hero->pos.toString()); return CMapHandler::AnimBitmapHolder(); } diff --git a/client/widgets/AdventureMapClasses.cpp b/client/widgets/AdventureMapClasses.cpp index 9a6bd3443..6fabf2e1a 100644 --- a/client/widgets/AdventureMapClasses.cpp +++ b/client/widgets/AdventureMapClasses.cpp @@ -242,7 +242,7 @@ void CHeroList::CHeroItem::showTooltip() std::string CHeroList::CHeroItem::getHoverText() { - return boost::str(boost::format(CGI->generaltexth->allTexts[15]) % hero->name % hero->type->heroClass->name); + return boost::str(boost::format(CGI->generaltexth->allTexts[15]) % hero->getNameTranslated() % hero->type->heroClass->getNameTranslated()); } std::shared_ptr CHeroList::createHeroItem(size_t index) diff --git a/client/windows/CCastleInterface.cpp b/client/windows/CCastleInterface.cpp index 3fd14ce7b..dfd288945 100644 --- a/client/windows/CCastleInterface.cpp +++ b/client/windows/CCastleInterface.cpp @@ -353,25 +353,25 @@ void CHeroGSlot::hover(bool on) if(isSelected())//view NNN { temp = CGI->generaltexth->tcommands[4]; - boost::algorithm::replace_first(temp,"%s",hero->name); + boost::algorithm::replace_first(temp,"%s",hero->getNameTranslated()); } else if(other->hero && other->isSelected())//exchange { temp = CGI->generaltexth->tcommands[7]; - boost::algorithm::replace_first(temp,"%s",hero->name); - boost::algorithm::replace_first(temp,"%s",other->hero->name); + boost::algorithm::replace_first(temp,"%s",hero->getNameTranslated()); + boost::algorithm::replace_first(temp,"%s",other->hero->getNameTranslated()); } else// select NNN (in ZZZ) { if(upg)//down - visiting { temp = CGI->generaltexth->tcommands[32]; - boost::algorithm::replace_first(temp,"%s",hero->name); + boost::algorithm::replace_first(temp,"%s",hero->getNameTranslated()); } else //up - garrison { temp = CGI->generaltexth->tcommands[12]; - boost::algorithm::replace_first(temp,"%s",hero->name); + boost::algorithm::replace_first(temp,"%s",hero->getNameTranslated()); } } } @@ -380,7 +380,7 @@ void CHeroGSlot::hover(bool on) if(other->isSelected() && other->hero) //move NNNN { temp = CGI->generaltexth->tcommands[6]; - boost::algorithm::replace_first(temp,"%s",other->hero->name); + boost::algorithm::replace_first(temp,"%s",other->hero->getNameTranslated()); } else //empty { diff --git a/client/windows/CHeroWindow.cpp b/client/windows/CHeroWindow.cpp index 39401c45e..afc4ed853 100644 --- a/client/windows/CHeroWindow.cpp +++ b/client/windows/CHeroWindow.cpp @@ -211,19 +211,19 @@ void CHeroWindow::update(const CGHeroInstance * hero, bool redrawNeeded) assert(hero == curHero); - name->setText(curHero->name); - title->setText((boost::format(CGI->generaltexth->allTexts[342]) % curHero->level % curHero->type->heroClass->name).str()); + name->setText(curHero->getNameTranslated()); + title->setText((boost::format(CGI->generaltexth->allTexts[342]) % curHero->level % curHero->type->heroClass->getNameTranslated()).str()); - specArea->text = curHero->type->specDescr; + specArea->text = curHero->type->getSpecialtyDescriptionTranslated(); specImage->setFrame(curHero->type->imageIndex); - specName->setText(curHero->type->specName); + specName->setText(curHero->type->getSpecialtyNameTranslated()); tacticsButton = std::make_shared(Point(539, 483), "hsbtns8.def", std::make_pair(heroscrn[26], heroscrn[31]), 0, SDLK_b); tacticsButton->addHoverText(CButton::HIGHLIGHTED, CGI->generaltexth->heroscrn[25]); - dismissButton->addHoverText(CButton::NORMAL, boost::str(boost::format(CGI->generaltexth->heroscrn[16]) % curHero->name % curHero->type->heroClass->name)); - portraitArea->hoverText = boost::str(boost::format(CGI->generaltexth->allTexts[15]) % curHero->name % curHero->type->heroClass->name); - portraitArea->text = curHero->getBiography(); + dismissButton->addHoverText(CButton::NORMAL, boost::str(boost::format(CGI->generaltexth->heroscrn[16]) % curHero->getNameTranslated() % curHero->type->heroClass->getNameTranslated())); + portraitArea->hoverText = boost::str(boost::format(CGI->generaltexth->allTexts[15]) % curHero->getNameTranslated() % curHero->type->heroClass->getNameTranslated()); + portraitArea->text = curHero->getBiographyTranslated(); portraitImage->setFrame(curHero->portrait); { @@ -291,7 +291,7 @@ void CHeroWindow::update(const CGHeroInstance * hero, bool redrawNeeded) //printing spell points, boost::format can't be used due to locale issues spellPointsArea->text = CGI->generaltexth->allTexts[205]; - boost::replace_first(spellPointsArea->text, "%s", boost::lexical_cast(curHero->name)); + boost::replace_first(spellPointsArea->text, "%s", boost::lexical_cast(curHero->getNameTranslated())); boost::replace_first(spellPointsArea->text, "%d", boost::lexical_cast(curHero->mana)); boost::replace_first(spellPointsArea->text, "%d", boost::lexical_cast(heroWArt.manaLimit())); diff --git a/client/windows/CKingdomInterface.cpp b/client/windows/CKingdomInterface.cpp index fc4729c66..7598ff1b1 100644 --- a/client/windows/CKingdomInterface.cpp +++ b/client/windows/CKingdomInterface.cpp @@ -163,7 +163,7 @@ std::string InfoBoxAbstractHeroData::getNameText() case HERO_EXPERIENCE: return CGI->generaltexth->jktexts[6]; case HERO_SPECIAL: - return CGI->heroh->objects[getSubID()]->specName; + return CGI->heroh->objects[getSubID()]->getSpecialtyNameTranslated(); case HERO_SECONDARY_SKILL: if (getValue()) return CGI->skillh->getByIndex(getSubID())->getNameTranslated(); @@ -256,7 +256,7 @@ void InfoBoxAbstractHeroData::prepareMessage(std::string & text, std::shared_ptr switch (type) { case HERO_SPECIAL: - text = CGI->heroh->objects[getSubID()]->specDescr; + text = CGI->heroh->objects[getSubID()]->getSpecialtyDescriptionTranslated(); break; case HERO_PRIMARY_SKILL: text = CGI->generaltexth->arraytxt[2+getSubID()]; @@ -303,7 +303,7 @@ int InfoBoxHeroData::getSubID() else return 0; case HERO_SPECIAL: - return hero->type->ID.getNum(); + return hero->type->getIndex(); case HERO_MANA: case HERO_EXPERIENCE: return 0; @@ -390,7 +390,7 @@ void InfoBoxHeroData::prepareMessage(std::string & text, std::shared_ptrgeneraltexth->allTexts[205]; - boost::replace_first(text, "%s", boost::lexical_cast(hero->name)); + boost::replace_first(text, "%s", boost::lexical_cast(hero->getNameTranslated())); boost::replace_first(text, "%d", boost::lexical_cast(hero->mana)); boost::replace_first(text, "%d", boost::lexical_cast(hero->manaLimit())); break; @@ -863,7 +863,7 @@ CHeroItem::CHeroItem(const CGHeroInstance * Hero) arts2->recActions = SHARE_POS; backpack->recActions = SHARE_POS; - name = std::make_shared(75, 7, FONT_SMALL, ETextAlignment::TOPLEFT, Colors::WHITE, hero->name); + name = std::make_shared(75, 7, FONT_SMALL, ETextAlignment::TOPLEFT, Colors::WHITE, hero->getNameTranslated()); //layout is not trivial: MACH4 - catapult - excluded, MISC[x] rearranged assert(arts1->arts.size() == 9); @@ -919,7 +919,7 @@ CHeroItem::CHeroItem(const CGHeroInstance * Hero) portrait = std::make_shared("PortraitsLarge", hero->portrait, 0, 5, 6); heroArea = std::make_shared(5, 6, hero); - name = std::make_shared(73, 7, FONT_SMALL, ETextAlignment::TOPLEFT, Colors::WHITE, hero->name); + name = std::make_shared(73, 7, FONT_SMALL, ETextAlignment::TOPLEFT, Colors::WHITE, hero->getNameTranslated()); artsText = std::make_shared(320, 55, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, CGI->generaltexth->overview[2]); for(size_t i=0; i(152, 102, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, boost::str(boost::format(CGI->generaltexth->allTexts[272]) % hero->name))); + labels.push_back(std::make_shared(152, 102, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, boost::str(boost::format(CGI->generaltexth->allTexts[272]) % hero->getNameTranslated()))); break; case EMarketMode::ARTIFACT_RESOURCE: //%s's Artifacts - labels.push_back(std::make_shared(152, 56, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, boost::str(boost::format(CGI->generaltexth->allTexts[271]) % hero->name))); + labels.push_back(std::make_shared(152, 56, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, boost::str(boost::format(CGI->generaltexth->allTexts[271]) % hero->getNameTranslated()))); break; } @@ -1099,7 +1099,7 @@ CAltarWindow::CAltarWindow(const IMarket * Market, const CGHeroInstance * Hero, { //%s's Creatures labels.push_back(std::make_shared(155, 30, FONT_SMALL, ETextAlignment::CENTER, Colors::YELLOW, - boost::str(boost::format(CGI->generaltexth->allTexts[272]) % hero->name))); + boost::str(boost::format(CGI->generaltexth->allTexts[272]) % hero->getNameTranslated()))); //Altar of Sacrifice labels.push_back(std::make_shared(450, 30, FONT_SMALL, ETextAlignment::CENTER, Colors::YELLOW, CGI->generaltexth->allTexts[479])); diff --git a/client/windows/GUIClasses.cpp b/client/windows/GUIClasses.cpp index 3fd6a588b..558145a37 100644 --- a/client/windows/GUIClasses.cpp +++ b/client/windows/GUIClasses.cpp @@ -404,11 +404,11 @@ CLevelWindow::CLevelWindow(const CGHeroInstance * hero, PrimarySkill::PrimarySki ok = std::make_shared(Point(297, 413), "IOKAY", CButton::tooltip(), std::bind(&CLevelWindow::close, this), SDLK_RETURN); //%s has gained a level. - mainTitle = std::make_shared(192, 33, FONT_MEDIUM, ETextAlignment::CENTER, Colors::WHITE, boost::str(boost::format(CGI->generaltexth->allTexts[444]) % hero->name)); + mainTitle = std::make_shared(192, 33, FONT_MEDIUM, ETextAlignment::CENTER, Colors::WHITE, boost::str(boost::format(CGI->generaltexth->allTexts[444]) % hero->getNameTranslated())); //%s is now a level %d %s. levelTitle = std::make_shared(192, 162, FONT_MEDIUM, ETextAlignment::CENTER, Colors::WHITE, - boost::str(boost::format(CGI->generaltexth->allTexts[445]) % hero->name % hero->level % hero->type->heroClass->name)); + boost::str(boost::format(CGI->generaltexth->allTexts[445]) % hero->getNameTranslated() % hero->level % hero->type->heroClass->getNameTranslated())); skillIcon = std::make_shared("PSKIL42", pskill, 0, 174, 190); @@ -743,7 +743,7 @@ void CTavernWindow::show(SDL_Surface * to) oldSelected = selected; //Recruit %s the %s - recruit->addHoverText(CButton::NORMAL, boost::str(boost::format(CGI->generaltexth->tavernInfo[3]) % sel->h->name % sel->h->type->heroClass->name)); + recruit->addHoverText(CButton::NORMAL, boost::str(boost::format(CGI->generaltexth->tavernInfo[3]) % sel->h->getNameTranslated() % sel->h->type->heroClass->getNameTranslated())); } printAtMiddleWBLoc(sel->description, 146, 395, FONT_SMALL, 200, Colors::WHITE, to); @@ -777,7 +777,7 @@ CTavernWindow::HeroPortrait::HeroPortrait(int & sel, int id, int x, int y, const if(H) { hoverName = CGI->generaltexth->tavernInfo[4]; - boost::algorithm::replace_first(hoverName,"%s",H->name); + boost::algorithm::replace_first(hoverName,"%s",H->getNameTranslated()); int artifs = (int)h->artifactsWorn.size() + (int)h->artifactsInBackpack.size(); for(int i=13; i<=17; i++) //war machines and spellbook don't count @@ -785,9 +785,9 @@ CTavernWindow::HeroPortrait::HeroPortrait(int & sel, int id, int x, int y, const artifs--; description = CGI->generaltexth->allTexts[215]; - boost::algorithm::replace_first(description, "%s", h->name); + boost::algorithm::replace_first(description, "%s", h->getNameTranslated()); boost::algorithm::replace_first(description, "%d", boost::lexical_cast(h->level)); - boost::algorithm::replace_first(description, "%s", h->type->heroClass->name); + boost::algorithm::replace_first(description, "%s", h->type->heroClass->getNameTranslated()); boost::algorithm::replace_first(description, "%d", boost::lexical_cast(artifs)); portrait = std::make_shared("portraitsLarge", h->portrait); @@ -1078,7 +1078,7 @@ CExchangeWindow::CExchangeWindow(ObjectInstanceID hero1, ObjectInstanceID hero2, auto genTitle = [](const CGHeroInstance * h) { boost::format fmt(CGI->generaltexth->allTexts[138]); - fmt % h->name % h->level % h->type->heroClass->name; + fmt % h->getNameTranslated() % h->level % h->type->heroClass->getNameTranslated(); return boost::str(fmt); }; @@ -1178,7 +1178,7 @@ CExchangeWindow::CExchangeWindow(ObjectInstanceID hero1, ObjectInstanceID hero2, specialtyAreas[b] = std::make_shared(); specialtyAreas[b]->pos = genRect(32, 32, pos.x + 69 + 490*b, pos.y + (qeLayout ? 41 : 45)); specialtyAreas[b]->hoverText = CGI->generaltexth->heroscrn[27]; - specialtyAreas[b]->text = hero->type->specDescr; + specialtyAreas[b]->text = hero->type->getSpecialtyDescriptionTranslated(); experienceAreas[b] = std::make_shared(); experienceAreas[b]->pos = genRect(32, 32, pos.x + 105 + 490*b, pos.y + (qeLayout ? 41 : 45)); @@ -1192,7 +1192,7 @@ CExchangeWindow::CExchangeWindow(ObjectInstanceID hero1, ObjectInstanceID hero2, spellPointsAreas[b]->pos = genRect(32, 32, pos.x + 141 + 490*b, pos.y + (qeLayout ? 41 : 45)); spellPointsAreas[b]->hoverText = CGI->generaltexth->heroscrn[22]; spellPointsAreas[b]->text = CGI->generaltexth->allTexts[205]; - boost::algorithm::replace_first(spellPointsAreas[b]->text, "%s", hero->name); + boost::algorithm::replace_first(spellPointsAreas[b]->text, "%s", hero->getNameTranslated()); boost::algorithm::replace_first(spellPointsAreas[b]->text, "%d", boost::lexical_cast(hero->mana)); boost::algorithm::replace_first(spellPointsAreas[b]->text, "%d", boost::lexical_cast(hero->manaLimit())); diff --git a/include/vcmi/HeroClass.h b/include/vcmi/HeroClass.h index 5440910e0..3f6c47c53 100644 --- a/include/vcmi/HeroClass.h +++ b/include/vcmi/HeroClass.h @@ -18,7 +18,11 @@ class HeroClassID; class DLL_LINKAGE HeroClass : public EntityT { + using EntityT::getName; public: + virtual std::string getNameTranslated() const = 0; + virtual std::string getNameTextID() const = 0; + }; diff --git a/include/vcmi/HeroType.h b/include/vcmi/HeroType.h index 664a370ec..3df57b24b 100644 --- a/include/vcmi/HeroType.h +++ b/include/vcmi/HeroType.h @@ -18,7 +18,19 @@ class HeroTypeID; class DLL_LINKAGE HeroType : public EntityT { + using EntityT::getName; public: + virtual std::string getNameTranslated() const = 0; + virtual std::string getBiographyTranslated() const = 0; + virtual std::string getSpecialtyNameTranslated() const = 0; + virtual std::string getSpecialtyDescriptionTranslated() const = 0; + virtual std::string getSpecialtyTooltipTranslated() const = 0; + + virtual std::string getNameTextID() const = 0; + virtual std::string getBiographyTextID() const = 0; + virtual std::string getSpecialtyNameTextID() const = 0; + virtual std::string getSpecialtyDescriptionTextID() const = 0; + virtual std::string getSpecialtyTooltipTextID() const = 0; }; diff --git a/lib/CGameState.cpp b/lib/CGameState.cpp index 202d73036..3f72410a7 100644 --- a/lib/CGameState.cpp +++ b/lib/CGameState.cpp @@ -1451,7 +1451,7 @@ void CGameState::initHeroes() hero->initHero(getRandomGenerator()); getPlayerState(hero->getOwner())->heroes.push_back(hero); - map->allHeroes[hero->type->ID.getNum()] = hero; + map->allHeroes[hero->type->getIndex()] = hero; } for(auto obj : map->objects) //prisons @@ -1468,7 +1468,7 @@ void CGameState::initHeroes() ph->initHero(getRandomGenerator()); hpool.heroesPool[ph->subID] = ph; hpool.pavailable[ph->subID] = 0xff; - heroesToCreate.erase(ph->type->ID); + heroesToCreate.erase(ph->type->getId()); map->allHeroes[ph->subID] = ph; } @@ -2796,7 +2796,7 @@ std::set CGameState::getUnusedAllowedHeroes(bool alsoIncludeNotAllow for(auto hero : map->heroesOnMap) //heroes instances initialization { if(hero->type) - ret -= hero->type->ID; + ret -= hero->type->getId(); else ret -= HeroTypeID(hero->subID); } @@ -2918,7 +2918,7 @@ CGHeroInstance * CGameState::getUsedHero(HeroTypeID hid) const { for(auto hero : map->heroesOnMap) //heroes instances initialization { - if(hero->type && hero->type->ID == hid) + if(hero->type && hero->type->getId() == hid) { return hero; } @@ -2930,7 +2930,7 @@ CGHeroInstance * CGameState::getUsedHero(HeroTypeID hid) const { auto hero = dynamic_cast(obj.get()); assert(hero); - if ( hero->type && hero->type->ID == hid ) + if ( hero->type && hero->type->getId() == hid ) return hero; } } @@ -3024,7 +3024,7 @@ void InfoAboutHero::initFromHero(const CGHeroInstance *h, InfoAboutHero::EInfoLe initFromArmy(h, detailed); hclass = h->type->heroClass; - name = h->name; + name = h->getNameTranslated(); portrait = h->portrait; if(detailed) diff --git a/lib/CHeroHandler.cpp b/lib/CHeroHandler.cpp index e1721d0f7..9b1eda46d 100644 --- a/lib/CHeroHandler.cpp +++ b/lib/CHeroHandler.cpp @@ -43,7 +43,7 @@ int32_t CHero::getIconIndex() const const std::string & CHero::getName() const { - return name; + return identifier; } const std::string & CHero::getJsonKey() const @@ -56,6 +56,56 @@ HeroTypeID CHero::getId() const return ID; } +std::string CHero::getNameTranslated() const +{ + return VLC->generaltexth->translate(getNameTextID()); +} + +std::string CHero::getBiographyTranslated() const +{ + return VLC->generaltexth->translate(getBiographyTextID()); +} + +std::string CHero::getSpecialtyNameTranslated() const +{ + return VLC->generaltexth->translate(getSpecialtyNameTextID()); +} + +std::string CHero::getSpecialtyDescriptionTranslated() const +{ + return VLC->generaltexth->translate(getSpecialtyDescriptionTextID()); +} + +std::string CHero::getSpecialtyTooltipTranslated() const +{ + return VLC->generaltexth->translate(getSpecialtyTooltipTextID()); +} + +std::string CHero::getNameTextID() const +{ + return TextIdentifier("hero", modScope, identifier, "name").get(); +} + +std::string CHero::getBiographyTextID() const +{ + return TextIdentifier("hero", modScope, identifier, "biography").get(); +} + +std::string CHero::getSpecialtyNameTextID() const +{ + return TextIdentifier("hero", modScope, identifier, "specialty", "name").get(); +} + +std::string CHero::getSpecialtyDescriptionTextID() const +{ + return TextIdentifier("hero", modScope, identifier, "specialty", "description").get(); +} + +std::string CHero::getSpecialtyTooltipTextID() const +{ + return TextIdentifier("hero", modScope, identifier, "specialty", "tooltip").get(); +} + void CHero::registerIcons(const IconRegistar & cb) const { cb(getIconIndex(), 0, "UN32", iconSpecSmall); @@ -120,7 +170,7 @@ int32_t CHeroClass::getIconIndex() const const std::string & CHeroClass::getName() const { - return name; + return identifier; } const std::string & CHeroClass::getJsonKey() const @@ -138,6 +188,16 @@ void CHeroClass::registerIcons(const IconRegistar & cb) const } +std::string CHeroClass::getNameTranslated() const +{ + return VLC->generaltexth->translate(getNameTextID()); +} + +std::string CHeroClass::getNameTextID() const +{ + return TextIdentifier("heroClass", modScope, identifier, "specialty", "name").get(); +} + void CHeroClass::updateFrom(const JsonNode & data) { //TODO: CHeroClass::updateFrom @@ -164,7 +224,7 @@ void CHeroClassHandler::fillPrimarySkillData(const JsonNode & node, CHeroClass * if(currentPrimarySkillValue < primarySkillLegalMinimum) { logMod->error("Hero class '%s' has incorrect initial value '%d' for skill '%s'. Value '%d' will be used instead.", - heroClass->identifier, currentPrimarySkillValue, skillName, primarySkillLegalMinimum); + heroClass->getName(), currentPrimarySkillValue, skillName, primarySkillLegalMinimum); currentPrimarySkillValue = primarySkillLegalMinimum; } heroClass->primarySkillInitial.push_back(currentPrimarySkillValue); @@ -192,7 +252,8 @@ CHeroClass * CHeroClassHandler::loadFromJson(const std::string & scope, const Js heroClass->imageMapFemale = node["animation"]["map"]["female"].String(); heroClass->imageMapMale = node["animation"]["map"]["male"].String(); - heroClass->name = node["name"].String(); + VLC->generaltexth->registerString( heroClass->getNameTextID(), node["name"].String()); + heroClass->affinity = vstd::find_pos(affinityStr, node["affinity"].String()); fillPrimarySkillData(node, heroClass, PrimarySkill::ATTACK); @@ -362,11 +423,11 @@ CHero * CHeroHandler::loadFromJson(const std::string & scope, const JsonNode & n hero->sex = node["female"].Bool(); hero->special = node["special"].Bool(); - hero->name = node["texts"]["name"].String(); - hero->biography = node["texts"]["biography"].String(); - hero->specName = node["texts"]["specialty"]["name"].String(); - hero->specTooltip = node["texts"]["specialty"]["tooltip"].String(); - hero->specDescr = node["texts"]["specialty"]["description"].String(); + VLC->generaltexth->registerString( hero->getNameTextID(), node["texts"]["name"].String()); + VLC->generaltexth->registerString( hero->getBiographyTextID(), node["texts"]["biography"].String()); + VLC->generaltexth->registerString( hero->getSpecialtyNameTextID(), node["texts"]["specialty"]["name"].String()); + VLC->generaltexth->registerString( hero->getSpecialtyTooltipTextID(), node["texts"]["specialty"]["tooltip"].String()); + VLC->generaltexth->registerString( hero->getSpecialtyDescriptionTextID(), node["texts"]["specialty"]["description"].String()); hero->iconSpecSmall = node["images"]["specialtySmall"].String(); hero->iconSpecLarge = node["images"]["specialtyLarge"].String(); @@ -703,7 +764,7 @@ void CHeroHandler::loadHeroSpecialty(CHero * hero, const JsonNode & node) const JsonNode & specialtiesNode = node["specialties"]; if (!specialtiesNode.isNull()) { - logMod->warn("Hero %s has deprecated specialties format.", hero->identifier); + logMod->warn("Hero %s has deprecated specialties format.", hero->getNameTranslated()); for(const JsonNode &specialty : specialtiesNode.Vector()) { SSpecialtyInfo spec; @@ -892,7 +953,7 @@ void CHeroHandler::afterLoadFinalization() if(hero->specDeprecated.size() > 0 || hero->specialtyDeprecated.size() > 0) { - logMod->debug("Converting specialty format for hero %s(%s)", hero->identifier, FactionID::encode(hero->heroClass->faction)); + logMod->debug("Converting specialty format for hero %s(%s)", hero->getNameTranslated(), FactionID::encode(hero->heroClass->faction)); std::vector> convertedBonuses; for(const SSpecialtyInfo & spec : hero->specDeprecated) { diff --git a/lib/CHeroHandler.h b/lib/CHeroHandler.h index 93e4f0f87..546439eac 100644 --- a/lib/CHeroHandler.h +++ b/lib/CHeroHandler.h @@ -30,7 +30,8 @@ class JsonSerializeFormat; class BattleField; struct SSpecialtyInfo -{ si32 type; +{ + si32 type; si32 val; si32 subtype; si32 additionalinfo; @@ -57,6 +58,16 @@ struct SSpecialtyBonus class DLL_LINKAGE CHero : public HeroType { + friend class CHeroHandler; + + HeroTypeID ID; + std::string identifier; + std::string modScope; + std::string nameTextID; //name of hero + std::string biographyTextID; + + const std::string & getName() const override; + public: struct InitialArmyStack { @@ -71,8 +82,6 @@ public: h & creature; } }; - std::string identifier; - HeroTypeID ID; si32 imageIndex; std::vector initialArmy; @@ -87,13 +96,6 @@ public: bool special; // hero is special and won't be placed in game (unless preset on map), e.g. campaign heroes ui8 sex; // default sex: 0=male, 1=female - /// Localized texts - std::string name; //name of hero - std::string biography; - std::string specName; - std::string specDescr; - std::string specTooltip; - /// Graphics std::string iconSpecSmall; std::string iconSpecLarge; @@ -106,11 +108,22 @@ public: int32_t getIndex() const override; int32_t getIconIndex() const override; - const std::string & getName() const override; const std::string & getJsonKey() const override; HeroTypeID getId() const override; void registerIcons(const IconRegistar & cb) const override; + std::string getNameTranslated() const override; + std::string getBiographyTranslated() const override; + std::string getSpecialtyNameTranslated() const override; + std::string getSpecialtyDescriptionTranslated() const override; + std::string getSpecialtyTooltipTranslated() const override; + + std::string getNameTextID() const override; + std::string getBiographyTextID() const override; + std::string getSpecialtyNameTextID() const override; + std::string getSpecialtyDescriptionTextID() const override; + std::string getSpecialtyTooltipTextID() const override; + void updateFrom(const JsonNode & data); void serializeJson(JsonSerializeFormat & handler); @@ -126,11 +139,8 @@ public: h & haveSpellBook; h & sex; h & special; - h & name; - h & biography; - h & specName; - h & specDescr; - h & specTooltip; + h & nameTextID; + h & biographyTextID; h & iconSpecSmall; h & iconSpecLarge; h & portraitSmall; @@ -146,6 +156,13 @@ std::vector> SpecialtyBonusToBonuses(const SSpecialtyBonu class DLL_LINKAGE CHeroClass : public HeroClass { + friend class CHeroClassHandler; + HeroClassID id; // use getId instead + std::string modScope; + std::string identifier; // use getJsonKey instead + std::string nameTextID; + + const std::string & getName() const override; public: enum EClassAffinity { @@ -153,11 +170,8 @@ public: MAGIC }; - std::string identifier; - std::string name; // translatable //double aggression; // not used in vcmi. TFaction faction; - HeroClassID id; ui8 affinity; // affinity, using EClassAffinity enum // default chance for hero of specific class to appear in tavern, if field "tavern" was not set @@ -183,11 +197,13 @@ public: int32_t getIndex() const override; int32_t getIconIndex() const override; - const std::string & getName() const override; const std::string & getJsonKey() const override; HeroClassID getId() const override; void registerIcons(const IconRegistar & cb) const override; + std::string getNameTranslated() const override; + std::string getNameTextID() const override; + bool isMagicHero() const; SecondarySkill chooseSecSkill(const std::set & possibles, CRandomGenerator & rand) const; //picks secondary skill out from given possibilities @@ -196,8 +212,9 @@ public: template void serialize(Handler & h, const int version) { + h & modScope; h & identifier; - h & name; + h & nameTextID; h & faction; h & id; h & defaultTavernChance; diff --git a/lib/HeroBonus.cpp b/lib/HeroBonus.cpp index 3ac8cf3b7..eb21e5063 100644 --- a/lib/HeroBonus.cpp +++ b/lib/HeroBonus.cpp @@ -1606,7 +1606,7 @@ std::string Bonus::Description() const str << VLC->skillh->getByIndex(sid)->getNameTranslated(); break; case HERO_SPECIAL: - str << VLC->heroh->objects[sid]->name; + str << VLC->heroh->objects[sid]->getNameTranslated(); break; default: //todo: handle all possible sources diff --git a/lib/mapObjects/CBank.cpp b/lib/mapObjects/CBank.cpp index ffdab4555..89d98b1b0 100644 --- a/lib/mapObjects/CBank.cpp +++ b/lib/mapObjects/CBank.cpp @@ -327,7 +327,7 @@ void CBank::doVisit(const CGHeroInstance * hero) const iw.text.addTxt(MetaString::ADVOB_TXT, 186); iw.text.addReplacement(loot.buildList()); - iw.text.addReplacement(hero->name); + iw.text.addReplacement(hero->getNameTranslated()); cb->showInfoDialog(&iw); cb->giveCreatures(this, hero, ourArmy, false); } diff --git a/lib/mapObjects/CGHeroInstance.cpp b/lib/mapObjects/CGHeroInstance.cpp index d2e153bbb..fa5939ee7 100644 --- a/lib/mapObjects/CGHeroInstance.cpp +++ b/lib/mapObjects/CGHeroInstance.cpp @@ -65,7 +65,7 @@ static int lowestSpeed(const CGHeroInstance * chi) return chi->commander->valOfBonuses(selectorSTACKS_SPEED, keySTACKS_SPEED); } - logGlobal->error("Hero %d (%s) has no army!", chi->id.getNum(), chi->name); + logGlobal->error("Hero %d (%s) has no army!", chi->id.getNum(), chi->getNameTranslated()); return 20; } @@ -309,8 +309,6 @@ void CGHeroInstance::initHero(CRandomGenerator & rand) } if(secSkills.size() == 1 && secSkills[0] == std::pair(SecondarySkill::DEFAULT, -1)) //set secondary skills to default secSkills = type->secSkillsInit; - if (!name.length()) - name = type->name; if (sex == 0xFF)//sex is default sex = type->sex; @@ -373,7 +371,7 @@ void CGHeroInstance::initArmy(CRandomGenerator & rand, IArmyDescriptor * dst) if(creature == nullptr) { - logGlobal->error("Hero %s has invalid creature with id %d in initial army", name, stack.creature.toEnum()); + logGlobal->error("Hero %s has invalid creature with id %d in initial army", getNameTranslated(), stack.creature.toEnum()); continue; } @@ -394,11 +392,11 @@ void CGHeroInstance::initArmy(CRandomGenerator & rand, IArmyDescriptor * dst) if(!getArt(slot)) putArtifact(slot, CArtifactInstance::createNewArtifactInstance(aid)); else - logGlobal->warn("Hero %s already has artifact at %d, omitting giving artifact %d", name, slot.toEnum(), aid.toEnum()); + logGlobal->warn("Hero %s already has artifact at %d, omitting giving artifact %d", getNameTranslated(), slot.toEnum(), aid.toEnum()); } else { - logGlobal->error("Hero %s has invalid war machine in initial army", name); + logGlobal->error("Hero %s has invalid war machine in initial army", getNameTranslated()); } } else @@ -469,21 +467,14 @@ std::string CGHeroInstance::getObjectName() const if(ID != Obj::PRISON) { std::string hoverName = VLC->generaltexth->allTexts[15]; - boost::algorithm::replace_first(hoverName,"%s",name); - boost::algorithm::replace_first(hoverName,"%s", type->heroClass->name); + boost::algorithm::replace_first(hoverName,"%s",getNameTranslated()); + boost::algorithm::replace_first(hoverName,"%s", type->heroClass->getNameTranslated()); return hoverName; } else return CGObjectInstance::getObjectName(); } -const std::string & CGHeroInstance::getBiography() const -{ - if (biography.length()) - return biography; - return type->biography; -} - ui8 CGHeroInstance::maxlevelsToMagicSchool() const { return type->heroClass->isMagicHero() ? 3 : 4; @@ -536,14 +527,13 @@ void CGHeroInstance::initObj(CRandomGenerator & rand) for(std::shared_ptr b : sb.bonuses) addNewBonus(b); for(SSpecialtyInfo & spec : type->specDeprecated) - for(std::shared_ptr b : SpecialtyInfoToBonuses(spec, type->ID.getNum())) + for(std::shared_ptr b : SpecialtyInfoToBonuses(spec, type->getIndex())) addNewBonus(b); //initialize bonuses recreateSecondarySkillsBonuses(); mana = manaLimit(); //after all bonuses are taken into account, make sure this line is the last one - type->name = name; } void CGHeroInstance::recreateSecondarySkillsBonuses() @@ -686,7 +676,7 @@ PlayerColor CGHeroInstance::getCasterOwner() const void CGHeroInstance::getCasterName(MetaString & text) const { //FIXME: use local name, MetaString need access to gamestate as hero name is part of map object - text.addReplacement(name); + text.addReplacement(getNameTranslated()); } void CGHeroInstance::getCastDescription(const spells::Spell * spell, const std::vector & attacked, MetaString & text) const @@ -995,7 +985,39 @@ void CGHeroInstance::initExp(CRandomGenerator & rand) std::string CGHeroInstance::nodeName() const { - return "Hero " + name; + return "Hero " + getNameTextID(); +} + +std::string CGHeroInstance::getNameTranslated() const +{ + return VLC->generaltexth->translate(getNameTextID()); +} + +std::string CGHeroInstance::getNameTextID() const +{ + if (!nameCustom.empty()) + return nameCustom; + if (type) + return type->getNameTextID(); + + assert(0); + return ""; +} + +std::string CGHeroInstance::getBiographyTranslated() const +{ + return VLC->generaltexth->translate(getBiographyTextID()); +} + +std::string CGHeroInstance::getBiographyTextID() const +{ + if (!biographyCustom.empty()) + return biographyCustom; + if (type) + return type->getBiographyTextID(); + + assert(0); + return ""; } void CGHeroInstance::putArtifact(ArtifactPosition pos, CArtifactInstance *art) @@ -1230,7 +1252,7 @@ PrimarySkill::PrimarySkill CGHeroInstance::nextPrimarySkill(CRandomGenerator & r if(primarySkill >= GameConstants::PRIMARY_SKILLS) { primarySkill = rand.nextInt(GameConstants::PRIMARY_SKILLS - 1); - logGlobal->error("Wrong values in primarySkill%sLevel for hero class %s", isLowLevelHero ? "Low" : "High", type->heroClass->identifier); + logGlobal->error("Wrong values in primarySkill%sLevel for hero class %s", isLowLevelHero ? "Low" : "High", type->heroClass->getNameTranslated()); randomValue = 100 / GameConstants::PRIMARY_SKILLS; } logGlobal->trace("The hero gets the primary skill %d with a probability of %d %%.", primarySkill, randomValue); @@ -1378,11 +1400,11 @@ std::string CGHeroInstance::getHeroTypeName() const { if(type) { - return type->identifier; + return type->getJsonKey(); } else { - return VLC->heroh->objects[subID]->identifier; + return VLC->heroh->objects[subID]->getJsonKey(); } } return ""; @@ -1421,7 +1443,7 @@ void CGHeroInstance::updateFrom(const JsonNode & data) void CGHeroInstance::serializeCommonOptions(JsonSerializeFormat & handler) { - handler.serializeString("biography", biography); + handler.serializeString("biography", biographyCustom); handler.serializeInt("experience", exp, 0); if(!handler.saving && exp != 0xffffffff) //do not gain levels if experience is not initialized @@ -1432,7 +1454,7 @@ void CGHeroInstance::serializeCommonOptions(JsonSerializeFormat & handler) } } - handler.serializeString("name", name); + handler.serializeString("name", nameCustom); handler.serializeBool("female", sex, 1, 0, 0xFF); { diff --git a/lib/mapObjects/CGHeroInstance.h b/lib/mapObjects/CGHeroInstance.h index b010f73f6..c9df2fb36 100644 --- a/lib/mapObjects/CGHeroInstance.h +++ b/lib/mapObjects/CGHeroInstance.h @@ -45,11 +45,13 @@ class DLL_LINKAGE CGHeroInstance : public CArmedInstance, public IBoatGenerator, // We serialize heroes into JSON for crossover friend class CCampaignState; friend class CMapLoaderH3M; + friend class CMapFormatJson; private: std::set spells; //known spells (spell IDs) public: + ////////////////////////////////////////////////////////////////////////// ui8 moveDir; //format: 123 @@ -62,13 +64,15 @@ public: ConstTransitivePtr type; TExpType exp; //experience points ui32 level; //current level of hero - std::string name; //may be custom - std::string biography; //if custom si32 portrait; //may be custom si32 mana; // remaining spell points std::vector > secSkills; //first - ID of skill, second - level of skill (1 - basic, 2 - adv., 3 - expert); if hero has ability (-1, -1) it meansthat it should have default secondary abilities ui32 movement; //remaining movement points ui8 sex; + + std::string nameCustom; + std::string biographyCustom; + bool inTownGarrison; // if hero is in town garrison ConstTransitivePtr visitedTown; //set if hero is visiting town or in the town garrison ConstTransitivePtr commander; @@ -145,6 +149,12 @@ public: ////////////////////////////////////////////////////////////////////////// + std::string getNameTranslated() const; + std::string getNameTextID() const; + + std::string getBiographyTranslated() const; + std::string getBiographyTextID() const; + bool hasSpellbook() const; int maxSpellLevel() const; void addSpellToSpellbook(SpellID spell); @@ -153,7 +163,6 @@ public: void removeSpellbook(); const std::set & getSpellsInSpellbook() const; EAlignment::EAlignment getAlignment() const; - const std::string &getBiography() const; bool needsLastStack()const override; ui32 getTileCost(const TerrainTile &dest, const TerrainTile &from, const TurnInfo * ti) const; //move cost - applying pathfinding skill, road and terrain modifiers. NOT includes diagonal move penalty, last move levelling @@ -299,8 +308,8 @@ public: h & static_cast(*this); h & exp; h & level; - h & name; - h & biography; + h & nameCustom; + h & biographyCustom; h & portrait; h & mana; h & secSkills; diff --git a/lib/mapObjects/CGPandoraBox.cpp b/lib/mapObjects/CGPandoraBox.cpp index e04dfa377..a71f68825 100644 --- a/lib/mapObjects/CGPandoraBox.cpp +++ b/lib/mapObjects/CGPandoraBox.cpp @@ -102,7 +102,7 @@ void CGPandoraBox::giveContentsUpToExp(const CGHeroInstance *h) const TExpType expVal = h->calculateXp(gainedExp); //getText(iw,afterBattle,175,h); //wtf? iw.text.addTxt(MetaString::ADVOB_TXT, 175); //%s learns something - iw.text.addReplacement(h->name); + iw.text.addReplacement(h->getNameTranslated()); if(expVal) iw.components.push_back(Component(Component::EXPERIENCE,0,static_cast(expVal),0)); @@ -183,7 +183,7 @@ void CGPandoraBox::giveContentsAfterExp(const CGHeroInstance *h) const { iw.text.addTxt(MetaString::ADVOB_TXT, 184); //%s learns a spell } - iw.text.addReplacement(h->name); + iw.text.addReplacement(h->getNameTranslated()); cb->changeSpells(h, true, spellsToGive); cb->showInfoDialog(&iw); } @@ -249,7 +249,7 @@ void CGPandoraBox::giveContentsAfterExp(const CGHeroInstance *h) const iw.components.clear(); // getText(iw,afterBattle,183,h); iw.text.addTxt(MetaString::ADVOB_TXT, 183); //% has found treasure - iw.text.addReplacement(h->name); + iw.text.addReplacement(h->getNameTranslated()); for(auto & elem : artifacts) { iw.components.push_back(Component(Component::ARTIFACT,elem,0,0)); @@ -258,7 +258,7 @@ void CGPandoraBox::giveContentsAfterExp(const CGHeroInstance *h) const cb->showInfoDialog(&iw); iw.components.clear(); iw.text.addTxt(MetaString::ADVOB_TXT, 183); //% has found treasure - once more? - iw.text.addReplacement(h->name); + iw.text.addReplacement(h->getNameTranslated()); } } if(iw.components.size()) @@ -290,7 +290,7 @@ void CGPandoraBox::giveContentsAfterExp(const CGHeroInstance *h) const iw.text.addTxt(MetaString::ADVOB_TXT, 186); iw.text.addReplacement(loot.buildList()); - iw.text.addReplacement(h->name); + iw.text.addReplacement(h->getNameTranslated()); cb->showInfoDialog(&iw); cb->giveCreatures(this, h, creatures, false); @@ -307,7 +307,7 @@ void CGPandoraBox::getText( InfoWindow &iw, bool &afterBattle, int text, const C if(afterBattle || !message.size()) { iw.text.addTxt(MetaString::ADVOB_TXT,text);//%s has lost treasure. - iw.text.addReplacement(h->name); + iw.text.addReplacement(h->getNameTranslated()); } else { @@ -323,7 +323,7 @@ void CGPandoraBox::getText( InfoWindow &iw, bool &afterBattle, int val, int nega if(afterBattle || !message.size()) { iw.text.addTxt(MetaString::ADVOB_TXT,val < 0 ? negative : positive); //%s's luck takes a turn for the worse / %s's luck increases - iw.text.addReplacement(h->name); + iw.text.addReplacement(h->getNameTranslated()); } else { diff --git a/lib/mapObjects/CGTownInstance.cpp b/lib/mapObjects/CGTownInstance.cpp index 6317e2425..deae9b107 100644 --- a/lib/mapObjects/CGTownInstance.cpp +++ b/lib/mapObjects/CGTownInstance.cpp @@ -720,7 +720,7 @@ void CGTownInstance::onHeroVisit(const CGHeroInstance * h) const } else { - logGlobal->error("%s visits allied town of %s from different pos?", h->name, name); + logGlobal->error("%s visits allied town of %s from different pos?", h->getNameTranslated(), name); } } @@ -730,10 +730,10 @@ void CGTownInstance::onHeroLeave(const CGHeroInstance * h) const if(visitingHero == h) { cb->stopHeroVisitCastle(this, h); - logGlobal->trace("%s correctly left town %s", h->name, name); + logGlobal->trace("%s correctly left town %s", h->getNameTranslated(), name); } else - logGlobal->warn("Warning, %s tries to leave the town %s but hero is not inside.", h->name, name); + logGlobal->warn("Warning, %s tries to leave the town %s but hero is not inside.", h->getNameTranslated(), name); } std::string CGTownInstance::getObjectName() const @@ -1451,7 +1451,7 @@ void CGTownInstance::addHeroToStructureVisitors(const CGHeroInstance *h, si64 st else { //should never ever happen - logGlobal->error("Cannot add hero %s to visitors of structure # %d", h->name, structureInstanceID); + logGlobal->error("Cannot add hero %s to visitors of structure # %d", h->getNameTranslated(), structureInstanceID); throw std::runtime_error("internal error"); } } diff --git a/lib/mapObjects/CObjectHandler.cpp b/lib/mapObjects/CObjectHandler.cpp index 1ac9b2675..c3774071f 100644 --- a/lib/mapObjects/CObjectHandler.cpp +++ b/lib/mapObjects/CObjectHandler.cpp @@ -494,7 +494,7 @@ void IBoatGenerator::getProblemText(MetaString &out, const CGHeroInstance *visit if(visitor) { out.addTxt(MetaString::GENERAL_TXT, 134); - out.addReplacement(visitor->name); + out.addReplacement(visitor->getNameTranslated()); } else out.addTxt(MetaString::ADVOB_TXT, 189); diff --git a/lib/mapObjects/CQuest.cpp b/lib/mapObjects/CQuest.cpp index d945c5eb6..5974c1149 100644 --- a/lib/mapObjects/CQuest.cpp +++ b/lib/mapObjects/CQuest.cpp @@ -170,7 +170,7 @@ bool CQuest::checkQuest(const CGHeroInstance * h) const } return true; case MISSION_HERO: - if(m13489val == h->type->ID.getNum()) + if(m13489val == h->type->getIndex()) return true; return false; case MISSION_PLAYER: @@ -230,7 +230,7 @@ void CQuest::getVisitText(MetaString &iwText, std::vector &components //FIXME: portrait may not match hero, if custom portrait was set in map editor components.push_back(Component(Component::HERO_PORTRAIT, VLC->heroh->objects[m13489val]->imageIndex, 0, 0)); if(!isCustom) - iwText.addReplacement(VLC->heroh->objects[m13489val]->name); + iwText.addReplacement(VLC->heroh->objects[m13489val]->getNameTextID()); break; case MISSION_KILL_CREATURE: { @@ -369,7 +369,7 @@ void CQuest::getRolloverText(MetaString &ms, bool onHover) const } break; case MISSION_HERO: - ms.addReplacement(VLC->heroh->objects[m13489val]->name); + ms.addReplacement(VLC->heroh->objects[m13489val]->getNameTextID()); break; case MISSION_PLAYER: ms.addReplacement(VLC->generaltexth->colors[m13489val]); @@ -452,7 +452,7 @@ void CQuest::getCompletionText(MetaString &iwText, std::vector &compo break; case MISSION_HERO: if (!isCustomComplete) - iwText.addReplacement(VLC->heroh->objects[m13489val]->name); + iwText.addReplacement(VLC->heroh->objects[m13489val]->getNameTextID()); break; case MISSION_PLAYER: if (!isCustomComplete) @@ -567,7 +567,7 @@ void CGSeerHut::setObjToKill() } else if(quest->missionType == CQuest::MISSION_KILL_HERO) { - quest->heroName = getHeroToKill(false)->name; + quest->heroName = getHeroToKill(false)->getNameTranslated(); quest->heroPortrait = getHeroToKill(false)->portrait; } } diff --git a/lib/mapObjects/CommonConstructors.cpp b/lib/mapObjects/CommonConstructors.cpp index 20f0ed114..bbd50ea07 100644 --- a/lib/mapObjects/CommonConstructors.cpp +++ b/lib/mapObjects/CommonConstructors.cpp @@ -123,7 +123,7 @@ bool CHeroInstanceConstructor::objectFilter(const CGObjectInstance * object, std auto heroTest = [&](const HeroTypeID & id) { - return hero->type->ID == id; + return hero->type->getId() == id; }; if(filters.count(templ->stringID)) diff --git a/lib/mapObjects/MiscObjects.cpp b/lib/mapObjects/MiscObjects.cpp index 84b3cda6e..3a4765824 100644 --- a/lib/mapObjects/MiscObjects.cpp +++ b/lib/mapObjects/MiscObjects.cpp @@ -596,7 +596,7 @@ void CGCreature::giveReward(const CGHeroInstance * h) const if(iw.components.size()) { iw.text.addTxt(MetaString::ADVOB_TXT, 183); // % has found treasure - iw.text.addReplacement(h->name); + iw.text.addReplacement(h->getNameTranslated()); cb->showInfoDialog(&iw); } } @@ -1347,7 +1347,7 @@ void CGArtifact::onHeroVisit(const CGHeroInstance * h) const else //fix for mod artifacts with no event text { iw.text.addTxt(MetaString::ADVOB_TXT, 183); //% has found treasure - iw.text.addReplacement(h->name); + iw.text.addReplacement(h->getNameTranslated()); } } } diff --git a/lib/mapping/CMap.cpp b/lib/mapping/CMap.cpp index edf9dec98..af6cb61ba 100644 --- a/lib/mapping/CMap.cpp +++ b/lib/mapping/CMap.cpp @@ -568,7 +568,7 @@ void CMap::checkForObjectives() boost::algorithm::replace_first(event.onFulfill, "%s", town->name); const CGHeroInstance *hero = dynamic_cast(cond.object); if (hero) - boost::algorithm::replace_first(event.onFulfill, "%s", hero->name); + boost::algorithm::replace_first(event.onFulfill, "%s", hero->getNameTranslated()); } break; @@ -580,7 +580,7 @@ void CMap::checkForObjectives() { const CGHeroInstance *hero = dynamic_cast(cond.object); if (hero) - boost::algorithm::replace_first(event.onFulfill, "%s", hero->name); + boost::algorithm::replace_first(event.onFulfill, "%s", hero->getNameTranslated()); } break; case EventCondition::TRANSPORT: diff --git a/lib/mapping/MapFormatH3M.cpp b/lib/mapping/MapFormatH3M.cpp index 794e30fcc..652f97ff0 100644 --- a/lib/mapping/MapFormatH3M.cpp +++ b/lib/mapping/MapFormatH3M.cpp @@ -787,7 +787,7 @@ void CMapLoaderH3M::readPredefinedHeroes() bool hasCustomBio = reader.readBool(); if(hasCustomBio) { - hero->biography = reader.readString(); + hero->biographyCustom = reader.readString(); } // 0xFF is default, 00 male, 01 female @@ -825,7 +825,7 @@ void CMapLoaderH3M::loadArtifactsOfHero(CGHeroInstance * hero) { if(hero->artifactsWorn.size() || hero->artifactsInBackpack.size()) { - logGlobal->warn("Hero %s at %s has set artifacts twice (in map properties and on adventure map instance). Using the latter set...", hero->name, hero->pos.toString()); + logGlobal->warn("Hero %s at %s has set artifacts twice (in map properties and on adventure map instance). Using the latter set...", hero->getNameTranslated(), hero->pos.toString()); hero->artifactsInBackpack.clear(); while(hero->artifactsWorn.size()) hero->eraseArtSlot(hero->artifactsWorn.begin()->first); @@ -1436,7 +1436,7 @@ void CMapLoaderH3M::readObjects() } else { - logGlobal->info("Hero placeholder: %s at %s", VLC->heroh->objects[htid]->name, objPos.toString()); + logGlobal->info("Hero placeholder: %s at %s", VLC->heroh->objects[htid]->getNameTranslated(), objPos.toString()); hp->power = 0; } @@ -1592,7 +1592,7 @@ CGObjectInstance * CMapLoaderH3M::readHero(ObjectInstanceID idToBeGiven, const i { if(elem.heroId == nhi->subID) { - nhi->name = elem.name; + nhi->nameCustom = elem.name; nhi->portrait = elem.portrait; break; } @@ -1601,7 +1601,7 @@ CGObjectInstance * CMapLoaderH3M::readHero(ObjectInstanceID idToBeGiven, const i bool hasName = reader.readBool(); if(hasName) { - nhi->name = reader.readString(); + nhi->nameCustom = reader.readString(); } if(map->version > EMapFormat::AB) { @@ -1666,7 +1666,7 @@ CGObjectInstance * CMapLoaderH3M::readHero(ObjectInstanceID idToBeGiven, const i bool hasCustomBiography = reader.readBool(); if(hasCustomBiography) { - nhi->biography = reader.readString(); + nhi->biographyCustom = reader.readString(); } nhi->sex = reader.readUInt8(); @@ -1688,7 +1688,7 @@ CGObjectInstance * CMapLoaderH3M::readHero(ObjectInstanceID idToBeGiven, const i if(nhi->spells.size()) { nhi->clear(); - logGlobal->warn("Hero %s subID=%d has spells set twice (in map properties and on adventure map instance). Using the latter set...", nhi->name, nhi->subID); + logGlobal->warn("Hero %s subID=%d has spells set twice (in map properties and on adventure map instance). Using the latter set...", nhi->getNameTranslated(), nhi->subID); } if(hasCustomSpells) @@ -1721,7 +1721,7 @@ CGObjectInstance * CMapLoaderH3M::readHero(ObjectInstanceID idToBeGiven, const i .And(Selector::sourceType()(Bonus::HERO_BASE_SKILL)), nullptr); if(ps->size()) { - logGlobal->warn("Hero %s subID=%d has set primary skills twice (in map properties and on adventure map instance). Using the latter set...", nhi->name, nhi->subID); + logGlobal->warn("Hero %s subID=%d has set primary skills twice (in map properties and on adventure map instance). Using the latter set...", nhi->getNameTranslated(), nhi->subID); for(auto b : *ps) nhi->removeBonus(b); } diff --git a/lib/mapping/MapFormatJson.cpp b/lib/mapping/MapFormatJson.cpp index fec83720b..bc1df5ba2 100644 --- a/lib/mapping/MapFormatJson.cpp +++ b/lib/mapping/MapFormatJson.cpp @@ -524,18 +524,18 @@ void CMapFormatJson::serializePlayerInfo(JsonSerializeFormat & handler) if(hero) { auto heroData = handler.enterStruct(hero->instanceName); - heroData->serializeString("name", hero->name); + heroData->serializeString("name", hero->nameCustom); if(hero->ID == Obj::HERO) { std::string temp; if(hero->type) { - temp = hero->type->identifier; + temp = hero->type->getJsonKey(); } else { - temp = VLC->heroh->objects[hero->subID]->identifier; + temp = VLC->heroh->objects[hero->subID]->getJsonKey(); } handler.serializeString("type", temp); } diff --git a/lib/serializer/CSerializer.cpp b/lib/serializer/CSerializer.cpp index fe53ad072..153c0c22a 100644 --- a/lib/serializer/CSerializer.cpp +++ b/lib/serializer/CSerializer.cpp @@ -34,9 +34,9 @@ void CSerializer::addStdVecItems(CGameState *gs, LibClasses *lib) registerVectoredType(&gs->map->objects, [](const CGObjectInstance &obj){ return obj.id; }); registerVectoredType(&lib->heroh->objects, - [](const CHero &h){ return h.ID; }); + [](const CHero &h){ return h.getId(); }); registerVectoredType(&gs->map->allHeroes, - [](const CGHeroInstance &h){ return h.type->ID; }); + [](const CGHeroInstance &h){ return h.type->getId(); }); registerVectoredType(&lib->creh->objects, [](const CCreature &cre){ return cre.idNumber; }); registerVectoredType(&lib->arth->objects, diff --git a/lib/spells/AdventureSpellMechanics.cpp b/lib/spells/AdventureSpellMechanics.cpp index a42920771..8f072dc10 100644 --- a/lib/spells/AdventureSpellMechanics.cpp +++ b/lib/spells/AdventureSpellMechanics.cpp @@ -147,7 +147,7 @@ ESpellCastResult SummonBoatMechanics::applyAdventureEffects(SpellCastEnvironment InfoWindow iw; iw.player = parameters.caster->tempOwner; iw.text.addTxt(MetaString::GENERAL_TXT, 333);//%s is already in boat - iw.text.addReplacement(parameters.caster->name); + iw.text.addReplacement(parameters.caster->getNameTranslated()); env->apply(&iw); return ESpellCastResult::CANCEL; } @@ -170,7 +170,7 @@ ESpellCastResult SummonBoatMechanics::applyAdventureEffects(SpellCastEnvironment InfoWindow iw; iw.player = parameters.caster->tempOwner; iw.text.addTxt(MetaString::GENERAL_TXT, 336); //%s tried to summon a boat, but failed. - iw.text.addReplacement(parameters.caster->name); + iw.text.addReplacement(parameters.caster->getNameTranslated()); env->apply(&iw); return ESpellCastResult::OK; } @@ -236,7 +236,7 @@ ESpellCastResult ScuttleBoatMechanics::applyAdventureEffects(SpellCastEnvironmen InfoWindow iw; iw.player = parameters.caster->tempOwner; iw.text.addTxt(MetaString::GENERAL_TXT, 337); //%s tried to scuttle the boat, but failed - iw.text.addReplacement(parameters.caster->name); + iw.text.addReplacement(parameters.caster->getNameTranslated()); env->apply(&iw); return ESpellCastResult::OK; } @@ -307,7 +307,7 @@ ESpellCastResult DimensionDoorMechanics::applyAdventureEffects(SpellCastEnvironm InfoWindow iw; iw.player = parameters.caster->tempOwner; iw.text.addTxt(MetaString::GENERAL_TXT, 338); //%s is not skilled enough to cast this spell again today. - iw.text.addReplacement(parameters.caster->name); + iw.text.addReplacement(parameters.caster->getNameTranslated()); env->apply(&iw); return ESpellCastResult::CANCEL; } diff --git a/lib/spells/effects/Summon.cpp b/lib/spells/effects/Summon.cpp index 83082b012..fc65c8dcd 100644 --- a/lib/spells/effects/Summon.cpp +++ b/lib/spells/effects/Summon.cpp @@ -80,7 +80,7 @@ bool Summon::applicable(Problem & problem, const Mechanics * m) const auto caster = dynamic_cast(m->caster); if(caster) { - text.addReplacement(caster->name); + text.addReplacement(caster->getNameTranslated()); text.addReplacement(MetaString::CRE_PL_NAMES, elemental->creatureIndex()); diff --git a/mapeditor/inspector/inspector.cpp b/mapeditor/inspector/inspector.cpp index e7a60417f..e260859f1 100644 --- a/mapeditor/inspector/inspector.cpp +++ b/mapeditor/inspector/inspector.cpp @@ -131,9 +131,7 @@ void Initializer::initialize(CGHeroInstance * o) if(!o->type) o->type = VLC->heroh->objects.at(o->subID); - o->name = o->type->getName(); o->sex = o->type->sex; - o->biography = o->type->biography; o->portrait = o->type->imageIndex; o->randomizeArmy(o->type->heroClass->faction); } @@ -237,15 +235,15 @@ void Inspector::updateProperties(CGHeroInstance * o) addProperty("Owner", o->tempOwner, o->ID == Obj::PRISON); //field is not editable for prison addProperty("Experience", o->exp, false); - addProperty("Hero class", o->type->heroClass->getName(), true); + addProperty("Hero class", o->type->heroClass->getNameTranslated(), true); { //Sex auto * delegate = new InspectorDelegate; delegate->options << "MALE" << "FEMALE"; addProperty("Sex", (o->sex ? "FEMALE" : "MALE"), delegate , false); } - addProperty("Name", o->name, false); - addProperty("Biography", o->biography, new MessageDelegate, false); + addProperty("Name", o->nameCustom, false); + addProperty("Biography", o->biographyCustom, new MessageDelegate, false); addProperty("Portrait", o->portrait, false); { //Hero type @@ -255,10 +253,10 @@ void Inspector::updateProperties(CGHeroInstance * o) if(map->allowedHeroes.at(i)) { if(o->ID == Obj::PRISON || (o->type && VLC->heroh->objects[i]->heroClass->getIndex() == o->type->heroClass->getIndex())) - delegate->options << QObject::tr(VLC->heroh->objects[i]->getName().c_str()); + delegate->options << QObject::tr(VLC->heroh->objects[i]->getNameTranslated().c_str()); } } - addProperty("Hero type", o->type->getName(), delegate, false); + addProperty("Hero type", o->type->getNameTranslated(), delegate, false); } } @@ -554,7 +552,7 @@ void Inspector::setProperty(CGHeroInstance * o, const QString & key, const QVari o->sex = value.toString() == "MALE" ? 0 : 1; if(key == "Name") - o->name = value.toString().toStdString(); + o->nameCustom = value.toString().toStdString(); if(key == "Experience") o->exp = value.toInt(); @@ -563,12 +561,10 @@ void Inspector::setProperty(CGHeroInstance * o, const QString & key, const QVari { for(auto t : VLC->heroh->objects) { - if(t->getName() == value.toString().toStdString()) + if(t->getNameTranslated() == value.toString().toStdString()) o->type = t.get(); } - o->name = o->type->getName(); o->sex = o->type->sex; - o->biography = o->type->biography; o->portrait = o->type->imageIndex; o->randomizeArmy(o->type->heroClass->faction); updateProperties(); //updating other properties after change diff --git a/mapeditor/inspector/questwidget.cpp b/mapeditor/inspector/questwidget.cpp index c7103a101..953408c6a 100644 --- a/mapeditor/inspector/questwidget.cpp +++ b/mapeditor/inspector/questwidget.cpp @@ -95,7 +95,7 @@ void QuestWidget::obtainData() case CQuest::Emission::MISSION_HERO: activeId = true; for(int i = 0; i < map.allowedHeroes.size(); ++i) - ui->targetId->addItem(QString::fromStdString(VLC->heroh->objects.at(i)->getName())); + ui->targetId->addItem(QString::fromStdString(VLC->heroh->objects.at(i)->getNameTranslated())); ui->targetId->setCurrentIndex(seerhut.quest->m13489val); break; case CQuest::Emission::MISSION_PLAYER: diff --git a/mapeditor/mapcontroller.cpp b/mapeditor/mapcontroller.cpp index 2a5d3fdd8..85127ee8b 100644 --- a/mapeditor/mapcontroller.cpp +++ b/mapeditor/mapcontroller.cpp @@ -131,7 +131,7 @@ void MapController::repairMap() if(obj->ID == Obj::HERO) { nih->typeName = "hero"; - nih->subTypeName = type->heroClass->identifier; + nih->subTypeName = type->heroClass->getJsonKey(); } if(obj->ID == Obj::PRISON) { @@ -140,10 +140,6 @@ void MapController::repairMap() } nih->type = type; - if(nih->name.empty()) - nih->name = nih->type->name; - if(nih->biography.empty()) - nih->biography = nih->type->biography; if(nih->ID == Obj::HERO) //not prison nih->appearance = VLC->objtypeh->getHandlerFor(Obj::HERO, type->heroClass->getIndex())->getTemplates().front(); diff --git a/mapeditor/mapsettings.cpp b/mapeditor/mapsettings.cpp index 232eeb806..000318f0c 100644 --- a/mapeditor/mapsettings.cpp +++ b/mapeditor/mapsettings.cpp @@ -58,7 +58,7 @@ MapSettings::MapSettings(MapController & ctrl, QWidget *parent) : } for(int i = 0; i < controller.map()->allowedHeroes.size(); ++i) { - auto * item = new QListWidgetItem(QString::fromStdString(VLC->heroh->objects[i]->getName())); + auto * item = new QListWidgetItem(QString::fromStdString(VLC->heroh->objects[i]->getNameTranslated())); item->setData(Qt::UserRole, QVariant::fromValue(i)); item->setFlags(item->flags() | Qt::ItemIsUserCheckable); item->setCheckState(controller.map()->allowedHeroes[i] ? Qt::Checked : Qt::Unchecked); diff --git a/mapeditor/validator.cpp b/mapeditor/validator.cpp index f2833909a..2fd622d69 100644 --- a/mapeditor/validator.cpp +++ b/mapeditor/validator.cpp @@ -119,7 +119,7 @@ std::list Validator::validate(const CMap * map) if(ins->type) { if(!map->allowedHeroes[ins->type->getId().getNum()]) - issues.emplace_back(QString("Hero %1 is prohibited by map settings").arg(ins->type->getName().c_str()), false); + issues.emplace_back(QString("Hero %1 is prohibited by map settings").arg(ins->type->getNameTranslated().c_str()), false); } else issues.emplace_back(QString("Hero %1 has an empty type and must be removed").arg(ins->instanceName.c_str()), true); diff --git a/server/CGameHandler.cpp b/server/CGameHandler.cpp index 589154c41..9d39f824f 100644 --- a/server/CGameHandler.cpp +++ b/server/CGameHandler.cpp @@ -423,7 +423,7 @@ void CGameHandler::levelUpHero(const CGHeroInstance * hero) } // give primary skill - logGlobal->trace("%s got level %d", hero->name, hero->level); + logGlobal->trace("%s got level %d", hero->getNameTranslated(), hero->level); auto primarySkill = hero->nextPrimarySkill(getRandomGenerator()); SetPrimSkill sps; @@ -633,7 +633,7 @@ void CGameHandler::changePrimSkill(const CGHeroInstance * hero, PrimarySkill::Pr InfoWindow iw; iw.player = hero->tempOwner; iw.text.addTxt(MetaString::GENERAL_TXT, 1); //can gain no more XP - iw.text.addReplacement(hero->name); + iw.text.addReplacement(hero->getNameTextID()); sendAndApply(&iw); } } @@ -856,7 +856,7 @@ void CGameHandler::endBattle(int3 tile, const CGHeroInstance * heroAttacker, con InfoWindow iw; iw.player = finishingBattle->winnerHero->tempOwner; iw.text.addTxt(MetaString::GENERAL_TXT, 221); //Through eagle-eyed observation, %s is able to learn %s - iw.text.addReplacement(finishingBattle->winnerHero->name); + iw.text.addReplacement(finishingBattle->winnerHero->getNameTextID()); std::ostringstream names; for (int i = 0; i < cs.spells.size(); i++) @@ -2392,7 +2392,7 @@ bool CGameHandler::moveHero(ObjectInstanceID hid, int3 dst, ui8 teleporting, boo auto doMove = [&](TryMoveHero::EResult result, EGuardLook lookForGuards, EVisitDest visitDest, ELEaveTile leavingTile) -> bool { - LOG_TRACE_PARAMS(logGlobal, "Hero %s starts movement from %s to %s", h->name % tmh.start.toString() % tmh.end.toString()); + LOG_TRACE_PARAMS(logGlobal, "Hero %s starts movement from %s to %s", h->getNameTranslated() % tmh.start.toString() % tmh.end.toString()); auto moveQuery = std::make_shared(this, tmh, h); queries.addQuery(moveQuery); @@ -2422,7 +2422,7 @@ bool CGameHandler::moveHero(ObjectInstanceID hid, int3 dst, ui8 teleporting, boo } queries.popIfTop(moveQuery); - logGlobal->trace("Hero %s ends movement", h->name); + logGlobal->trace("Hero %s ends movement", h->getNameTranslated()); return result != TryMoveHero::FAILED; }; @@ -2822,7 +2822,7 @@ void CGameHandler::useScholarSkill(ObjectInstanceID fromHero, ObjectInstanceID t iw.components.push_back(Component(Component::SEC_SKILL, 18, ScholarSkillLevel, 0)); iw.text.addTxt(MetaString::GENERAL_TXT, 139);//"%s, who has studied magic extensively, - iw.text.addReplacement(h1->name); + iw.text.addReplacement(h1->getNameTextID()); if (!cs2.spells.empty())//if found new spell - apply { @@ -2840,7 +2840,7 @@ void CGameHandler::useScholarSkill(ObjectInstanceID fromHero, ObjectInstanceID t } } iw.text.addTxt(MetaString::GENERAL_TXT, 142);//from %s - iw.text.addReplacement(h2->name); + iw.text.addReplacement(h2->getNameTextID()); sendAndApply(&cs2); } @@ -2864,7 +2864,7 @@ void CGameHandler::useScholarSkill(ObjectInstanceID fromHero, ObjectInstanceID t default: iw.text << ", "; } } iw.text.addTxt(MetaString::GENERAL_TXT, 148);//from %s - iw.text.addReplacement(h2->name); + iw.text.addReplacement(h2->getNameTextID()); sendAndApply(&cs1); } sendAndApply(&iw); diff --git a/server/CQuery.cpp b/server/CQuery.cpp index 6ae3375c0..b42699e27 100644 --- a/server/CQuery.cpp +++ b/server/CQuery.cpp @@ -486,7 +486,7 @@ void CHeroMovementQuery::onExposure(QueryPtr topQuery) if(visitDestAfterVictory && hero->tempOwner == players[0]) //hero still alive, so he won with the guard //TODO what if there were H4-like escape? we should also check pos { - logGlobal->trace("Hero %s after victory over guard finishes visit to %s", hero->name, tmh.end.toString()); + logGlobal->trace("Hero %s after victory over guard finishes visit to %s", hero->getNameTranslated(), tmh.end.toString()); //finish movement visitDestAfterVictory = false; gh->visitObjectOnTile(*gh->getTile(hero->convertToVisitablePos(tmh.end)), hero);