1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-24 22:14:36 +02:00

All heroes-related strings are passed through translator

This commit is contained in:
Ivan Savenko 2023-01-02 13:27:03 +02:00
parent e22f6283c2
commit fa6f7513e8
64 changed files with 356 additions and 239 deletions

View File

@ -283,7 +283,7 @@ void AIGateway::heroExchangeStarted(ObjectInstanceID hero1, ObjectInstanceID her
auto firstHero = cb->getHero(hero1); auto firstHero = cb->getHero(hero1);
auto secondHero = cb->getHero(hero2); 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([=]() requestActionASAP([=]()
{ {
@ -544,7 +544,7 @@ void AIGateway::heroGotLevel(const CGHeroInstance * hero, PrimarySkill::PrimaryS
LOG_TRACE_PARAMS(logAi, "queryID '%i'", queryID); LOG_TRACE_PARAMS(logAi, "queryID '%i'", queryID);
NET_EVENT_HANDLER; 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; HeroPtr hPtr = hero;
requestActionASAP([=]() requestActionASAP([=]()
@ -787,7 +787,7 @@ void AIGateway::makeTurn()
for (auto h : cb->getHeroesInfo()) for (auto h : cb->getHeroesInfo())
{ {
if (h->movement) 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 #if NKAI_TRACE_LEVEL == 0
} }
@ -808,7 +808,7 @@ void AIGateway::makeTurn()
void AIGateway::performObjectInteraction(const CGObjectInstance * obj, HeroPtr h) 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) switch(obj->ID)
{ {
case Obj::CREATURE_GENERATOR1: 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); assert(playerID > PlayerColor::PLAYER_LIMIT || status.getBattle() == UPCOMING_BATTLE);
status.setBattle(ONGOING_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 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); 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(); int3 startHpos = h->visitablePos();
bool ret = false; bool ret = false;
if(startHpos == dst) if(startHpos == dst)
@ -1192,7 +1192,7 @@ bool AIGateway::moveHeroToTile(int3 dst, HeroPtr h)
cb->getPathsInfo(h.get())->getPath(path, dst); cb->getPathsInfo(h.get())->getPath(path, dst);
if(path.nodes.empty()) 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; return true;
} }
int i = (int)path.nodes.size() - 1; int i = (int)path.nodes.size() - 1;
@ -1344,7 +1344,7 @@ bool AIGateway::moveHeroToTile(int3 dst, HeroPtr h)
throw cannotFulfillGoalException("Invalid path found!"); 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; return ret;
} }

View File

@ -69,7 +69,7 @@ HeroPtr::HeroPtr(const CGHeroInstance * H)
} }
h = H; h = H;
name = h->name; name = h->getNameTranslated();
hid = H->id; hid = H->id;
// infosCount[ai->playerID][hid]++; // infosCount[ai->playerID][hid]++;
} }

View File

@ -70,7 +70,7 @@ float HeroManager::evaluateSecSkill(SecondarySkill skill, const CGHeroInstance *
float HeroManager::evaluateSpeciality(const CGHeroInstance * hero) const 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 secondarySkillBonus = Selector::type()(Bonus::SECONDARY_SKILL_PREMY);
auto specialSecondarySkillBonuses = hero->getBonuses(heroSpecial.And(secondarySkillBonus)); auto specialSecondarySkillBonuses = hero->getBonuses(heroSpecial.And(secondarySkillBonus));
float specialityScore = 0.0f; float specialityScore = 0.0f;
@ -172,7 +172,7 @@ void HeroManager::update()
for(auto hero : myHeroes) 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");
} }
} }

View File

@ -78,7 +78,7 @@ void DefenceBehavior::evaluateDefence(Goals::TGoalVec & tasks, const CGTownInsta
logAi->trace( logAi->trace(
"Hero %s in garrison of town %s is suposed to defend the town", "Hero %s in garrison of town %s is suposed to defend the town",
town->garrisonHero->name, town->garrisonHero->getNameTranslated(),
town->name); town->name);
return; return;
@ -101,7 +101,7 @@ void DefenceBehavior::evaluateDefence(Goals::TGoalVec & tasks, const CGTownInsta
town->name, town->name,
treat.danger, treat.danger,
std::to_string(treat.turn), std::to_string(treat.turn),
treat.hero->name); treat.hero->getNameTranslated());
bool treatIsUnderControl = false; bool treatIsUnderControl = false;

View File

@ -69,7 +69,7 @@ std::string AbstractGoal::toString() const //TODO: virtualize
return boost::lexical_cast<std::string>(goalType); return boost::lexical_cast<std::string>(goalType);
} }
if(hero.get(true)) //FIXME: used to crash when we lost hero and failed goal if(hero.get(true)) //FIXME: used to crash when we lost hero and failed goal
desc += " (" + hero->name + ")"; desc += " (" + hero->getNameTranslated() + ")";
return desc; return desc;
} }

View File

@ -33,7 +33,7 @@ void AdventureSpellCast::accept(AIGateway * ai)
auto spell = getSpell(); 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()) if(!spell->isAdventure())
throw cannotFulfillGoalException(spell->getNameTranslated() + " is not an adventure spell."); 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()); throw cannotFulfillGoalException("Hero has not enough mana to cast " + spell->getNameTranslated());
if(spellID == SpellID::TOWN_PORTAL && town && town->visitingHero) 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) if(town && spellID == SpellID::TOWN_PORTAL)
{ {

View File

@ -54,13 +54,13 @@ void ExchangeSwapTownHeroes::accept(AIGateway * ai)
if(currentGarrisonHero.get() != town->visitingHero.get()) 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; return;
} }
ai->buildArmyIn(town); ai->buildArmyIn(town);
ai->nullkiller->unlockHero(currentGarrisonHero.get()); 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; return;
} }
@ -91,7 +91,7 @@ void ExchangeSwapTownHeroes::accept(AIGateway * ai)
ai->makePossibleUpgrades(town->visitingHero); 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);
} }
} }

View File

@ -75,7 +75,7 @@ void ExecuteHeroChain::accept(AIGateway * ai)
continue; 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 try
{ {
@ -111,7 +111,7 @@ void ExecuteHeroChain::accept(AIGateway * ai)
{ {
logAi->error( logAi->error(
"Unable to complete chain. Expected hero %s to arrive to %s in 0 turns but he cannot do this", "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()); node.coord.toString());
return; return;
@ -143,7 +143,7 @@ void ExecuteHeroChain::accept(AIGateway * ai)
if(isOk && path.nodes.back().turns > 0) 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); ai->nullkiller->lockHero(hero, HeroLockedReason::HERO_CHAIN);
return; return;
@ -162,7 +162,7 @@ void ExecuteHeroChain::accept(AIGateway * ai)
{ {
logAi->error( logAi->error(
"Enable to complete chain. Expected hero %s to arive to %s but he is at %s", "Enable to complete chain. Expected hero %s to arive to %s but he is at %s",
hero->name, hero->getNameTranslated(),
node.coord.toString(), node.coord.toString(),
hero->visitablePos().toString()); hero->visitablePos().toString());
@ -187,14 +187,14 @@ void ExecuteHeroChain::accept(AIGateway * ai)
std::string ExecuteHeroChain::toString() const 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) bool ExecuteHeroChain::moveHeroToTile(const CGHeroInstance * hero, const int3 & tile)
{ {
if(tile == hero->visitablePos() && cb->getVisitableObjs(hero->visitablePos()).size() < 2) 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; return true;
} }

View File

@ -1437,10 +1437,10 @@ std::string AIPath::toString() const
{ {
std::stringstream str; 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) 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(); return str.str();
} }

View File

@ -27,7 +27,7 @@ namespace AIPathfinding
if(!hero->visitedTown) if(!hero->visitedTown)
{ {
throw cannotFulfillGoalException( 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); ai->recruitCreatures(hero->visitedTown, hero);

View File

@ -80,7 +80,7 @@ int ChainActor::maxMovePoints(CGPathNode::ELayer layer)
std::string ChainActor::toString() const std::string ChainActor::toString() const
{ {
return hero->name; return hero->getNameTranslated();
} }
ObjectActor::ObjectActor(const CGObjectInstance * obj, const CCreatureSet * army, uint64_t chainMask, int initialTurn) ObjectActor::ObjectActor(const CGObjectInstance * obj, const CCreatureSet * army, uint64_t chainMask, int initialTurn)

View File

@ -69,7 +69,7 @@ HeroPtr::HeroPtr(const CGHeroInstance * H)
} }
h = H; h = H;
name = h->name; name = h->getNameTranslated();
hid = H->id; hid = H->id;
// infosCount[ai->playerID][hid]++; // infosCount[ai->playerID][hid]++;
} }

View File

@ -106,7 +106,7 @@ std::string AbstractGoal::name() const //TODO: virtualize
return boost::lexical_cast<std::string>(goalType); return boost::lexical_cast<std::string>(goalType);
} }
if(hero.get(true)) //FIXME: used to crash when we lost hero and failed goal if(hero.get(true)) //FIXME: used to crash when we lost hero and failed goal
desc += " (" + hero->name + ")"; desc += " (" + hero->getNameTranslated() + ")";
return desc; return desc;
} }

View File

@ -33,7 +33,7 @@ TSubgoal AdventureSpellCast::whatToDoToAchieve()
auto spell = getSpell(); 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()) if(!spell->isAdventure())
throw cannotFulfillGoalException(spell->getName() + " is not an adventure spell."); 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()); throw cannotFulfillGoalException("Hero has not enough mana to cast " + spell->getName());
if(spellID == SpellID::TOWN_PORTAL && town && town->visitingHero) 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(); return iAmElementar();
} }

View File

@ -92,7 +92,7 @@ TSubgoal CompleteQuest::whatToDoToAchieve()
result->name(), result->name(),
result->tile.toString(), result->tile.toString(),
result->objid, result->objid,
result->hero.validAndSet() ? result->hero->name : "not specified"); result->hero.validAndSet() ? result->hero->getNameTranslated() : "not specified");
return result; return result;
} }
@ -273,4 +273,4 @@ TGoalVec CompleteQuest::missionDestroyObj() const
} }
return solutions; return solutions;
} }

View File

@ -240,7 +240,7 @@ bool Explore::operator==(const Explore & other) const
std::string Explore::completeMessage() const std::string Explore::completeMessage() const
{ {
return "Hero " + hero.get()->name + " completed exploration"; return "Hero " + hero.get()->getNameTranslated() + " completed exploration";
} }
TSubgoal Explore::whatToDoToAchieve() TSubgoal Explore::whatToDoToAchieve()
@ -339,7 +339,7 @@ TGoalVec Explore::getAllPossibleSubgoals()
{ {
for(auto h : heroes) 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); TSubgoal goal = explorationNewPoint(h);

View File

@ -33,7 +33,7 @@ bool GatherArmy::operator==(const GatherArmy & other) const
std::string GatherArmy::completeMessage() const std::string GatherArmy::completeMessage() const
{ {
return "Hero " + hero.get()->name + " gathered army of value " + boost::lexical_cast<std::string>(value); return "Hero " + hero.get()->getNameTranslated() + " gathered army of value " + boost::lexical_cast<std::string>(value);
} }
TSubgoal GatherArmy::whatToDoToAchieve() TSubgoal GatherArmy::whatToDoToAchieve()

View File

@ -56,7 +56,7 @@ TSubgoal GatherTroops::whatToDoToAchieve()
{ {
if(getCreaturesCount(hero) >= this->value) 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)); throw goalFulfilledException(sptr(*this));
} }

View File

@ -33,7 +33,7 @@ bool VisitHero::operator==(const VisitHero & other) const
std::string VisitHero::completeMessage() const std::string VisitHero::completeMessage() const
{ {
return "hero " + hero.get()->name + " visited hero " + boost::lexical_cast<std::string>(objid); return "hero " + hero.get()->getNameTranslated() + " visited hero " + boost::lexical_cast<std::string>(objid);
} }
TSubgoal VisitHero::whatToDoToAchieve() TSubgoal VisitHero::whatToDoToAchieve()

View File

@ -33,7 +33,7 @@ bool VisitObj::operator==(const VisitObj & other) const
std::string VisitObj::completeMessage() const std::string VisitObj::completeMessage() const
{ {
return "hero " + hero.get()->name + " captured Object ID = " + boost::lexical_cast<std::string>(objid); return "hero " + hero.get()->getNameTranslated() + " captured Object ID = " + boost::lexical_cast<std::string>(objid);
} }
TGoalVec VisitObj::getAllPossibleSubgoals() TGoalVec VisitObj::getAllPossibleSubgoals()

View File

@ -33,7 +33,7 @@ bool VisitTile::operator==(const VisitTile & other) const
std::string VisitTile::completeMessage() 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() TSubgoal VisitTile::whatToDoToAchieve()

View File

@ -55,7 +55,7 @@ void AIPathfinder::updatePaths(std::vector<HeroPtr> heroes)
auto calculatePaths = [&](const CGHeroInstance * hero, std::shared_ptr<AIPathfinding::AIPathfinderConfig> config) auto calculatePaths = [&](const CGHeroInstance * hero, std::shared_ptr<AIPathfinding::AIPathfinderConfig> config)
{ {
logAi->debug("Recalculate paths for %s", hero->name); logAi->debug("Recalculate paths for %s", hero->getNameTranslated());
cb->calculatePaths(config); cb->calculatePaths(config);
}; };

View File

@ -303,7 +303,7 @@ void VCAI::heroExchangeStarted(ObjectInstanceID hero1, ObjectInstanceID hero2, Q
auto firstHero = cb->getHero(hero1); auto firstHero = cb->getHero(hero1);
auto secondHero = cb->getHero(hero2); 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([=]() requestActionASAP([=]()
{ {
@ -617,7 +617,7 @@ void VCAI::heroGotLevel(const CGHeroInstance * hero, PrimarySkill::PrimarySkill
{ {
LOG_TRACE_PARAMS(logAi, "queryID '%i'", queryID); LOG_TRACE_PARAMS(logAi, "queryID '%i'", queryID);
NET_EVENT_HANDLER; 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); }); requestActionASAP([=](){ answerQuery(queryID, 0); });
} }
@ -814,7 +814,7 @@ void VCAI::makeTurn()
for (auto h : cb->getHeroesInfo()) for (auto h : cb->getHeroesInfo())
{ {
if (h->movement) 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) catch (boost::thread_interrupted & e)
@ -1034,7 +1034,7 @@ void VCAI::mainLoop()
void VCAI::performObjectInteraction(const CGObjectInstance * obj, HeroPtr h) 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) switch(obj->ID)
{ {
case Obj::CREATURE_GENERATOR1: case Obj::CREATURE_GENERATOR1:
@ -1427,7 +1427,7 @@ void VCAI::wander(HeroPtr h)
{ {
//TODO pick the truly best //TODO pick the truly best
const CGTownInstance * t = *boost::max_element(townsNotReachable, compareReinforcements); 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; int3 pos1 = h->pos;
striveToGoal(sptr(Goals::ClearWayTo(t->visitablePos()).sethero(h))); //TODO: drop "strive", add to mainLoop 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 //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); assert(playerID > PlayerColor::PLAYER_LIMIT || status.getBattle() == UPCOMING_BATTLE);
status.setBattle(ONGOING_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 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); CAdventureAI::battleStart(army1, army2, tile, hero1, hero2, side);
} }
@ -1667,7 +1667,7 @@ void VCAI::validateVisitableObjs()
}); });
for(auto & p : reservedHeroesMap) 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); 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(); int3 startHpos = h->visitablePos();
bool ret = false; bool ret = false;
if(startHpos == dst) if(startHpos == dst)
@ -1828,7 +1828,7 @@ bool VCAI::moveHeroToTile(int3 dst, HeroPtr h)
cb->getPathsInfo(h.get())->getPath(path, dst); cb->getPathsInfo(h.get())->getPath(path, dst);
if(path.nodes.empty()) 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))); throw goalFulfilledException(sptr(Goals::VisitTile(dst).sethero(h)));
} }
int i = (int)path.nodes.size() - 1; int i = (int)path.nodes.size() - 1;
@ -1990,7 +1990,7 @@ bool VCAI::moveHeroToTile(int3 dst, HeroPtr h)
throw cannotFulfillGoalException("Invalid path found!"); throw cannotFulfillGoalException("Invalid path found!");
} }
evaluateGoal(h); //new hero position means new game situation 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; return ret;
} }
@ -2027,7 +2027,7 @@ void VCAI::tryRealize(Goals::VisitTile & g)
throw cannotFulfillGoalException("Cannot visit tile: hero is out of MPs!"); throw cannotFulfillGoalException("Cannot visit tile: hero is out of MPs!");
if(g.tile == g.hero->visitablePos() && cb->getVisitableObjs(g.hero->visitablePos()).size() < 2) 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)); throw goalFulfilledException(sptr(g));
} }
if(ai->moveHeroToTile(g.tile, g.hero.get())) 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!"); throw cannotFulfillGoalException("Cannot visit object: hero is out of MPs!");
if(position == g.hero->visitablePos() && cb->getVisitableObjs(g.hero->visitablePos()).size() < 2) 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)); throw goalFulfilledException(sptr(g));
} }
if(ai->moveHeroToTile(position, g.hero.get())) 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 if(!h) //hero might be lost. getUnblockedHeroes() called once on start of turn
continue; 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); makePossibleUpgrades(*h);
pickBestArtifacts(*h); pickBestArtifacts(*h);
try try

View File

@ -410,7 +410,7 @@ void CPlayerInterface::heroMoved(const TryMoveHero & details, bool verbose)
void CPlayerInterface::heroKilled(const CGHeroInstance* hero) void CPlayerInterface::heroKilled(const CGHeroInstance* hero)
{ {
EVENT_HANDLER_CALLED_BY_CLIENT; 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; const CArmedInstance *newSelection = nullptr;
if (makingTurn) if (makingTurn)
@ -1268,7 +1268,7 @@ template <typename Handler> void CPlayerInterface::serializeTempl( Handler &h, c
if (p.second.nodes.size()) if (p.second.nodes.size())
pathsMap[p.first] = p.second.endPos(); pathsMap[p.first] = p.second.endPos();
else 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; h & pathsMap;
} }

View File

@ -317,7 +317,7 @@ void ClientCommandManager::processCommand(const std::string &message, bool calle
if(what == "hs") if(what == "hs")
{ {
for(const CGHeroInstance *h : LOCPLINT->cb->getHeroesInfo()) 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))) if(const CArtifactInstance *a = h->getArt(ArtifactPosition(id2)))
printCommandMessage(a->nodeName()); printCommandMessage(a->nodeName());
} }
@ -491,4 +491,4 @@ void ClientCommandManager::printCommandMessage(const std::string &commandMessage
LOCPLINT->cingconsole->print(commandMessage); LOCPLINT->cingconsole->print(commandMessage);
} }
} }
} }

View File

@ -613,7 +613,7 @@ BattleResultWindow::BattleResultWindow(const BattleResult & br, CPlayerInterface
if (ourHero) if (ourHero)
{ {
str += CGI->generaltexth->allTexts[305]; 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<std::string>(br.exp[weAreAttacker ? 0 : 1])); boost::algorithm::replace_first(str, "%d", boost::lexical_cast<std::string>(br.exp[weAreAttacker ? 0 : 1]));
} }

View File

@ -274,10 +274,10 @@ void BattleWindow::bFleef()
//calculating fleeing hero's name //calculating fleeing hero's name
if (owner.attackingHeroInstance) if (owner.attackingHeroInstance)
if (owner.attackingHeroInstance->tempOwner == owner.curInt->cb->getMyColor()) if (owner.attackingHeroInstance->tempOwner == owner.curInt->cb->getMyColor())
heroName = owner.attackingHeroInstance->name; heroName = owner.attackingHeroInstance->getNameTranslated();
if (owner.defendingHeroInstance) if (owner.defendingHeroInstance)
if (owner.defendingHeroInstance->tempOwner == owner.curInt->cb->getMyColor()) if (owner.defendingHeroInstance->tempOwner == owner.curInt->cb->getMyColor())
heroName = owner.defendingHeroInstance->name; heroName = owner.defendingHeroInstance->getNameTranslated();
//calculating text //calculating text
auto txt = boost::format(CGI->generaltexth->allTexts[340]) % heroName; //The Shackles of War are present. %s can not retreat! 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); const auto artID = ArtifactID(blockingBonus->sid);
//If we have artifact, put name of our hero. Otherwise assume it's the enemy. //If we have artifact, put name of our hero. Otherwise assume it's the enemy.
//TODO check who *really* is source of bonus //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. //%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]) LOCPLINT->showInfoDialog(boost::str(boost::format(CGI->generaltexth->allTexts[683])

View File

@ -318,7 +318,7 @@ void CBonusSelection::createBonusesIcons()
} }
else 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; break;
} }

View File

@ -201,7 +201,7 @@ std::string OptionsTab::CPlayerSettingsHelper::getName()
if(!settings.heroName.empty()) if(!settings.heroName.empty())
return settings.heroName; return settings.heroName;
auto index = settings.hero >= CGI->heroh->size() ? 0 : settings.hero; 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: case HERO:
{ {
if(settings.hero >= 0) if(settings.hero >= 0)
return getName() + " - " + (*CGI->heroh)[heroIndex]->heroClass->name; return getName() + " - " + (*CGI->heroh)[heroIndex]->heroClass->getNameTranslated();
return getName(); return getName();
} }
@ -398,7 +398,7 @@ void OptionsTab::CPlayerOptionTooltipBox::genHeroWindow()
auto heroIndex = settings.hero >= CGI->heroh->size() ? 0 : settings.hero; auto heroIndex = settings.hero >= CGI->heroh->size() ? 0 : settings.hero;
imageSpeciality = std::make_shared<CAnimImage>("UN44", (*CGI->heroh)[heroIndex]->imageIndex, 0, pos.w / 2 - 22, 134); imageSpeciality = std::make_shared<CAnimImage>("UN44", (*CGI->heroh)[heroIndex]->imageIndex, 0, pos.w / 2 - 22, 134);
labelSpecialityName = std::make_shared<CLabel>(pos.w / 2, 188, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, (*CGI->heroh)[heroIndex]->specName); labelSpecialityName = std::make_shared<CLabel>(pos.w / 2, 188, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, (*CGI->heroh)[heroIndex]->getSpecialtyNameTranslated());
} }
void OptionsTab::CPlayerOptionTooltipBox::genBonusWindow() void OptionsTab::CPlayerOptionTooltipBox::genBonusWindow()

View File

@ -960,7 +960,7 @@ CMapHandler::AnimBitmapHolder CMapHandler::CMapBlitter::findHeroBitmap(const CGH
{ {
if(hero->tempOwner >= PlayerColor::PLAYER_LIMIT) //Neutral hero? 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(); return CMapHandler::AnimBitmapHolder();
} }

View File

@ -242,7 +242,7 @@ void CHeroList::CHeroItem::showTooltip()
std::string CHeroList::CHeroItem::getHoverText() 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<CIntObject> CHeroList::createHeroItem(size_t index) std::shared_ptr<CIntObject> CHeroList::createHeroItem(size_t index)

View File

@ -353,25 +353,25 @@ void CHeroGSlot::hover(bool on)
if(isSelected())//view NNN if(isSelected())//view NNN
{ {
temp = CGI->generaltexth->tcommands[4]; 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 else if(other->hero && other->isSelected())//exchange
{ {
temp = CGI->generaltexth->tcommands[7]; temp = CGI->generaltexth->tcommands[7];
boost::algorithm::replace_first(temp,"%s",hero->name); boost::algorithm::replace_first(temp,"%s",hero->getNameTranslated());
boost::algorithm::replace_first(temp,"%s",other->hero->name); boost::algorithm::replace_first(temp,"%s",other->hero->getNameTranslated());
} }
else// select NNN (in ZZZ) else// select NNN (in ZZZ)
{ {
if(upg)//down - visiting if(upg)//down - visiting
{ {
temp = CGI->generaltexth->tcommands[32]; temp = CGI->generaltexth->tcommands[32];
boost::algorithm::replace_first(temp,"%s",hero->name); boost::algorithm::replace_first(temp,"%s",hero->getNameTranslated());
} }
else //up - garrison else //up - garrison
{ {
temp = CGI->generaltexth->tcommands[12]; 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 if(other->isSelected() && other->hero) //move NNNN
{ {
temp = CGI->generaltexth->tcommands[6]; 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 else //empty
{ {

View File

@ -211,19 +211,19 @@ void CHeroWindow::update(const CGHeroInstance * hero, bool redrawNeeded)
assert(hero == curHero); assert(hero == curHero);
name->setText(curHero->name); name->setText(curHero->getNameTranslated());
title->setText((boost::format(CGI->generaltexth->allTexts[342]) % curHero->level % curHero->type->heroClass->name).str()); 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); specImage->setFrame(curHero->type->imageIndex);
specName->setText(curHero->type->specName); specName->setText(curHero->type->getSpecialtyNameTranslated());
tacticsButton = std::make_shared<CToggleButton>(Point(539, 483), "hsbtns8.def", std::make_pair(heroscrn[26], heroscrn[31]), 0, SDLK_b); tacticsButton = std::make_shared<CToggleButton>(Point(539, 483), "hsbtns8.def", std::make_pair(heroscrn[26], heroscrn[31]), 0, SDLK_b);
tacticsButton->addHoverText(CButton::HIGHLIGHTED, CGI->generaltexth->heroscrn[25]); 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)); 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->name % curHero->type->heroClass->name); portraitArea->hoverText = boost::str(boost::format(CGI->generaltexth->allTexts[15]) % curHero->getNameTranslated() % curHero->type->heroClass->getNameTranslated());
portraitArea->text = curHero->getBiography(); portraitArea->text = curHero->getBiographyTranslated();
portraitImage->setFrame(curHero->portrait); 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 //printing spell points, boost::format can't be used due to locale issues
spellPointsArea->text = CGI->generaltexth->allTexts[205]; spellPointsArea->text = CGI->generaltexth->allTexts[205];
boost::replace_first(spellPointsArea->text, "%s", boost::lexical_cast<std::string>(curHero->name)); boost::replace_first(spellPointsArea->text, "%s", boost::lexical_cast<std::string>(curHero->getNameTranslated()));
boost::replace_first(spellPointsArea->text, "%d", boost::lexical_cast<std::string>(curHero->mana)); boost::replace_first(spellPointsArea->text, "%d", boost::lexical_cast<std::string>(curHero->mana));
boost::replace_first(spellPointsArea->text, "%d", boost::lexical_cast<std::string>(heroWArt.manaLimit())); boost::replace_first(spellPointsArea->text, "%d", boost::lexical_cast<std::string>(heroWArt.manaLimit()));

View File

@ -163,7 +163,7 @@ std::string InfoBoxAbstractHeroData::getNameText()
case HERO_EXPERIENCE: case HERO_EXPERIENCE:
return CGI->generaltexth->jktexts[6]; return CGI->generaltexth->jktexts[6];
case HERO_SPECIAL: case HERO_SPECIAL:
return CGI->heroh->objects[getSubID()]->specName; return CGI->heroh->objects[getSubID()]->getSpecialtyNameTranslated();
case HERO_SECONDARY_SKILL: case HERO_SECONDARY_SKILL:
if (getValue()) if (getValue())
return CGI->skillh->getByIndex(getSubID())->getNameTranslated(); return CGI->skillh->getByIndex(getSubID())->getNameTranslated();
@ -256,7 +256,7 @@ void InfoBoxAbstractHeroData::prepareMessage(std::string & text, std::shared_ptr
switch (type) switch (type)
{ {
case HERO_SPECIAL: case HERO_SPECIAL:
text = CGI->heroh->objects[getSubID()]->specDescr; text = CGI->heroh->objects[getSubID()]->getSpecialtyDescriptionTranslated();
break; break;
case HERO_PRIMARY_SKILL: case HERO_PRIMARY_SKILL:
text = CGI->generaltexth->arraytxt[2+getSubID()]; text = CGI->generaltexth->arraytxt[2+getSubID()];
@ -303,7 +303,7 @@ int InfoBoxHeroData::getSubID()
else else
return 0; return 0;
case HERO_SPECIAL: case HERO_SPECIAL:
return hero->type->ID.getNum(); return hero->type->getIndex();
case HERO_MANA: case HERO_MANA:
case HERO_EXPERIENCE: case HERO_EXPERIENCE:
return 0; return 0;
@ -390,7 +390,7 @@ void InfoBoxHeroData::prepareMessage(std::string & text, std::shared_ptr<CCompon
{ {
case HERO_MANA: case HERO_MANA:
text = CGI->generaltexth->allTexts[205]; text = CGI->generaltexth->allTexts[205];
boost::replace_first(text, "%s", boost::lexical_cast<std::string>(hero->name)); boost::replace_first(text, "%s", boost::lexical_cast<std::string>(hero->getNameTranslated()));
boost::replace_first(text, "%d", boost::lexical_cast<std::string>(hero->mana)); boost::replace_first(text, "%d", boost::lexical_cast<std::string>(hero->mana));
boost::replace_first(text, "%d", boost::lexical_cast<std::string>(hero->manaLimit())); boost::replace_first(text, "%d", boost::lexical_cast<std::string>(hero->manaLimit()));
break; break;
@ -863,7 +863,7 @@ CHeroItem::CHeroItem(const CGHeroInstance * Hero)
arts2->recActions = SHARE_POS; arts2->recActions = SHARE_POS;
backpack->recActions = SHARE_POS; backpack->recActions = SHARE_POS;
name = std::make_shared<CLabel>(75, 7, FONT_SMALL, ETextAlignment::TOPLEFT, Colors::WHITE, hero->name); name = std::make_shared<CLabel>(75, 7, FONT_SMALL, ETextAlignment::TOPLEFT, Colors::WHITE, hero->getNameTranslated());
//layout is not trivial: MACH4 - catapult - excluded, MISC[x] rearranged //layout is not trivial: MACH4 - catapult - excluded, MISC[x] rearranged
assert(arts1->arts.size() == 9); assert(arts1->arts.size() == 9);
@ -919,7 +919,7 @@ CHeroItem::CHeroItem(const CGHeroInstance * Hero)
portrait = std::make_shared<CAnimImage>("PortraitsLarge", hero->portrait, 0, 5, 6); portrait = std::make_shared<CAnimImage>("PortraitsLarge", hero->portrait, 0, 5, 6);
heroArea = std::make_shared<CHeroArea>(5, 6, hero); heroArea = std::make_shared<CHeroArea>(5, 6, hero);
name = std::make_shared<CLabel>(73, 7, FONT_SMALL, ETextAlignment::TOPLEFT, Colors::WHITE, hero->name); name = std::make_shared<CLabel>(73, 7, FONT_SMALL, ETextAlignment::TOPLEFT, Colors::WHITE, hero->getNameTranslated());
artsText = std::make_shared<CLabel>(320, 55, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, CGI->generaltexth->overview[2]); artsText = std::make_shared<CLabel>(320, 55, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, CGI->generaltexth->overview[2]);
for(size_t i=0; i<GameConstants::PRIMARY_SKILLS; i++) for(size_t i=0; i<GameConstants::PRIMARY_SKILLS; i++)

View File

@ -738,11 +738,11 @@ CMarketplaceWindow::CMarketplaceWindow(const IMarket * Market, const CGHeroInsta
break; break;
case EMarketMode::CREATURE_RESOURCE: case EMarketMode::CREATURE_RESOURCE:
//%s's Creatures //%s's Creatures
labels.push_back(std::make_shared<CLabel>(152, 102, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, boost::str(boost::format(CGI->generaltexth->allTexts[272]) % hero->name))); labels.push_back(std::make_shared<CLabel>(152, 102, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, boost::str(boost::format(CGI->generaltexth->allTexts[272]) % hero->getNameTranslated())));
break; break;
case EMarketMode::ARTIFACT_RESOURCE: case EMarketMode::ARTIFACT_RESOURCE:
//%s's Artifacts //%s's Artifacts
labels.push_back(std::make_shared<CLabel>(152, 56, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, boost::str(boost::format(CGI->generaltexth->allTexts[271]) % hero->name))); labels.push_back(std::make_shared<CLabel>(152, 56, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, boost::str(boost::format(CGI->generaltexth->allTexts[271]) % hero->getNameTranslated())));
break; break;
} }
@ -1099,7 +1099,7 @@ CAltarWindow::CAltarWindow(const IMarket * Market, const CGHeroInstance * Hero,
{ {
//%s's Creatures //%s's Creatures
labels.push_back(std::make_shared<CLabel>(155, 30, FONT_SMALL, ETextAlignment::CENTER, Colors::YELLOW, labels.push_back(std::make_shared<CLabel>(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 //Altar of Sacrifice
labels.push_back(std::make_shared<CLabel>(450, 30, FONT_SMALL, ETextAlignment::CENTER, Colors::YELLOW, CGI->generaltexth->allTexts[479])); labels.push_back(std::make_shared<CLabel>(450, 30, FONT_SMALL, ETextAlignment::CENTER, Colors::YELLOW, CGI->generaltexth->allTexts[479]));

View File

@ -404,11 +404,11 @@ CLevelWindow::CLevelWindow(const CGHeroInstance * hero, PrimarySkill::PrimarySki
ok = std::make_shared<CButton>(Point(297, 413), "IOKAY", CButton::tooltip(), std::bind(&CLevelWindow::close, this), SDLK_RETURN); ok = std::make_shared<CButton>(Point(297, 413), "IOKAY", CButton::tooltip(), std::bind(&CLevelWindow::close, this), SDLK_RETURN);
//%s has gained a level. //%s has gained a level.
mainTitle = std::make_shared<CLabel>(192, 33, FONT_MEDIUM, ETextAlignment::CENTER, Colors::WHITE, boost::str(boost::format(CGI->generaltexth->allTexts[444]) % hero->name)); mainTitle = std::make_shared<CLabel>(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. //%s is now a level %d %s.
levelTitle = std::make_shared<CLabel>(192, 162, FONT_MEDIUM, ETextAlignment::CENTER, Colors::WHITE, levelTitle = std::make_shared<CLabel>(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<CAnimImage>("PSKIL42", pskill, 0, 174, 190); skillIcon = std::make_shared<CAnimImage>("PSKIL42", pskill, 0, 174, 190);
@ -743,7 +743,7 @@ void CTavernWindow::show(SDL_Surface * to)
oldSelected = selected; oldSelected = selected;
//Recruit %s the %s //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); 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) if(H)
{ {
hoverName = CGI->generaltexth->tavernInfo[4]; 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(); int artifs = (int)h->artifactsWorn.size() + (int)h->artifactsInBackpack.size();
for(int i=13; i<=17; i++) //war machines and spellbook don't count 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--; artifs--;
description = CGI->generaltexth->allTexts[215]; 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<std::string>(h->level)); boost::algorithm::replace_first(description, "%d", boost::lexical_cast<std::string>(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<std::string>(artifs)); boost::algorithm::replace_first(description, "%d", boost::lexical_cast<std::string>(artifs));
portrait = std::make_shared<CAnimImage>("portraitsLarge", h->portrait); portrait = std::make_shared<CAnimImage>("portraitsLarge", h->portrait);
@ -1078,7 +1078,7 @@ CExchangeWindow::CExchangeWindow(ObjectInstanceID hero1, ObjectInstanceID hero2,
auto genTitle = [](const CGHeroInstance * h) auto genTitle = [](const CGHeroInstance * h)
{ {
boost::format fmt(CGI->generaltexth->allTexts[138]); 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); return boost::str(fmt);
}; };
@ -1178,7 +1178,7 @@ CExchangeWindow::CExchangeWindow(ObjectInstanceID hero1, ObjectInstanceID hero2,
specialtyAreas[b] = std::make_shared<LRClickableAreaWText>(); specialtyAreas[b] = std::make_shared<LRClickableAreaWText>();
specialtyAreas[b]->pos = genRect(32, 32, pos.x + 69 + 490*b, pos.y + (qeLayout ? 41 : 45)); 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]->hoverText = CGI->generaltexth->heroscrn[27];
specialtyAreas[b]->text = hero->type->specDescr; specialtyAreas[b]->text = hero->type->getSpecialtyDescriptionTranslated();
experienceAreas[b] = std::make_shared<LRClickableAreaWText>(); experienceAreas[b] = std::make_shared<LRClickableAreaWText>();
experienceAreas[b]->pos = genRect(32, 32, pos.x + 105 + 490*b, pos.y + (qeLayout ? 41 : 45)); 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]->pos = genRect(32, 32, pos.x + 141 + 490*b, pos.y + (qeLayout ? 41 : 45));
spellPointsAreas[b]->hoverText = CGI->generaltexth->heroscrn[22]; spellPointsAreas[b]->hoverText = CGI->generaltexth->heroscrn[22];
spellPointsAreas[b]->text = CGI->generaltexth->allTexts[205]; 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<std::string>(hero->mana)); boost::algorithm::replace_first(spellPointsAreas[b]->text, "%d", boost::lexical_cast<std::string>(hero->mana));
boost::algorithm::replace_first(spellPointsAreas[b]->text, "%d", boost::lexical_cast<std::string>(hero->manaLimit())); boost::algorithm::replace_first(spellPointsAreas[b]->text, "%d", boost::lexical_cast<std::string>(hero->manaLimit()));

View File

@ -18,7 +18,11 @@ class HeroClassID;
class DLL_LINKAGE HeroClass : public EntityT<HeroClassID> class DLL_LINKAGE HeroClass : public EntityT<HeroClassID>
{ {
using EntityT<HeroClassID>::getName;
public: public:
virtual std::string getNameTranslated() const = 0;
virtual std::string getNameTextID() const = 0;
}; };

View File

@ -18,7 +18,19 @@ class HeroTypeID;
class DLL_LINKAGE HeroType : public EntityT<HeroTypeID> class DLL_LINKAGE HeroType : public EntityT<HeroTypeID>
{ {
using EntityT<HeroTypeID>::getName;
public: 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;
}; };

View File

@ -1451,7 +1451,7 @@ void CGameState::initHeroes()
hero->initHero(getRandomGenerator()); hero->initHero(getRandomGenerator());
getPlayerState(hero->getOwner())->heroes.push_back(hero); 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 for(auto obj : map->objects) //prisons
@ -1468,7 +1468,7 @@ void CGameState::initHeroes()
ph->initHero(getRandomGenerator()); ph->initHero(getRandomGenerator());
hpool.heroesPool[ph->subID] = ph; hpool.heroesPool[ph->subID] = ph;
hpool.pavailable[ph->subID] = 0xff; hpool.pavailable[ph->subID] = 0xff;
heroesToCreate.erase(ph->type->ID); heroesToCreate.erase(ph->type->getId());
map->allHeroes[ph->subID] = ph; map->allHeroes[ph->subID] = ph;
} }
@ -2796,7 +2796,7 @@ std::set<HeroTypeID> CGameState::getUnusedAllowedHeroes(bool alsoIncludeNotAllow
for(auto hero : map->heroesOnMap) //heroes instances initialization for(auto hero : map->heroesOnMap) //heroes instances initialization
{ {
if(hero->type) if(hero->type)
ret -= hero->type->ID; ret -= hero->type->getId();
else else
ret -= HeroTypeID(hero->subID); ret -= HeroTypeID(hero->subID);
} }
@ -2918,7 +2918,7 @@ CGHeroInstance * CGameState::getUsedHero(HeroTypeID hid) const
{ {
for(auto hero : map->heroesOnMap) //heroes instances initialization for(auto hero : map->heroesOnMap) //heroes instances initialization
{ {
if(hero->type && hero->type->ID == hid) if(hero->type && hero->type->getId() == hid)
{ {
return hero; return hero;
} }
@ -2930,7 +2930,7 @@ CGHeroInstance * CGameState::getUsedHero(HeroTypeID hid) const
{ {
auto hero = dynamic_cast<CGHeroInstance *>(obj.get()); auto hero = dynamic_cast<CGHeroInstance *>(obj.get());
assert(hero); assert(hero);
if ( hero->type && hero->type->ID == hid ) if ( hero->type && hero->type->getId() == hid )
return hero; return hero;
} }
} }
@ -3024,7 +3024,7 @@ void InfoAboutHero::initFromHero(const CGHeroInstance *h, InfoAboutHero::EInfoLe
initFromArmy(h, detailed); initFromArmy(h, detailed);
hclass = h->type->heroClass; hclass = h->type->heroClass;
name = h->name; name = h->getNameTranslated();
portrait = h->portrait; portrait = h->portrait;
if(detailed) if(detailed)

View File

@ -43,7 +43,7 @@ int32_t CHero::getIconIndex() const
const std::string & CHero::getName() const const std::string & CHero::getName() const
{ {
return name; return identifier;
} }
const std::string & CHero::getJsonKey() const const std::string & CHero::getJsonKey() const
@ -56,6 +56,56 @@ HeroTypeID CHero::getId() const
return ID; 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 void CHero::registerIcons(const IconRegistar & cb) const
{ {
cb(getIconIndex(), 0, "UN32", iconSpecSmall); cb(getIconIndex(), 0, "UN32", iconSpecSmall);
@ -120,7 +170,7 @@ int32_t CHeroClass::getIconIndex() const
const std::string & CHeroClass::getName() const const std::string & CHeroClass::getName() const
{ {
return name; return identifier;
} }
const std::string & CHeroClass::getJsonKey() const 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) void CHeroClass::updateFrom(const JsonNode & data)
{ {
//TODO: CHeroClass::updateFrom //TODO: CHeroClass::updateFrom
@ -164,7 +224,7 @@ void CHeroClassHandler::fillPrimarySkillData(const JsonNode & node, CHeroClass *
if(currentPrimarySkillValue < primarySkillLegalMinimum) if(currentPrimarySkillValue < primarySkillLegalMinimum)
{ {
logMod->error("Hero class '%s' has incorrect initial value '%d' for skill '%s'. Value '%d' will be used instead.", 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; currentPrimarySkillValue = primarySkillLegalMinimum;
} }
heroClass->primarySkillInitial.push_back(currentPrimarySkillValue); 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->imageMapFemale = node["animation"]["map"]["female"].String();
heroClass->imageMapMale = node["animation"]["map"]["male"].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()); heroClass->affinity = vstd::find_pos(affinityStr, node["affinity"].String());
fillPrimarySkillData(node, heroClass, PrimarySkill::ATTACK); 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->sex = node["female"].Bool();
hero->special = node["special"].Bool(); hero->special = node["special"].Bool();
hero->name = node["texts"]["name"].String(); VLC->generaltexth->registerString( hero->getNameTextID(), node["texts"]["name"].String());
hero->biography = node["texts"]["biography"].String(); VLC->generaltexth->registerString( hero->getBiographyTextID(), node["texts"]["biography"].String());
hero->specName = node["texts"]["specialty"]["name"].String(); VLC->generaltexth->registerString( hero->getSpecialtyNameTextID(), node["texts"]["specialty"]["name"].String());
hero->specTooltip = node["texts"]["specialty"]["tooltip"].String(); VLC->generaltexth->registerString( hero->getSpecialtyTooltipTextID(), node["texts"]["specialty"]["tooltip"].String());
hero->specDescr = node["texts"]["specialty"]["description"].String(); VLC->generaltexth->registerString( hero->getSpecialtyDescriptionTextID(), node["texts"]["specialty"]["description"].String());
hero->iconSpecSmall = node["images"]["specialtySmall"].String(); hero->iconSpecSmall = node["images"]["specialtySmall"].String();
hero->iconSpecLarge = node["images"]["specialtyLarge"].String(); hero->iconSpecLarge = node["images"]["specialtyLarge"].String();
@ -703,7 +764,7 @@ void CHeroHandler::loadHeroSpecialty(CHero * hero, const JsonNode & node)
const JsonNode & specialtiesNode = node["specialties"]; const JsonNode & specialtiesNode = node["specialties"];
if (!specialtiesNode.isNull()) 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()) for(const JsonNode &specialty : specialtiesNode.Vector())
{ {
SSpecialtyInfo spec; SSpecialtyInfo spec;
@ -892,7 +953,7 @@ void CHeroHandler::afterLoadFinalization()
if(hero->specDeprecated.size() > 0 || hero->specialtyDeprecated.size() > 0) 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<std::shared_ptr<Bonus>> convertedBonuses; std::vector<std::shared_ptr<Bonus>> convertedBonuses;
for(const SSpecialtyInfo & spec : hero->specDeprecated) for(const SSpecialtyInfo & spec : hero->specDeprecated)
{ {

View File

@ -30,7 +30,8 @@ class JsonSerializeFormat;
class BattleField; class BattleField;
struct SSpecialtyInfo struct SSpecialtyInfo
{ si32 type; {
si32 type;
si32 val; si32 val;
si32 subtype; si32 subtype;
si32 additionalinfo; si32 additionalinfo;
@ -57,6 +58,16 @@ struct SSpecialtyBonus
class DLL_LINKAGE CHero : public HeroType 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: public:
struct InitialArmyStack struct InitialArmyStack
{ {
@ -71,8 +82,6 @@ public:
h & creature; h & creature;
} }
}; };
std::string identifier;
HeroTypeID ID;
si32 imageIndex; si32 imageIndex;
std::vector<InitialArmyStack> initialArmy; std::vector<InitialArmyStack> 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 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 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 /// Graphics
std::string iconSpecSmall; std::string iconSpecSmall;
std::string iconSpecLarge; std::string iconSpecLarge;
@ -106,11 +108,22 @@ public:
int32_t getIndex() const override; int32_t getIndex() const override;
int32_t getIconIndex() const override; int32_t getIconIndex() const override;
const std::string & getName() const override;
const std::string & getJsonKey() const override; const std::string & getJsonKey() const override;
HeroTypeID getId() const override; HeroTypeID getId() const override;
void registerIcons(const IconRegistar & cb) 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 updateFrom(const JsonNode & data);
void serializeJson(JsonSerializeFormat & handler); void serializeJson(JsonSerializeFormat & handler);
@ -126,11 +139,8 @@ public:
h & haveSpellBook; h & haveSpellBook;
h & sex; h & sex;
h & special; h & special;
h & name; h & nameTextID;
h & biography; h & biographyTextID;
h & specName;
h & specDescr;
h & specTooltip;
h & iconSpecSmall; h & iconSpecSmall;
h & iconSpecLarge; h & iconSpecLarge;
h & portraitSmall; h & portraitSmall;
@ -146,6 +156,13 @@ std::vector<std::shared_ptr<Bonus>> SpecialtyBonusToBonuses(const SSpecialtyBonu
class DLL_LINKAGE CHeroClass : public HeroClass 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: public:
enum EClassAffinity enum EClassAffinity
{ {
@ -153,11 +170,8 @@ public:
MAGIC MAGIC
}; };
std::string identifier;
std::string name; // translatable
//double aggression; // not used in vcmi. //double aggression; // not used in vcmi.
TFaction faction; TFaction faction;
HeroClassID id;
ui8 affinity; // affinity, using EClassAffinity enum ui8 affinity; // affinity, using EClassAffinity enum
// default chance for hero of specific class to appear in tavern, if field "tavern" was not set // 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 getIndex() const override;
int32_t getIconIndex() const override; int32_t getIconIndex() const override;
const std::string & getName() const override;
const std::string & getJsonKey() const override; const std::string & getJsonKey() const override;
HeroClassID getId() const override; HeroClassID getId() const override;
void registerIcons(const IconRegistar & cb) const override; void registerIcons(const IconRegistar & cb) const override;
std::string getNameTranslated() const override;
std::string getNameTextID() const override;
bool isMagicHero() const; bool isMagicHero() const;
SecondarySkill chooseSecSkill(const std::set<SecondarySkill> & possibles, CRandomGenerator & rand) const; //picks secondary skill out from given possibilities SecondarySkill chooseSecSkill(const std::set<SecondarySkill> & possibles, CRandomGenerator & rand) const; //picks secondary skill out from given possibilities
@ -196,8 +212,9 @@ public:
template <typename Handler> void serialize(Handler & h, const int version) template <typename Handler> void serialize(Handler & h, const int version)
{ {
h & modScope;
h & identifier; h & identifier;
h & name; h & nameTextID;
h & faction; h & faction;
h & id; h & id;
h & defaultTavernChance; h & defaultTavernChance;

View File

@ -1606,7 +1606,7 @@ std::string Bonus::Description() const
str << VLC->skillh->getByIndex(sid)->getNameTranslated(); str << VLC->skillh->getByIndex(sid)->getNameTranslated();
break; break;
case HERO_SPECIAL: case HERO_SPECIAL:
str << VLC->heroh->objects[sid]->name; str << VLC->heroh->objects[sid]->getNameTranslated();
break; break;
default: default:
//todo: handle all possible sources //todo: handle all possible sources

View File

@ -327,7 +327,7 @@ void CBank::doVisit(const CGHeroInstance * hero) const
iw.text.addTxt(MetaString::ADVOB_TXT, 186); iw.text.addTxt(MetaString::ADVOB_TXT, 186);
iw.text.addReplacement(loot.buildList()); iw.text.addReplacement(loot.buildList());
iw.text.addReplacement(hero->name); iw.text.addReplacement(hero->getNameTranslated());
cb->showInfoDialog(&iw); cb->showInfoDialog(&iw);
cb->giveCreatures(this, hero, ourArmy, false); cb->giveCreatures(this, hero, ourArmy, false);
} }

View File

@ -65,7 +65,7 @@ static int lowestSpeed(const CGHeroInstance * chi)
return chi->commander->valOfBonuses(selectorSTACKS_SPEED, keySTACKS_SPEED); 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; return 20;
} }
@ -309,8 +309,6 @@ void CGHeroInstance::initHero(CRandomGenerator & rand)
} }
if(secSkills.size() == 1 && secSkills[0] == std::pair<SecondarySkill,ui8>(SecondarySkill::DEFAULT, -1)) //set secondary skills to default if(secSkills.size() == 1 && secSkills[0] == std::pair<SecondarySkill,ui8>(SecondarySkill::DEFAULT, -1)) //set secondary skills to default
secSkills = type->secSkillsInit; secSkills = type->secSkillsInit;
if (!name.length())
name = type->name;
if (sex == 0xFF)//sex is default if (sex == 0xFF)//sex is default
sex = type->sex; sex = type->sex;
@ -373,7 +371,7 @@ void CGHeroInstance::initArmy(CRandomGenerator & rand, IArmyDescriptor * dst)
if(creature == nullptr) 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; continue;
} }
@ -394,11 +392,11 @@ void CGHeroInstance::initArmy(CRandomGenerator & rand, IArmyDescriptor * dst)
if(!getArt(slot)) if(!getArt(slot))
putArtifact(slot, CArtifactInstance::createNewArtifactInstance(aid)); putArtifact(slot, CArtifactInstance::createNewArtifactInstance(aid));
else 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 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 else
@ -469,21 +467,14 @@ std::string CGHeroInstance::getObjectName() const
if(ID != Obj::PRISON) if(ID != Obj::PRISON)
{ {
std::string hoverName = VLC->generaltexth->allTexts[15]; std::string hoverName = VLC->generaltexth->allTexts[15];
boost::algorithm::replace_first(hoverName,"%s",name); boost::algorithm::replace_first(hoverName,"%s",getNameTranslated());
boost::algorithm::replace_first(hoverName,"%s", type->heroClass->name); boost::algorithm::replace_first(hoverName,"%s", type->heroClass->getNameTranslated());
return hoverName; return hoverName;
} }
else else
return CGObjectInstance::getObjectName(); return CGObjectInstance::getObjectName();
} }
const std::string & CGHeroInstance::getBiography() const
{
if (biography.length())
return biography;
return type->biography;
}
ui8 CGHeroInstance::maxlevelsToMagicSchool() const ui8 CGHeroInstance::maxlevelsToMagicSchool() const
{ {
return type->heroClass->isMagicHero() ? 3 : 4; return type->heroClass->isMagicHero() ? 3 : 4;
@ -536,14 +527,13 @@ void CGHeroInstance::initObj(CRandomGenerator & rand)
for(std::shared_ptr<Bonus> b : sb.bonuses) for(std::shared_ptr<Bonus> b : sb.bonuses)
addNewBonus(b); addNewBonus(b);
for(SSpecialtyInfo & spec : type->specDeprecated) for(SSpecialtyInfo & spec : type->specDeprecated)
for(std::shared_ptr<Bonus> b : SpecialtyInfoToBonuses(spec, type->ID.getNum())) for(std::shared_ptr<Bonus> b : SpecialtyInfoToBonuses(spec, type->getIndex()))
addNewBonus(b); addNewBonus(b);
//initialize bonuses //initialize bonuses
recreateSecondarySkillsBonuses(); recreateSecondarySkillsBonuses();
mana = manaLimit(); //after all bonuses are taken into account, make sure this line is the last one mana = manaLimit(); //after all bonuses are taken into account, make sure this line is the last one
type->name = name;
} }
void CGHeroInstance::recreateSecondarySkillsBonuses() void CGHeroInstance::recreateSecondarySkillsBonuses()
@ -686,7 +676,7 @@ PlayerColor CGHeroInstance::getCasterOwner() const
void CGHeroInstance::getCasterName(MetaString & text) const void CGHeroInstance::getCasterName(MetaString & text) const
{ {
//FIXME: use local name, MetaString need access to gamestate as hero name is part of map object //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<const battle::Unit *> & attacked, MetaString & text) const void CGHeroInstance::getCastDescription(const spells::Spell * spell, const std::vector<const battle::Unit *> & attacked, MetaString & text) const
@ -995,7 +985,39 @@ void CGHeroInstance::initExp(CRandomGenerator & rand)
std::string CGHeroInstance::nodeName() const 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) void CGHeroInstance::putArtifact(ArtifactPosition pos, CArtifactInstance *art)
@ -1230,7 +1252,7 @@ PrimarySkill::PrimarySkill CGHeroInstance::nextPrimarySkill(CRandomGenerator & r
if(primarySkill >= GameConstants::PRIMARY_SKILLS) if(primarySkill >= GameConstants::PRIMARY_SKILLS)
{ {
primarySkill = rand.nextInt(GameConstants::PRIMARY_SKILLS - 1); 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; randomValue = 100 / GameConstants::PRIMARY_SKILLS;
} }
logGlobal->trace("The hero gets the primary skill %d with a probability of %d %%.", primarySkill, randomValue); 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) if(type)
{ {
return type->identifier; return type->getJsonKey();
} }
else else
{ {
return VLC->heroh->objects[subID]->identifier; return VLC->heroh->objects[subID]->getJsonKey();
} }
} }
return ""; return "";
@ -1421,7 +1443,7 @@ void CGHeroInstance::updateFrom(const JsonNode & data)
void CGHeroInstance::serializeCommonOptions(JsonSerializeFormat & handler) void CGHeroInstance::serializeCommonOptions(JsonSerializeFormat & handler)
{ {
handler.serializeString("biography", biography); handler.serializeString("biography", biographyCustom);
handler.serializeInt("experience", exp, 0); handler.serializeInt("experience", exp, 0);
if(!handler.saving && exp != 0xffffffff) //do not gain levels if experience is not initialized 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<ui8>("female", sex, 1, 0, 0xFF); handler.serializeBool<ui8>("female", sex, 1, 0, 0xFF);
{ {

View File

@ -45,11 +45,13 @@ class DLL_LINKAGE CGHeroInstance : public CArmedInstance, public IBoatGenerator,
// We serialize heroes into JSON for crossover // We serialize heroes into JSON for crossover
friend class CCampaignState; friend class CCampaignState;
friend class CMapLoaderH3M; friend class CMapLoaderH3M;
friend class CMapFormatJson;
private: private:
std::set<SpellID> spells; //known spells (spell IDs) std::set<SpellID> spells; //known spells (spell IDs)
public: public:
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
ui8 moveDir; //format: 123 ui8 moveDir; //format: 123
@ -62,13 +64,15 @@ public:
ConstTransitivePtr<CHero> type; ConstTransitivePtr<CHero> type;
TExpType exp; //experience points TExpType exp; //experience points
ui32 level; //current level of hero ui32 level; //current level of hero
std::string name; //may be custom
std::string biography; //if custom
si32 portrait; //may be custom si32 portrait; //may be custom
si32 mana; // remaining spell points si32 mana; // remaining spell points
std::vector<std::pair<SecondarySkill,ui8> > 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 std::vector<std::pair<SecondarySkill,ui8> > 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 ui32 movement; //remaining movement points
ui8 sex; ui8 sex;
std::string nameCustom;
std::string biographyCustom;
bool inTownGarrison; // if hero is in town garrison bool inTownGarrison; // if hero is in town garrison
ConstTransitivePtr<CGTownInstance> visitedTown; //set if hero is visiting town or in the town garrison ConstTransitivePtr<CGTownInstance> visitedTown; //set if hero is visiting town or in the town garrison
ConstTransitivePtr<CCommanderInstance> commander; ConstTransitivePtr<CCommanderInstance> 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; bool hasSpellbook() const;
int maxSpellLevel() const; int maxSpellLevel() const;
void addSpellToSpellbook(SpellID spell); void addSpellToSpellbook(SpellID spell);
@ -153,7 +163,6 @@ public:
void removeSpellbook(); void removeSpellbook();
const std::set<SpellID> & getSpellsInSpellbook() const; const std::set<SpellID> & getSpellsInSpellbook() const;
EAlignment::EAlignment getAlignment() const; EAlignment::EAlignment getAlignment() const;
const std::string &getBiography() const;
bool needsLastStack()const override; 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 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<CArtifactSet&>(*this); h & static_cast<CArtifactSet&>(*this);
h & exp; h & exp;
h & level; h & level;
h & name; h & nameCustom;
h & biography; h & biographyCustom;
h & portrait; h & portrait;
h & mana; h & mana;
h & secSkills; h & secSkills;

View File

@ -102,7 +102,7 @@ void CGPandoraBox::giveContentsUpToExp(const CGHeroInstance *h) const
TExpType expVal = h->calculateXp(gainedExp); TExpType expVal = h->calculateXp(gainedExp);
//getText(iw,afterBattle,175,h); //wtf? //getText(iw,afterBattle,175,h); //wtf?
iw.text.addTxt(MetaString::ADVOB_TXT, 175); //%s learns something iw.text.addTxt(MetaString::ADVOB_TXT, 175); //%s learns something
iw.text.addReplacement(h->name); iw.text.addReplacement(h->getNameTranslated());
if(expVal) if(expVal)
iw.components.push_back(Component(Component::EXPERIENCE,0,static_cast<si32>(expVal),0)); iw.components.push_back(Component(Component::EXPERIENCE,0,static_cast<si32>(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.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->changeSpells(h, true, spellsToGive);
cb->showInfoDialog(&iw); cb->showInfoDialog(&iw);
} }
@ -249,7 +249,7 @@ void CGPandoraBox::giveContentsAfterExp(const CGHeroInstance *h) const
iw.components.clear(); iw.components.clear();
// getText(iw,afterBattle,183,h); // getText(iw,afterBattle,183,h);
iw.text.addTxt(MetaString::ADVOB_TXT, 183); //% has found treasure iw.text.addTxt(MetaString::ADVOB_TXT, 183); //% has found treasure
iw.text.addReplacement(h->name); iw.text.addReplacement(h->getNameTranslated());
for(auto & elem : artifacts) for(auto & elem : artifacts)
{ {
iw.components.push_back(Component(Component::ARTIFACT,elem,0,0)); iw.components.push_back(Component(Component::ARTIFACT,elem,0,0));
@ -258,7 +258,7 @@ void CGPandoraBox::giveContentsAfterExp(const CGHeroInstance *h) const
cb->showInfoDialog(&iw); cb->showInfoDialog(&iw);
iw.components.clear(); iw.components.clear();
iw.text.addTxt(MetaString::ADVOB_TXT, 183); //% has found treasure - once more? 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()) if(iw.components.size())
@ -290,7 +290,7 @@ void CGPandoraBox::giveContentsAfterExp(const CGHeroInstance *h) const
iw.text.addTxt(MetaString::ADVOB_TXT, 186); iw.text.addTxt(MetaString::ADVOB_TXT, 186);
iw.text.addReplacement(loot.buildList()); iw.text.addReplacement(loot.buildList());
iw.text.addReplacement(h->name); iw.text.addReplacement(h->getNameTranslated());
cb->showInfoDialog(&iw); cb->showInfoDialog(&iw);
cb->giveCreatures(this, h, creatures, false); 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()) if(afterBattle || !message.size())
{ {
iw.text.addTxt(MetaString::ADVOB_TXT,text);//%s has lost treasure. iw.text.addTxt(MetaString::ADVOB_TXT,text);//%s has lost treasure.
iw.text.addReplacement(h->name); iw.text.addReplacement(h->getNameTranslated());
} }
else else
{ {
@ -323,7 +323,7 @@ void CGPandoraBox::getText( InfoWindow &iw, bool &afterBattle, int val, int nega
if(afterBattle || !message.size()) 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.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 else
{ {

View File

@ -720,7 +720,7 @@ void CGTownInstance::onHeroVisit(const CGHeroInstance * h) const
} }
else 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) if(visitingHero == h)
{ {
cb->stopHeroVisitCastle(this, 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 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 std::string CGTownInstance::getObjectName() const
@ -1451,7 +1451,7 @@ void CGTownInstance::addHeroToStructureVisitors(const CGHeroInstance *h, si64 st
else else
{ {
//should never ever happen //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"); throw std::runtime_error("internal error");
} }
} }

View File

@ -494,7 +494,7 @@ void IBoatGenerator::getProblemText(MetaString &out, const CGHeroInstance *visit
if(visitor) if(visitor)
{ {
out.addTxt(MetaString::GENERAL_TXT, 134); out.addTxt(MetaString::GENERAL_TXT, 134);
out.addReplacement(visitor->name); out.addReplacement(visitor->getNameTranslated());
} }
else else
out.addTxt(MetaString::ADVOB_TXT, 189); out.addTxt(MetaString::ADVOB_TXT, 189);

View File

@ -170,7 +170,7 @@ bool CQuest::checkQuest(const CGHeroInstance * h) const
} }
return true; return true;
case MISSION_HERO: case MISSION_HERO:
if(m13489val == h->type->ID.getNum()) if(m13489val == h->type->getIndex())
return true; return true;
return false; return false;
case MISSION_PLAYER: case MISSION_PLAYER:
@ -230,7 +230,7 @@ void CQuest::getVisitText(MetaString &iwText, std::vector<Component> &components
//FIXME: portrait may not match hero, if custom portrait was set in map editor //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)); components.push_back(Component(Component::HERO_PORTRAIT, VLC->heroh->objects[m13489val]->imageIndex, 0, 0));
if(!isCustom) if(!isCustom)
iwText.addReplacement(VLC->heroh->objects[m13489val]->name); iwText.addReplacement(VLC->heroh->objects[m13489val]->getNameTextID());
break; break;
case MISSION_KILL_CREATURE: case MISSION_KILL_CREATURE:
{ {
@ -369,7 +369,7 @@ void CQuest::getRolloverText(MetaString &ms, bool onHover) const
} }
break; break;
case MISSION_HERO: case MISSION_HERO:
ms.addReplacement(VLC->heroh->objects[m13489val]->name); ms.addReplacement(VLC->heroh->objects[m13489val]->getNameTextID());
break; break;
case MISSION_PLAYER: case MISSION_PLAYER:
ms.addReplacement(VLC->generaltexth->colors[m13489val]); ms.addReplacement(VLC->generaltexth->colors[m13489val]);
@ -452,7 +452,7 @@ void CQuest::getCompletionText(MetaString &iwText, std::vector<Component> &compo
break; break;
case MISSION_HERO: case MISSION_HERO:
if (!isCustomComplete) if (!isCustomComplete)
iwText.addReplacement(VLC->heroh->objects[m13489val]->name); iwText.addReplacement(VLC->heroh->objects[m13489val]->getNameTextID());
break; break;
case MISSION_PLAYER: case MISSION_PLAYER:
if (!isCustomComplete) if (!isCustomComplete)
@ -567,7 +567,7 @@ void CGSeerHut::setObjToKill()
} }
else if(quest->missionType == CQuest::MISSION_KILL_HERO) else if(quest->missionType == CQuest::MISSION_KILL_HERO)
{ {
quest->heroName = getHeroToKill(false)->name; quest->heroName = getHeroToKill(false)->getNameTranslated();
quest->heroPortrait = getHeroToKill(false)->portrait; quest->heroPortrait = getHeroToKill(false)->portrait;
} }
} }

View File

@ -123,7 +123,7 @@ bool CHeroInstanceConstructor::objectFilter(const CGObjectInstance * object, std
auto heroTest = [&](const HeroTypeID & id) auto heroTest = [&](const HeroTypeID & id)
{ {
return hero->type->ID == id; return hero->type->getId() == id;
}; };
if(filters.count(templ->stringID)) if(filters.count(templ->stringID))

View File

@ -596,7 +596,7 @@ void CGCreature::giveReward(const CGHeroInstance * h) const
if(iw.components.size()) if(iw.components.size())
{ {
iw.text.addTxt(MetaString::ADVOB_TXT, 183); // % has found treasure iw.text.addTxt(MetaString::ADVOB_TXT, 183); // % has found treasure
iw.text.addReplacement(h->name); iw.text.addReplacement(h->getNameTranslated());
cb->showInfoDialog(&iw); cb->showInfoDialog(&iw);
} }
} }
@ -1347,7 +1347,7 @@ void CGArtifact::onHeroVisit(const CGHeroInstance * h) const
else //fix for mod artifacts with no event text else //fix for mod artifacts with no event text
{ {
iw.text.addTxt(MetaString::ADVOB_TXT, 183); //% has found treasure iw.text.addTxt(MetaString::ADVOB_TXT, 183); //% has found treasure
iw.text.addReplacement(h->name); iw.text.addReplacement(h->getNameTranslated());
} }
} }
} }

View File

@ -568,7 +568,7 @@ void CMap::checkForObjectives()
boost::algorithm::replace_first(event.onFulfill, "%s", town->name); boost::algorithm::replace_first(event.onFulfill, "%s", town->name);
const CGHeroInstance *hero = dynamic_cast<const CGHeroInstance*>(cond.object); const CGHeroInstance *hero = dynamic_cast<const CGHeroInstance*>(cond.object);
if (hero) if (hero)
boost::algorithm::replace_first(event.onFulfill, "%s", hero->name); boost::algorithm::replace_first(event.onFulfill, "%s", hero->getNameTranslated());
} }
break; break;
@ -580,7 +580,7 @@ void CMap::checkForObjectives()
{ {
const CGHeroInstance *hero = dynamic_cast<const CGHeroInstance*>(cond.object); const CGHeroInstance *hero = dynamic_cast<const CGHeroInstance*>(cond.object);
if (hero) if (hero)
boost::algorithm::replace_first(event.onFulfill, "%s", hero->name); boost::algorithm::replace_first(event.onFulfill, "%s", hero->getNameTranslated());
} }
break; break;
case EventCondition::TRANSPORT: case EventCondition::TRANSPORT:

View File

@ -787,7 +787,7 @@ void CMapLoaderH3M::readPredefinedHeroes()
bool hasCustomBio = reader.readBool(); bool hasCustomBio = reader.readBool();
if(hasCustomBio) if(hasCustomBio)
{ {
hero->biography = reader.readString(); hero->biographyCustom = reader.readString();
} }
// 0xFF is default, 00 male, 01 female // 0xFF is default, 00 male, 01 female
@ -825,7 +825,7 @@ void CMapLoaderH3M::loadArtifactsOfHero(CGHeroInstance * hero)
{ {
if(hero->artifactsWorn.size() || hero->artifactsInBackpack.size()) 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(); hero->artifactsInBackpack.clear();
while(hero->artifactsWorn.size()) while(hero->artifactsWorn.size())
hero->eraseArtSlot(hero->artifactsWorn.begin()->first); hero->eraseArtSlot(hero->artifactsWorn.begin()->first);
@ -1436,7 +1436,7 @@ void CMapLoaderH3M::readObjects()
} }
else 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; hp->power = 0;
} }
@ -1592,7 +1592,7 @@ CGObjectInstance * CMapLoaderH3M::readHero(ObjectInstanceID idToBeGiven, const i
{ {
if(elem.heroId == nhi->subID) if(elem.heroId == nhi->subID)
{ {
nhi->name = elem.name; nhi->nameCustom = elem.name;
nhi->portrait = elem.portrait; nhi->portrait = elem.portrait;
break; break;
} }
@ -1601,7 +1601,7 @@ CGObjectInstance * CMapLoaderH3M::readHero(ObjectInstanceID idToBeGiven, const i
bool hasName = reader.readBool(); bool hasName = reader.readBool();
if(hasName) if(hasName)
{ {
nhi->name = reader.readString(); nhi->nameCustom = reader.readString();
} }
if(map->version > EMapFormat::AB) if(map->version > EMapFormat::AB)
{ {
@ -1666,7 +1666,7 @@ CGObjectInstance * CMapLoaderH3M::readHero(ObjectInstanceID idToBeGiven, const i
bool hasCustomBiography = reader.readBool(); bool hasCustomBiography = reader.readBool();
if(hasCustomBiography) if(hasCustomBiography)
{ {
nhi->biography = reader.readString(); nhi->biographyCustom = reader.readString();
} }
nhi->sex = reader.readUInt8(); nhi->sex = reader.readUInt8();
@ -1688,7 +1688,7 @@ CGObjectInstance * CMapLoaderH3M::readHero(ObjectInstanceID idToBeGiven, const i
if(nhi->spells.size()) if(nhi->spells.size())
{ {
nhi->clear(); 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) if(hasCustomSpells)
@ -1721,7 +1721,7 @@ CGObjectInstance * CMapLoaderH3M::readHero(ObjectInstanceID idToBeGiven, const i
.And(Selector::sourceType()(Bonus::HERO_BASE_SKILL)), nullptr); .And(Selector::sourceType()(Bonus::HERO_BASE_SKILL)), nullptr);
if(ps->size()) 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) for(auto b : *ps)
nhi->removeBonus(b); nhi->removeBonus(b);
} }

View File

@ -524,18 +524,18 @@ void CMapFormatJson::serializePlayerInfo(JsonSerializeFormat & handler)
if(hero) if(hero)
{ {
auto heroData = handler.enterStruct(hero->instanceName); auto heroData = handler.enterStruct(hero->instanceName);
heroData->serializeString("name", hero->name); heroData->serializeString("name", hero->nameCustom);
if(hero->ID == Obj::HERO) if(hero->ID == Obj::HERO)
{ {
std::string temp; std::string temp;
if(hero->type) if(hero->type)
{ {
temp = hero->type->identifier; temp = hero->type->getJsonKey();
} }
else else
{ {
temp = VLC->heroh->objects[hero->subID]->identifier; temp = VLC->heroh->objects[hero->subID]->getJsonKey();
} }
handler.serializeString("type", temp); handler.serializeString("type", temp);
} }

View File

@ -34,9 +34,9 @@ void CSerializer::addStdVecItems(CGameState *gs, LibClasses *lib)
registerVectoredType<CGObjectInstance, ObjectInstanceID>(&gs->map->objects, registerVectoredType<CGObjectInstance, ObjectInstanceID>(&gs->map->objects,
[](const CGObjectInstance &obj){ return obj.id; }); [](const CGObjectInstance &obj){ return obj.id; });
registerVectoredType<CHero, HeroTypeID>(&lib->heroh->objects, registerVectoredType<CHero, HeroTypeID>(&lib->heroh->objects,
[](const CHero &h){ return h.ID; }); [](const CHero &h){ return h.getId(); });
registerVectoredType<CGHeroInstance, HeroTypeID>(&gs->map->allHeroes, registerVectoredType<CGHeroInstance, HeroTypeID>(&gs->map->allHeroes,
[](const CGHeroInstance &h){ return h.type->ID; }); [](const CGHeroInstance &h){ return h.type->getId(); });
registerVectoredType<CCreature, CreatureID>(&lib->creh->objects, registerVectoredType<CCreature, CreatureID>(&lib->creh->objects,
[](const CCreature &cre){ return cre.idNumber; }); [](const CCreature &cre){ return cre.idNumber; });
registerVectoredType<CArtifact, ArtifactID>(&lib->arth->objects, registerVectoredType<CArtifact, ArtifactID>(&lib->arth->objects,

View File

@ -147,7 +147,7 @@ ESpellCastResult SummonBoatMechanics::applyAdventureEffects(SpellCastEnvironment
InfoWindow iw; InfoWindow iw;
iw.player = parameters.caster->tempOwner; iw.player = parameters.caster->tempOwner;
iw.text.addTxt(MetaString::GENERAL_TXT, 333);//%s is already in boat 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); env->apply(&iw);
return ESpellCastResult::CANCEL; return ESpellCastResult::CANCEL;
} }
@ -170,7 +170,7 @@ ESpellCastResult SummonBoatMechanics::applyAdventureEffects(SpellCastEnvironment
InfoWindow iw; InfoWindow iw;
iw.player = parameters.caster->tempOwner; iw.player = parameters.caster->tempOwner;
iw.text.addTxt(MetaString::GENERAL_TXT, 336); //%s tried to summon a boat, but failed. 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); env->apply(&iw);
return ESpellCastResult::OK; return ESpellCastResult::OK;
} }
@ -236,7 +236,7 @@ ESpellCastResult ScuttleBoatMechanics::applyAdventureEffects(SpellCastEnvironmen
InfoWindow iw; InfoWindow iw;
iw.player = parameters.caster->tempOwner; iw.player = parameters.caster->tempOwner;
iw.text.addTxt(MetaString::GENERAL_TXT, 337); //%s tried to scuttle the boat, but failed 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); env->apply(&iw);
return ESpellCastResult::OK; return ESpellCastResult::OK;
} }
@ -307,7 +307,7 @@ ESpellCastResult DimensionDoorMechanics::applyAdventureEffects(SpellCastEnvironm
InfoWindow iw; InfoWindow iw;
iw.player = parameters.caster->tempOwner; 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.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); env->apply(&iw);
return ESpellCastResult::CANCEL; return ESpellCastResult::CANCEL;
} }

View File

@ -80,7 +80,7 @@ bool Summon::applicable(Problem & problem, const Mechanics * m) const
auto caster = dynamic_cast<const CGHeroInstance *>(m->caster); auto caster = dynamic_cast<const CGHeroInstance *>(m->caster);
if(caster) if(caster)
{ {
text.addReplacement(caster->name); text.addReplacement(caster->getNameTranslated());
text.addReplacement(MetaString::CRE_PL_NAMES, elemental->creatureIndex()); text.addReplacement(MetaString::CRE_PL_NAMES, elemental->creatureIndex());

View File

@ -131,9 +131,7 @@ void Initializer::initialize(CGHeroInstance * o)
if(!o->type) if(!o->type)
o->type = VLC->heroh->objects.at(o->subID); o->type = VLC->heroh->objects.at(o->subID);
o->name = o->type->getName();
o->sex = o->type->sex; o->sex = o->type->sex;
o->biography = o->type->biography;
o->portrait = o->type->imageIndex; o->portrait = o->type->imageIndex;
o->randomizeArmy(o->type->heroClass->faction); 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("Owner", o->tempOwner, o->ID == Obj::PRISON); //field is not editable for prison
addProperty<int>("Experience", o->exp, false); addProperty<int>("Experience", o->exp, false);
addProperty("Hero class", o->type->heroClass->getName(), true); addProperty("Hero class", o->type->heroClass->getNameTranslated(), true);
{ //Sex { //Sex
auto * delegate = new InspectorDelegate; auto * delegate = new InspectorDelegate;
delegate->options << "MALE" << "FEMALE"; delegate->options << "MALE" << "FEMALE";
addProperty<std::string>("Sex", (o->sex ? "FEMALE" : "MALE"), delegate , false); addProperty<std::string>("Sex", (o->sex ? "FEMALE" : "MALE"), delegate , false);
} }
addProperty("Name", o->name, false); addProperty("Name", o->nameCustom, false);
addProperty("Biography", o->biography, new MessageDelegate, false); addProperty("Biography", o->biographyCustom, new MessageDelegate, false);
addProperty("Portrait", o->portrait, false); addProperty("Portrait", o->portrait, false);
{ //Hero type { //Hero type
@ -255,10 +253,10 @@ void Inspector::updateProperties(CGHeroInstance * o)
if(map->allowedHeroes.at(i)) if(map->allowedHeroes.at(i))
{ {
if(o->ID == Obj::PRISON || (o->type && VLC->heroh->objects[i]->heroClass->getIndex() == o->type->heroClass->getIndex())) 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; o->sex = value.toString() == "MALE" ? 0 : 1;
if(key == "Name") if(key == "Name")
o->name = value.toString().toStdString(); o->nameCustom = value.toString().toStdString();
if(key == "Experience") if(key == "Experience")
o->exp = value.toInt(); o->exp = value.toInt();
@ -563,12 +561,10 @@ void Inspector::setProperty(CGHeroInstance * o, const QString & key, const QVari
{ {
for(auto t : VLC->heroh->objects) for(auto t : VLC->heroh->objects)
{ {
if(t->getName() == value.toString().toStdString()) if(t->getNameTranslated() == value.toString().toStdString())
o->type = t.get(); o->type = t.get();
} }
o->name = o->type->getName();
o->sex = o->type->sex; o->sex = o->type->sex;
o->biography = o->type->biography;
o->portrait = o->type->imageIndex; o->portrait = o->type->imageIndex;
o->randomizeArmy(o->type->heroClass->faction); o->randomizeArmy(o->type->heroClass->faction);
updateProperties(); //updating other properties after change updateProperties(); //updating other properties after change

View File

@ -95,7 +95,7 @@ void QuestWidget::obtainData()
case CQuest::Emission::MISSION_HERO: case CQuest::Emission::MISSION_HERO:
activeId = true; activeId = true;
for(int i = 0; i < map.allowedHeroes.size(); ++i) 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); ui->targetId->setCurrentIndex(seerhut.quest->m13489val);
break; break;
case CQuest::Emission::MISSION_PLAYER: case CQuest::Emission::MISSION_PLAYER:

View File

@ -131,7 +131,7 @@ void MapController::repairMap()
if(obj->ID == Obj::HERO) if(obj->ID == Obj::HERO)
{ {
nih->typeName = "hero"; nih->typeName = "hero";
nih->subTypeName = type->heroClass->identifier; nih->subTypeName = type->heroClass->getJsonKey();
} }
if(obj->ID == Obj::PRISON) if(obj->ID == Obj::PRISON)
{ {
@ -140,10 +140,6 @@ void MapController::repairMap()
} }
nih->type = type; 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 if(nih->ID == Obj::HERO) //not prison
nih->appearance = VLC->objtypeh->getHandlerFor(Obj::HERO, type->heroClass->getIndex())->getTemplates().front(); nih->appearance = VLC->objtypeh->getHandlerFor(Obj::HERO, type->heroClass->getIndex())->getTemplates().front();

View File

@ -58,7 +58,7 @@ MapSettings::MapSettings(MapController & ctrl, QWidget *parent) :
} }
for(int i = 0; i < controller.map()->allowedHeroes.size(); ++i) 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->setData(Qt::UserRole, QVariant::fromValue(i));
item->setFlags(item->flags() | Qt::ItemIsUserCheckable); item->setFlags(item->flags() | Qt::ItemIsUserCheckable);
item->setCheckState(controller.map()->allowedHeroes[i] ? Qt::Checked : Qt::Unchecked); item->setCheckState(controller.map()->allowedHeroes[i] ? Qt::Checked : Qt::Unchecked);

View File

@ -119,7 +119,7 @@ std::list<Validator::Issue> Validator::validate(const CMap * map)
if(ins->type) if(ins->type)
{ {
if(!map->allowedHeroes[ins->type->getId().getNum()]) 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 else
issues.emplace_back(QString("Hero %1 has an empty type and must be removed").arg(ins->instanceName.c_str()), true); issues.emplace_back(QString("Hero %1 has an empty type and must be removed").arg(ins->instanceName.c_str()), true);

View File

@ -423,7 +423,7 @@ void CGameHandler::levelUpHero(const CGHeroInstance * hero)
} }
// give primary skill // 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()); auto primarySkill = hero->nextPrimarySkill(getRandomGenerator());
SetPrimSkill sps; SetPrimSkill sps;
@ -633,7 +633,7 @@ void CGameHandler::changePrimSkill(const CGHeroInstance * hero, PrimarySkill::Pr
InfoWindow iw; InfoWindow iw;
iw.player = hero->tempOwner; iw.player = hero->tempOwner;
iw.text.addTxt(MetaString::GENERAL_TXT, 1); //can gain no more XP iw.text.addTxt(MetaString::GENERAL_TXT, 1); //can gain no more XP
iw.text.addReplacement(hero->name); iw.text.addReplacement(hero->getNameTextID());
sendAndApply(&iw); sendAndApply(&iw);
} }
} }
@ -856,7 +856,7 @@ void CGameHandler::endBattle(int3 tile, const CGHeroInstance * heroAttacker, con
InfoWindow iw; InfoWindow iw;
iw.player = finishingBattle->winnerHero->tempOwner; iw.player = finishingBattle->winnerHero->tempOwner;
iw.text.addTxt(MetaString::GENERAL_TXT, 221); //Through eagle-eyed observation, %s is able to learn %s 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; std::ostringstream names;
for (int i = 0; i < cs.spells.size(); i++) 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, auto doMove = [&](TryMoveHero::EResult result, EGuardLook lookForGuards,
EVisitDest visitDest, ELEaveTile leavingTile) -> bool 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<CHeroMovementQuery>(this, tmh, h); auto moveQuery = std::make_shared<CHeroMovementQuery>(this, tmh, h);
queries.addQuery(moveQuery); queries.addQuery(moveQuery);
@ -2422,7 +2422,7 @@ bool CGameHandler::moveHero(ObjectInstanceID hid, int3 dst, ui8 teleporting, boo
} }
queries.popIfTop(moveQuery); queries.popIfTop(moveQuery);
logGlobal->trace("Hero %s ends movement", h->name); logGlobal->trace("Hero %s ends movement", h->getNameTranslated());
return result != TryMoveHero::FAILED; 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.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.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 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.addTxt(MetaString::GENERAL_TXT, 142);//from %s
iw.text.addReplacement(h2->name); iw.text.addReplacement(h2->getNameTextID());
sendAndApply(&cs2); sendAndApply(&cs2);
} }
@ -2864,7 +2864,7 @@ void CGameHandler::useScholarSkill(ObjectInstanceID fromHero, ObjectInstanceID t
default: iw.text << ", "; default: iw.text << ", ";
} } } }
iw.text.addTxt(MetaString::GENERAL_TXT, 148);//from %s iw.text.addTxt(MetaString::GENERAL_TXT, 148);//from %s
iw.text.addReplacement(h2->name); iw.text.addReplacement(h2->getNameTextID());
sendAndApply(&cs1); sendAndApply(&cs1);
} }
sendAndApply(&iw); sendAndApply(&iw);

View File

@ -486,7 +486,7 @@ void CHeroMovementQuery::onExposure(QueryPtr topQuery)
if(visitDestAfterVictory && hero->tempOwner == players[0]) //hero still alive, so he won with the guard 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 //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 //finish movement
visitDestAfterVictory = false; visitDestAfterVictory = false;
gh->visitObjectOnTile(*gh->getTile(hero->convertToVisitablePos(tmh.end)), hero); gh->visitObjectOnTile(*gh->getTile(hero->convertToVisitablePos(tmh.end)), hero);